From 495c8b9dd98f2406581737f474ff339da4161d1a Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 30 Sep 2025 16:15:59 -0400 Subject: [PATCH] rubocop -a --- .rubocop_todo.yml | 1513 +++++++++-------- Gemfile | 14 +- Rakefile | 274 +-- lib/solargraph.rb | 14 +- lib/solargraph/api_map.rb | 88 +- lib/solargraph/api_map/index.rb | 4 +- lib/solargraph/api_map/source_to_yard.rb | 15 +- lib/solargraph/api_map/store.rb | 40 +- lib/solargraph/bench.rb | 1 - lib/solargraph/complex_type.rb | 57 +- lib/solargraph/complex_type/type_methods.rb | 18 +- lib/solargraph/complex_type/unique_type.rb | 72 +- lib/solargraph/convention.rb | 4 +- lib/solargraph/convention/data_definition.rb | 2 +- .../data_definition/data_assignment_node.rb | 2 +- .../data_definition/data_definition_node.rb | 6 +- .../convention/struct_definition.rb | 6 +- .../struct_assignment_node.rb | 2 +- .../struct_definition_node.rb | 6 +- lib/solargraph/diagnostics/rubocop.rb | 18 +- lib/solargraph/diagnostics/rubocop_helpers.rb | 4 +- lib/solargraph/diagnostics/type_check.rb | 20 +- lib/solargraph/diagnostics/update_errors.rb | 2 +- lib/solargraph/doc_map.rb | 48 +- lib/solargraph/equality.rb | 6 +- lib/solargraph/gem_pins.rb | 14 +- lib/solargraph/language_server/error_codes.rb | 20 +- lib/solargraph/language_server/host.rb | 33 +- .../language_server/host/diagnoser.rb | 2 +- .../language_server/host/dispatch.rb | 3 +- .../language_server/host/message_worker.rb | 4 +- .../language_server/host/sources.rb | 2 +- .../message/client/register_capability.rb | 4 +- .../message/completion_item/resolve.rb | 12 +- .../message/extended/check_gem_version.rb | 21 +- .../message/extended/document_gems.rb | 14 +- .../message/extended/download_core.rb | 3 +- .../message/extended/search.rb | 2 +- .../language_server/message/initialize.rb | 34 +- .../message/text_document/completion.rb | 19 +- .../message/text_document/definition.rb | 3 +- .../text_document/document_highlight.rb | 3 +- .../message/text_document/formatting.rb | 12 +- .../message/text_document/hover.rb | 8 +- .../message/text_document/prepare_rename.rb | 3 +- .../message/text_document/references.rb | 3 +- .../message/text_document/rename.rb | 9 +- .../message/text_document/signature_help.rb | 4 +- .../workspace/did_change_watched_files.rb | 7 +- .../workspace/did_change_workspace_folders.rb | 2 +- .../language_server/transport/data_reader.rb | 24 +- lib/solargraph/language_server/uri_helpers.rb | 4 +- lib/solargraph/library.rb | 49 +- lib/solargraph/location.rb | 6 +- lib/solargraph/logging.rb | 2 +- lib/solargraph/parser/comment_ripper.rb | 14 +- .../parser/flow_sensitive_typing.rb | 62 +- lib/solargraph/parser/node_methods.rb | 8 +- lib/solargraph/parser/node_processor.rb | 2 +- lib/solargraph/parser/node_processor/base.rb | 4 +- .../parser/parser_gem/class_methods.rb | 8 +- .../parser/parser_gem/flawed_builder.rb | 2 +- .../parser/parser_gem/node_chainer.rb | 36 +- .../parser/parser_gem/node_methods.rb | 101 +- .../parser_gem/node_processors/and_node.rb | 4 +- .../parser_gem/node_processors/args_node.rb | 22 +- .../parser_gem/node_processors/block_node.rb | 20 +- .../parser_gem/node_processors/def_node.rb | 6 +- .../parser_gem/node_processors/defs_node.rb | 16 +- .../parser_gem/node_processors/if_node.rb | 4 +- .../parser_gem/node_processors/ivasgn_node.rb | 3 +- .../parser_gem/node_processors/opasgn_node.rb | 2 +- .../parser_gem/node_processors/sclass_node.rb | 6 +- .../parser_gem/node_processors/send_node.rb | 216 +-- .../parser_gem/node_processors/until_node.rb | 2 +- .../parser_gem/node_processors/while_node.rb | 2 +- lib/solargraph/pin/base.rb | 101 +- lib/solargraph/pin/base_variable.rb | 13 +- lib/solargraph/pin/block.rb | 5 +- lib/solargraph/pin/callable.rb | 41 +- lib/solargraph/pin/closure.rb | 7 +- lib/solargraph/pin/common.rb | 5 +- lib/solargraph/pin/constant.rb | 6 +- lib/solargraph/pin/conversions.rb | 10 +- lib/solargraph/pin/delegated_method.rb | 6 +- lib/solargraph/pin/documenting.rb | 5 +- lib/solargraph/pin/keyword.rb | 4 +- lib/solargraph/pin/local_variable.rb | 6 +- lib/solargraph/pin/method.rb | 107 +- lib/solargraph/pin/namespace.rb | 21 +- lib/solargraph/pin/parameter.rb | 40 +- lib/solargraph/pin/proxy_type.rb | 2 + lib/solargraph/pin/reference.rb | 1 + lib/solargraph/pin/search.rb | 2 +- lib/solargraph/pin/signature.rb | 11 +- lib/solargraph/pin/symbol.rb | 1 + lib/solargraph/pin_cache.rb | 33 +- lib/solargraph/position.rb | 2 +- lib/solargraph/range.rb | 9 +- lib/solargraph/rbs_map.rb | 20 +- lib/solargraph/rbs_map/conversions.rb | 131 +- lib/solargraph/rbs_map/core_fills.rb | 23 +- lib/solargraph/server_methods.rb | 2 +- lib/solargraph/shell.rb | 80 +- lib/solargraph/source.rb | 51 +- lib/solargraph/source/chain.rb | 28 +- lib/solargraph/source/chain/call.rb | 81 +- lib/solargraph/source/chain/class_variable.rb | 2 +- .../source/chain/global_variable.rb | 2 +- lib/solargraph/source/chain/if.rb | 3 +- .../source/chain/instance_variable.rb | 4 +- lib/solargraph/source/chain/link.rb | 4 +- lib/solargraph/source/chain/literal.rb | 2 +- lib/solargraph/source/chain/variable.rb | 4 +- lib/solargraph/source/chain/z_super.rb | 2 +- lib/solargraph/source/change.rb | 6 +- lib/solargraph/source/cursor.rb | 30 +- lib/solargraph/source/encoding_fixes.rb | 45 +- lib/solargraph/source/source_chainer.rb | 51 +- lib/solargraph/source_map.rb | 10 +- lib/solargraph/source_map/clip.rb | 64 +- lib/solargraph/source_map/mapper.rb | 84 +- lib/solargraph/type_checker.rb | 162 +- lib/solargraph/type_checker/checks.rb | 11 +- lib/solargraph/type_checker/rules.rb | 10 +- lib/solargraph/workspace.rb | 42 +- lib/solargraph/workspace/config.rb | 17 +- lib/solargraph/yard_map/helpers.rb | 6 +- lib/solargraph/yard_map/mapper.rb | 8 +- lib/solargraph/yard_map/mapper/to_method.rb | 12 +- .../yard_map/mapper/to_namespace.rb | 2 +- lib/solargraph/yard_tags.rb | 4 +- lib/solargraph/yardoc.rb | 8 +- solargraph.gemspec | 147 +- spec/api_map/cache_spec.rb | 2 +- spec/api_map/config_spec.rb | 46 +- spec/api_map/source_to_yard_spec.rb | 26 +- spec/api_map_spec.rb | 2 +- spec/complex_type_spec.rb | 39 +- spec/convention/struct_definition_spec.rb | 18 +- spec/diagnostics/base_spec.rb | 2 +- spec/diagnostics/require_not_found_spec.rb | 4 +- spec/diagnostics/rubocop_helpers_spec.rb | 10 +- spec/diagnostics/rubocop_spec.rb | 14 +- spec/diagnostics/type_check_spec.rb | 14 +- spec/diagnostics/update_errors_spec.rb | 12 +- spec/diagnostics_spec.rb | 2 +- spec/doc_map_spec.rb | 4 +- spec/language_server/host/diagnoser_spec.rb | 2 +- spec/language_server/host/dispatch_spec.rb | 8 +- .../host/message_worker_spec.rb | 4 +- spec/language_server/host_spec.rb | 136 +- .../message/completion_item/resolve_spec.rb | 15 +- .../extended/check_gem_version_spec.rb | 35 +- .../message/initialize_spec.rb | 116 +- .../message/text_document/definition_spec.rb | 45 +- .../message/text_document/formatting_spec.rb | 2 +- .../message/text_document/hover_spec.rb | 40 +- .../message/text_document/rename_spec.rb | 112 +- .../text_document/type_definition_spec.rb | 20 +- .../did_change_watched_files_spec.rb | 84 +- spec/language_server/message_spec.rb | 4 +- spec/language_server/protocol_spec.rb | 107 +- .../language_server/transport/adapter_spec.rb | 12 +- .../transport/data_reader_spec.rb | 8 +- spec/library_spec.rb | 72 +- spec/logging_spec.rb | 4 +- spec/parser/node_chainer_spec.rb | 22 +- spec/parser/node_methods_spec.rb | 90 +- spec/parser/node_processor_spec.rb | 4 +- spec/parser_spec.rb | 2 +- spec/pin/base_spec.rb | 16 +- spec/pin/base_variable_spec.rb | 2 +- spec/pin/constant_spec.rb | 8 +- spec/pin/documenting_spec.rb | 4 +- spec/pin/instance_variable_spec.rb | 6 +- spec/pin/keyword_spec.rb | 2 +- spec/pin/local_variable_spec.rb | 5 +- spec/pin/method_spec.rb | 12 +- spec/pin/namespace_spec.rb | 8 +- spec/pin/symbol_spec.rb | 27 +- spec/position_spec.rb | 10 +- spec/rbs_map/conversions_spec.rb | 26 +- spec/rbs_map/core_map_spec.rb | 18 +- spec/rbs_map/stdlib_map_spec.rb | 2 +- spec/shell_spec.rb | 18 +- spec/source/chain/array_spec.rb | 2 +- spec/source/chain/call_spec.rb | 18 +- spec/source/chain/class_variable_spec.rb | 4 +- spec/source/chain/constant_spec.rb | 2 +- spec/source/chain/global_variable_spec.rb | 2 +- spec/source/chain/head_spec.rb | 2 +- spec/source/chain/instance_variable_spec.rb | 2 +- spec/source/chain/link_spec.rb | 10 +- spec/source/chain/literal_spec.rb | 2 +- spec/source/chain/z_super_spec.rb | 2 +- spec/source/chain_spec.rb | 49 +- spec/source/change_spec.rb | 18 +- spec/source/cursor_spec.rb | 48 +- spec/source/source_chainer_spec.rb | 134 +- spec/source/updater_spec.rb | 6 +- spec/source_map/clip_spec.rb | 8 +- spec/source_map/mapper_spec.rb | 340 ++-- spec/source_map_spec.rb | 18 +- spec/source_spec.rb | 68 +- spec/spec_helper.rb | 10 +- spec/type_checker/levels/normal_spec.rb | 2 +- spec/type_checker/levels/strict_spec.rb | 16 +- spec/type_checker/levels/strong_spec.rb | 2 +- spec/type_checker/levels/typed_spec.rb | 2 +- spec/type_checker_spec.rb | 6 +- spec/workspace/config_spec.rb | 17 +- spec/workspace_spec.rb | 45 +- spec/yard_map/mapper/to_method_spec.rb | 40 +- spec/yard_map/mapper_spec.rb | 2 +- 215 files changed, 3596 insertions(+), 3282 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 83339e756..1691864cd 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,21 +1,15 @@ # This configuration was generated by -# `rubocop --auto-gen-config --exclude-limit 5 --no-offense-counts --no-auto-gen-timestamp` +# `rubocop --auto-gen-config --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp` # using RuboCop version 1.80.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# This cop supports safe autocorrection (--autocorrect). -Gemspec/AddRuntimeDependency: - Exclude: - - 'solargraph.gemspec' - # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: Severity. Gemspec/DeprecatedAttributeAssignment: Exclude: - - 'solargraph.gemspec' - 'spec/fixtures/rdoc-lib/rdoc-lib.gemspec' # Configuration parameters: EnforcedStyle, AllowedGems. @@ -24,17 +18,10 @@ Gemspec/DevelopmentDependencies: Exclude: - 'solargraph.gemspec' -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation. -Gemspec/OrderedDependencies: - Exclude: - - 'solargraph.gemspec' - # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: Severity. Gemspec/RequireMFA: Exclude: - - 'solargraph.gemspec' - 'spec/fixtures/rdoc-lib/rdoc-lib.gemspec' - 'spec/fixtures/rubocop-custom-version/specifications/rubocop-0.0.0.gemspec' @@ -45,255 +32,18 @@ Gemspec/RequiredRubyVersion: - 'spec/fixtures/rubocop-custom-version/specifications/rubocop-0.0.0.gemspec' - 'spec/fixtures/vendored/vendor/do_not_use.gemspec' -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: with_first_argument, with_fixed_indentation -Layout/ArgumentAlignment: - Exclude: - - 'lib/solargraph/pin/callable.rb' - - 'spec/source/source_chainer_spec.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyleAlignWith. -# SupportedStylesAlignWith: either, start_of_block, start_of_line -Layout/BlockAlignment: - Exclude: - - 'spec/source_map/mapper_spec.rb' - -# This cop supports safe autocorrection (--autocorrect). -Layout/ClosingHeredocIndentation: - Exclude: - - 'spec/diagnostics/rubocop_spec.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowForAlignment. -Layout/CommentIndentation: +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: RequireParenthesesForMethodChains. +Lint/AmbiguousRange: Exclude: - - 'lib/solargraph/language_server/host.rb' + - 'lib/solargraph/library.rb' - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/source_map/mapper.rb' - -# This cop supports safe autocorrection (--autocorrect). -Layout/ElseAlignment: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EmptyLineBetweenMethodDefs, EmptyLineBetweenClassDefs, EmptyLineBetweenModuleDefs, DefLikeMacros, AllowAdjacentOneLineDefs, NumberOfEmptyLines. -Layout/EmptyLineBetweenDefs: - Exclude: - - 'lib/solargraph/doc_map.rb' - - 'lib/solargraph/language_server/message/initialize.rb' - - 'lib/solargraph/pin/delegated_method.rb' - -# This cop supports safe autocorrection (--autocorrect). -Layout/EmptyLines: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines -Layout/EmptyLinesAroundModuleBody: - Exclude: - - 'lib/solargraph/api_map/source_to_yard.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyleAlignWith, Severity. -# SupportedStylesAlignWith: keyword, variable, start_of_line -Layout/EndAlignment: - Enabled: false - -# Configuration parameters: EnforcedStyle. -# SupportedStyles: native, lf, crlf -Layout/EndOfLine: - Exclude: - - 'Gemfile' - - 'Rakefile' - - 'lib/solargraph/source/encoding_fixes.rb' - - 'solargraph.gemspec' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowForAlignment, AllowBeforeTrailingComments, ForceEqualSignAlignment. -Layout/ExtraSpacing: - Exclude: - - 'lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb' - - 'lib/solargraph/pin/closure.rb' - - 'lib/solargraph/rbs_map/conversions.rb' - - 'lib/solargraph/type_checker.rb' - - 'spec/spec_helper.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: consistent, consistent_relative_to_receiver, special_for_inner_method_call, special_for_inner_method_call_in_parentheses -Layout/FirstArgumentIndentation: - Exclude: - - 'lib/solargraph/parser/parser_gem/node_processors/args_node.rb' - - 'spec/source/source_chainer_spec.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: special_inside_parentheses, consistent, align_brackets -Layout/FirstArrayElementIndentation: - Exclude: - 'lib/solargraph/source.rb' - - 'spec/diagnostics/update_errors_spec.rb' - - 'spec/source/cursor_spec.rb' - - 'spec/source/source_chainer_spec.rb' - - 'spec/source_spec.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: special_inside_parentheses, consistent, align_braces -Layout/FirstHashElementIndentation: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle. -# SupportedHashRocketStyles: key, separator, table -# SupportedColonStyles: key, separator, table -# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit -Layout/HashAlignment: - Exclude: - - 'lib/solargraph/workspace/config.rb' - -# This cop supports safe autocorrection (--autocorrect). -Layout/HeredocIndentation: - Exclude: - - 'spec/diagnostics/rubocop_spec.rb' - - 'spec/yard_map/mapper/to_method_spec.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: Width, AllowedPatterns. -Layout/IndentationWidth: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowDoxygenCommentStyle, AllowGemfileRubyComment, AllowRBSInlineAnnotation, AllowSteepAnnotation. -Layout/LeadingCommentSpace: - Exclude: - - 'lib/solargraph/complex_type.rb' - - 'lib/solargraph/rbs_map/conversions.rb' - - 'lib/solargraph/source/chain/call.rb' + - 'lib/solargraph/source/change.rb' + - 'lib/solargraph/source/cursor.rb' + - 'lib/solargraph/source/source_chainer.rb' - 'lib/solargraph/source_map/clip.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: space, no_space -Layout/LineContinuationSpacing: - Exclude: - - 'lib/solargraph/diagnostics/rubocop_helpers.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: symmetrical, new_line, same_line -Layout/MultilineMethodCallBraceLayout: - Exclude: - - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' - - 'spec/source/source_chainer_spec.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: aligned, indented, indented_relative_to_receiver -Layout/MultilineMethodCallIndentation: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: aligned, indented -Layout/MultilineOperationIndentation: - Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/language_server/host/dispatch.rb' - - 'lib/solargraph/source.rb' - -# This cop supports safe autocorrection (--autocorrect). -Layout/SpaceAfterComma: - Exclude: - - 'spec/source/cursor_spec.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: space, no_space -Layout/SpaceAroundEqualsInParameterDefault: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -Layout/SpaceAroundKeyword: - Exclude: - - 'spec/rbs_map/conversions_spec.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowForAlignment, EnforcedStyleForExponentOperator, EnforcedStyleForRationalLiterals. -# SupportedStylesForExponentOperator: space, no_space -# SupportedStylesForRationalLiterals: space, no_space -Layout/SpaceAroundOperators: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. -# SupportedStyles: space, no_space -# SupportedStylesForEmptyBraces: space, no_space -Layout/SpaceBeforeBlockBraces: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -Layout/SpaceBeforeComma: - Exclude: - - 'spec/source/cursor_spec.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters. -# SupportedStyles: space, no_space -# SupportedStylesForEmptyBraces: space, no_space -Layout/SpaceInsideBlockBraces: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. -# SupportedStyles: space, no_space, compact -# SupportedStylesForEmptyBraces: space, no_space -Layout/SpaceInsideHashLiteralBraces: - Exclude: - - 'lib/solargraph/language_server/message/extended/search.rb' - - 'lib/solargraph/language_server/message/initialize.rb' - - 'lib/solargraph/workspace/config.rb' - - 'spec/language_server/host/message_worker_spec.rb' - - 'spec/language_server/message/extended/check_gem_version_spec.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: space, compact, no_space -Layout/SpaceInsideParens: - Exclude: - - 'lib/solargraph/pin/namespace.rb' - - 'lib/solargraph/source_map.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowInHeredoc. -Layout/TrailingWhitespace: - Exclude: - - 'lib/solargraph/language_server/message/client/register_capability.rb' - - 'spec/api_map/config_spec.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowedMethods, AllowedPatterns. -Lint/AmbiguousBlockAssociation: - Exclude: - - 'lib/solargraph/language_server/host.rb' - -# This cop supports safe autocorrection (--autocorrect). -Lint/AmbiguousOperator: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -Lint/AmbiguousOperatorPrecedence: - Exclude: - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/source.rb' - -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: RequireParenthesesForMethodChains. -Lint/AmbiguousRange: - Enabled: false + - 'spec/library_spec.rb' # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: AllowSafeAssignment. @@ -309,7 +59,6 @@ Lint/BinaryOperatorWithIdenticalOperands: Lint/BooleanSymbol: Exclude: - 'lib/solargraph/convention/struct_definition/struct_definition_node.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - 'lib/solargraph/source/chain/literal.rb' # Configuration parameters: AllowedMethods. @@ -327,11 +76,23 @@ Lint/DuplicateBranch: - 'lib/solargraph/rbs_map/conversions.rb' Lint/DuplicateMethods: - Enabled: false + Exclude: + - 'lib/solargraph/complex_type.rb' + - 'lib/solargraph/location.rb' + - 'lib/solargraph/pin/base.rb' + - 'lib/solargraph/pin/signature.rb' + - 'lib/solargraph/rbs_map.rb' + - 'lib/solargraph/source/chain/link.rb' # Configuration parameters: AllowComments. Lint/EmptyClass: - Enabled: false + Exclude: + - 'spec/fixtures/rubocop-validation-error/app.rb' + - 'spec/fixtures/workspace-with-gemfile/lib/other.rb' + - 'spec/fixtures/workspace/lib/other.rb' + - 'spec/fixtures/workspace/lib/something.rb' + - 'spec/fixtures/workspace_folders/folder1/app.rb' + - 'spec/fixtures/workspace_folders/folder2/app.rb' # Configuration parameters: AllowComments. Lint/EmptyFile: @@ -360,19 +121,6 @@ Lint/NonAtomicFileOperation: Exclude: - 'spec/diagnostics/rubocop_spec.rb' -# This cop supports safe autocorrection (--autocorrect). -Lint/ParenthesesAsGroupedExpression: - Exclude: - - 'lib/solargraph.rb' - - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - - 'spec/language_server/host_spec.rb' - - 'spec/source_map/clip_spec.rb' - -# This cop supports safe autocorrection (--autocorrect). -Lint/RedundantRequireStatement: - Exclude: - - 'spec/language_server/protocol_spec.rb' - # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: AllowedMethods, InferNonNilReceiver, AdditionalNilMethods. # AllowedMethods: instance_of?, kind_of?, is_a?, eql?, respond_to?, equal? @@ -382,27 +130,6 @@ Lint/RedundantSafeNavigation: - 'lib/solargraph/api_map/source_to_yard.rb' - 'lib/solargraph/rbs_map.rb' -# This cop supports safe autocorrection (--autocorrect). -Lint/RedundantStringCoercion: - Exclude: - - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - - 'lib/solargraph/pin/conversions.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/pin/namespace.rb' - - 'lib/solargraph/rbs_map/conversions.rb' - -# This cop supports safe autocorrection (--autocorrect). -Lint/RedundantWithIndex: - Exclude: - - 'lib/solargraph/language_server/message/completion_item/resolve.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: strict, consistent -Lint/SymbolConversion: - Exclude: - - 'lib/solargraph/pin/base.rb' - # Configuration parameters: AllowKeywordBlockArguments. Lint/UnderscorePrefixedVariableName: Exclude: @@ -411,36 +138,48 @@ Lint/UnderscorePrefixedVariableName: # Configuration parameters: Methods. Lint/UnexpectedBlockArity: Exclude: - - 'lib/solargraph/language_server/message/completion_item/resolve.rb' - 'lib/solargraph/type_checker.rb' Lint/UnmodifiedReduceAccumulator: Exclude: - 'lib/solargraph/pin/method.rb' -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments. -Lint/UnusedBlockArgument: - Exclude: - - 'lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb' - - 'lib/solargraph/logging.rb' - - 'spec/language_server/transport/data_reader_spec.rb' - # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions. # NotImplementedExceptions: NotImplementedError Lint/UnusedMethodArgument: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: ContextCreatingMethods, MethodCreatingMethods. -Lint/UselessAccessModifier: Exclude: - - 'lib/solargraph/api_map.rb' + - 'lib/solargraph.rb' + - 'lib/solargraph/complex_type/type_methods.rb' + - 'lib/solargraph/convention/base.rb' + - 'lib/solargraph/diagnostics/base.rb' + - 'lib/solargraph/diagnostics/update_errors.rb' + - 'lib/solargraph/doc_map.rb' + - 'lib/solargraph/pin/namespace.rb' + - 'lib/solargraph/rbs_map/conversions.rb' + - 'lib/solargraph/source.rb' + - 'lib/solargraph/source/chain.rb' + - 'lib/solargraph/source/chain/block_symbol.rb' + - 'lib/solargraph/source/chain/block_variable.rb' + - 'lib/solargraph/source/chain/call.rb' + - 'lib/solargraph/source/chain/class_variable.rb' + - 'lib/solargraph/source/chain/constant.rb' + - 'lib/solargraph/source/chain/global_variable.rb' + - 'lib/solargraph/source/chain/hash.rb' + - 'lib/solargraph/source/chain/head.rb' + - 'lib/solargraph/source/chain/instance_variable.rb' + - 'lib/solargraph/source/chain/link.rb' + - 'lib/solargraph/source/chain/literal.rb' + - 'lib/solargraph/source/chain/variable.rb' + - 'lib/solargraph/source/chain/z_super.rb' + - 'spec/doc_map_spec.rb' # This cop supports safe autocorrection (--autocorrect). Lint/UselessAssignment: - Enabled: false + Exclude: + - 'spec/fixtures/long_squiggly_heredoc.rb' + - 'spec/fixtures/rubocop-unused-variable-error/app.rb' + - 'spec/fixtures/unicode.rb' Lint/UselessConstantScoping: Exclude: @@ -453,36 +192,84 @@ Lint/UselessMethodDefinition: # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max. Metrics/AbcSize: - Enabled: false + Exclude: + - 'lib/solargraph/api_map.rb' + - 'lib/solargraph/api_map/source_to_yard.rb' + - 'lib/solargraph/complex_type.rb' + - 'lib/solargraph/doc_map.rb' + - 'lib/solargraph/language_server/host.rb' + - 'lib/solargraph/language_server/message/initialize.rb' + - 'lib/solargraph/library.rb' + - 'lib/solargraph/parser/parser_gem/node_chainer.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' + - 'lib/solargraph/pin/method.rb' + - 'lib/solargraph/rbs_map/conversions.rb' + - 'lib/solargraph/source/chain/call.rb' + - 'lib/solargraph/source/source_chainer.rb' + - 'lib/solargraph/source_map/clip.rb' + - 'lib/solargraph/source_map/mapper.rb' + - 'lib/solargraph/type_checker.rb' -# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode. +# Configuration parameters: CountComments, Max, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode. # AllowedMethods: refine Metrics/BlockLength: - Max: 54 + Exclude: + - 'lib/solargraph/api_map.rb' + - 'lib/solargraph/api_map/source_to_yard.rb' + - 'lib/solargraph/complex_type.rb' + - 'lib/solargraph/convention/struct_definition.rb' + - 'lib/solargraph/library.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' + - 'lib/solargraph/source/chain/call.rb' + - 'lib/solargraph/type_checker.rb' -# Configuration parameters: CountBlocks, CountModifierForms. +# Configuration parameters: CountBlocks, CountModifierForms, Max. Metrics/BlockNesting: - Max: 5 + Exclude: + - 'lib/solargraph/source/source_chainer.rb' + - 'lib/solargraph/source_map/clip.rb' + - 'lib/solargraph/type_checker.rb' # Configuration parameters: CountComments, Max, CountAsOne. Metrics/ClassLength: Exclude: - 'lib/solargraph/api_map.rb' - 'lib/solargraph/language_server/host.rb' + - 'lib/solargraph/pin/method.rb' - 'lib/solargraph/rbs_map/conversions.rb' - 'lib/solargraph/type_checker.rb' # Configuration parameters: AllowedMethods, AllowedPatterns, Max. Metrics/CyclomaticComplexity: - Enabled: false + Exclude: + - 'lib/solargraph/api_map.rb' + - 'lib/solargraph/api_map/source_to_yard.rb' + - 'lib/solargraph/complex_type.rb' + - 'lib/solargraph/parser/parser_gem/node_chainer.rb' + - 'lib/solargraph/pin/method.rb' + - 'lib/solargraph/rbs_map/conversions.rb' + - 'lib/solargraph/source/chain/call.rb' + - 'lib/solargraph/source/source_chainer.rb' + - 'lib/solargraph/source_map/mapper.rb' + - 'lib/solargraph/type_checker.rb' # Configuration parameters: CountComments, Max, CountAsOne, AllowedMethods, AllowedPatterns. Metrics/MethodLength: - Enabled: false + Exclude: + - 'lib/solargraph/api_map.rb' + - 'lib/solargraph/complex_type.rb' + - 'lib/solargraph/convention/struct_definition.rb' + - 'lib/solargraph/parser/parser_gem/node_chainer.rb' + - 'lib/solargraph/source/chain/call.rb' + - 'lib/solargraph/source_map/mapper.rb' -# Configuration parameters: CountComments, CountAsOne. +# Configuration parameters: CountComments, Max, CountAsOne. Metrics/ModuleLength: - Max: 169 + Exclude: + - 'lib/solargraph/complex_type/type_methods.rb' + - 'lib/solargraph/parser/parser_gem/node_methods.rb' + - 'lib/solargraph/pin_cache.rb' # Configuration parameters: Max, CountKeywordArgs, MaxOptionalParameters. Metrics/ParameterLists: @@ -495,7 +282,13 @@ Metrics/ParameterLists: # Configuration parameters: AllowedMethods, AllowedPatterns, Max. Metrics/PerceivedComplexity: - Enabled: false + Exclude: + - 'lib/solargraph/complex_type.rb' + - 'lib/solargraph/parser/parser_gem/node_chainer.rb' + - 'lib/solargraph/source/chain/call.rb' + - 'lib/solargraph/source/source_chainer.rb' + - 'lib/solargraph/source_map/mapper.rb' + - 'lib/solargraph/type_checker.rb' Naming/AccessorMethodName: Exclude: @@ -518,18 +311,41 @@ Naming/HeredocDelimiterNaming: # Configuration parameters: EnforcedStyleForLeadingUnderscores. # SupportedStylesForLeadingUnderscores: disallowed, required, optional Naming/MemoizedInstanceVariableName: - Enabled: false + Exclude: + - 'lib/solargraph/complex_type/type_methods.rb' + - 'lib/solargraph/convention/gemfile.rb' + - 'lib/solargraph/convention/gemspec.rb' + - 'lib/solargraph/convention/rakefile.rb' + - 'lib/solargraph/doc_map.rb' + - 'lib/solargraph/rbs_map.rb' + - 'lib/solargraph/workspace.rb' # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. # AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to Naming/MethodParameterName: - Enabled: false + Exclude: + - 'lib/solargraph/parser/parser_gem/node_chainer.rb' + - 'lib/solargraph/pin/base.rb' + - 'lib/solargraph/range.rb' + - 'lib/solargraph/source.rb' + - 'lib/solargraph/yard_map/mapper/to_method.rb' + - 'lib/solargraph/yard_map/to_method.rb' # Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates. # AllowedMethods: call # WaywardPredicates: nonzero? Naming/PredicateMethod: - Enabled: false + Exclude: + - 'lib/solargraph/api_map/store.rb' + - 'lib/solargraph/convention/data_definition.rb' + - 'lib/solargraph/convention/struct_definition.rb' + - 'lib/solargraph/language_server/progress.rb' + - 'lib/solargraph/library.rb' + - 'lib/solargraph/parser/node_processor/base.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' + - 'lib/solargraph/pin/base.rb' + - 'lib/solargraph/pin/local_variable.rb' + - 'lib/solargraph/workspace.rb' # Configuration parameters: NamePrefix, ForbiddenPrefixes, AllowedMethods, MethodDefinitionMacros, UseSorbetSigs. # NamePrefix: is_, has_, have_, does_ @@ -563,14 +379,6 @@ RSpec/BeEq: - 'spec/complex_type_spec.rb' - 'spec/pin/method_spec.rb' -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: be, be_nil -RSpec/BeNil: - Exclude: - - 'spec/api_map/source_to_yard_spec.rb' - - 'spec/language_server/host_spec.rb' - RSpec/BeforeAfterAll: Exclude: - '**/spec/spec_helper.rb' @@ -584,7 +392,16 @@ RSpec/BeforeAfterAll: # Configuration parameters: Prefixes, AllowedPatterns. # Prefixes: when, with, without RSpec/ContextWording: - Enabled: false + Exclude: + - 'spec/complex_type_spec.rb' + - 'spec/library_spec.rb' + - 'spec/pin/method_spec.rb' + - 'spec/pin/parameter_spec.rb' + - 'spec/pin/symbol_spec.rb' + - 'spec/type_checker/levels/normal_spec.rb' + - 'spec/type_checker/levels/strict_spec.rb' + - 'spec/type_checker/levels/strong_spec.rb' + - 'spec/type_checker/levels/typed_spec.rb' # Configuration parameters: IgnoredMetadata. RSpec/DescribeClass: @@ -602,30 +419,108 @@ RSpec/DescribeClass: # Configuration parameters: SkipBlocks, EnforcedStyle, OnlyStaticConstants. # SupportedStyles: described_class, explicit RSpec/DescribedClass: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -RSpec/EmptyLineAfterFinalLet: Exclude: + - 'spec/api_map/cache_spec.rb' + - 'spec/api_map/source_to_yard_spec.rb' + - 'spec/api_map/store_spec.rb' + - 'spec/api_map_spec.rb' + - 'spec/diagnostics/base_spec.rb' + - 'spec/diagnostics/require_not_found_spec.rb' + - 'spec/diagnostics/rubocop_helpers_spec.rb' + - 'spec/diagnostics/rubocop_spec.rb' + - 'spec/diagnostics/type_check_spec.rb' + - 'spec/diagnostics/update_errors_spec.rb' + - 'spec/diagnostics_spec.rb' + - 'spec/doc_map_spec.rb' + - 'spec/gem_pins_spec.rb' + - 'spec/language_server/host/diagnoser_spec.rb' + - 'spec/language_server/host/dispatch_spec.rb' + - 'spec/language_server/host/message_worker_spec.rb' + - 'spec/language_server/host_spec.rb' + - 'spec/language_server/message/completion_item/resolve_spec.rb' + - 'spec/language_server/message/extended/check_gem_version_spec.rb' + - 'spec/language_server/message/initialize_spec.rb' + - 'spec/language_server/message/text_document/definition_spec.rb' + - 'spec/language_server/message/text_document/formatting_spec.rb' + - 'spec/language_server/message/text_document/hover_spec.rb' + - 'spec/language_server/message/text_document/rename_spec.rb' + - 'spec/language_server/message/text_document/type_definition_spec.rb' + - 'spec/language_server/message/workspace/did_change_watched_files_spec.rb' + - 'spec/language_server/message_spec.rb' + - 'spec/language_server/protocol_spec.rb' + - 'spec/language_server/transport/data_reader_spec.rb' + - 'spec/language_server/uri_helpers_spec.rb' + - 'spec/library_spec.rb' + - 'spec/logging_spec.rb' + - 'spec/parser/node_methods_spec.rb' + - 'spec/parser/node_processor_spec.rb' + - 'spec/parser_spec.rb' + - 'spec/pin/base_spec.rb' + - 'spec/pin/delegated_method_spec.rb' + - 'spec/pin/instance_variable_spec.rb' + - 'spec/pin/keyword_spec.rb' + - 'spec/pin/local_variable_spec.rb' + - 'spec/pin/method_spec.rb' + - 'spec/pin/namespace_spec.rb' + - 'spec/pin/parameter_spec.rb' + - 'spec/pin/search_spec.rb' + - 'spec/pin/symbol_spec.rb' + - 'spec/position_spec.rb' + - 'spec/rbs_map/conversions_spec.rb' + - 'spec/rbs_map/core_map_spec.rb' + - 'spec/rbs_map/stdlib_map_spec.rb' + - 'spec/rbs_map_spec.rb' + - 'spec/source/chain/class_variable_spec.rb' + - 'spec/source/chain/global_variable_spec.rb' + - 'spec/source/chain/head_spec.rb' + - 'spec/source/chain/instance_variable_spec.rb' + - 'spec/source/chain/z_super_spec.rb' + - 'spec/source/change_spec.rb' + - 'spec/source/source_chainer_spec.rb' + - 'spec/source/updater_spec.rb' + - 'spec/source_map/mapper_spec.rb' + - 'spec/source_map_spec.rb' + - 'spec/source_spec.rb' + - 'spec/type_checker/checks_spec.rb' + - 'spec/type_checker/levels/normal_spec.rb' + - 'spec/type_checker/levels/strict_spec.rb' + - 'spec/type_checker/rules_spec.rb' + - 'spec/type_checker_spec.rb' - 'spec/workspace/config_spec.rb' + - 'spec/workspace_spec.rb' + - 'spec/yard_map/mapper/to_method_spec.rb' + - 'spec/yard_map/mapper_spec.rb' # Configuration parameters: Max, CountAsOne. RSpec/ExampleLength: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: CustomTransform, IgnoredWords, DisallowedExamples. -# DisallowedExamples: works -RSpec/ExampleWording: - Exclude: - - 'spec/pin/base_spec.rb' - - 'spec/pin/method_spec.rb' - -# This cop supports safe autocorrection (--autocorrect). -RSpec/ExcessiveDocstringSpacing: Exclude: - - 'spec/rbs_map/conversions_spec.rb' + - 'spec/api_map_spec.rb' + - 'spec/complex_type_spec.rb' + - 'spec/convention_spec.rb' + - 'spec/language_server/host_spec.rb' + - 'spec/language_server/message/initialize_spec.rb' + - 'spec/language_server/message/text_document/definition_spec.rb' + - 'spec/language_server/message/text_document/hover_spec.rb' + - 'spec/language_server/message/text_document/rename_spec.rb' + - 'spec/language_server/message/text_document/type_definition_spec.rb' + - 'spec/language_server/message/workspace/did_change_watched_files_spec.rb' + - 'spec/language_server/protocol_spec.rb' + - 'spec/library_spec.rb' + - 'spec/parser/flow_sensitive_typing_spec.rb' + - 'spec/parser/node_methods_spec.rb' + - 'spec/parser/node_processor_spec.rb' + - 'spec/pin/base_variable_spec.rb' + - 'spec/pin/delegated_method_spec.rb' + - 'spec/pin/local_variable_spec.rb' + - 'spec/pin/parameter_spec.rb' - 'spec/source/chain/call_spec.rb' + - 'spec/source/chain_spec.rb' + - 'spec/source_map/clip_spec.rb' + - 'spec/source_map/mapper_spec.rb' + - 'spec/source_map_spec.rb' + - 'spec/source_spec.rb' + - 'spec/type_checker/levels/strict_spec.rb' + - 'spec/type_checker_spec.rb' # This cop supports safe autocorrection (--autocorrect). RSpec/ExpectActual: @@ -634,36 +529,20 @@ RSpec/ExpectActual: - 'spec/rbs_map/stdlib_map_spec.rb' - 'spec/source_map/mapper_spec.rb' -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: implicit, each, example -RSpec/HookArgument: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: . -# SupportedStyles: is_expected, should -RSpec/ImplicitExpect: - EnforcedStyle: should - # Configuration parameters: AssignmentOnly. RSpec/InstanceVariable: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -RSpec/LeadingSubject: Exclude: - - 'spec/rbs_map/conversions_spec.rb' + - 'spec/api_map/config_spec.rb' + - 'spec/api_map_spec.rb' + - 'spec/diagnostics/require_not_found_spec.rb' + - 'spec/language_server/host/dispatch_spec.rb' + - 'spec/language_server/host_spec.rb' + - 'spec/language_server/protocol_spec.rb' RSpec/LeakyConstantDeclaration: Exclude: - 'spec/complex_type_spec.rb' -# This cop supports safe autocorrection (--autocorrect). -RSpec/LetBeforeExamples: - Exclude: - - 'spec/complex_type_spec.rb' - # Configuration parameters: EnforcedStyle. # SupportedStyles: have_received, receive RSpec/MessageSpies: @@ -676,28 +555,104 @@ RSpec/MissingExampleGroupArgument: Exclude: - 'spec/diagnostics/rubocop_helpers_spec.rb' +# Configuration parameters: Max. RSpec/MultipleExpectations: - Max: 14 + Exclude: + - 'spec/api_map/cache_spec.rb' + - 'spec/api_map/config_spec.rb' + - 'spec/api_map/source_to_yard_spec.rb' + - 'spec/api_map/store_spec.rb' + - 'spec/api_map_spec.rb' + - 'spec/complex_type_spec.rb' + - 'spec/convention/struct_definition_spec.rb' + - 'spec/convention_spec.rb' + - 'spec/diagnostics/rubocop_spec.rb' + - 'spec/diagnostics/type_check_spec.rb' + - 'spec/diagnostics/update_errors_spec.rb' + - 'spec/diagnostics_spec.rb' + - 'spec/doc_map_spec.rb' + - 'spec/gem_pins_spec.rb' + - 'spec/language_server/host/message_worker_spec.rb' + - 'spec/language_server/host_spec.rb' + - 'spec/language_server/message/completion_item/resolve_spec.rb' + - 'spec/language_server/message/initialize_spec.rb' + - 'spec/language_server/message/text_document/rename_spec.rb' + - 'spec/language_server/message/workspace/did_change_watched_files_spec.rb' + - 'spec/language_server/protocol_spec.rb' + - 'spec/language_server/transport/adapter_spec.rb' + - 'spec/language_server/transport/data_reader_spec.rb' + - 'spec/library_spec.rb' + - 'spec/parser/flow_sensitive_typing_spec.rb' + - 'spec/parser/node_chainer_spec.rb' + - 'spec/parser/node_methods_spec.rb' + - 'spec/parser/node_processor_spec.rb' + - 'spec/pin/base_spec.rb' + - 'spec/pin/base_variable_spec.rb' + - 'spec/pin/constant_spec.rb' + - 'spec/pin/instance_variable_spec.rb' + - 'spec/pin/local_variable_spec.rb' + - 'spec/pin/method_spec.rb' + - 'spec/pin/namespace_spec.rb' + - 'spec/pin/parameter_spec.rb' + - 'spec/position_spec.rb' + - 'spec/rbs_map/core_map_spec.rb' + - 'spec/rbs_map/stdlib_map_spec.rb' + - 'spec/rbs_map_spec.rb' + - 'spec/shell_spec.rb' + - 'spec/source/chain/call_spec.rb' + - 'spec/source/chain/class_variable_spec.rb' + - 'spec/source/chain/global_variable_spec.rb' + - 'spec/source/chain/head_spec.rb' + - 'spec/source/chain/instance_variable_spec.rb' + - 'spec/source/chain_spec.rb' + - 'spec/source/cursor_spec.rb' + - 'spec/source/source_chainer_spec.rb' + - 'spec/source_map/clip_spec.rb' + - 'spec/source_map/mapper_spec.rb' + - 'spec/source_map/node_processor_spec.rb' + - 'spec/source_map_spec.rb' + - 'spec/source_spec.rb' + - 'spec/type_checker/checks_spec.rb' + - 'spec/type_checker/levels/normal_spec.rb' + - 'spec/type_checker/levels/strict_spec.rb' + - 'spec/type_checker/levels/strong_spec.rb' + - 'spec/type_checker/levels/typed_spec.rb' + - 'spec/type_checker/rules_spec.rb' + - 'spec/workspace/config_spec.rb' + - 'spec/workspace_spec.rb' + - 'spec/yard_map/mapper/to_method_spec.rb' + - 'spec/yard_map/mapper_spec.rb' -# Configuration parameters: AllowedGroups. +# Configuration parameters: Max, AllowedGroups. RSpec/NestedGroups: - Max: 4 + Exclude: + - 'spec/complex_type_spec.rb' # Configuration parameters: AllowedPatterns. # AllowedPatterns: ^expect_, ^assert_ RSpec/NoExpectationExample: - Enabled: false + Exclude: + - 'spec/language_server/protocol_spec.rb' + - 'spec/parser/node_methods_spec.rb' + - 'spec/pin/block_spec.rb' + - 'spec/pin/method_spec.rb' + - 'spec/source/chain/call_spec.rb' + - 'spec/type_checker/checks_spec.rb' + - 'spec/type_checker/levels/typed_spec.rb' -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: not_to, to_not -RSpec/NotToNot: +RSpec/PendingWithoutReason: Exclude: - 'spec/api_map_spec.rb' + - 'spec/complex_type_spec.rb' + - 'spec/parser/node_chainer_spec.rb' + - 'spec/parser/node_methods_spec.rb' + - 'spec/pin/local_variable_spec.rb' - 'spec/rbs_map/core_map_spec.rb' - -RSpec/PendingWithoutReason: - Enabled: false + - 'spec/source/chain/call_spec.rb' + - 'spec/source/chain_spec.rb' + - 'spec/source_map/clip_spec.rb' + - 'spec/type_checker/levels/strict_spec.rb' + - 'spec/yard_map/mapper/to_method_spec.rb' # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: Strict, EnforcedStyle, AllowedExplicitMatchers. @@ -717,7 +672,16 @@ RSpec/RemoveConst: - 'spec/diagnostics/rubocop_helpers_spec.rb' RSpec/RepeatedDescription: - Enabled: false + Exclude: + - 'spec/api_map_spec.rb' + - 'spec/language_server/protocol_spec.rb' + - 'spec/parser/node_methods_spec.rb' + - 'spec/source/chain/call_spec.rb' + - 'spec/source/source_chainer_spec.rb' + - 'spec/source_map/clip_spec.rb' + - 'spec/source_map/mapper_spec.rb' + - 'spec/type_checker/levels/normal_spec.rb' + - 'spec/type_checker/levels/strict_spec.rb' RSpec/RepeatedExample: Exclude: @@ -727,18 +691,26 @@ RSpec/RepeatedExample: - 'spec/source_map/clip_spec.rb' - 'spec/type_checker/levels/strict_spec.rb' -# This cop supports safe autocorrection (--autocorrect). -RSpec/ScatteredLet: - Exclude: - - 'spec/complex_type_spec.rb' - RSpec/StubbedMock: Exclude: - 'spec/language_server/host/message_worker_spec.rb' # Configuration parameters: IgnoreNameless, IgnoreSymbolicNames. RSpec/VerifiedDoubles: - Enabled: false + Exclude: + - 'spec/complex_type_spec.rb' + - 'spec/language_server/host/diagnoser_spec.rb' + - 'spec/language_server/host/message_worker_spec.rb' + - 'spec/language_server/host_spec.rb' + - 'spec/language_server/message/completion_item/resolve_spec.rb' + - 'spec/language_server/message/extended/check_gem_version_spec.rb' + - 'spec/language_server/message/text_document/formatting_spec.rb' + - 'spec/language_server/message/workspace/did_change_watched_files_spec.rb' + - 'spec/language_server/protocol_spec.rb' + - 'spec/source/chain/class_variable_spec.rb' + - 'spec/source/cursor_spec.rb' + - 'spec/source/source_chainer_spec.rb' + - 'spec/workspace_spec.rb' Security/MarshalLoad: Exclude: @@ -748,23 +720,38 @@ Security/MarshalLoad: # Configuration parameters: EnforcedStyle, AllowModifiersOnSymbols, AllowModifiersOnAttrs, AllowModifiersOnAliasMethod. # SupportedStyles: inline, group Style/AccessModifierDeclarations: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: separated, grouped -Style/AccessorGrouping: Exclude: - - 'lib/solargraph/parser/flow_sensitive_typing.rb' + - 'lib/solargraph/api_map.rb' + - 'lib/solargraph/complex_type.rb' + - 'lib/solargraph/complex_type/unique_type.rb' + - 'lib/solargraph/location.rb' - 'lib/solargraph/pin/base.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/rbs_map.rb' + - 'lib/solargraph/position.rb' + - 'lib/solargraph/range.rb' + - 'lib/solargraph/source/chain.rb' + - 'lib/solargraph/source/chain/call.rb' + - 'lib/solargraph/source/chain/hash.rb' + - 'lib/solargraph/source/chain/if.rb' + - 'lib/solargraph/source/chain/link.rb' + - 'lib/solargraph/source/chain/literal.rb' # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle. # SupportedStyles: always, conditionals Style/AndOr: - Enabled: false + Exclude: + - 'lib/solargraph/complex_type/unique_type.rb' + - 'lib/solargraph/language_server/message/base.rb' + - 'lib/solargraph/page.rb' + - 'lib/solargraph/pin/method.rb' + - 'lib/solargraph/pin/parameter.rb' + - 'lib/solargraph/position.rb' + - 'lib/solargraph/source/change.rb' + - 'lib/solargraph/source/cursor.rb' + - 'lib/solargraph/source/source_chainer.rb' + - 'lib/solargraph/source/updater.rb' + - 'lib/solargraph/workspace.rb' + - 'lib/solargraph/yard_map/mapper.rb' # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowOnlyRestArgument, UseAnonymousForwarding, RedundantRestArgumentNames, RedundantKeywordRestArgumentNames, RedundantBlockArgumentNames. @@ -776,19 +763,15 @@ Style/ArgumentsForwarding: - 'lib/solargraph/api_map.rb' - 'lib/solargraph/complex_type.rb' -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, AllowedMethods, AllowedPatterns, AllowBracesOnProceduralOneLiners, BracesRequiredMethods. -# SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces -# ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object -# FunctionalMethods: let, let!, subject, watch -# AllowedMethods: lambda, proc, it -Style/BlockDelimiters: - Enabled: false - # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: MinBranchesCount. Style/CaseLikeIf: - Enabled: false + Exclude: + - 'lib/solargraph/language_server/message/workspace/did_change_watched_files.rb' + - 'lib/solargraph/pin/parameter.rb' + - 'lib/solargraph/rbs_map/conversions.rb' + - 'lib/solargraph/source/source_chainer.rb' + - 'lib/solargraph/yard_map/mapper.rb' # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle, EnforcedStyleForClasses, EnforcedStyleForModules. @@ -796,7 +779,18 @@ Style/CaseLikeIf: # SupportedStylesForClasses: ~, nested, compact # SupportedStylesForModules: ~, nested, compact Style/ClassAndModuleChildren: - Enabled: false + Exclude: + - 'lib/solargraph/language_server/message/text_document/definition.rb' + - 'lib/solargraph/language_server/message/text_document/document_highlight.rb' + - 'lib/solargraph/language_server/message/text_document/document_symbol.rb' + - 'lib/solargraph/language_server/message/text_document/prepare_rename.rb' + - 'lib/solargraph/language_server/message/text_document/references.rb' + - 'lib/solargraph/language_server/message/text_document/rename.rb' + - 'lib/solargraph/language_server/message/text_document/type_definition.rb' + - 'lib/solargraph/language_server/message/workspace/did_change_configuration.rb' + - 'lib/solargraph/language_server/message/workspace/did_change_watched_files.rb' + - 'lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb' + - 'lib/solargraph/language_server/message/workspace/workspace_symbol.rb' # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: AllowedMethods, AllowedPatterns. @@ -812,11 +806,6 @@ Style/CollectionCompact: Exclude: - 'lib/solargraph/pin/constant.rb' -# This cop supports safe autocorrection (--autocorrect). -Style/ColonMethodCall: - Exclude: - - 'spec/type_checker_spec.rb' - # This cop supports unsafe autocorrection (--autocorrect-all). Style/CombinableLoops: Exclude: @@ -827,56 +816,158 @@ Style/ConcatArrayLiterals: Exclude: - 'lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb' -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, SingleLineConditionsOnly, IncludeTernaryExpressions. -# SupportedStyles: assign_to_condition, assign_inside_condition -Style/ConditionalAssignment: - Exclude: - - 'lib/solargraph/api_map/source_to_yard.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/defs_node.rb' - - 'lib/solargraph/source/chain/call.rb' - # Configuration parameters: AllowedConstants. Style/Documentation: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -Style/EmptyLambdaParameter: Exclude: - - 'spec/rbs_map/core_map_spec.rb' + - 'spec/**/*' + - 'test/**/*' + - 'lib/solargraph/api_map/cache.rb' + - 'lib/solargraph/api_map/index.rb' + - 'lib/solargraph/api_map/source_to_yard.rb' + - 'lib/solargraph/convention/data_definition.rb' + - 'lib/solargraph/convention/gemfile.rb' + - 'lib/solargraph/convention/gemspec.rb' + - 'lib/solargraph/convention/rakefile.rb' + - 'lib/solargraph/convention/struct_definition.rb' + - 'lib/solargraph/converters/dd.rb' + - 'lib/solargraph/converters/dl.rb' + - 'lib/solargraph/converters/dt.rb' + - 'lib/solargraph/diagnostics/update_errors.rb' + - 'lib/solargraph/language_server/message/base.rb' + - 'lib/solargraph/language_server/message/cancel_request.rb' + - 'lib/solargraph/language_server/message/client.rb' + - 'lib/solargraph/language_server/message/client/register_capability.rb' + - 'lib/solargraph/language_server/message/completion_item.rb' + - 'lib/solargraph/language_server/message/exit_notification.rb' + - 'lib/solargraph/language_server/message/extended/document.rb' + - 'lib/solargraph/language_server/message/extended/search.rb' + - 'lib/solargraph/language_server/message/initialize.rb' + - 'lib/solargraph/language_server/message/initialized.rb' + - 'lib/solargraph/language_server/message/method_not_found.rb' + - 'lib/solargraph/language_server/message/method_not_implemented.rb' + - 'lib/solargraph/language_server/message/shutdown.rb' + - 'lib/solargraph/language_server/message/text_document.rb' + - 'lib/solargraph/language_server/message/text_document/base.rb' + - 'lib/solargraph/language_server/message/text_document/code_action.rb' + - 'lib/solargraph/language_server/message/text_document/completion.rb' + - 'lib/solargraph/language_server/message/text_document/definition.rb' + - 'lib/solargraph/language_server/message/text_document/did_change.rb' + - 'lib/solargraph/language_server/message/text_document/did_close.rb' + - 'lib/solargraph/language_server/message/text_document/did_open.rb' + - 'lib/solargraph/language_server/message/text_document/did_save.rb' + - 'lib/solargraph/language_server/message/text_document/document_highlight.rb' + - 'lib/solargraph/language_server/message/text_document/document_symbol.rb' + - 'lib/solargraph/language_server/message/text_document/folding_range.rb' + - 'lib/solargraph/language_server/message/text_document/formatting.rb' + - 'lib/solargraph/language_server/message/text_document/hover.rb' + - 'lib/solargraph/language_server/message/text_document/on_type_formatting.rb' + - 'lib/solargraph/language_server/message/text_document/prepare_rename.rb' + - 'lib/solargraph/language_server/message/text_document/references.rb' + - 'lib/solargraph/language_server/message/text_document/rename.rb' + - 'lib/solargraph/language_server/message/text_document/signature_help.rb' + - 'lib/solargraph/language_server/message/text_document/type_definition.rb' + - 'lib/solargraph/language_server/message/workspace.rb' + - 'lib/solargraph/language_server/message/workspace/did_change_configuration.rb' + - 'lib/solargraph/language_server/message/workspace/did_change_watched_files.rb' + - 'lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb' + - 'lib/solargraph/language_server/message/workspace/workspace_symbol.rb' + - 'lib/solargraph/language_server/request.rb' + - 'lib/solargraph/language_server/transport/data_reader.rb' + - 'lib/solargraph/logging.rb' + - 'lib/solargraph/page.rb' + - 'lib/solargraph/parser.rb' + - 'lib/solargraph/parser/comment_ripper.rb' + - 'lib/solargraph/parser/flow_sensitive_typing.rb' + - 'lib/solargraph/parser/node_methods.rb' + - 'lib/solargraph/parser/node_processor/base.rb' + - 'lib/solargraph/parser/parser_gem.rb' + - 'lib/solargraph/parser/parser_gem/class_methods.rb' + - 'lib/solargraph/parser/parser_gem/node_methods.rb' + - 'lib/solargraph/parser/parser_gem/node_processors.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/alias_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/and_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/args_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/begin_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/block_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/def_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/defs_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/if_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/sym_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/until_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/while_node.rb' + - 'lib/solargraph/parser/snippet.rb' + - 'lib/solargraph/pin/base_variable.rb' + - 'lib/solargraph/pin/block.rb' + - 'lib/solargraph/pin/callable.rb' + - 'lib/solargraph/pin/closure.rb' + - 'lib/solargraph/pin/common.rb' + - 'lib/solargraph/pin/constant.rb' + - 'lib/solargraph/pin/instance_variable.rb' + - 'lib/solargraph/pin/keyword.rb' + - 'lib/solargraph/pin/local_variable.rb' + - 'lib/solargraph/pin/namespace.rb' + - 'lib/solargraph/pin/parameter.rb' + - 'lib/solargraph/pin/proxy_type.rb' + - 'lib/solargraph/pin/reference.rb' + - 'lib/solargraph/pin/reference/override.rb' + - 'lib/solargraph/pin/reference/require.rb' + - 'lib/solargraph/pin/search.rb' + - 'lib/solargraph/pin/signature.rb' + - 'lib/solargraph/pin/singleton.rb' + - 'lib/solargraph/pin/symbol.rb' + - 'lib/solargraph/pin/until.rb' + - 'lib/solargraph/pin/while.rb' + - 'lib/solargraph/pin_cache.rb' + - 'lib/solargraph/rbs_map.rb' + - 'lib/solargraph/repro.rb' + - 'lib/solargraph/server_methods.rb' + - 'lib/solargraph/shell.rb' + - 'lib/solargraph/source/chain/array.rb' + - 'lib/solargraph/source/chain/block_symbol.rb' + - 'lib/solargraph/source/chain/block_variable.rb' + - 'lib/solargraph/source/chain/class_variable.rb' + - 'lib/solargraph/source/chain/constant.rb' + - 'lib/solargraph/source/chain/global_variable.rb' + - 'lib/solargraph/source/chain/hash.rb' + - 'lib/solargraph/source/chain/if.rb' + - 'lib/solargraph/source/chain/instance_variable.rb' + - 'lib/solargraph/source/chain/link.rb' + - 'lib/solargraph/source/chain/literal.rb' + - 'lib/solargraph/source/chain/or.rb' + - 'lib/solargraph/source/chain/q_call.rb' + - 'lib/solargraph/source/chain/variable.rb' + - 'lib/solargraph/source/chain/z_super.rb' + - 'lib/solargraph/source/encoding_fixes.rb' + - 'lib/solargraph/source_map/data.rb' + - 'lib/solargraph/yard_map/cache.rb' + - 'lib/solargraph/yard_map/helpers.rb' + - 'lib/solargraph/yard_map/mapper.rb' + - 'lib/solargraph/yard_map/mapper/to_constant.rb' + - 'lib/solargraph/yard_map/mapper/to_method.rb' + - 'lib/solargraph/yard_map/mapper/to_namespace.rb' + - 'lib/solargraph/yard_map/to_method.rb' # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle. # SupportedStyles: compact, expanded Style/EmptyMethod: Exclude: - - 'lib/solargraph/language_server/message/client/register_capability.rb' - - 'lib/solargraph/pin/base.rb' - 'spec/fixtures/formattable.rb' - 'spec/fixtures/rdoc-lib/lib/example.rb' - 'spec/fixtures/workspace-with-gemfile/lib/thing.rb' -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: trailing_conditional, ternary -Style/EmptyStringInsideInterpolation: - Exclude: - - 'lib/solargraph/library.rb' - - 'lib/solargraph/pin/documenting.rb' - - 'lib/solargraph/shell.rb' - -# This cop supports safe autocorrection (--autocorrect). -Style/ExpandPathArguments: - Exclude: - - 'solargraph.gemspec' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowedVars, DefaultToNil. -Style/FetchEnvVar: - Exclude: - - 'spec/api_map/config_spec.rb' - - 'spec/spec_helper.rb' - # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle. # SupportedStyles: left_coerce, right_coerce, single_coerce, fdiv @@ -889,21 +980,146 @@ Style/FloatDivision: # Configuration parameters: EnforcedStyle. # SupportedStyles: always, always_true, never Style/FrozenStringLiteralComment: - Enabled: false + Exclude: + - '**/*.arb' + - '.pryrc' + - 'Gemfile' + - 'Rakefile' + - 'bin/solargraph' + - 'lib/solargraph/converters/dd.rb' + - 'lib/solargraph/converters/dl.rb' + - 'lib/solargraph/converters/dt.rb' + - 'lib/solargraph/converters/misc.rb' + - 'lib/solargraph/parser.rb' + - 'lib/solargraph/parser/comment_ripper.rb' + - 'lib/solargraph/parser/flow_sensitive_typing.rb' + - 'lib/solargraph/parser/node_methods.rb' + - 'lib/solargraph/parser/parser_gem.rb' + - 'lib/solargraph/parser/snippet.rb' + - 'lib/solargraph/pin/breakable.rb' + - 'lib/solargraph/pin/signature.rb' + - 'lib/solargraph/pin_cache.rb' + - 'lib/solargraph/repro.rb' + - 'lib/solargraph/source/chain/array.rb' + - 'lib/solargraph/source/chain/q_call.rb' + - 'lib/solargraph/yard_map/helpers.rb' + - 'solargraph.gemspec' + - 'spec/api_map/cache_spec.rb' + - 'spec/api_map/config_spec.rb' + - 'spec/api_map/source_to_yard_spec.rb' + - 'spec/api_map_spec.rb' + - 'spec/complex_type_spec.rb' + - 'spec/convention/struct_definition_spec.rb' + - 'spec/convention_spec.rb' + - 'spec/diagnostics/base_spec.rb' + - 'spec/diagnostics/require_not_found_spec.rb' + - 'spec/diagnostics/rubocop_helpers_spec.rb' + - 'spec/diagnostics/type_check_spec.rb' + - 'spec/diagnostics/update_errors_spec.rb' + - 'spec/diagnostics_spec.rb' + - 'spec/fixtures/formattable.rb' + - 'spec/fixtures/long_squiggly_heredoc.rb' + - 'spec/fixtures/rdoc-lib/Gemfile' + - 'spec/fixtures/rdoc-lib/lib/example.rb' + - 'spec/fixtures/rdoc-lib/rdoc-lib.gemspec' + - 'spec/fixtures/rubocop-custom-version/specifications/rubocop-0.0.0.gemspec' + - 'spec/fixtures/rubocop-validation-error/app.rb' + - 'spec/fixtures/unicode.rb' + - 'spec/fixtures/workspace-with-gemfile/Gemfile' + - 'spec/fixtures/workspace-with-gemfile/app.rb' + - 'spec/fixtures/workspace-with-gemfile/lib/other.rb' + - 'spec/fixtures/workspace-with-gemfile/lib/thing.rb' + - 'spec/fixtures/workspace/app.rb' + - 'spec/fixtures/workspace/lib/other.rb' + - 'spec/fixtures/workspace/lib/something.rb' + - 'spec/fixtures/workspace/lib/thing.rb' + - 'spec/fixtures/workspace_folders/folder1/app.rb' + - 'spec/fixtures/workspace_folders/folder2/app.rb' + - 'spec/fixtures/yard_map/attr.rb' + - 'spec/language_server/host/diagnoser_spec.rb' + - 'spec/language_server/host/dispatch_spec.rb' + - 'spec/language_server/host/message_worker_spec.rb' + - 'spec/language_server/host_spec.rb' + - 'spec/language_server/message/completion_item/resolve_spec.rb' + - 'spec/language_server/message/extended/check_gem_version_spec.rb' + - 'spec/language_server/message/initialize_spec.rb' + - 'spec/language_server/message/text_document/definition_spec.rb' + - 'spec/language_server/message/text_document/formatting_spec.rb' + - 'spec/language_server/message/text_document/hover_spec.rb' + - 'spec/language_server/message/text_document/type_definition_spec.rb' + - 'spec/language_server/message/workspace/did_change_watched_files_spec.rb' + - 'spec/language_server/message_spec.rb' + - 'spec/language_server/protocol_spec.rb' + - 'spec/language_server/transport/adapter_spec.rb' + - 'spec/language_server/transport/data_reader_spec.rb' + - 'spec/language_server/uri_helpers_spec.rb' + - 'spec/library_spec.rb' + - 'spec/logging_spec.rb' + - 'spec/parser/node_chainer_spec.rb' + - 'spec/parser/node_methods_spec.rb' + - 'spec/parser/node_processor_spec.rb' + - 'spec/parser_spec.rb' + - 'spec/pin/base_spec.rb' + - 'spec/pin/base_variable_spec.rb' + - 'spec/pin/block_spec.rb' + - 'spec/pin/class_variable_spec.rb' + - 'spec/pin/constant_spec.rb' + - 'spec/pin/delegated_method_spec.rb' + - 'spec/pin/documenting_spec.rb' + - 'spec/pin/instance_variable_spec.rb' + - 'spec/pin/keyword_spec.rb' + - 'spec/pin/local_variable_spec.rb' + - 'spec/pin/method_spec.rb' + - 'spec/pin/namespace_spec.rb' + - 'spec/pin/parameter_spec.rb' + - 'spec/pin/search_spec.rb' + - 'spec/pin/symbol_spec.rb' + - 'spec/position_spec.rb' + - 'spec/rbs_map/conversions_spec.rb' + - 'spec/rbs_map/core_map_spec.rb' + - 'spec/rbs_map/stdlib_map_spec.rb' + - 'spec/rbs_map_spec.rb' + - 'spec/shell_spec.rb' + - 'spec/source/chain/array_spec.rb' + - 'spec/source/chain/call_spec.rb' + - 'spec/source/chain/class_variable_spec.rb' + - 'spec/source/chain/constant_spec.rb' + - 'spec/source/chain/global_variable_spec.rb' + - 'spec/source/chain/head_spec.rb' + - 'spec/source/chain/instance_variable_spec.rb' + - 'spec/source/chain/link_spec.rb' + - 'spec/source/chain/literal_spec.rb' + - 'spec/source/chain/z_super_spec.rb' + - 'spec/source/chain_spec.rb' + - 'spec/source/change_spec.rb' + - 'spec/source/cursor_spec.rb' + - 'spec/source/source_chainer_spec.rb' + - 'spec/source/updater_spec.rb' + - 'spec/source_map/clip_spec.rb' + - 'spec/source_map/mapper_spec.rb' + - 'spec/source_map/node_processor_spec.rb' + - 'spec/source_map_spec.rb' + - 'spec/source_spec.rb' + - 'spec/spec_helper.rb' + - 'spec/type_checker/checks_spec.rb' + - 'spec/type_checker/levels/normal_spec.rb' + - 'spec/type_checker/levels/strict_spec.rb' + - 'spec/type_checker/levels/strong_spec.rb' + - 'spec/type_checker/levels/typed_spec.rb' + - 'spec/type_checker/rules_spec.rb' + - 'spec/type_checker_spec.rb' + - 'spec/workspace/config_spec.rb' + - 'spec/workspace_spec.rb' + - 'spec/yard_map/mapper/to_method_spec.rb' + - 'spec/yard_map/mapper_spec.rb' # This cop supports unsafe autocorrection (--autocorrect-all). Style/GlobalStdStream: Exclude: - 'lib/solargraph/logging.rb' - - 'lib/solargraph/pin/base.rb' - 'lib/solargraph/shell.rb' - 'spec/logging_spec.rb' -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: MinBodyLength, AllowConsecutiveConditionals. -Style/GuardClause: - Enabled: false - # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: AllowSplatArgument. Style/HashConversion: @@ -918,37 +1134,22 @@ Style/HashEachMethods: - 'lib/solargraph/library.rb' - 'lib/solargraph/source.rb' -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, EnforcedShorthandSyntax, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols. -# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys -# SupportedShorthandSyntax: always, never, either, consistent, either_consistent -Style/HashSyntax: - Exclude: - - 'spec/source/chain/class_variable_spec.rb' - - 'spec/source/cursor_spec.rb' - - 'spec/source/source_chainer_spec.rb' - # This cop supports unsafe autocorrection (--autocorrect-all). Style/IdenticalConditionalBranches: Exclude: - 'lib/solargraph/library.rb' - 'lib/solargraph/type_checker.rb' -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowIfModifier. -Style/IfInsideElse: - Enabled: false - # This cop supports safe autocorrection (--autocorrect). Style/IfUnlessModifier: - Enabled: false + Exclude: + - 'lib/solargraph/shell.rb' -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: call, braces -Style/LambdaCall: +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: InverseMethods, InverseBlocks. +Style/InverseMethods: Exclude: - - 'lib/solargraph/library.rb' + - 'lib/solargraph/source.rb' # This cop supports unsafe autocorrection (--autocorrect-all). Style/MapIntoArray: @@ -972,75 +1173,47 @@ Style/MapToSet: # Configuration parameters: EnforcedStyle. # SupportedStyles: require_parentheses, require_no_parentheses, require_no_parentheses_except_multiline Style/MethodDefParentheses: - Enabled: false + Exclude: + - 'spec/fixtures/rdoc-lib/lib/example.rb' Style/MultilineBlockChain: Exclude: - 'lib/solargraph/pin/search.rb' -# This cop supports safe autocorrection (--autocorrect). -Style/MultilineIfModifier: - Exclude: - - 'lib/solargraph/pin/callable.rb' - -# This cop supports safe autocorrection (--autocorrect). -Style/MultilineTernaryOperator: - Exclude: - - 'lib/solargraph/language_server/host.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowMethodComparison, ComparisonsThreshold. -Style/MultipleComparison: - Enabled: false - # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle. # SupportedStyles: literals, strict Style/MutableConstant: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: both, prefix, postfix -Style/NegatedIf: - Exclude: - - 'lib/solargraph/language_server/host/diagnoser.rb' - -# This cop supports safe autocorrection (--autocorrect). -Style/NegatedIfElseCondition: Exclude: - 'lib/solargraph/diagnostics/rubocop.rb' - - 'lib/solargraph/language_server/message/extended/document_gems.rb' + - 'lib/solargraph/logging.rb' - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/shell.rb' - - 'lib/solargraph/type_checker.rb' - -# This cop supports safe autocorrection (--autocorrect). -Style/NestedTernaryOperator: - Exclude: - - 'lib/solargraph/pin/conversions.rb' - - 'lib/solargraph/pin/method.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, MinBodyLength, AllowConsecutiveConditionals. -# SupportedStyles: skip_modifier_ifs, always -Style/Next: - Exclude: - - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' - - 'lib/solargraph/pin/signature.rb' - - 'lib/solargraph/source_map/clip.rb' - - 'lib/solargraph/type_checker/checks.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: Strict, AllowedNumbers, AllowedPatterns. -Style/NumericLiterals: - MinDigits: 6 + - 'lib/solargraph/rbs_map/conversions.rb' + - 'lib/solargraph/rbs_map/core_fills.rb' + - 'lib/solargraph/yard_map/mapper/to_method.rb' + - 'spec/complex_type_spec.rb' # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle, AllowedMethods, AllowedPatterns. # SupportedStyles: predicate, comparison Style/NumericPredicate: - Enabled: false + Exclude: + - 'spec/**/*' + - 'lib/solargraph/api_map/store.rb' + - 'lib/solargraph/complex_type.rb' + - 'lib/solargraph/complex_type/type_methods.rb' + - 'lib/solargraph/complex_type/unique_type.rb' + - 'lib/solargraph/language_server/message/extended/check_gem_version.rb' + - 'lib/solargraph/language_server/message/extended/document_gems.rb' + - 'lib/solargraph/library.rb' + - 'lib/solargraph/parser/comment_ripper.rb' + - 'lib/solargraph/pin/delegated_method.rb' + - 'lib/solargraph/pin/method.rb' + - 'lib/solargraph/shell.rb' + - 'lib/solargraph/source/chain/array.rb' + - 'lib/solargraph/source/change.rb' + - 'lib/solargraph/source/source_chainer.rb' + - 'lib/solargraph/workspace.rb' Style/OpenStructUse: Exclude: @@ -1049,14 +1222,14 @@ Style/OpenStructUse: # Configuration parameters: AllowedMethods. # AllowedMethods: respond_to_missing? Style/OptionalBooleanParameter: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowSafeAssignment, AllowInMultilineConditions. -Style/ParenthesesAroundCondition: Exclude: - - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' - - 'lib/solargraph/type_checker.rb' + - 'lib/solargraph/api_map.rb' + - 'lib/solargraph/language_server/message/text_document/completion.rb' + - 'lib/solargraph/source/chain.rb' + - 'lib/solargraph/source/chain/hash.rb' + - 'lib/solargraph/source/chain/z_super.rb' + - 'lib/solargraph/source/change.rb' + - 'lib/solargraph/source/updater.rb' # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle. @@ -1071,88 +1244,30 @@ Style/RedundantArgument: Exclude: - 'lib/solargraph/source_map/mapper.rb' -# This cop supports safe autocorrection (--autocorrect). -Style/RedundantAssignment: - Exclude: - - 'lib/solargraph/language_server/host/dispatch.rb' - - 'lib/solargraph/workspace/config.rb' - -# This cop supports safe autocorrection (--autocorrect). -Style/RedundantBegin: - Exclude: - - 'lib/solargraph/language_server/transport/data_reader.rb' - - 'lib/solargraph/shell.rb' - - 'lib/solargraph/source/cursor.rb' - - 'lib/solargraph/source/encoding_fixes.rb' - - 'lib/solargraph/workspace.rb' - -# This cop supports safe autocorrection (--autocorrect). -Style/RedundantException: - Exclude: - - 'spec/language_server/host_spec.rb' - -# This cop supports safe autocorrection (--autocorrect). -Style/RedundantFreeze: - Exclude: - - 'lib/solargraph/complex_type.rb' - - 'lib/solargraph/source_map/mapper.rb' - # This cop supports unsafe autocorrection (--autocorrect-all). Style/RedundantInterpolation: Exclude: - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - 'lib/solargraph/source_map/mapper.rb' -# This cop supports safe autocorrection (--autocorrect). -Style/RedundantParentheses: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -Style/RedundantRegexpArgument: - Exclude: - - 'lib/solargraph/api_map/index.rb' - - 'lib/solargraph/workspace/config.rb' - - 'spec/diagnostics/rubocop_helpers_spec.rb' - - 'spec/diagnostics/rubocop_spec.rb' - - 'spec/language_server/host_spec.rb' - -# This cop supports safe autocorrection (--autocorrect). -Style/RedundantRegexpEscape: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowMultipleReturnValues. -Style/RedundantReturn: - Exclude: - - 'lib/solargraph/complex_type/type_methods.rb' - - 'lib/solargraph/doc_map.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/source/chain/z_super.rb' - -# This cop supports safe autocorrection (--autocorrect). -Style/RedundantSelf: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, AllowInnerSlashes. -# SupportedStyles: slashes, percent_r, mixed -Style/RegexpLiteral: - Exclude: - - 'lib/solargraph/language_server/uri_helpers.rb' - - 'lib/solargraph/workspace/config.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: implicit, explicit -Style/RescueStandardError: - Exclude: - - 'lib/solargraph/pin/base.rb' - # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength. # AllowedMethods: present?, blank?, presence, try, try! Style/SafeNavigation: - Enabled: false + Exclude: + - 'lib/solargraph/api_map/index.rb' + - 'lib/solargraph/doc_map.rb' + - 'lib/solargraph/language_server/message/completion_item/resolve.rb' + - 'lib/solargraph/language_server/request.rb' + - 'lib/solargraph/language_server/transport/data_reader.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' + - 'lib/solargraph/pin/base.rb' + - 'lib/solargraph/pin/conversions.rb' + - 'lib/solargraph/pin/method.rb' + - 'lib/solargraph/pin_cache.rb' + - 'lib/solargraph/range.rb' + - 'lib/solargraph/repro.rb' + - 'lib/solargraph/type_checker.rb' # Configuration parameters: Max. Style/SafeNavigationChainLength: @@ -1161,29 +1276,44 @@ Style/SafeNavigationChainLength: # This cop supports unsafe autocorrection (--autocorrect-all). Style/SlicingWithRange: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowModifier. -Style/SoleNestedConditional: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -Style/StderrPuts: Exclude: - - 'lib/solargraph/pin/base.rb' - - 'lib/solargraph/shell.rb' + - 'lib/solargraph/api_map.rb' + - 'lib/solargraph/complex_type/unique_type.rb' + - 'lib/solargraph/convention/data_definition/data_definition_node.rb' + - 'lib/solargraph/convention/struct_definition/struct_definition_node.rb' + - 'lib/solargraph/diagnostics/rubocop_helpers.rb' + - 'lib/solargraph/library.rb' + - 'lib/solargraph/parser/parser_gem/node_chainer.rb' + - 'lib/solargraph/parser/parser_gem/node_methods.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' + - 'lib/solargraph/pin/method.rb' + - 'lib/solargraph/pin/namespace.rb' + - 'lib/solargraph/source.rb' + - 'lib/solargraph/source/chain/constant.rb' + - 'lib/solargraph/source/change.rb' + - 'lib/solargraph/source/cursor.rb' + - 'lib/solargraph/source/source_chainer.rb' + - 'lib/solargraph/source_map/mapper.rb' + - 'lib/solargraph/type_checker/checks.rb' # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: Mode. Style/StringConcatenation: - Enabled: false + Exclude: + - 'lib/solargraph/pin/base.rb' + - 'lib/solargraph/pin/callable.rb' + - 'lib/solargraph/pin/closure.rb' + - 'lib/solargraph/pin/local_variable.rb' + - 'lib/solargraph/pin/method.rb' + - 'lib/solargraph/pin/namespace.rb' + - 'solargraph.gemspec' # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline. # SupportedStyles: single_quotes, double_quotes Style/StringLiterals: - Enabled: false + Exclude: + - 'spec/fixtures/rdoc-lib/rdoc-lib.gemspec' # This cop supports safe autocorrection (--autocorrect). Style/SuperArguments: @@ -1193,68 +1323,18 @@ Style/SuperArguments: - 'lib/solargraph/pin/method.rb' - 'lib/solargraph/pin/signature.rb' -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, MinSize. -# SupportedStyles: percent, brackets -Style/SymbolArray: - Enabled: false - # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: AllowMethodsWithArguments, AllowedMethods, AllowedPatterns, AllowComments. # AllowedMethods: define_method Style/SymbolProc: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, AllowSafeAssignment. -# SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex -Style/TernaryParentheses: - Exclude: - - 'lib/solargraph/source_map/mapper.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyleForMultiline. -# SupportedStylesForMultiline: comma, consistent_comma, no_comma -Style/TrailingCommaInArguments: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyleForMultiline. -# SupportedStylesForMultiline: comma, consistent_comma, diff_comma, no_comma -Style/TrailingCommaInArrayLiteral: - Exclude: - - 'lib/solargraph/language_server/message/text_document/formatting.rb' - - 'lib/solargraph/rbs_map/core_fills.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyleForMultiline. -# SupportedStylesForMultiline: comma, consistent_comma, diff_comma, no_comma -Style/TrailingCommaInHashLiteral: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: ExactNameMatch, AllowPredicates, AllowDSLWriters, IgnoreClassMethods, AllowedMethods. -# AllowedMethods: to_ary, to_a, to_c, to_enum, to_h, to_hash, to_i, to_int, to_io, to_open, to_path, to_proc, to_r, to_regexp, to_str, to_s, to_sym -Style/TrivialAccessors: - Exclude: - - 'lib/solargraph/language_server/message/extended/check_gem_version.rb' - - 'lib/solargraph/pin/keyword.rb' - -# This cop supports safe autocorrection (--autocorrect). -Style/WhileUntilModifier: Exclude: - - 'lib/solargraph/complex_type.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, MinSize, WordRegex. -# SupportedStyles: percent, brackets -Style/WordArray: - Enabled: false - -# This cop supports safe autocorrection (--autocorrect). -Style/YAMLFileRead: - Exclude: - - 'lib/solargraph/workspace/config.rb' + - 'lib/solargraph/gem_pins.rb' + - 'lib/solargraph/language_server/message/text_document/hover.rb' + - 'lib/solargraph/language_server/message/text_document/signature_help.rb' + - 'lib/solargraph/parser/flow_sensitive_typing.rb' + - 'lib/solargraph/pin/base.rb' + - 'lib/solargraph/pin/callable.rb' + - 'lib/solargraph/pin/closure.rb' # This cop supports unsafe autocorrection (--autocorrect-all). Style/ZeroLengthPredicate: @@ -1264,18 +1344,25 @@ Style/ZeroLengthPredicate: - 'lib/solargraph/source/chain/array.rb' - 'spec/language_server/protocol_spec.rb' -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: long, short -YARD/CollectionType: - Exclude: - - 'lib/solargraph/range.rb' - # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStylePrototypeName. # SupportedStylesPrototypeName: before, after YARD/MismatchName: - Enabled: false + Exclude: + - 'lib/solargraph/complex_type.rb' + - 'lib/solargraph/complex_type/unique_type.rb' + - 'lib/solargraph/language_server/host.rb' + - 'lib/solargraph/language_server/host/dispatch.rb' + - 'lib/solargraph/language_server/request.rb' + - 'lib/solargraph/parser/parser_gem/node_methods.rb' + - 'lib/solargraph/parser/region.rb' + - 'lib/solargraph/pin/base.rb' + - 'lib/solargraph/pin/callable.rb' + - 'lib/solargraph/pin/until.rb' + - 'lib/solargraph/pin/while.rb' + - 'lib/solargraph/source/chain/call.rb' + - 'lib/solargraph/source/chain/z_super.rb' + - 'lib/solargraph/type_checker.rb' YARD/TagTypeSyntax: Exclude: @@ -1286,7 +1373,47 @@ YARD/TagTypeSyntax: - 'lib/solargraph/type_checker.rb' # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings. +# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings. # URISchemes: http, https Layout/LineLength: - Max: 244 + Exclude: + - 'lib/solargraph/api_map.rb' + - 'lib/solargraph/api_map/store.rb' + - 'lib/solargraph/complex_type/unique_type.rb' + - 'lib/solargraph/convention/data_definition.rb' + - 'lib/solargraph/doc_map.rb' + - 'lib/solargraph/gem_pins.rb' + - 'lib/solargraph/language_server/host.rb' + - 'lib/solargraph/language_server/message/extended/check_gem_version.rb' + - 'lib/solargraph/language_server/message/extended/download_core.rb' + - 'lib/solargraph/language_server/message/initialize.rb' + - 'lib/solargraph/language_server/message/text_document/completion.rb' + - 'lib/solargraph/library.rb' + - 'lib/solargraph/parser/flow_sensitive_typing.rb' + - 'lib/solargraph/parser/parser_gem/node_methods.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb' + - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' + - 'lib/solargraph/pin/base.rb' + - 'lib/solargraph/pin/callable.rb' + - 'lib/solargraph/pin/documenting.rb' + - 'lib/solargraph/pin/method.rb' + - 'lib/solargraph/rbs_map/conversions.rb' + - 'lib/solargraph/rbs_map/core_fills.rb' + - 'lib/solargraph/shell.rb' + - 'lib/solargraph/source.rb' + - 'lib/solargraph/source/chain.rb' + - 'lib/solargraph/source/chain/call.rb' + - 'lib/solargraph/source/cursor.rb' + - 'lib/solargraph/source/source_chainer.rb' + - 'lib/solargraph/source_map/clip.rb' + - 'lib/solargraph/source_map/mapper.rb' + - 'lib/solargraph/type_checker.rb' + - 'spec/complex_type_spec.rb' + - 'spec/language_server/message/text_document/definition_spec.rb' + - 'spec/language_server/message/text_document/hover_spec.rb' + - 'spec/language_server/message/workspace/did_change_watched_files_spec.rb' + - 'spec/pin/parameter_spec.rb' + - 'spec/source/chain_spec.rb' + - 'spec/source/cursor_spec.rb' + - 'spec/source/source_chainer_spec.rb' + - 'spec/source_map/clip_spec.rb' diff --git a/Gemfile b/Gemfile index 3a5ae2b84..6849d21b5 100755 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ -source 'https://rubygems.org' - -gemspec name: 'solargraph' - -# Local gemfile for development tools, etc. -local_gemfile = File.expand_path(".Gemfile", __dir__) -instance_eval File.read local_gemfile if File.exist? local_gemfile +source 'https://rubygems.org' + +gemspec name: 'solargraph' + +# Local gemfile for development tools, etc. +local_gemfile = File.expand_path('.Gemfile', __dir__) +instance_eval File.read local_gemfile if File.exist? local_gemfile diff --git a/Rakefile b/Rakefile index d731fc786..e187a65f3 100755 --- a/Rakefile +++ b/Rakefile @@ -1,137 +1,137 @@ -require 'rake' -require 'bundler/gem_tasks' -require 'fileutils' -require 'open3' - -desc "Open a Pry session preloaded with this library" -task :console do - sh "pry -I lib -r solargraph.rb" -end - -desc "Run the type checker" -task typecheck: [:typecheck_typed] - -desc "Run the type checker at typed level - return code issues provable without annotations being correct" -task :typecheck_typed do - sh "SOLARGRAPH_ASSERTS=on bundle exec solargraph typecheck --level typed" -end - -desc "Run the type checker at strict level - report issues using type annotations" -task :typecheck_strict do - sh "SOLARGRAPH_ASSERTS=on bundle exec solargraph typecheck --level strict" -end - -desc "Run the type checker at strong level - enforce that type annotations exist" -task :typecheck_strong do - sh "SOLARGRAPH_ASSERTS=on bundle exec solargraph typecheck --level strong" -end - -desc "Run the type checker at alpha level - run high-false-alarm checks" -task :typecheck_alpha do - sh "SOLARGRAPH_ASSERTS=on bundle exec solargraph typecheck --level alpha" -end - -desc "Run RSpec tests, starting with the ones that failed last time" -task spec: %i[spec_failed undercover_no_fail full_spec] do - undercover -end - -desc "Run all RSpec tests" -task :full_spec do - warn 'starting spec' - sh 'TEST_COVERAGE_COMMAND_NAME=full-new bundle exec rspec' # --profile' - warn 'ending spec' - # move coverage/full-new to coverage/full on success so that we - # always have the last successful run's 'coverage info - FileUtils.rm_rf('coverage/full') - FileUtils.mv('coverage/full-new', 'coverage/full') -end - -# @sg-ignore #undercover return type could not be inferred -# @return [Process::Status] -def undercover - simplecov_collate - cmd = 'bundle exec undercover ' \ - '--simplecov coverage/combined/coverage.json ' \ - '--exclude-files "Rakefile,spec/*,spec/**/*,lib/solargraph/version.rb" ' \ - '--compare origin/master' - output, status = Bundler.with_unbundled_env do - Open3.capture2e(cmd) - end - puts output - $stdout.flush - status -rescue StandardError => e - warn "hit error: #{e.message}" - warn "Backtrace:\n#{e.backtrace.join("\n")}" - warn "output: #{output}" - puts "Flushing" - $stdout.flush - raise -end - -desc "Check PR coverage" -task :undercover do - raise "Undercover failed" unless undercover.success? -end - -desc "Branch-focused fast-feedback quality/spec/coverage checks" -task test: %i[overcommit spec typecheck] do - # do these in order - Rake::Task['typecheck_strict'].invoke - Rake::Task['typecheck_strong'].invoke - Rake::Task['typecheck_alpha'].invoke -end - -desc "Re-run failed specs. Add --fail-fast in your .rspec-local file if desired." -task :spec_failed do - # allow user to check out any persistent failures while looking for - # more in the whole test suite - sh 'TEST_COVERAGE_COMMAND_NAME=next-failure bundle exec rspec --only-failures || true' -end - -desc "Run undercover and show output without failing the task if it fails" -task :undercover_no_fail do - undercover -rescue StandardError - puts "Undercover failed, but continuing with other tasks." -end - -# @return [void] -def simplecov_collate - require 'simplecov' - require 'simplecov-lcov' - require 'undercover/simplecov_formatter' - - SimpleCov.collate(Dir["coverage/{next-failure,full,ad-hoc}/.resultset.json"]) do - cname = 'combined' - command_name cname - new_dir = File.join('coverage', cname) - coverage_dir new_dir - - formatter \ - SimpleCov::Formatter::MultiFormatter - .new([ - SimpleCov::Formatter::HTMLFormatter, - SimpleCov::Formatter::Undercover, - SimpleCov::Formatter::LcovFormatter - ]) - SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true - end - puts "Simplecov collated results into coverage/combined/.resultset.json" -rescue StandardError => e - puts "Simplecov collate failed: #{e.message}" -ensure - $stdout.flush -end - -desc 'Add incremental coverage for rapid iteration with undercover' -task :simplecov_collate do - simplecov_collate -end - -desc "Show quality checks on this development branch so far, including any staged files" -task :overcommit do - # OVERCOMMIT_DEBUG=1 will show more detail - sh 'SOLARGRAPH_ASSERTS=on bundle exec overcommit --run --diff origin/master' -end +require 'rake' +require 'bundler/gem_tasks' +require 'fileutils' +require 'open3' + +desc 'Open a Pry session preloaded with this library' +task :console do + sh 'pry -I lib -r solargraph.rb' +end + +desc 'Run the type checker' +task typecheck: [:typecheck_typed] + +desc 'Run the type checker at typed level - return code issues provable without annotations being correct' +task :typecheck_typed do + sh 'SOLARGRAPH_ASSERTS=on bundle exec solargraph typecheck --level typed' +end + +desc 'Run the type checker at strict level - report issues using type annotations' +task :typecheck_strict do + sh 'SOLARGRAPH_ASSERTS=on bundle exec solargraph typecheck --level strict' +end + +desc 'Run the type checker at strong level - enforce that type annotations exist' +task :typecheck_strong do + sh 'SOLARGRAPH_ASSERTS=on bundle exec solargraph typecheck --level strong' +end + +desc 'Run the type checker at alpha level - run high-false-alarm checks' +task :typecheck_alpha do + sh 'SOLARGRAPH_ASSERTS=on bundle exec solargraph typecheck --level alpha' +end + +desc 'Run RSpec tests, starting with the ones that failed last time' +task spec: %i[spec_failed undercover_no_fail full_spec] do + undercover +end + +desc 'Run all RSpec tests' +task :full_spec do + warn 'starting spec' + sh 'TEST_COVERAGE_COMMAND_NAME=full-new bundle exec rspec' # --profile' + warn 'ending spec' + # move coverage/full-new to coverage/full on success so that we + # always have the last successful run's 'coverage info + FileUtils.rm_rf('coverage/full') + FileUtils.mv('coverage/full-new', 'coverage/full') +end + +# @sg-ignore #undercover return type could not be inferred +# @return [Process::Status] +def undercover + simplecov_collate + cmd = 'bundle exec undercover ' \ + '--simplecov coverage/combined/coverage.json ' \ + '--exclude-files "Rakefile,spec/*,spec/**/*,lib/solargraph/version.rb" ' \ + '--compare origin/master' + output, status = Bundler.with_unbundled_env do + Open3.capture2e(cmd) + end + puts output + $stdout.flush + status +rescue StandardError => e + warn "hit error: #{e.message}" + warn "Backtrace:\n#{e.backtrace.join("\n")}" + warn "output: #{output}" + puts 'Flushing' + $stdout.flush + raise +end + +desc 'Check PR coverage' +task :undercover do + raise 'Undercover failed' unless undercover.success? +end + +desc 'Branch-focused fast-feedback quality/spec/coverage checks' +task test: %i[overcommit spec typecheck] do + # do these in order + Rake::Task['typecheck_strict'].invoke + Rake::Task['typecheck_strong'].invoke + Rake::Task['typecheck_alpha'].invoke +end + +desc 'Re-run failed specs. Add --fail-fast in your .rspec-local file if desired.' +task :spec_failed do + # allow user to check out any persistent failures while looking for + # more in the whole test suite + sh 'TEST_COVERAGE_COMMAND_NAME=next-failure bundle exec rspec --only-failures || true' +end + +desc 'Run undercover and show output without failing the task if it fails' +task :undercover_no_fail do + undercover +rescue StandardError + puts 'Undercover failed, but continuing with other tasks.' +end + +# @return [void] +def simplecov_collate + require 'simplecov' + require 'simplecov-lcov' + require 'undercover/simplecov_formatter' + + SimpleCov.collate(Dir['coverage/{next-failure,full,ad-hoc}/.resultset.json']) do + cname = 'combined' + command_name cname + new_dir = File.join('coverage', cname) + coverage_dir new_dir + + formatter \ + SimpleCov::Formatter::MultiFormatter + .new([ + SimpleCov::Formatter::HTMLFormatter, + SimpleCov::Formatter::Undercover, + SimpleCov::Formatter::LcovFormatter + ]) + SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true + end + puts 'Simplecov collated results into coverage/combined/.resultset.json' +rescue StandardError => e + puts "Simplecov collate failed: #{e.message}" +ensure + $stdout.flush +end + +desc 'Add incremental coverage for rapid iteration with undercover' +task :simplecov_collate do + simplecov_collate +end + +desc 'Show quality checks on this development branch so far, including any staged files' +task :overcommit do + # OVERCOMMIT_DEBUG=1 will show more detail + sh 'SOLARGRAPH_ASSERTS=on bundle exec overcommit --run --diff origin/master' +end diff --git a/lib/solargraph.rb b/lib/solargraph.rb index 038e7bccf..4b6e9355b 100755 --- a/lib/solargraph.rb +++ b/lib/solargraph.rb @@ -56,7 +56,7 @@ class InvalidRubocopVersionError < RuntimeError; end CHDIR_MUTEX = Mutex.new # @param type [Symbol] Type of assert. - def self.asserts_on?(type) + def self.asserts_on? type if ENV['SOLARGRAPH_ASSERTS'].nil? || ENV['SOLARGRAPH_ASSERTS'].empty? false elsif ENV['SOLARGRAPH_ASSERTS'] == 'on' @@ -71,8 +71,8 @@ def self.asserts_on?(type) # @param msg [String, nil] An optional message to log # @param block [Proc] A block that returns a message to log # @return [void] - def self.assert_or_log(type, msg = nil, &block) - raise (msg || block.call) if asserts_on?(type) && ![:combine_with_visibility].include?(type) + def self.assert_or_log type, msg = nil, &block + raise(msg || block.call) if asserts_on?(type) && ![:combine_with_visibility].include?(type) logger.info msg, &block end @@ -92,10 +92,10 @@ def self.logger # @return [generic] def self.with_clean_env &block meth = if Bundler.respond_to?(:with_original_env) - :with_original_env - else - :with_clean_env - end + :with_original_env + else + :with_clean_env + end Bundler.send meth, &block end end diff --git a/lib/solargraph/api_map.rb b/lib/solargraph/api_map.rb index 71855d04a..b75d814fa 100755 --- a/lib/solargraph/api_map.rb +++ b/lib/solargraph/api_map.rb @@ -37,14 +37,14 @@ def initialize pins: [] # # @param other [Object] - def eql?(other) + def eql? other self.class == other.class && equality_fields == other.equality_fields end # @param other [Object] - def ==(other) - self.eql?(other) + def == other + eql?(other) end def hash @@ -97,9 +97,9 @@ def catalog bench end unresolved_requires = (bench.external_requires + conventions_environ.requires + bench.workspace.config.required).to_a.compact.uniq recreate_docmap = @unresolved_requires != unresolved_requires || - @doc_map&.uncached_yard_gemspecs&.any? || - @doc_map&.uncached_rbs_collection_gemspecs&.any? || - @doc_map&.rbs_collection_path != bench.workspace.rbs_collection_path + @doc_map&.uncached_yard_gemspecs&.any? || + @doc_map&.uncached_rbs_collection_gemspecs&.any? || + @doc_map&.rbs_collection_path != bench.workspace.rbs_collection_path if recreate_docmap @doc_map = DocMap.new(unresolved_requires, [], bench.workspace) # @todo Implement gem preferences @unresolved_requires = @doc_map.unresolved_requires @@ -193,7 +193,7 @@ def self.load directory # @param out [IO, nil] # @return [void] - def cache_all!(out) + def cache_all! out @doc_map.cache_all!(out) end @@ -201,7 +201,7 @@ def cache_all!(out) # @param rebuild [Boolean] # @param out [IO, nil] # @return [void] - def cache_gem(gemspec, rebuild: false, out: nil) + def cache_gem gemspec, rebuild: false, out: nil @doc_map.cache(gemspec, rebuild: rebuild, out: out) end @@ -312,19 +312,19 @@ def resolve name, *gates # # @param pin [Pin::Reference] # @return [String, nil] - def dereference(pin) + def dereference pin store.constants.dereference(pin) end # @param fqns [String] # @return [Array] - def get_extends(fqns) + def get_extends fqns store.get_extends(fqns) end # @param fqns [String] # @return [Array] - def get_includes(fqns) + def get_includes fqns store.get_includes(fqns) end @@ -334,9 +334,9 @@ def get_includes(fqns) # @param namespace [String] A fully qualified namespace # @param scope [Symbol] :instance or :class # @return [Array] - def get_instance_variable_pins(namespace, scope = :instance) + def get_instance_variable_pins namespace, scope = :instance result = [] - used = [namespace] + [namespace] result.concat store.get_instance_variables(namespace, scope) sc_fqns = namespace while (sc = store.get_superclass(sc_fqns)) @@ -356,7 +356,7 @@ def visible_pins(*args, **kwargs, &blk) # # @param namespace [String] A fully qualified namespace # @return [Enumerable] - def get_class_variable_pins(namespace) + def get_class_variable_pins namespace prefer_non_nil_variables(store.get_class_variables(namespace)) end @@ -423,7 +423,7 @@ def get_methods rooted_tag, scope: :instance, visibility: [:public], deep: true comments: init_pin.comments, closure: init_pin.closure, source: init_pin.source, - type_location: init_pin.type_location, + type_location: init_pin.type_location ) new_pin.parameters = init_pin.parameters.map do |init_param| param = init_param.clone @@ -513,7 +513,8 @@ def get_complex_type_methods complex_type, context = '', internal = false # @param preserve_generics [Boolean] True to preserve any # unresolved generic parameters, false to erase them # @return [Array] - def get_method_stack rooted_tag, name, scope: :instance, visibility: [:private, :protected, :public], preserve_generics: false + def get_method_stack rooted_tag, name, scope: :instance, visibility: %i[private protected public], + preserve_generics: false rooted_type = ComplexType.parse(rooted_tag) fqns = rooted_type.namespace namespace_pin = store.get_path_pins(fqns).first @@ -636,7 +637,7 @@ def bundled? filename # @param sup [String] The superclass # @param sub [String] The subclass # @return [Boolean] - def super_and_sub?(sup, sub) + def super_and_sub? sup, sub sup = ComplexType.try_parse(sup) sub = ComplexType.try_parse(sub) # @todo If two literals are different values of the same type, it would @@ -664,21 +665,23 @@ def super_and_sub?(sup, sub) # @param module_ns [String] The module namespace (no type parameters) # # @return [Boolean] - def type_include?(host_ns, module_ns) + def type_include? host_ns, module_ns store.get_includes(host_ns).map { |inc_tag| inc_tag.parametrized_tag.name }.include?(module_ns) end # @param pins [Enumerable] # @param visibility [Enumerable] # @return [Array] - def resolve_method_aliases pins, visibility = [:public, :private, :protected] + def resolve_method_aliases pins, visibility = %i[public private protected] with_resolved_aliases = pins.map do |pin| next pin unless pin.is_a?(Pin::MethodAlias) resolved = resolve_method_alias(pin) next nil if resolved.respond_to?(:visibility) && !visibility.include?(resolved.visibility) resolved end.compact - logger.debug { "ApiMap#resolve_method_aliases(pins=#{pins.map(&:name)}, visibility=#{visibility}) => #{with_resolved_aliases.map(&:name)}" } + logger.debug do + "ApiMap#resolve_method_aliases(pins=#{pins.map(&:name)}, visibility=#{visibility}) => #{with_resolved_aliases.map(&:name)}" + end GemPins.combine_method_pins_by_path(with_resolved_aliases) end @@ -693,7 +696,7 @@ def resolve_method_aliases pins, visibility = [:public, :private, :protected] # @param skip [Set] # @param no_core [Boolean] Skip core classes if true # @return [Array] - def inner_get_methods_from_reference(fq_reference_tag, namespace_pin, type, scope, visibility, deep, skip, no_core) + def inner_get_methods_from_reference fq_reference_tag, namespace_pin, type, scope, visibility, deep, skip, no_core logger.debug { "ApiMap#add_methods_from_reference(type=#{type}) starting" } # Ensure the types returned by the methods in the referenced @@ -743,7 +746,7 @@ def store def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false rooted_type = ComplexType.parse(rooted_tag).force_rooted fqns = rooted_type.namespace - fqns_generic_params = rooted_type.all_params + rooted_type.all_params namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first return [] if no_core && fqns =~ /^(Object|BasicObject|Class|Module)$/ reqstr = "#{fqns}|#{scope}|#{visibility.sort}|#{deep}" @@ -754,7 +757,9 @@ def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false # ensure we start out with any immediate methods in this # namespace so we roughly match the same ordering of get_methods # and obey the 'deep' instruction - direct_convention_methods, convention_methods_by_reference = environ.pins.partition { |p| p.namespace == rooted_tag } + direct_convention_methods, convention_methods_by_reference = environ.pins.partition do |p| + p.namespace == rooted_tag + end result.concat direct_convention_methods if deep && scope == :instance @@ -766,8 +771,10 @@ def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false # Store#get_methods doesn't know about full tags, just # namespaces; resolving the generics in the method pins is this # class' responsibility - methods = store.get_methods(fqns, scope: scope, visibility: visibility).sort{ |a, b| a.name <=> b.name } - logger.info { "ApiMap#inner_get_methods(rooted_tag=#{rooted_tag.inspect}, scope=#{scope.inspect}, visibility=#{visibility.inspect}, deep=#{deep.inspect}, skip=#{skip.inspect}, fqns=#{fqns}) - added from store: #{methods}" } + methods = store.get_methods(fqns, scope: scope, visibility: visibility).sort { |a, b| a.name <=> b.name } + logger.info do + "ApiMap#inner_get_methods(rooted_tag=#{rooted_tag.inspect}, scope=#{scope.inspect}, visibility=#{visibility.inspect}, deep=#{deep.inspect}, skip=#{skip.inspect}, fqns=#{fqns}) - added from store: #{methods}" + end result.concat methods if deep result.concat convention_methods_by_reference @@ -783,22 +790,27 @@ def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false else referenced_tag = ref.parametrized_tag next unless referenced_tag.defined? - result.concat inner_get_methods_from_reference(referenced_tag.to_s, namespace_pin, rooted_type, scope, visibility, deep, skip, true) + result.concat inner_get_methods_from_reference(referenced_tag.to_s, namespace_pin, rooted_type, scope, + visibility, deep, skip, true) end end rooted_sc_tag = qualify_superclass(rooted_tag) unless rooted_sc_tag.nil? - result.concat inner_get_methods_from_reference(rooted_sc_tag, namespace_pin, rooted_type, scope, visibility, true, skip, no_core) + result.concat inner_get_methods_from_reference(rooted_sc_tag, namespace_pin, rooted_type, scope, + visibility, true, skip, no_core) end else - logger.info { "ApiMap#inner_get_methods(#{fqns}, #{scope}, #{visibility}, #{deep}, #{skip}) - looking for get_extends() from #{fqns}" } + logger.info do + "ApiMap#inner_get_methods(#{fqns}, #{scope}, #{visibility}, #{deep}, #{skip}) - looking for get_extends() from #{fqns}" + end store.get_extends(fqns).reverse.each do |em| fqem = store.constants.dereference(em) result.concat inner_get_methods(fqem, :instance, visibility, deep, skip, true) unless fqem.nil? end rooted_sc_tag = qualify_superclass(rooted_tag) unless rooted_sc_tag.nil? - result.concat inner_get_methods_from_reference(rooted_sc_tag, namespace_pin, rooted_type, scope, visibility, true, skip, true) + result.concat inner_get_methods_from_reference(rooted_sc_tag, namespace_pin, rooted_type, scope, + visibility, true, skip, true) end unless no_core || fqns.empty? type = get_namespace_type(fqns) @@ -832,7 +844,7 @@ def qualify_superclass fq_sub_tag def get_namespace_type fqns return nil if fqns.nil? # @type [Pin::Namespace, nil] - pin = store.get_path_pins(fqns).select{|p| p.is_a?(Pin::Namespace)}.first + pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first return nil if pin.nil? pin.type end @@ -856,11 +868,9 @@ def prefer_non_nil_variables pins include Logging - private - # @param alias_pin [Pin::MethodAlias] # @return [Pin::Method, nil] - def resolve_method_alias(alias_pin) + def resolve_method_alias alias_pin ancestors = store.get_ancestors(alias_pin.full_context.reduce_class_type.tag) original = nil @@ -893,7 +903,7 @@ def resolve_method_alias(alias_pin) # @param alias_pin [Pin::MethodAlias] The alias pin to resolve # @param original [Pin::Method] The original method pin that was already found # @return [Pin::Method] The resolved method pin - def create_resolved_alias_pin(alias_pin, original) + def create_resolved_alias_pin alias_pin, original # Build the resolved method pin directly (same logic as resolve_method_alias but without lookup) args = { location: alias_pin.location, @@ -909,7 +919,7 @@ def create_resolved_alias_pin(alias_pin, original) return_type: original.return_type, source: :resolve_method_alias } - resolved_pin = Pin::Method.new **args + resolved_pin = Pin::Method.new(**args) # Clone signatures and parameters resolved_pin.signatures.each do |sig| @@ -931,7 +941,7 @@ def create_resolved_alias_pin(alias_pin, original) # @param rooted_type [ComplexType] # @param pins [Enumerable] # @return [Array] - def erase_generics(namespace_pin, rooted_type, pins) + def erase_generics namespace_pin, rooted_type, pins return pins unless should_erase_generics_when_done?(namespace_pin, rooted_type) logger.debug("Erasing generics on namespace_pin=#{namespace_pin} / rooted_type=#{rooted_type}") @@ -942,18 +952,18 @@ def erase_generics(namespace_pin, rooted_type, pins) # @param namespace_pin [Pin::Namespace] # @param rooted_type [ComplexType] - def should_erase_generics_when_done?(namespace_pin, rooted_type) + def should_erase_generics_when_done? namespace_pin, rooted_type has_generics?(namespace_pin) && !can_resolve_generics?(namespace_pin, rooted_type) end # @param namespace_pin [Pin::Namespace, Pin::Constant] - def has_generics?(namespace_pin) + def has_generics? namespace_pin namespace_pin.is_a?(Pin::Namespace) && !namespace_pin.generics.empty? end # @param namespace_pin [Pin::Namespace] # @param rooted_type [ComplexType] - def can_resolve_generics?(namespace_pin, rooted_type) + def can_resolve_generics? namespace_pin, rooted_type has_generics?(namespace_pin) && !rooted_type.all_params.empty? end end diff --git a/lib/solargraph/api_map/index.rb b/lib/solargraph/api_map/index.rb index 35d86446a..fbf8fc45c 100644 --- a/lib/solargraph/api_map/index.rb +++ b/lib/solargraph/api_map/index.rb @@ -130,9 +130,7 @@ def map_overrides pins = path_pin_hash[ovr.name] logger.debug { "ApiMap::Index#map_overrides: pins for path=#{ovr.name}: #{pins}" } pins.each do |pin| - new_pin = if pin.path.end_with?('#initialize') - path_pin_hash[pin.path.sub(/#initialize/, '.new')].first - end + new_pin = (path_pin_hash[pin.path.sub('#initialize', '.new')].first if pin.path.end_with?('#initialize')) (ovr.tags.map(&:tag_name) + ovr.delete).uniq.each do |tag| pin.docstring.delete_tags tag new_pin.docstring.delete_tags tag if new_pin diff --git a/lib/solargraph/api_map/source_to_yard.rb b/lib/solargraph/api_map/source_to_yard.rb index ccbed3eb6..42d53189b 100644 --- a/lib/solargraph/api_map/source_to_yard.rb +++ b/lib/solargraph/api_map/source_to_yard.rb @@ -3,7 +3,6 @@ module Solargraph class ApiMap module SourceToYard - # Get the YARD CodeObject at the specified path. # # @generic T @@ -32,15 +31,15 @@ def rake_yard store next end if pin.type == :class - code_object_map[pin.path] ||= YARD::CodeObjects::ClassObject.new(root_code_object, pin.path) { |obj| + code_object_map[pin.path] ||= YARD::CodeObjects::ClassObject.new(root_code_object, pin.path) do |obj| next if pin.location.nil? || pin.location.filename.nil? obj.add_file(pin.location.filename, pin.location.range.start.line, !pin.comments.empty?) - } + end else - code_object_map[pin.path] ||= YARD::CodeObjects::ModuleObject.new(root_code_object, pin.path) { |obj| + code_object_map[pin.path] ||= YARD::CodeObjects::ModuleObject.new(root_code_object, pin.path) do |obj| next if pin.location.nil? || pin.location.filename.nil? obj.add_file(pin.location.filename, pin.location.range.start.line, !pin.comments.empty?) - } + end end code_object_map[pin.path].docstring = pin.docstring store.get_includes(pin.path).each do |ref| @@ -65,10 +64,12 @@ def rake_yard store next end - code_object_map[pin.path] ||= YARD::CodeObjects::MethodObject.new(code_object_at(pin.namespace, YARD::CodeObjects::NamespaceObject), pin.name, pin.scope) { |obj| + code_object_map[pin.path] ||= YARD::CodeObjects::MethodObject.new( + code_object_at(pin.namespace, YARD::CodeObjects::NamespaceObject), pin.name, pin.scope + ) do |obj| next if pin.location.nil? || pin.location.filename.nil? obj.add_file pin.location.filename, pin.location.range.start.line - } + end method_object = code_object_at(pin.path, YARD::CodeObjects::MethodObject) method_object.docstring = pin.docstring method_object.visibility = pin.visibility || :public diff --git a/lib/solargraph/api_map/store.rb b/lib/solargraph/api_map/store.rb index c41e19c09..59cbc969f 100644 --- a/lib/solargraph/api_map/store.rb +++ b/lib/solargraph/api_map/store.rb @@ -37,10 +37,10 @@ def update *pinsets pinsets[changed..].each_with_index do |pins, idx| @pinsets[changed + idx] = pins @indexes[changed + idx] = if pins.empty? - @indexes[changed + idx - 1] - else - @indexes[changed + idx - 1].merge(pins) - end + @indexes[changed + idx - 1] + else + @indexes[changed + idx - 1].merge(pins) + end end constants.clear cached_qualify_superclass.clear @@ -59,9 +59,9 @@ def inspect # @param visibility [Array] # @return [Enumerable] def get_constants fqns, visibility = [:public] - namespace_children(fqns).select { |pin| + namespace_children(fqns).select do |pin| !pin.name.empty? && (pin.is_a?(Pin::Namespace) || pin.is_a?(Pin::Constant)) && visibility.include?(pin.visibility) - } + end end # @param fqns [String] @@ -75,8 +75,10 @@ def get_methods fqns, scope: :instance, visibility: [:public] GemPins.combine_method_pins_by_path(all_pins) end - BOOLEAN_SUPERCLASS_PIN = Pin::Reference::Superclass.new(name: 'Boolean', closure: Pin::ROOT_PIN, source: :solargraph) - OBJECT_SUPERCLASS_PIN = Pin::Reference::Superclass.new(name: 'Object', closure: Pin::ROOT_PIN, source: :solargraph) + BOOLEAN_SUPERCLASS_PIN = Pin::Reference::Superclass.new(name: 'Boolean', closure: Pin::ROOT_PIN, + source: :solargraph) + OBJECT_SUPERCLASS_PIN = Pin::Reference::Superclass.new(name: 'Object', closure: Pin::ROOT_PIN, + source: :solargraph) # @param fqns [String] # @return [Pin::Reference::Superclass] @@ -127,17 +129,17 @@ def get_path_pins path # @param fqns [String] # @param scope [Symbol] :class or :instance # @return [Enumerable] - def get_instance_variables(fqns, scope = :instance) - all_instance_variables.select { |pin| + def get_instance_variables fqns, scope = :instance + all_instance_variables.select do |pin| pin.binder.namespace == fqns && pin.binder.scope == scope - } + end end # @param fqns [String] # # @return [Enumerable] - def get_class_variables(fqns) - namespace_children(fqns).select { |pin| pin.is_a?(Pin::ClassVariable)} + def get_class_variables fqns + namespace_children(fqns).select { |pin| pin.is_a?(Pin::ClassVariable) } end # @return [Enumerable] @@ -147,7 +149,7 @@ def get_symbols # @param fqns [String] # @return [Boolean] - def namespace_exists?(fqns) + def namespace_exists? fqns fqns_pins(fqns).any? end @@ -168,7 +170,7 @@ def method_pins # @param fqns [String] # @return [Array] - def domains(fqns) + def domains fqns result = [] fqns_pins(fqns).each do |nspin| result.concat nspin.domains @@ -181,7 +183,7 @@ def named_macros @named_macros ||= begin result = {} pins.each do |pin| - pin.macros.select{|m| m.tag.tag_name == 'macro' && !m.tag.text.empty? }.each do |macro| + pin.macros.select { |m| m.tag.tag_name == 'macro' && !m.tag.text.empty? }.each do |macro| next if macro.tag.name.nil? || macro.tag.name.empty? result[macro.tag.name] = macro end @@ -220,7 +222,7 @@ def fqns_pins fqns # Get all ancestors (superclasses, includes, prepends, extends) for a namespace # @param fqns [String] The fully qualified namespace # @return [Array] Array of ancestor namespaces including the original - def get_ancestors(fqns) + def get_ancestors fqns return [] if fqns.nil? || fqns.empty? ancestors = [fqns] @@ -259,7 +261,7 @@ def get_ancestors(fqns) # @param fqns [String] # # @return [Array] - def get_ancestor_references(fqns) + def get_ancestor_references fqns (get_prepends(fqns) + get_includes(fqns) + [get_superclass(fqns)]).compact end @@ -346,7 +348,7 @@ def all_instance_variables # @param fqns [String] # @return [Pin::Reference::Superclass, nil] - def try_special_superclasses(fqns) + def try_special_superclasses fqns return OBJECT_SUPERCLASS_PIN if fqns == 'Boolean' return OBJECT_SUPERCLASS_PIN if !%w[BasicObject Object].include?(fqns) && namespace_exists?(fqns) diff --git a/lib/solargraph/bench.rb b/lib/solargraph/bench.rb index e6180c933..ed72c5a82 100644 --- a/lib/solargraph/bench.rb +++ b/lib/solargraph/bench.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true - module Solargraph # A container of source maps and workspace data to be cataloged in an ApiMap. # diff --git a/lib/solargraph/complex_type.rb b/lib/solargraph/complex_type.rb index 669a66900..f3ce631c4 100644 --- a/lib/solargraph/complex_type.rb +++ b/lib/solargraph/complex_type.rb @@ -4,7 +4,7 @@ module Solargraph # A container for type data based on YARD type tags. # class ComplexType - GENERIC_TAG_NAME = 'generic'.freeze + GENERIC_TAG_NAME = 'generic' # @!parse # include TypeMethods include Equality @@ -18,7 +18,7 @@ def initialize types = [UniqueType::UNDEFINED] # @type [Array] items = types.flat_map(&:items).uniq(&:to_s) if items.any? { |i| i.name == 'false' } && items.any? { |i| i.name == 'true' } - items.delete_if { |i| i.name == 'false' || i.name == 'true' } + items.delete_if { |i| %w[false true].include?(i.name) } items.unshift(ComplexType::BOOLEAN) end items = [UniqueType::UNDEFINED] if items.any?(&:undefined?) @@ -33,10 +33,11 @@ def initialize types = [UniqueType::UNDEFINED] # @param api_map [ApiMap] # @param context [String] # @return [ComplexType] + # @param [Array] gates def qualify api_map, *gates red = reduce_object types = red.items.map do |t| - next t if ['nil', 'void', 'undefined'].include?(t.name) + next t if %w[nil void undefined].include?(t.name) next t if ['::Boolean'].include?(t.rooted_name) t.qualify api_map, *gates end @@ -50,7 +51,10 @@ def qualify api_map, *gates def resolve_generics_from_context generics_to_resolve, context_type, resolved_generic_values: {} return self unless generic? - ComplexType.new(@items.map { |i| i.resolve_generics_from_context(generics_to_resolve, context_type, resolved_generic_values: resolved_generic_values) }) + ComplexType.new(@items.map do |i| + i.resolve_generics_from_context(generics_to_resolve, context_type, + resolved_generic_values: resolved_generic_values) + end) end # @return [UniqueType] @@ -78,13 +82,13 @@ def self_to_type dst # @yieldparam [UniqueType] # @return [Array] def map &block - @items.map &block + @items.map(&block) end # @yieldparam [UniqueType] # @return [Enumerable] def each &block - @items.each &block + @items.each(&block) end # @yieldparam [UniqueType] @@ -95,13 +99,13 @@ def each_unique_type &block return enum_for(__method__) unless block_given? @items.each do |item| - item.each_unique_type &block + item.each_unique_type(&block) end end # @param atype [ComplexType] type which may be assigned to this type # @param api_map [ApiMap] The ApiMap that performs qualification - def can_assign?(api_map, atype) + def can_assign? api_map, atype any? { |ut| ut.can_assign?(api_map, atype) } end @@ -117,13 +121,13 @@ def to_a # @param index [Integer] # @return [UniqueType] - def [](index) + def [] index @items[index] end # @return [Array] def select &block - @items.select &block + @items.select(&block) end # @return [String] @@ -139,6 +143,7 @@ def namespaces # @param name [Symbol] # @return [Object, nil] + # @param [Array] args def method_missing name, *args, &block return if @items.first.nil? return @items.first.send(name, *args, &block) if respond_to_missing?(name) @@ -147,7 +152,7 @@ def method_missing name, *args, &block # @param name [Symbol] # @param include_private [Boolean] - def respond_to_missing?(name, include_private = false) + def respond_to_missing? name, include_private = false TypeMethods.public_instance_methods.include?(name) || super end @@ -186,14 +191,14 @@ def rooted_tags # @yieldparam [UniqueType] def all? &block - @items.all? &block + @items.all?(&block) end # @yieldparam [UniqueType] # @yieldreturn [Boolean] # @return [Boolean] def any? &block - @items.compact.any? &block + @items.compact.any?(&block) end def selfy? @@ -213,8 +218,10 @@ def simplify_literals # @yieldparam t [UniqueType] # @yieldreturn [UniqueType] # @return [ComplexType] - def transform(new_name = nil, &transform_type) - raise "Please remove leading :: and set rooted with recreate() instead - #{new_name}" if new_name&.start_with?('::') + def transform new_name = nil, &transform_type + if new_name&.start_with?('::') + raise "Please remove leading :: and set rooted with recreate() instead - #{new_name}" + end ComplexType.new(map { |ut| ut.transform(new_name, &transform_type) }) end @@ -245,7 +252,7 @@ def all_params # @return [ComplexType] def reduce_class_type new_items = items.flat_map do |type| - next type unless ['Module', 'Class'].include?(type.name) + next type unless %w[Module Class].include?(type.name) next type if type.all_params.empty? type.all_params @@ -309,6 +316,7 @@ class << self # Chain::Call needs to know the decl type (:arg, :optarg, # :kwarg, etc) of the arguments given, instead of just having # an array of Chains as the arguments. + # @param [Boolean] partial def parse *strings, partial: false # @type [Hash{Array => ComplexType}] @cache ||= {} @@ -326,14 +334,14 @@ def parse *strings, partial: false subtype_string = String.new type_string&.each_char do |char| if char == '=' - #raise ComplexTypeError, "Invalid = in type #{type_string}" unless curly_stack > 0 + # raise ComplexTypeError, "Invalid = in type #{type_string}" unless curly_stack > 0 elsif char == '<' point_stack += 1 elsif char == '>' if subtype_string.end_with?('=') && curly_stack > 0 subtype_string += char elsif base.end_with?('=') - raise ComplexTypeError, "Invalid hash thing" unless key_types.nil? + raise ComplexTypeError, 'Invalid hash thing' unless key_types.nil? # types.push ComplexType.new([UniqueType.new(base[0..-2].strip)]) types.push UniqueType.parse(base[0..-2].strip, subtype_string) # @todo this should either expand key_type's type @@ -377,12 +385,15 @@ def parse *strings, partial: false subtype_string.concat char end end - raise ComplexTypeError, "Unclosed subtype in #{type_string}" if point_stack != 0 || curly_stack != 0 || paren_stack != 0 + if point_stack != 0 || curly_stack != 0 || paren_stack != 0 + raise ComplexTypeError, + "Unclosed subtype in #{type_string}" + end # types.push ComplexType.new([UniqueType.new(base, subtype_string)]) types.push UniqueType.parse(base.strip, subtype_string.strip) end unless key_types.nil? - raise ComplexTypeError, "Invalid use of key/value parameters" unless partial + raise ComplexTypeError, 'Invalid use of key/value parameters' unless partial return key_types if types.empty? return [key_types, types] end @@ -394,7 +405,7 @@ def parse *strings, partial: false # @param strings [Array] # @return [ComplexType] def try_parse *strings - parse *strings + parse(*strings) rescue ComplexTypeError => e Solargraph.logger.info "Error parsing complex type `#{strings.join(', ')}`: #{e.message}" ComplexType::UNDEFINED @@ -419,9 +430,7 @@ def try_parse *strings # @param dst [String] # @return [String] def reduce_class dst - while dst =~ /^(Class|Module)\<(.*?)\>$/ - dst = dst.sub(/^(Class|Module)\$/, '') - end + dst = dst.sub(/^(Class|Module)$/, '') while dst =~ /^(Class|Module)<(.*?)>$/ dst end end diff --git a/lib/solargraph/complex_type/type_methods.rb b/lib/solargraph/complex_type/type_methods.rb index d8d4fc7d7..a19d3306f 100644 --- a/lib/solargraph/complex_type/type_methods.rb +++ b/lib/solargraph/complex_type/type_methods.rb @@ -71,7 +71,7 @@ def undefined? # @param generics_to_erase [Enumerable] # @return [self] - def erase_generics(generics_to_erase) + def erase_generics generics_to_erase transform do |type| if type.name == ComplexType::GENERIC_TAG_NAME if type.all_params.length == 1 && generics_to_erase.include?(type.all_params.first.to_s) @@ -126,7 +126,7 @@ def namespace @namespace ||= lambda do return 'Object' if duck_type? return 'NilClass' if nil_type? - return (name == 'Class' || name == 'Module') && !subtypes.empty? ? subtypes.first.name : name + %w[Class Module].include?(name) && !subtypes.empty? ? subtypes.first.name : name end.call end @@ -134,7 +134,7 @@ def namespace def namespace_type return ComplexType.parse('::Object') if duck_type? return ComplexType.parse('::NilClass') if nil_type? - return subtypes.first if (name == 'Class' || name == 'Module') && !subtypes.empty? + return subtypes.first if %w[Class Module].include?(name) && !subtypes.empty? self end @@ -161,7 +161,7 @@ def rooted_substring end # @return [String] - def generate_substring_from(&to_str) + def generate_substring_from &to_str key_types_str = key_types.map(&to_str).join(', ') subtypes_str = subtypes.map(&to_str).join(', ') if key_types.none?(&:defined?) && subtypes.none?(&:defined?) @@ -172,19 +172,17 @@ def generate_substring_from(&to_str) "{#{key_types_str} => #{subtypes_str}}" elsif fixed_parameters? "(#{subtypes_str})" + elsif name == 'Hash' + "<#{key_types_str}, #{subtypes_str}>" else - if name == 'Hash' - "<#{key_types_str}, #{subtypes_str}>" - else - "<#{key_types_str}#{subtypes_str}>" - end + "<#{key_types_str}#{subtypes_str}>" end end # @return [::Symbol] :class or :instance def scope @scope ||= :instance if duck_type? || nil_type? - @scope ||= (name == 'Class' || name == 'Module') && !subtypes.empty? ? :class : :instance + @scope ||= %w[Class Module].include?(name) && !subtypes.empty? ? :class : :instance end # @param other [Object] diff --git a/lib/solargraph/complex_type/unique_type.rb b/lib/solargraph/complex_type/unique_type.rb index 05a585dcf..5e95ab3d0 100644 --- a/lib/solargraph/complex_type/unique_type.rb +++ b/lib/solargraph/complex_type/unique_type.rb @@ -26,9 +26,7 @@ class UniqueType # @param make_rooted [Boolean, nil] # @return [UniqueType] def self.parse name, substring = '', make_rooted: nil - if name.start_with?(':::') - raise ComplexTypeError, "Illegal prefix: #{name}" - end + raise ComplexTypeError, "Illegal prefix: #{name}" if name.start_with?(':::') if name.start_with?('::') name = name[2..-1] rooted = true @@ -48,13 +46,17 @@ def self.parse name, substring = '', make_rooted: nil subs = ComplexType.parse(substring[1..-2], partial: true) parameters_type = PARAMETERS_TYPE_BY_STARTING_TAG.fetch(substring[0]) if parameters_type == :hash - raise ComplexTypeError, "Bad hash type: name=#{name}, substring=#{substring}" unless !subs.is_a?(ComplexType) and subs.length == 2 and !subs[0].is_a?(UniqueType) and !subs[1].is_a?(UniqueType) + unless !subs.is_a?(ComplexType) and subs.length == 2 and !subs[0].is_a?(UniqueType) and !subs[1].is_a?(UniqueType) + raise ComplexTypeError, + "Bad hash type: name=#{name}, substring=#{substring}" + end key_types.concat(subs[0].map { |u| ComplexType.new([u]) }) subtypes.concat(subs[1].map { |u| ComplexType.new([u]) }) elsif parameters_type == :list && name == 'Hash' # Treat Hash as Hash{A => B} if subs.length != 2 - raise ComplexTypeError, "Bad hash type: name=#{name}, substring=#{substring} - must have exactly two parameters" + raise ComplexTypeError, + "Bad hash type: name=#{name}, substring=#{substring} - must have exactly two parameters" end key_types.concat(subs[0].map { |u| ComplexType.new([u]) }) subtypes.concat(subs[1].map { |u| ComplexType.new([u]) }) @@ -70,9 +72,9 @@ def self.parse name, substring = '', make_rooted: nil # @param subtypes [Array] # @param rooted [Boolean] # @param parameters_type [Symbol, nil] - def initialize(name, key_types = [], subtypes = [], rooted:, parameters_type: nil) - if parameters_type.nil? - raise "You must supply parameters_type if you provide parameters" unless key_types.empty? && subtypes.empty? + def initialize name, key_types = [], subtypes = [], rooted:, parameters_type: nil + if parameters_type.nil? && !(key_types.empty? && subtypes.empty?) + raise 'You must supply parameters_type if you provide parameters' end raise "Please remove leading :: and set rooted instead - #{name.inspect}" if name.start_with?('::') @name = name @@ -94,7 +96,7 @@ def implicit_union? # @todo use api_map to establish number of generics in type; # if only one is allowed but multiple are passed in, treat # those as implicit unions - ['Hash', 'Array', 'Set', '_ToAry', 'Enumerable', '_Each'].include?(name) && parameters_type != :fixed + %w[Hash Array Set _ToAry Enumerable _Each].include?(name) && parameters_type != :fixed end def to_s @@ -129,14 +131,14 @@ def determine_non_literal_name # | `false` return name if name.empty? return 'NilClass' if name == 'nil' - return 'Boolean' if ['true', 'false'].include?(name) + return 'Boolean' if %w[true false].include?(name) return 'Symbol' if name[0] == ':' return 'String' if ['"', "'"].include?(name[0]) return 'Integer' if name.match?(/^-?\d+$/) name end - def eql?(other) + def eql? other self.class == other.class && @name == other.name && @key_types == other.key_types && @@ -146,7 +148,7 @@ def eql?(other) @parameters_type == other.parameters_type end - def ==(other) + def == other eql?(other) end @@ -185,9 +187,9 @@ def to_rbs 'nil' elsif name == GENERIC_TAG_NAME all_params.first.name - elsif ['Class', 'Module'].include?(name) + elsif %w[Class Module].include?(name) rbs_name - elsif ['Tuple', 'Array'].include?(name) && fixed_parameters? + elsif %w[Tuple Array].include?(name) && fixed_parameters? # tuples don't have a name; they're just [foo, bar, baz]. if substring == '()' # but there are no zero element tuples, so we go with an array @@ -212,7 +214,7 @@ def parameters? # @param types [Array] # @return [String] - def rbs_union(types) + def rbs_union types if types.length == 1 types.first.to_rbs else @@ -238,13 +240,15 @@ def generic? # @param api_map [ApiMap] The ApiMap that performs qualification # @param atype [ComplexType] type which may be assigned to this type - def can_assign?(api_map, atype) + def can_assign? api_map, atype logger.debug { "UniqueType#can_assign?(self=#{rooted_tags.inspect}, atype=#{atype.rooted_tags.inspect})" } downcasted_atype = atype.downcast_to_literal_if_possible out = downcasted_atype.all? do |autype| autype.name == name || api_map.super_and_sub?(name, autype.name) end - logger.debug { "UniqueType#can_assign?(self=#{rooted_tags.inspect}, atype=#{atype.rooted_tags.inspect}) => #{out}" } + logger.debug do + "UniqueType#can_assign?(self=#{rooted_tags.inspect}, atype=#{atype.rooted_tags.inspect}) => #{out}" + end out end @@ -267,15 +271,18 @@ def resolve_generics_from_context generics_to_resolve, context_type, resolved_ge end if new_binding resolved_generic_values.transform_values! do |complex_type| - complex_type.resolve_generics_from_context(generics_to_resolve, nil, resolved_generic_values: resolved_generic_values) + complex_type.resolve_generics_from_context(generics_to_resolve, nil, + resolved_generic_values: resolved_generic_values) end end return resolved_generic_values[type_param] || self end # @todo typechecking should complain when the method being called has no @yieldparam tag - new_key_types = resolve_param_generics_from_context(generics_to_resolve, context_type, resolved_generic_values, &:key_types) - new_subtypes = resolve_param_generics_from_context(generics_to_resolve, context_type, resolved_generic_values, &:subtypes) + new_key_types = resolve_param_generics_from_context(generics_to_resolve, context_type, resolved_generic_values, + &:key_types) + new_subtypes = resolve_param_generics_from_context(generics_to_resolve, context_type, resolved_generic_values, + &:subtypes) recreate(new_key_types: new_key_types, new_subtypes: new_subtypes) end @@ -284,7 +291,7 @@ def resolve_generics_from_context generics_to_resolve, context_type, resolved_ge # @param resolved_generic_values [Hash{String => ComplexType}] # @yieldreturn [Array] # @return [Array] - def resolve_param_generics_from_context(generics_to_resolve, context_type, resolved_generic_values) + def resolve_param_generics_from_context generics_to_resolve, context_type, resolved_generic_values types = yield self types.each_with_index.flat_map do |ct, i| ct.items.flat_map do |ut| @@ -292,10 +299,12 @@ def resolve_param_generics_from_context(generics_to_resolve, context_type, resol if context_params && context_params[i] type_arg = context_params[i] type_arg.map do |new_unique_context_type| - ut.resolve_generics_from_context generics_to_resolve, new_unique_context_type, resolved_generic_values: resolved_generic_values + ut.resolve_generics_from_context generics_to_resolve, new_unique_context_type, + resolved_generic_values: resolved_generic_values end else - ut.resolve_generics_from_context generics_to_resolve, nil, resolved_generic_values: resolved_generic_values + ut.resolve_generics_from_context generics_to_resolve, nil, + resolved_generic_values: resolved_generic_values end end end @@ -357,7 +366,7 @@ def to_a # @param rooted [Boolean, nil] # @param new_subtypes [Array, nil] # @return [self] - def recreate(new_name: nil, make_rooted: nil, new_key_types: nil, new_subtypes: nil) + def recreate new_name: nil, make_rooted: nil, new_key_types: nil, new_subtypes: nil raise "Please remove leading :: and set rooted instead - #{new_name}" if new_name&.start_with?('::') new_name ||= name @@ -390,8 +399,10 @@ def force_rooted # @yieldparam t [UniqueType] # @yieldreturn [self] # @return [self] - def transform(new_name = nil, &transform_type) - raise "Please remove leading :: and set rooted with recreate() instead - #{new_name}" if new_name&.start_with?('::') + def transform new_name = nil, &transform_type + if new_name&.start_with?('::') + raise "Please remove leading :: and set rooted with recreate() instead - #{new_name}" + end if name == ComplexType::GENERIC_TAG_NAME # doesn't make sense to manipulate the name of the generic new_key_types = @key_types @@ -400,7 +411,8 @@ def transform(new_name = nil, &transform_type) new_key_types = @key_types.flat_map { |ct| ct.items.map { |ut| ut.transform(&transform_type) } } new_subtypes = @subtypes.flat_map { |ct| ct.items.map { |ut| ut.transform(&transform_type) } } end - new_type = recreate(new_name: new_name || name, new_key_types: new_key_types, new_subtypes: new_subtypes, make_rooted: @rooted) + new_type = recreate(new_name: new_name || name, new_key_types: new_key_types, new_subtypes: new_subtypes, + make_rooted: @rooted) yield new_type end @@ -409,6 +421,7 @@ def transform(new_name = nil, &transform_type) # @param api_map [ApiMap] The ApiMap that performs qualification # @param context [String] The namespace from which to resolve names # @return [self, ComplexType, UniqueType] The generated ComplexType + # @param [Array] gates def qualify api_map, *gates transform do |t| next t if t.name == GENERIC_TAG_NAME @@ -447,12 +460,12 @@ def rooted? end # @param name_to_check [String] - def can_root_name?(name_to_check = name) + def can_root_name? name_to_check = name self.class.can_root_name?(name_to_check) end # @param name [String] - def self.can_root_name?(name) + def self.can_root_name? name # name is not lowercase !name.empty? && name != name.downcase end @@ -469,7 +482,6 @@ def self.can_root_name?(name) '::NilClass' => UniqueType::NIL }.freeze - include Logging end end diff --git a/lib/solargraph/convention.rb b/lib/solargraph/convention.rb index 89eac82b7..5e73eb3bf 100644 --- a/lib/solargraph/convention.rb +++ b/lib/solargraph/convention.rb @@ -30,7 +30,7 @@ def self.unregister convention # @param source_map [SourceMap] # @return [Environ] - def self.for_local(source_map) + def self.for_local source_map result = Environ.new @@conventions.each do |conv| result.merge conv.local(source_map) @@ -40,7 +40,7 @@ def self.for_local(source_map) # @param doc_map [DocMap] # @return [Environ] - def self.for_global(doc_map) + def self.for_global doc_map result = Environ.new @@conventions.each do |conv| result.merge conv.global(doc_map) diff --git a/lib/solargraph/convention/data_definition.rb b/lib/solargraph/convention/data_definition.rb index 8efe27932..ef437238d 100644 --- a/lib/solargraph/convention/data_definition.rb +++ b/lib/solargraph/convention/data_definition.rb @@ -90,7 +90,7 @@ def data_definition_node # @param attribute_node [Parser::AST::Node] # @param attribute_name [String] # @return [String, nil] - def attribute_comments(attribute_node, attribute_name) + def attribute_comments attribute_node, attribute_name data_comments = comments_for(attribute_node) return if data_comments.nil? || data_comments.empty? diff --git a/lib/solargraph/convention/data_definition/data_assignment_node.rb b/lib/solargraph/convention/data_definition/data_assignment_node.rb index cffe77494..97ef272cf 100644 --- a/lib/solargraph/convention/data_definition/data_assignment_node.rb +++ b/lib/solargraph/convention/data_definition/data_assignment_node.rb @@ -23,7 +23,7 @@ class << self # s(:args), # s(:send, nil, :bar)))) # @param node [::Parser::AST::Node] - def match?(node) + def match? node return false unless node&.type == :casgn return false if node.children[2].nil? diff --git a/lib/solargraph/convention/data_definition/data_definition_node.rb b/lib/solargraph/convention/data_definition/data_definition_node.rb index e86161c2d..0eab343e1 100644 --- a/lib/solargraph/convention/data_definition/data_definition_node.rb +++ b/lib/solargraph/convention/data_definition/data_definition_node.rb @@ -27,7 +27,7 @@ class << self # s(:send, nil, :bar))) # # @param node [Parser::AST::Node] - def match?(node) + def match? node return false unless node&.type == :class data_definition_node?(node.children[1]) @@ -37,7 +37,7 @@ def match?(node) # @param data_node [Parser::AST::Node] # @return [Boolean] - def data_definition_node?(data_node) + def data_definition_node? data_node return false unless data_node.is_a?(::Parser::AST::Node) return false unless data_node&.type == :send return false unless data_node.children[0]&.type == :const @@ -49,7 +49,7 @@ def data_definition_node?(data_node) end # @param node [Parser::AST::Node] - def initialize(node) + def initialize node @node = node end diff --git a/lib/solargraph/convention/struct_definition.rb b/lib/solargraph/convention/struct_definition.rb index b34ae5494..18dc5b26e 100644 --- a/lib/solargraph/convention/struct_definition.rb +++ b/lib/solargraph/convention/struct_definition.rb @@ -138,7 +138,7 @@ def parse_comments # @param tag [YARD::Tags::Tag, nil] The param tag for this attribute.xtract_ # # @return [String] - def tag_string(tag) + def tag_string tag tag&.types&.join(',') || 'undefined' end @@ -146,8 +146,8 @@ def tag_string(tag) # @param for_setter [Boolean] If true, will return a @param tag instead of a @return tag # # @return [String] The formatted comment for the attribute - def attribute_comment(tag, for_setter) - return "" if tag.nil? + def attribute_comment tag, for_setter + return '' if tag.nil? suffix = "[#{tag_string(tag)}] #{tag.text}" diff --git a/lib/solargraph/convention/struct_definition/struct_assignment_node.rb b/lib/solargraph/convention/struct_definition/struct_assignment_node.rb index 141abf599..aa72a37d5 100644 --- a/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +++ b/lib/solargraph/convention/struct_definition/struct_assignment_node.rb @@ -23,7 +23,7 @@ class << self # s(:args), # s(:send, nil, :bar)))) # @param node [Parser::AST::Node] - def match?(node) + def match? node return false unless node&.type == :casgn return false if node.children[2].nil? diff --git a/lib/solargraph/convention/struct_definition/struct_definition_node.rb b/lib/solargraph/convention/struct_definition/struct_definition_node.rb index 725e4227f..5a376cfb2 100644 --- a/lib/solargraph/convention/struct_definition/struct_definition_node.rb +++ b/lib/solargraph/convention/struct_definition/struct_definition_node.rb @@ -27,7 +27,7 @@ class << self # s(:send, nil, :bar))) # # @param node [Parser::AST::Node] - def match?(node) + def match? node return false unless node&.type == :class struct_definition_node?(node.children[1]) @@ -37,7 +37,7 @@ def match?(node) # @param struct_node [Parser::AST::Node] # @return [Boolean] - def struct_definition_node?(struct_node) + def struct_definition_node? struct_node return false unless struct_node.is_a?(::Parser::AST::Node) return false unless struct_node&.type == :send return false unless struct_node.children[0]&.type == :const @@ -49,7 +49,7 @@ def struct_definition_node?(struct_node) end # @param node [Parser::AST::Node] - def initialize(node) + def initialize node @node = node end diff --git a/lib/solargraph/diagnostics/rubocop.rb b/lib/solargraph/diagnostics/rubocop.rb index 0a55d0367..f9ae158eb 100644 --- a/lib/solargraph/diagnostics/rubocop.rb +++ b/lib/solargraph/diagnostics/rubocop.rb @@ -32,7 +32,7 @@ def diagnose source, _api_map # a time - it uses 'chdir' to read config files with ERB, # which can conflict with other chdirs. result = Solargraph::CHDIR_MUTEX.synchronize do - redirect_stdout{ runner.run(paths) } + redirect_stdout { runner.run(paths) } end return [] if result.empty? @@ -76,7 +76,7 @@ def offense_to_diagnostic off severity: SEVERITIES[off['severity']], source: 'rubocop', code: off['cop_name'], - message: off['message'].gsub(/^#{off['cop_name']}\:/, '') + message: off['message'].gsub(/^#{off['cop_name']}:/, '') } end @@ -95,22 +95,22 @@ def offense_start_position off # @param off [Hash{String => Hash{String => Integer}}] # @return [Position] def offense_ending_position off - if off['location']['start_line'] != off['location']['last_line'] - Position.new(off['location']['start_line'], 0) - else + if off['location']['start_line'] == off['location']['last_line'] start_line = off['location']['start_line'] - 1 # @type [Integer] last_column = off['location']['last_column'] line = @source.code.lines[start_line] col_off = if line.nil? || line.empty? - 1 - else - 0 - end + 1 + else + 0 + end Position.new( start_line, last_column - col_off ) + else + Position.new(off['location']['start_line'], 0) end end end diff --git a/lib/solargraph/diagnostics/rubocop_helpers.rb b/lib/solargraph/diagnostics/rubocop_helpers.rb index f6f4c82c8..8e530d3f8 100644 --- a/lib/solargraph/diagnostics/rubocop_helpers.rb +++ b/lib/solargraph/diagnostics/rubocop_helpers.rb @@ -13,7 +13,7 @@ module RubocopHelpers # @param version [String, nil] # @raise [InvalidRubocopVersionError] if _version_ is not installed # @return [void] - def require_rubocop(version = nil) + def require_rubocop version = nil begin # @type [String] gem_path = Gem::Specification.find_by_name('rubocop', version).full_gem_path @@ -21,7 +21,7 @@ def require_rubocop(version = nil) $LOAD_PATH.unshift(gem_lib_path) unless $LOAD_PATH.include?(gem_lib_path) rescue Gem::MissingSpecVersionError => e raise InvalidRubocopVersionError, - "could not find '#{e.name}' (#{e.requirement}) - "\ + "could not find '#{e.name}' (#{e.requirement}) - " \ "did find: [#{e.specs.map { |s| s.version.version }.join(', ')}]" end require 'rubocop' diff --git a/lib/solargraph/diagnostics/type_check.rb b/lib/solargraph/diagnostics/type_check.rb index 80f53eb7c..8d857b647 100644 --- a/lib/solargraph/diagnostics/type_check.rb +++ b/lib/solargraph/diagnostics/type_check.rb @@ -10,18 +10,18 @@ class TypeCheck < Base def diagnose source, api_map # return [] unless args.include?('always') || api_map.workspaced?(source.filename) severity = Diagnostics::Severities::ERROR - level = (args.reverse.find { |a| ['normal', 'typed', 'strict', 'strong'].include?(a) }) || :normal + level = args.reverse.find { |a| %w[normal typed strict strong].include?(a) } || :normal checker = Solargraph::TypeChecker.new(source.filename, api_map: api_map, level: level.to_sym) checker.problems - .sort { |a, b| a.location.range.start.line <=> b.location.range.start.line } - .map do |problem| - { - range: extract_first_line(problem.location, source), - severity: severity, - source: 'Typecheck', - message: problem.message - } - end + .sort { |a, b| a.location.range.start.line <=> b.location.range.start.line } + .map do |problem| + { + range: extract_first_line(problem.location, source), + severity: severity, + source: 'Typecheck', + message: problem.message + } + end end private diff --git a/lib/solargraph/diagnostics/update_errors.rb b/lib/solargraph/diagnostics/update_errors.rb index b6f9baa89..6da4c5835 100644 --- a/lib/solargraph/diagnostics/update_errors.rb +++ b/lib/solargraph/diagnostics/update_errors.rb @@ -26,7 +26,7 @@ def diagnose source, api_map def combine_ranges code, ranges result = [] lines = [] - ranges.sort{|a, b| a.start.line <=> b.start.line}.each do |rng| + ranges.sort { |a, b| a.start.line <=> b.start.line }.each do |rng| next if rng.nil? || lines.include?(rng.start.line) lines.push rng.start.line next if rng.start.line >= code.lines.length diff --git a/lib/solargraph/doc_map.rb b/lib/solargraph/doc_map.rb index 5966717f4..9cd527e92 100644 --- a/lib/solargraph/doc_map.rb +++ b/lib/solargraph/doc_map.rb @@ -48,7 +48,7 @@ def uncached_gemspecs # @param requires [Array] # @param preferences [Array] # @param workspace [Workspace, nil] - def initialize(requires, preferences, workspace = nil) + def initialize requires, preferences, workspace = nil @requires = requires.compact @preferences = preferences.compact @workspace = workspace @@ -62,7 +62,7 @@ def initialize(requires, preferences, workspace = nil) # @param out [IO] # @return [void] - def cache_all!(out) + def cache_all! out # if we log at debug level: if logger.info? gem_desc = uncached_gemspecs.map { |gemspec| "#{gemspec.name}:#{gemspec.version}" }.join(', ') @@ -82,7 +82,7 @@ def cache_all!(out) # @param gemspec [Gem::Specification] # @param out [IO] # @return [void] - def cache_yard_pins(gemspec, out) + def cache_yard_pins gemspec, out pins = GemPins.build_yard_pins(yard_plugins, gemspec) PinCache.serialize_yard_gem(gemspec, pins) logger.info { "Cached #{pins.length} YARD pins for gem #{gemspec.name}:#{gemspec.version}" } unless pins.empty? @@ -91,21 +91,25 @@ def cache_yard_pins(gemspec, out) # @param gemspec [Gem::Specification] # @param out [IO] # @return [void] - def cache_rbs_collection_pins(gemspec, out) + def cache_rbs_collection_pins gemspec, out rbs_map = RbsMap.from_gemspec(gemspec, rbs_collection_path, rbs_collection_config_path) pins = rbs_map.pins rbs_version_cache_key = rbs_map.cache_key # cache pins even if result is zero, so we don't retry building pins pins ||= [] PinCache.serialize_rbs_collection_gem(gemspec, rbs_version_cache_key, pins) - logger.info { "Cached #{pins.length} RBS collection pins for gem #{gemspec.name} #{gemspec.version} with cache_key #{rbs_version_cache_key.inspect}" unless pins.empty? } + logger.info do + unless pins.empty? + "Cached #{pins.length} RBS collection pins for gem #{gemspec.name} #{gemspec.version} with cache_key #{rbs_version_cache_key.inspect}" + end + end end # @param gemspec [Gem::Specification] # @param rebuild [Boolean] whether to rebuild the pins even if they are cached # @param out [IO, nil] output stream for logging # @return [void] - def cache(gemspec, rebuild: false, out: nil) + def cache gemspec, rebuild: false, out: nil build_yard = uncached_yard_gemspecs.include?(gemspec) || rebuild build_rbs_collection = uncached_rbs_collection_gemspecs.include?(gemspec) || rebuild if build_yard || build_rbs_collection @@ -185,17 +189,19 @@ def load_serialized_gem_pins gemspecs = Hash[with_gemspecs].values.flatten.compact + dependencies.to_a paths.each do |path| - rbs_pins = deserialize_stdlib_rbs_map path + deserialize_stdlib_rbs_map path end - logger.debug { "DocMap#load_serialized_gem_pins: Combining pins..." } + logger.debug { 'DocMap#load_serialized_gem_pins: Combining pins...' } time = Benchmark.measure do gemspecs.each do |gemspec| pins = deserialize_combined_pin_cache gemspec @pins.concat pins if pins end end - logger.info { "DocMap#load_serialized_gem_pins: Loaded and processed serialized pins together in #{time.real} seconds" } + logger.info do + "DocMap#load_serialized_gem_pins: Loaded and processed serialized pins together in #{time.real} seconds" + end @uncached_yard_gemspecs.uniq! @uncached_rbs_collection_gemspecs.uniq! nil @@ -232,7 +238,7 @@ def deserialize_yard_pin_cache gemspec # @param gemspec [Gem::Specification] # @return [void] - def deserialize_combined_pin_cache(gemspec) + def deserialize_combined_pin_cache gemspec unless combined_pins_in_memory[[gemspec.name, gemspec.version]].nil? return combined_pins_in_memory[[gemspec.name, gemspec.version]] end @@ -256,21 +262,24 @@ def deserialize_combined_pin_cache(gemspec) combined_pins = GemPins.combine(yard_pins, rbs_collection_pins) PinCache.serialize_combined_gem(gemspec, rbs_version_cache_key, combined_pins) combined_pins_in_memory[[gemspec.name, gemspec.version]] = combined_pins - logger.info { "Generated #{combined_pins_in_memory[[gemspec.name, gemspec.version]].length} combined pins for #{gemspec.name} #{gemspec.version}" } + logger.info do + "Generated #{combined_pins_in_memory[[gemspec.name, + gemspec.version]].length} combined pins for #{gemspec.name} #{gemspec.version}" + end return combined_pins end if !yard_pins.nil? logger.debug { "Using only YARD pins for #{gemspec.name}:#{gemspec.version}" } combined_pins_in_memory[[gemspec.name, gemspec.version]] = yard_pins - return combined_pins_in_memory[[gemspec.name, gemspec.version]] + combined_pins_in_memory[[gemspec.name, gemspec.version]] elsif !rbs_collection_pins.nil? logger.debug { "Using only RBS collection pins for #{gemspec.name}:#{gemspec.version}" } combined_pins_in_memory[[gemspec.name, gemspec.version]] = rbs_collection_pins - return combined_pins_in_memory[[gemspec.name, gemspec.version]] + combined_pins_in_memory[[gemspec.name, gemspec.version]] else logger.debug { "Pins not yet cached for #{gemspec.name}:#{gemspec.version}" } - return nil + nil end end @@ -297,7 +306,11 @@ def deserialize_rbs_collection_cache gemspec, rbs_version_cache_key return if rbs_collection_pins_in_memory.key?([gemspec, rbs_version_cache_key]) cached = PinCache.deserialize_rbs_collection_gem(gemspec, rbs_version_cache_key) if cached - logger.info { "Loaded #{cached.length} pins from RBS collection cache for #{gemspec.name}:#{gemspec.version}" } unless cached.empty? + unless cached.empty? + logger.info do + "Loaded #{cached.length} pins from RBS collection cache for #{gemspec.name}:#{gemspec.version}" + end + end rbs_collection_pins_in_memory[[gemspec, rbs_version_cache_key]] = cached cached else @@ -326,7 +339,9 @@ def resolve_path_to_gemspecs path file = "lib/#{path}.rb" gemspec = potential_gemspec if potential_gemspec.files.any? { |gemspec_file| file == gemspec_file } rescue Gem::MissingSpecError - logger.debug { "Require path #{path} could not be resolved to a gem via find_by_path or guess of #{gem_name_guess}" } + logger.debug do + "Require path #{path} could not be resolved to a gem via find_by_path or guess of #{gem_name_guess}" + end [] end end @@ -376,7 +391,6 @@ def only_runtime_dependencies gemspec gemspec.dependencies - gemspec.development_dependencies end - def inspect self.class.inspect end diff --git a/lib/solargraph/equality.rb b/lib/solargraph/equality.rb index 0667efacd..bb598099b 100644 --- a/lib/solargraph/equality.rb +++ b/lib/solargraph/equality.rb @@ -10,15 +10,15 @@ module Equality # @param other [Object] # @return [Boolean] - def eql?(other) + def eql? other self.class.eql?(other.class) && equality_fields.eql?(other.equality_fields) end # @param other [Object] # @return [Boolean] - def ==(other) - self.eql?(other) + def == other + eql?(other) end def hash diff --git a/lib/solargraph/gem_pins.rb b/lib/solargraph/gem_pins.rb index a193a8a39..babdbf1d1 100644 --- a/lib/solargraph/gem_pins.rb +++ b/lib/solargraph/gem_pins.rb @@ -13,7 +13,7 @@ class << self # @param pins [Array] # @return [Array] - def self.combine_method_pins_by_path(pins) + def self.combine_method_pins_by_path pins method_pins, alias_pins = pins.partition { |pin| pin.class == Pin::Method } by_path = method_pins.group_by(&:path) by_path.transform_values! do |pins| @@ -44,7 +44,7 @@ def self.combine_method_pins(*pins) # @param yard_plugins [Array] The names of YARD plugins to use. # @param gemspec [Gem::Specification] # @return [Array] - def self.build_yard_pins(yard_plugins, gemspec) + def self.build_yard_pins yard_plugins, gemspec Yardoc.cache(yard_plugins, gemspec) unless Yardoc.cached?(gemspec) yardoc = Yardoc.load!(gemspec) YardMap::Mapper.new(yardoc, gemspec).map @@ -54,7 +54,7 @@ def self.build_yard_pins(yard_plugins, gemspec) # @param rbs_pins [Array] # # @return [Array] - def self.combine(yard_pins, rbs_pins) + def self.combine yard_pins, rbs_pins in_yard = Set.new rbs_api_map = Solargraph::ApiMap.new(pins: rbs_pins) combined = yard_pins.map do |yard_pin| @@ -63,12 +63,16 @@ def self.combine(yard_pins, rbs_pins) next yard_pin unless rbs_pin && yard_pin.class == Pin::Method unless rbs_pin - logger.debug { "GemPins.combine: No rbs pin for #{yard_pin.path} - using YARD's '#{yard_pin.inspect} (return_type=#{yard_pin.return_type}; signatures=#{yard_pin.signatures})" } + logger.debug do + "GemPins.combine: No rbs pin for #{yard_pin.path} - using YARD's '#{yard_pin.inspect} (return_type=#{yard_pin.return_type}; signatures=#{yard_pin.signatures})" + end next yard_pin end out = combine_method_pins(rbs_pin, yard_pin) - logger.debug { "GemPins.combine: Combining yard.path=#{yard_pin.path} - rbs=#{rbs_pin.inspect} with yard=#{yard_pin.inspect} into #{out}" } + logger.debug do + "GemPins.combine: Combining yard.path=#{yard_pin.path} - rbs=#{rbs_pin.inspect} with yard=#{yard_pin.inspect} into #{out}" + end out end in_rbs_only = rbs_pins.select do |pin| diff --git a/lib/solargraph/language_server/error_codes.rb b/lib/solargraph/language_server/error_codes.rb index 492ca6462..7df65388a 100644 --- a/lib/solargraph/language_server/error_codes.rb +++ b/lib/solargraph/language_server/error_codes.rb @@ -5,16 +5,16 @@ module LanguageServer # The ErrorCode constants for the language server protocol. # module ErrorCodes - PARSE_ERROR = -32700 - INVALID_REQUEST = -32600 - METHOD_NOT_FOUND = -32601 - INVALID_PARAMS = -32602 - INTERNAL_ERROR = -32603 - SERVER_ERROR_START = -32099 - SERVER_ERROR_END = -32000 - SERVER_NOT_INITIALIZED = -32002 - UNKNOWN_ERROR_CODE = -32001 - REQUEST_CANCELLED = -32800 + PARSE_ERROR = -32_700 + INVALID_REQUEST = -32_600 + METHOD_NOT_FOUND = -32_601 + INVALID_PARAMS = -32_602 + INTERNAL_ERROR = -32_603 + SERVER_ERROR_START = -32_099 + SERVER_ERROR_END = -32_000 + SERVER_NOT_INITIALIZED = -32_002 + UNKNOWN_ERROR_CODE = -32_001 + REQUEST_CANCELLED = -32_800 end end end diff --git a/lib/solargraph/language_server/host.rb b/lib/solargraph/language_server/host.rb index 53da20175..36ee059fc 100644 --- a/lib/solargraph/language_server/host.rb +++ b/lib/solargraph/language_server/host.rb @@ -118,7 +118,7 @@ def receive request nil end else - logger.warn "Invalid message received." + logger.warn 'Invalid message received.' logger.debug request nil end @@ -153,7 +153,7 @@ def delete *uris lib.delete(*filenames) end uris.each do |uri| - send_notification "textDocument/publishDiagnostics", { + send_notification 'textDocument/publishDiagnostics', { uri: uri, diagnostics: [] } @@ -208,7 +208,7 @@ def diagnose uri logger.info "Diagnosing #{uri}" begin results = library.diagnose uri_to_file(uri) - send_notification "textDocument/publishDiagnostics", { + send_notification 'textDocument/publishDiagnostics', { uri: uri, diagnostics: results } @@ -350,7 +350,7 @@ def folders # @return [void] def send_notification method, params response = { - jsonrpc: "2.0", + jsonrpc: '2.0', method: method, params: params } @@ -373,7 +373,7 @@ def send_notification method, params def send_request method, params, &block @request_mutex.synchronize do message = { - jsonrpc: "2.0", + jsonrpc: '2.0', method: method, params: params, id: @next_request_id @@ -415,13 +415,13 @@ def register_capabilities methods # @return [void] def unregister_capabilities methods logger.debug "Unregistering capabilities: #{methods}" - unregisterations = methods.select{|m| registered?(m)}.map{ |m| + unregisterations = methods.select { |m| registered?(m) }.map do |m| @registered_capabilities.delete m { id: m, method: m } - } + end return if unregisterations.empty? send_request 'client/unregisterCapability', { unregisterations: unregisterations } end @@ -489,7 +489,7 @@ def locate_pins params params['data']['location']['range']['end']['character'] ) ) - result.concat library.locate_pins(location).select{ |pin| pin.name == params['label'] } + result.concat(library.locate_pins(location).select { |pin| pin.name == params['label'] }) end if params['data']['path'] result.concat library.path_pins(params['data']['path']) @@ -741,9 +741,12 @@ def generate_updater params params['contentChanges'].each do |recvd| chng = check_diff(params['textDocument']['uri'], recvd) changes.push Solargraph::Source::Change.new( - (chng['range'].nil? ? - nil : - Solargraph::Range.from_to(chng['range']['start']['line'], chng['range']['start']['character'], chng['range']['end']['line'], chng['range']['end']['character']) + (if chng['range'].nil? + nil + else + Solargraph::Range.from_to(chng['range']['start']['line'], chng['range']['start']['character'], + chng['range']['end']['line'], chng['range']['end']['character']) + end ), chng['text'] ) @@ -807,10 +810,10 @@ def dynamic_capability_options # documentSymbolProvider: true, # workspaceSymbolProvider: true, # workspace: { - # workspaceFolders: { - # supported: true, - # changeNotifications: true - # } + # workspaceFolders: { + # supported: true, + # changeNotifications: true + # } # } 'textDocument/definition' => { definitionProvider: true diff --git a/lib/solargraph/language_server/host/diagnoser.rb b/lib/solargraph/language_server/host/diagnoser.rb index e69ae16f9..8c259c131 100644 --- a/lib/solargraph/language_server/host/diagnoser.rb +++ b/lib/solargraph/language_server/host/diagnoser.rb @@ -56,7 +56,7 @@ def start # @return [void] def tick return if queue.empty? || host.synchronizing? - if !host.options['diagnostics'] + unless host.options['diagnostics'] mutex.synchronize { queue.clear } return end diff --git a/lib/solargraph/language_server/host/dispatch.rb b/lib/solargraph/language_server/host/dispatch.rb index 1ff1227b8..9eca0397e 100644 --- a/lib/solargraph/language_server/host/dispatch.rb +++ b/lib/solargraph/language_server/host/dispatch.rb @@ -44,12 +44,11 @@ def update_libraries uri # @param uri [String] # @return [Library] def library_for uri - result = explicit_library_for(uri) || + explicit_library_for(uri) || implicit_library_for(uri) || generic_library_for(uri) # previous library for already call attach. avoid call twice # result.attach sources.find(uri) if sources.include?(uri) - result end # Find an explicit library match for the given URI. An explicit match diff --git a/lib/solargraph/language_server/host/message_worker.rb b/lib/solargraph/language_server/host/message_worker.rb index ec426b99f..4d900dda1 100644 --- a/lib/solargraph/language_server/host/message_worker.rb +++ b/lib/solargraph/language_server/host/message_worker.rb @@ -20,7 +20,7 @@ class MessageWorker ].freeze # @param host [Host] - def initialize(host) + def initialize host @host = host @mutex = Mutex.new @resource = ConditionVariable.new @@ -44,7 +44,7 @@ def stop # @param message [Hash] The message to handle. Will be forwarded to Host#receive # @return [void] - def queue(message) + def queue message @mutex.synchronize do messages.push(message) @resource.signal diff --git a/lib/solargraph/language_server/host/sources.rb b/lib/solargraph/language_server/host/sources.rb index da0c63b93..96b0982f2 100644 --- a/lib/solargraph/language_server/host/sources.rb +++ b/lib/solargraph/language_server/host/sources.rb @@ -13,7 +13,7 @@ class Sources # @param uri [String] # @return [void] - def add_uri(uri) + def add_uri uri queue.push(uri) end diff --git a/lib/solargraph/language_server/message/client/register_capability.rb b/lib/solargraph/language_server/message/client/register_capability.rb index a9af8748e..67469def8 100644 --- a/lib/solargraph/language_server/message/client/register_capability.rb +++ b/lib/solargraph/language_server/message/client/register_capability.rb @@ -5,9 +5,7 @@ module LanguageServer module Message module Client class RegisterCapability < Solargraph::LanguageServer::Message::Base - def process - - end + def process; end end end end diff --git a/lib/solargraph/language_server/message/completion_item/resolve.rb b/lib/solargraph/language_server/message/completion_item/resolve.rb index 85e03ad4f..171ec6a6c 100644 --- a/lib/solargraph/language_server/message/completion_item/resolve.rb +++ b/lib/solargraph/language_server/message/completion_item/resolve.rb @@ -21,9 +21,9 @@ def merge pins docs = pins .reject { |pin| pin.documentation.empty? && pin.return_type.undefined? } result = params - .transform_keys(&:to_sym) - .merge(pins.first.resolve_completion_item) - .merge(documentation: markup_content(join_docs(docs))) + .transform_keys(&:to_sym) + .merge(pins.first.resolve_completion_item) + .merge(documentation: markup_content(join_docs(docs))) result[:detail] = pins.first.detail result end @@ -43,11 +43,9 @@ def markup_content text def join_docs pins result = [] last_link = nil - pins.each_with_index do |pin| + pins.each do |pin| this_link = host.options['enablePages'] ? pin.link_documentation : pin.text_documentation - if this_link && this_link != last_link && this_link != 'undefined' - result.push this_link - end + result.push this_link if this_link && this_link != last_link && this_link != 'undefined' result.push pin.documentation unless result.last && result.last.end_with?(pin.documentation) last_link = this_link end diff --git a/lib/solargraph/language_server/message/extended/check_gem_version.rb b/lib/solargraph/language_server/message/extended/check_gem_version.rb index ead1eeaf2..619bb2703 100644 --- a/lib/solargraph/language_server/message/extended/check_gem_version.rb +++ b/lib/solargraph/language_server/message/extended/check_gem_version.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true - # @todo PR the RBS gem to add this # @!parse # module ::Gem @@ -23,8 +22,8 @@ def self.fetcher # @param obj [Gem::SpecFetcher] # @return [Gem::SpecFetcher] - def self.fetcher= obj - @fetcher = obj + class << self + attr_writer :fetcher end GEM_ZERO = Gem::Version.new('0.0.0') @@ -47,11 +46,11 @@ def process ['Update now'] do |result| next unless result == 'Update now' cmd = if host.options['useBundler'] - 'bundle update solargraph' - else - 'gem update solargraph' - end - o, s = Open3.capture2(cmd) + 'bundle update solargraph' + else + 'gem update solargraph' + end + _, s = Open3.capture2(cmd) if s == 0 host.show_message 'Successfully updated the Solargraph gem.', LanguageServer::MessageTypes::INFO host.send_notification '$/solargraph/restart', {} @@ -67,9 +66,9 @@ def process host.show_message(error, MessageTypes::ERROR) if params['verbose'] end set_result({ - installed: current, - available: available - }) + installed: current, + available: available + }) end private diff --git a/lib/solargraph/language_server/message/extended/document_gems.rb b/lib/solargraph/language_server/message/extended/document_gems.rb index f1cfca0b8..403632390 100644 --- a/lib/solargraph/language_server/message/extended/document_gems.rb +++ b/lib/solargraph/language_server/message/extended/document_gems.rb @@ -13,16 +13,16 @@ class DocumentGems < Base def process cmd = [host.command_path, 'gems'] cmd.push '--rebuild' if params['rebuild'] - o, s = Open3.capture2(*cmd) - if s != 0 - host.show_message "An error occurred while building gem documentation.", LanguageServer::MessageTypes::ERROR + _, s = Open3.capture2(*cmd) + if s == 0 set_result({ - status: 'err' - }) + status: 'ok' + }) else + host.show_message 'An error occurred while building gem documentation.', LanguageServer::MessageTypes::ERROR set_result({ - status: 'ok' - }) + status: 'err' + }) end end end diff --git a/lib/solargraph/language_server/message/extended/download_core.rb b/lib/solargraph/language_server/message/extended/download_core.rb index 7310757a1..4e0775c14 100644 --- a/lib/solargraph/language_server/message/extended/download_core.rb +++ b/lib/solargraph/language_server/message/extended/download_core.rb @@ -10,7 +10,8 @@ module Extended # class DownloadCore < Base def process - host.show_message "Downloading cores is deprecated. Solargraph currently uses RBS for core and stdlib documentation", LanguageServer::MessageTypes::INFO + host.show_message 'Downloading cores is deprecated. Solargraph currently uses RBS for core and stdlib documentation', + LanguageServer::MessageTypes::INFO end end end diff --git a/lib/solargraph/language_server/message/extended/search.rb b/lib/solargraph/language_server/message/extended/search.rb index 1f09a8890..312c048bb 100644 --- a/lib/solargraph/language_server/message/extended/search.rb +++ b/lib/solargraph/language_server/message/extended/search.rb @@ -8,7 +8,7 @@ class Search < Base def process results = host.search(params['query']) page = Solargraph::Page.new(host.options['viewsPath']) - content = page.render('search', layout: true, locals: {query: params['query'], results: results}) + content = page.render('search', layout: true, locals: { query: params['query'], results: results }) set_result( content: content ) diff --git a/lib/solargraph/language_server/message/initialize.rb b/lib/solargraph/language_server/message/initialize.rb index 3f3e1338b..f0f54f22e 100644 --- a/lib/solargraph/language_server/message/initialize.rb +++ b/lib/solargraph/language_server/message/initialize.rb @@ -26,20 +26,27 @@ def process } } # FIXME: lsp default is utf-16, may have different position - result[:capabilities][:positionEncoding] = "utf-32" if params.dig("capabilities", "general", "positionEncodings")&.include?("utf-32") + result[:capabilities][:positionEncoding] = 'utf-32' if params.dig('capabilities', 'general', + 'positionEncodings')&.include?('utf-32') result[:capabilities].merge! static_completion unless dynamic_registration_for?('textDocument', 'completion') - result[:capabilities].merge! static_signature_help unless dynamic_registration_for?('textDocument', 'signatureHelp') + result[:capabilities].merge! static_signature_help unless dynamic_registration_for?('textDocument', + 'signatureHelp') # result[:capabilities].merge! static_on_type_formatting unless dynamic_registration_for?('textDocument', 'onTypeFormatting') result[:capabilities].merge! static_hover unless dynamic_registration_for?('textDocument', 'hover') - result[:capabilities].merge! static_document_formatting unless dynamic_registration_for?('textDocument', 'formatting') - result[:capabilities].merge! static_document_symbols unless dynamic_registration_for?('textDocument', 'documentSymbol') + result[:capabilities].merge! static_document_formatting unless dynamic_registration_for?('textDocument', + 'formatting') + result[:capabilities].merge! static_document_symbols unless dynamic_registration_for?('textDocument', + 'documentSymbol') result[:capabilities].merge! static_definitions unless dynamic_registration_for?('textDocument', 'definition') - result[:capabilities].merge! static_type_definitions unless dynamic_registration_for?('textDocument', 'typeDefinition') + result[:capabilities].merge! static_type_definitions unless dynamic_registration_for?('textDocument', + 'typeDefinition') result[:capabilities].merge! static_rename unless dynamic_registration_for?('textDocument', 'rename') result[:capabilities].merge! static_references unless dynamic_registration_for?('textDocument', 'references') result[:capabilities].merge! static_workspace_symbols unless dynamic_registration_for?('workspace', 'symbol') - result[:capabilities].merge! static_folding_range unless dynamic_registration_for?('textDocument', 'foldingRange') - result[:capabilities].merge! static_highlights unless dynamic_registration_for?('textDocument', 'documentHighlight') + result[:capabilities].merge! static_folding_range unless dynamic_registration_for?('textDocument', + 'foldingRange') + result[:capabilities].merge! static_highlights unless dynamic_registration_for?('textDocument', + 'documentHighlight') # @todo Temporarily disabled # result[:capabilities].merge! static_code_action unless dynamic_registration_for?('textDocument', 'codeAction') set_result result @@ -71,7 +78,7 @@ def static_completion def static_code_action { codeActionProvider: true, - codeActionKinds: ["quickfix"] + codeActionKinds: ['quickfix'] } end @@ -144,11 +151,10 @@ def static_type_definitions # @return [Hash{Symbol => Hash{Symbol => Boolean}}] def static_rename { - renameProvider: {prepareProvider: true} + renameProvider: { prepareProvider: true } } end - # @return [Hash{Symbol => Boolean}] def static_references return {} unless host.options['references'] @@ -178,10 +184,10 @@ def static_highlights # enforce strict true/false-ness # @sg-ignore def dynamic_registration_for? section, capability - result = (params['capabilities'] && - params['capabilities'][section] && - params['capabilities'][section][capability] && - params['capabilities'][section][capability]['dynamicRegistration']) + result = params['capabilities'] && + params['capabilities'][section] && + params['capabilities'][section][capability] && + params['capabilities'][section][capability]['dynamicRegistration'] host.allow_registration("#{section}/#{capability}") if result result end diff --git a/lib/solargraph/language_server/message/text_document/completion.rb b/lib/solargraph/language_server/message/text_document/completion.rb index ef7ad1be4..ffeccead7 100644 --- a/lib/solargraph/language_server/message/text_document/completion.rb +++ b/lib/solargraph/language_server/message/text_document/completion.rb @@ -6,7 +6,10 @@ module Message module TextDocument class Completion < Base def process - return set_error(ErrorCodes::REQUEST_CANCELLED, "cancelled by so many request") if host.has_pending_completions? + if host.has_pending_completions? + return set_error(ErrorCodes::REQUEST_CANCELLED, + 'cancelled by so many request') + end line = params['position']['line'] col = params['position']['character'] @@ -18,12 +21,12 @@ def process completion.pins.each do |pin| idx += 1 if last_context != pin.context items.push pin.completion_item.merge({ - textEdit: { - range: completion.range.to_hash, - newText: pin.name.sub(/=$/, ' = ').sub(/:$/, ': ') - }, - sortText: "#{idx.to_s.rjust(4, '0')}#{pin.name}" - }) + textEdit: { + range: completion.range.to_hash, + newText: pin.name.sub(/=$/, ' = ').sub(/:$/, ': ') + }, + sortText: "#{idx.to_s.rjust(4, '0')}#{pin.name}" + }) items.last[:data][:uri] = params['textDocument']['uri'] last_context = pin.context end @@ -31,7 +34,7 @@ def process isIncomplete: false, items: items ) - rescue InvalidOffsetError => e + rescue InvalidOffsetError Logging.logger.info "Completion ignored invalid offset: #{params['textDocument']['uri']}, line #{line}, character #{col}" set_result empty_result end diff --git a/lib/solargraph/language_server/message/text_document/definition.rb b/lib/solargraph/language_server/message/text_document/definition.rb index ea0942dd5..470271211 100644 --- a/lib/solargraph/language_server/message/text_document/definition.rb +++ b/lib/solargraph/language_server/message/text_document/definition.rb @@ -26,7 +26,8 @@ def code_location def require_location # @todo Terrible hack lib = host.library_for(params['textDocument']['uri']) - rloc = Solargraph::Location.new(uri_to_file(params['textDocument']['uri']), Solargraph::Range.from_to(@line, @column, @line, @column)) + rloc = Solargraph::Location.new(uri_to_file(params['textDocument']['uri']), + Solargraph::Range.from_to(@line, @column, @line, @column)) dloc = lib.locate_ref(rloc) return nil if dloc.nil? [ diff --git a/lib/solargraph/language_server/message/text_document/document_highlight.rb b/lib/solargraph/language_server/message/text_document/document_highlight.rb index 2aded7641..a0541762a 100644 --- a/lib/solargraph/language_server/message/text_document/document_highlight.rb +++ b/lib/solargraph/language_server/message/text_document/document_highlight.rb @@ -3,7 +3,8 @@ module Solargraph::LanguageServer::Message::TextDocument class DocumentHighlight < Base def process - locs = host.references_from(params['textDocument']['uri'], params['position']['line'], params['position']['character'], strip: true, only: true) + locs = host.references_from(params['textDocument']['uri'], params['position']['line'], + params['position']['character'], strip: true, only: true) result = locs.map do |loc| { range: loc.range.to_hash, diff --git a/lib/solargraph/language_server/message/text_document/formatting.rb b/lib/solargraph/language_server/message/text_document/formatting.rb index 821de7ffc..2917251e1 100644 --- a/lib/solargraph/language_server/message/text_document/formatting.rb +++ b/lib/solargraph/language_server/message/text_document/formatting.rb @@ -41,7 +41,7 @@ def process # @param corrections [String] # @return [void] - def log_corrections(corrections) + def log_corrections corrections corrections = corrections&.strip return if corrections&.empty? @@ -54,7 +54,7 @@ def log_corrections(corrections) # @param file_uri [String] # @return [Hash{String => undefined}] - def config_for(file_uri) + def config_for file_uri conf = host.formatter_config(file_uri) return {} unless conf.is_a?(Hash) @@ -69,10 +69,10 @@ def cli_args file_uri, config args = [ config['cops'] == 'all' ? '-A' : '-a', '--cache', 'false', - '--format', formatter_class(config).name, + '--format', formatter_class(config).name ] - ['except', 'only'].each do |arg| + %w[except only].each do |arg| cops = cop_list(config[arg]) args += ["--#{arg}", cops] if cops end @@ -84,7 +84,7 @@ def cli_args file_uri, config # @param config [Hash{String => String}] # @sg-ignore # @return [Class] - def formatter_class(config) + def formatter_class config if self.class.const_defined?('BlankRubocopFormatter') # @sg-ignore BlankRubocopFormatter @@ -97,7 +97,7 @@ def formatter_class(config) # @param value [Array, String] # @return [String, nil] - def cop_list(value) + def cop_list value # @type [String] value = value.join(',') if value.respond_to?(:join) return nil if value == '' || !value.is_a?(String) diff --git a/lib/solargraph/language_server/message/text_document/hover.rb b/lib/solargraph/language_server/message/text_document/hover.rb index 72eff4296..baf71cc5e 100644 --- a/lib/solargraph/language_server/message/text_document/hover.rb +++ b/lib/solargraph/language_server/message/text_document/hover.rb @@ -14,9 +14,7 @@ def process suggestions.each do |pin| parts = [] this_link = host.options['enablePages'] ? pin.link_documentation : pin.text_documentation - if !this_link.nil? && this_link != last_link - parts.push this_link - end + parts.push this_link if !this_link.nil? && this_link != last_link parts.push "`#{pin.detail}`" unless pin.is_a?(Pin::Namespace) || pin.detail.nil? parts.push pin.documentation unless pin.documentation.nil? || pin.documentation.empty? unless parts.empty? @@ -41,8 +39,8 @@ def process # @return [Hash{Symbol => Hash{Symbol => String}}, nil] def contents_or_nil contents stripped = contents - .map(&:strip) - .reject { |c| c.empty? } + .map(&:strip) + .reject { |c| c.empty? } return nil if stripped.empty? { contents: { diff --git a/lib/solargraph/language_server/message/text_document/prepare_rename.rb b/lib/solargraph/language_server/message/text_document/prepare_rename.rb index 4a37410dd..770d126ad 100644 --- a/lib/solargraph/language_server/message/text_document/prepare_rename.rb +++ b/lib/solargraph/language_server/message/text_document/prepare_rename.rb @@ -5,7 +5,8 @@ class PrepareRename < Base def process line = params['position']['line'] col = params['position']['character'] - set_result host.sources.find(params['textDocument']['uri']).cursor_at(Solargraph::Position.new(line, col)).range.to_hash + set_result host.sources.find(params['textDocument']['uri']).cursor_at(Solargraph::Position.new(line, + col)).range.to_hash end end end diff --git a/lib/solargraph/language_server/message/text_document/references.rb b/lib/solargraph/language_server/message/text_document/references.rb index 2de266214..08ae35c9d 100644 --- a/lib/solargraph/language_server/message/text_document/references.rb +++ b/lib/solargraph/language_server/message/text_document/references.rb @@ -3,7 +3,8 @@ module Solargraph::LanguageServer::Message::TextDocument class References < Base def process - locs = host.references_from(params['textDocument']['uri'], params['position']['line'], params['position']['character']) + locs = host.references_from(params['textDocument']['uri'], params['position']['line'], + params['position']['character']) result = locs.map do |loc| { uri: file_to_uri(loc.filename), diff --git a/lib/solargraph/language_server/message/text_document/rename.rb b/lib/solargraph/language_server/message/text_document/rename.rb index 997e9595b..66bdce274 100644 --- a/lib/solargraph/language_server/message/text_document/rename.rb +++ b/lib/solargraph/language_server/message/text_document/rename.rb @@ -3,15 +3,16 @@ module Solargraph::LanguageServer::Message::TextDocument class Rename < Base def process - locs = host.references_from(params['textDocument']['uri'], params['position']['line'], params['position']['character'], strip: true) + locs = host.references_from(params['textDocument']['uri'], params['position']['line'], + params['position']['character'], strip: true) changes = {} locs.each do |loc| uri = file_to_uri(loc.filename) changes[uri] ||= [] changes[uri].push({ - range: loc.range.to_hash, - newText: params['newName'] - }) + range: loc.range.to_hash, + newText: params['newName'] + }) end set_result changes: changes end diff --git a/lib/solargraph/language_server/message/text_document/signature_help.rb b/lib/solargraph/language_server/message/text_document/signature_help.rb index e4e8795db..435c6a6a7 100644 --- a/lib/solargraph/language_server/message/text_document/signature_help.rb +++ b/lib/solargraph/language_server/message/text_document/signature_help.rb @@ -10,8 +10,8 @@ def process col = params['position']['character'] suggestions = host.signatures_at(params['textDocument']['uri'], line, col) set_result({ - signatures: suggestions.flat_map { |pin| pin.signature_help } - }) + signatures: suggestions.flat_map { |pin| pin.signature_help } + }) rescue FileNotFoundError => e Logging.logger.warn "[#{e.class}] #{e.message}" Logging.logger.warn e.backtrace.join("\n") diff --git a/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb b/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb index 32b2c1c50..133cf883d 100644 --- a/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +++ b/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb @@ -26,12 +26,13 @@ def process to_delete << change['uri'] need_catalog = true else - set_error Solargraph::LanguageServer::ErrorCodes::INVALID_PARAMS, "Unknown change type ##{change['type']} for #{uri_to_file(change['uri'])}" + set_error Solargraph::LanguageServer::ErrorCodes::INVALID_PARAMS, + "Unknown change type ##{change['type']} for #{uri_to_file(change['uri'])}" end end - host.create *to_create - host.delete *to_delete + host.create(*to_create) + host.delete(*to_delete) # Force host to catalog libraries after file changes (see castwide/solargraph#139) host.catalog if need_catalog diff --git a/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb b/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb index e1e83fc1e..8f93c02e7 100644 --- a/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +++ b/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb @@ -18,7 +18,7 @@ def add_folders # @return [void] def remove_folders return unless params['event'] && params['event']['removed'] - params['event']['removed'].each do |folder| + params['event']['removed'].each do |_folder| host.remove_folders params['event']['removed'] end end diff --git a/lib/solargraph/language_server/transport/data_reader.rb b/lib/solargraph/language_server/transport/data_reader.rb index 3fc3ed311..c24118f03 100644 --- a/lib/solargraph/language_server/transport/data_reader.rb +++ b/lib/solargraph/language_server/transport/data_reader.rb @@ -33,8 +33,8 @@ def receive data @buffer.concat char if @in_header prepare_to_parse_message if @buffer.end_with?("\r\n\r\n") - else - parse_message_from_buffer if @buffer.bytesize == @content_length + elsif @buffer.bytesize == @content_length + parse_message_from_buffer end end end @@ -56,17 +56,15 @@ def prepare_to_parse_message # @return [void] def parse_message_from_buffer - begin - msg = JSON.parse(@buffer) - @message_handler.call msg unless @message_handler.nil? - rescue JSON::ParserError => e - Solargraph::Logging.logger.warn "Failed to parse request: #{e.message}" - Solargraph::Logging.logger.debug "Buffer: #{@buffer}" - ensure - @buffer.clear - @in_header = true - @content_length = 0 - end + msg = JSON.parse(@buffer) + @message_handler.call msg unless @message_handler.nil? + rescue JSON::ParserError => e + Solargraph::Logging.logger.warn "Failed to parse request: #{e.message}" + Solargraph::Logging.logger.debug "Buffer: #{@buffer}" + ensure + @buffer.clear + @in_header = true + @content_length = 0 end end end diff --git a/lib/solargraph/language_server/uri_helpers.rb b/lib/solargraph/language_server/uri_helpers.rb index c7e55afb8..fcf2e0dcb 100644 --- a/lib/solargraph/language_server/uri_helpers.rb +++ b/lib/solargraph/language_server/uri_helpers.rb @@ -14,7 +14,7 @@ module UriHelpers # @param uri [String] # @return [String] def uri_to_file uri - decode(uri).sub(/^file\:(?:\/\/)?/, '').sub(/^\/([a-z]\:)/i, '\1') + decode(uri).sub(%r{^file:(?://)?}, '').sub(%r{^/([a-z]:)}i, '\1') end # Convert a file path to a URI. @@ -22,7 +22,7 @@ def uri_to_file uri # @param file [String] # @return [String] def file_to_uri file - "file://#{encode(file.gsub(/^([a-z]\:)/i, '/\1'))}" + "file://#{encode(file.gsub(/^([a-z]:)/i, '/\1'))}" end # Encode text to be used as a URI path component in LSP. diff --git a/lib/solargraph/library.rb b/lib/solargraph/library.rb index bdd579976..1886b5df6 100644 --- a/lib/solargraph/library.rb +++ b/lib/solargraph/library.rb @@ -116,8 +116,8 @@ def create filename, text # @return [Boolean] True if at least one file was added to the workspace. def create_from_disk *filenames sources = filenames - .reject { |filename| File.directory?(filename) || !File.exist?(filename) } - .map { |filename| Solargraph::Source.load_string(File.read(filename), filename) } + .reject { |filename| File.directory?(filename) || !File.exist?(filename) } + .map { |filename| Solargraph::Source.load_string(File.read(filename), filename) } result = workspace.merge(*sources) sources.each { |source| maybe_map source } result @@ -182,7 +182,7 @@ def definitions_at filename, line, column if cursor.comment? source = read(filename) offset = Solargraph::Position.to_offset(source.code, Solargraph::Position.new(line, column)) - lft = source.code[0..offset-1].match(/\[[a-z0-9_:<, ]*?([a-z0-9_:]*)\z/i) + lft = source.code[0..offset - 1].match(/\[[a-z0-9_:<, ]*?([a-z0-9_:]*)\z/i) rgt = source.code[offset..-1].match(/^([a-z0-9_]*)(:[a-z0-9_:]*)?[\]>, ]/i) if lft && rgt tag = (lft[1] + rgt[1]).sub(/:+$/, '') @@ -248,10 +248,10 @@ def references_from filename, line, column, strip: false, only: false return [] unless pin result = [] files = if only - [api_map.source_map(filename)] - else - (workspace.sources + (@current ? [@current] : [])) - end + [api_map.source_map(filename)] + else + (workspace.sources + (@current ? [@current] : [])) + end files.uniq(&:filename).each do |source| found = source.references(pin.name) found.select! do |loc| @@ -273,7 +273,9 @@ def references_from filename, line, column, strip: false, only: false # HACK: for language clients that exclude special characters from the start of variable names if strip && match = cursor.word.match(/^[^a-z0-9_]+/i) found.map! do |loc| - Solargraph::Location.new(loc.filename, Solargraph::Range.from_to(loc.range.start.line, loc.range.start.column + match[0].length, loc.range.ending.line, loc.range.ending.column)) + Solargraph::Location.new(loc.filename, + Solargraph::Range.from_to(loc.range.start.line, loc.range.start.column + match[0].length, loc.range.ending.line, + loc.range.ending.column)) end end result.concat(found.sort do |a, b| @@ -303,14 +305,12 @@ def locate_ref location return nil if pin.nil? # @param full [String] return_if_match = proc do |full| - if source_map_hash.key?(full) - return Location.new(full, Solargraph::Range.from_to(0, 0, 0, 0)) - end + return Location.new(full, Solargraph::Range.from_to(0, 0, 0, 0)) if source_map_hash.key?(full) end workspace.require_paths.each do |path| full = File.join path, pin.name - return_if_match.(full) - return_if_match.(full << ".rb") + return_if_match.call(full) + return_if_match.call(full << '.rb') end nil rescue FileNotFoundError @@ -512,11 +512,11 @@ def find_external_requires source_map new_set = source_map.requires.map(&:name).to_set # return if new_set == source_map_external_require_hash[source_map.filename] _filenames = nil - filenames = ->{ _filenames ||= workspace.filenames.to_set } + filenames = -> { _filenames ||= workspace.filenames.to_set } source_map_external_require_hash[source_map.filename] = new_set.reject do |path| workspace.require_paths.any? do |base| full = File.join(base, path) - filenames[].include?(full) or filenames[].include?(full << ".rb") + filenames[].include?(full) or filenames[].include?(full << '.rb') end end @external_requires = nil @@ -550,12 +550,9 @@ def read filename # @param error [FileNotFoundError] # @return [nil] def handle_file_not_found filename, error - if workspace.source(filename) - Solargraph.logger.debug "#{filename} is not cataloged in the ApiMap" - nil - else - raise error - end + raise error unless workspace.source(filename) + Solargraph.logger.debug "#{filename} is not cataloged in the ApiMap" + nil end # @param source [Source, nil] @@ -635,11 +632,11 @@ def report_cache_progress gem_name, pending @total = pending if pending > @total finished = @total - pending pct = if @total.zero? - 0 - else - ((finished.to_f / @total.to_f) * 100).to_i - end - message = "#{gem_name}#{pending > 0 ? " (+#{pending})" : ''}" + 0 + else + ((finished.to_f / @total.to_f) * 100).to_i + end + message = "#{gem_name}#{" (+#{pending})" if pending > 0}" # " if @cache_progress @cache_progress.report(message, pct) diff --git a/lib/solargraph/location.rb b/lib/solargraph/location.rb index 713b4fef1..007e72c79 100644 --- a/lib/solargraph/location.rb +++ b/lib/solargraph/location.rb @@ -26,7 +26,7 @@ def initialize filename, range end # @param other [self] - def <=>(other) + def <=> other return nil unless other.is_a?(Location) if filename == other.filename range <=> other.range @@ -62,10 +62,10 @@ def to_hash # @param node [Parser::AST::Node, nil] # @return [Location, nil] - def self.from_node(node) + def self.from_node node return nil if node.nil? || node.loc.nil? range = Range.from_node(node) - self.new(node.loc.expression.source_buffer.name, range) + new(node.loc.expression.source_buffer.name, range) end # @param other [BasicObject] diff --git a/lib/solargraph/logging.rb b/lib/solargraph/logging.rb index 8f3edaba2..126ce1b45 100644 --- a/lib/solargraph/logging.rb +++ b/lib/solargraph/logging.rb @@ -23,7 +23,7 @@ module Logging end @@logger = Logger.new(STDERR, level: level) # @sg-ignore Fix cvar issue - @@logger.formatter = proc do |severity, datetime, progname, msg| + @@logger.formatter = proc do |severity, _datetime, _progname, msg| "[#{severity}] #{msg}\n" end diff --git a/lib/solargraph/parser/comment_ripper.rb b/lib/solargraph/parser/comment_ripper.rb index 92373df20..cb478e146 100644 --- a/lib/solargraph/parser/comment_ripper.rb +++ b/lib/solargraph/parser/comment_ripper.rb @@ -25,19 +25,25 @@ def on_comment *args result = super if @buffer_lines[result[2][0]][0..result[2][1]].strip =~ /^#/ chomped = result[1].chomp - if result[2][0] == 0 && chomped.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '').match(/^#\s*frozen_string_literal:/) + if result[2][0] == 0 && chomped.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, + replace: '').match(/^#\s*frozen_string_literal:/) chomped = '#' end - @comments[result[2][0]] = Snippet.new(Range.from_to(result[2][0], result[2][1], result[2][0], result[2][1] + chomped.length), chomped) + @comments[result[2][0]] = + Snippet.new(Range.from_to(result[2][0], result[2][1], result[2][0], result[2][1] + chomped.length), chomped) end result end # @param result [Array(Symbol, String, Array([Integer, nil], [Integer, nil]))] # @return [void] - def create_snippet(result) + def create_snippet result chomped = result[1].chomp - @comments[result[2][0]] = Snippet.new(Range.from_to(result[2][0] || 0, result[2][1] || 0, result[2][0] || 0, (result[2][1] || 0) + chomped.length), chomped) + @comments[result[2][0]] = + Snippet.new( + Range.from_to(result[2][0] || 0, result[2][1] || 0, result[2][0] || 0, + (result[2][1] || 0) + chomped.length), chomped + ) end def on_embdoc_beg *args diff --git a/lib/solargraph/parser/flow_sensitive_typing.rb b/lib/solargraph/parser/flow_sensitive_typing.rb index 41ce6eeaf..26b8f6675 100644 --- a/lib/solargraph/parser/flow_sensitive_typing.rb +++ b/lib/solargraph/parser/flow_sensitive_typing.rb @@ -5,7 +5,7 @@ class FlowSensitiveTyping # @param locals [Array] # @param enclosing_breakable_pin [Solargraph::Pin::Breakable, nil] - def initialize(locals, enclosing_breakable_pin = nil) + def initialize locals, enclosing_breakable_pin = nil @locals = locals @enclosing_breakable_pin = enclosing_breakable_pin end @@ -14,7 +14,7 @@ def initialize(locals, enclosing_breakable_pin = nil) # @param true_ranges [Array] # # @return [void] - def process_and(and_node, true_ranges = []) + def process_and and_node, true_ranges = [] # @type [Parser::AST::Node] lhs = and_node.children[0] # @type [Parser::AST::Node] @@ -31,7 +31,7 @@ def process_and(and_node, true_ranges = []) # @param if_node [Parser::AST::Node] # # @return [void] - def process_if(if_node) + def process_if if_node # # See if we can refine a type based on the result of 'if foo.nil?' # @@ -50,12 +50,10 @@ def process_if(if_node) else_clause = if_node.children[2] true_ranges = [] - if always_breaks?(else_clause) - unless enclosing_breakable_pin.nil? - rest_of_breakable_body = Range.new(get_node_end_position(if_node), - get_node_end_position(enclosing_breakable_pin.node)) - true_ranges << rest_of_breakable_body - end + if always_breaks?(else_clause) && !enclosing_breakable_pin.nil? + rest_of_breakable_body = Range.new(get_node_end_position(if_node), + get_node_end_position(enclosing_breakable_pin.node)) + true_ranges << rest_of_breakable_body end unless then_clause.nil? @@ -87,30 +85,42 @@ class << self # @param location [Location] # # @return [Array] - def self.visible_pins(pins, name, closure, location) + def self.visible_pins pins, name, closure, location logger.debug { "FlowSensitiveTyping#visible_pins(name=#{name}, closure=#{closure}, location=#{location})" } pins_with_name = pins.select { |p| p.name == name } if pins_with_name.empty? - logger.debug { "FlowSensitiveTyping#visible_pins(name=#{name}, closure=#{closure}, location=#{location}) => [] - no pins with name" } + logger.debug do + "FlowSensitiveTyping#visible_pins(name=#{name}, closure=#{closure}, location=#{location}) => [] - no pins with name" + end return [] end - pins_with_specific_visibility = pins.select { |p| p.name == name && p.presence && p.visible_at?(closure, location) } + pins_with_specific_visibility = pins.select do |p| + p.name == name && p.presence && p.visible_at?(closure, location) + end if pins_with_specific_visibility.empty? - logger.debug { "FlowSensitiveTyping#visible_pins(name=#{name}, closure=#{closure}, location=#{location}) => #{pins_with_name} - no pins with specific visibility" } + logger.debug do + "FlowSensitiveTyping#visible_pins(name=#{name}, closure=#{closure}, location=#{location}) => #{pins_with_name} - no pins with specific visibility" + end return pins_with_name end visible_pins_specific_to_this_closure = pins_with_specific_visibility.select { |p| p.closure == closure } if visible_pins_specific_to_this_closure.empty? - logger.debug { "FlowSensitiveTyping#visible_pins(name=#{name}, closure=#{closure}, location=#{location}) => #{pins_with_specific_visibility} - no visible pins specific to this closure (#{closure})}" } + logger.debug do + "FlowSensitiveTyping#visible_pins(name=#{name}, closure=#{closure}, location=#{location}) => #{pins_with_specific_visibility} - no visible pins specific to this closure (#{closure})}" + end return pins_with_specific_visibility end flow_defined_pins = pins_with_specific_visibility.select { |p| p.presence_certain? } if flow_defined_pins.empty? - logger.debug { "FlowSensitiveTyping#visible_pins(name=#{name}, closure=#{closure}, location=#{location}) => #{visible_pins_specific_to_this_closure} - no flow-defined pins" } + logger.debug do + "FlowSensitiveTyping#visible_pins(name=#{name}, closure=#{closure}, location=#{location}) => #{visible_pins_specific_to_this_closure} - no flow-defined pins" + end return visible_pins_specific_to_this_closure end - logger.debug { "FlowSensitiveTyping#visible_pins(name=#{name}, closure=#{closure}, location=#{location}) => #{flow_defined_pins}" } + logger.debug do + "FlowSensitiveTyping#visible_pins(name=#{name}, closure=#{closure}, location=#{location}) => #{flow_defined_pins}" + end flow_defined_pins end @@ -124,7 +134,7 @@ def self.visible_pins(pins, name, closure, location) # @param presence [Range] # # @return [void] - def add_downcast_local(pin, downcast_type_name, presence) + def add_downcast_local pin, downcast_type_name, presence # @todo Create pin#update method new_pin = Solargraph::Pin::LocalVariable.new( location: pin.location, @@ -144,7 +154,7 @@ def add_downcast_local(pin, downcast_type_name, presence) # @param presences [Array] # # @return [void] - def process_facts(facts_by_pin, presences) + def process_facts facts_by_pin, presences # # Add specialized locals for the rest of the block # @@ -162,7 +172,7 @@ def process_facts(facts_by_pin, presences) # @param true_ranges [Array] # # @return [void] - def process_conditional(conditional_node, true_ranges) + def process_conditional conditional_node, true_ranges if conditional_node.type == :send process_isa(conditional_node, true_ranges) elsif conditional_node.type == :and @@ -172,7 +182,7 @@ def process_conditional(conditional_node, true_ranges) # @param isa_node [Parser::AST::Node] # @return [Array(String, String), nil] - def parse_isa(isa_node) + def parse_isa isa_node return unless isa_node&.type == :send && isa_node.children[1] == :is_a? # Check if conditional node follows this pattern: # s(:send, @@ -200,7 +210,7 @@ def parse_isa(isa_node) # @param position [Position] # # @return [Solargraph::Pin::LocalVariable, nil] - def find_local(variable_name, position) + def find_local variable_name, position pins = locals.select { |pin| pin.name == variable_name && pin.presence.include?(position) } return unless pins.length == 1 pins.first @@ -210,7 +220,7 @@ def find_local(variable_name, position) # @param true_presences [Array] # # @return [void] - def process_isa(isa_node, true_presences) + def process_isa isa_node, true_presences isa_type_name, variable_name = parse_isa(isa_node) return if variable_name.nil? || variable_name.empty? isa_position = Range.from_node(isa_node).start @@ -227,7 +237,7 @@ def process_isa(isa_node, true_presences) # @param node [Parser::AST::Node] # # @return [String, nil] - def type_name(node) + def type_name node # e.g., # s(:const, nil, :Baz) return unless node&.type == :const @@ -243,13 +253,11 @@ def type_name(node) end # @param clause_node [Parser::AST::Node] - def always_breaks?(clause_node) + def always_breaks? clause_node clause_node&.type == :break end - attr_reader :locals - - attr_reader :enclosing_breakable_pin + attr_reader :locals, :enclosing_breakable_pin end end end diff --git a/lib/solargraph/parser/node_methods.rb b/lib/solargraph/parser/node_methods.rb index f33a924c1..ff9d48671 100644 --- a/lib/solargraph/parser/node_methods.rb +++ b/lib/solargraph/parser/node_methods.rb @@ -55,13 +55,13 @@ def find_recipient_node cursor # @return [Array] low-level value nodes in # value position. Does not include explicit return # statements - def value_position_nodes_only(node) + def value_position_nodes_only node raise NotImplementedError end # @abstract # @param nodes [Enumerable] - def any_splatted_call?(nodes) + def any_splatted_call? nodes raise NotImplementedError end @@ -82,14 +82,14 @@ def convert_hash node # @abstract # @param node [Parser::AST::Node] # @return [Position] - def get_node_start_position(node) + def get_node_start_position node raise NotImplementedError end # @abstract # @param node [Parser::AST::Node] # @return [Position] - def get_node_end_position(node) + def get_node_end_position node raise NotImplementedError end end diff --git a/lib/solargraph/parser/node_processor.rb b/lib/solargraph/parser/node_processor.rb index dbe0b7cd5..a15209589 100644 --- a/lib/solargraph/parser/node_processor.rb +++ b/lib/solargraph/parser/node_processor.rb @@ -42,7 +42,7 @@ def self.process node, region = Region.new, pins = [], locals = [] pins.push Pin::Namespace.new( location: region.source.location, name: '', - source: :parser, + source: :parser ) end return [pins, locals] unless Parser.is_ast_node?(node) diff --git a/lib/solargraph/parser/node_processor/base.rb b/lib/solargraph/parser/node_processor/base.rb index fad31e95b..544eb693e 100644 --- a/lib/solargraph/parser/node_processor/base.rb +++ b/lib/solargraph/parser/node_processor/base.rb @@ -53,14 +53,14 @@ def process_children subregion = region # @param node [Parser::AST::Node] # @return [Solargraph::Location] - def get_node_location(node) + def get_node_location node range = Parser.node_range(node) Location.new(region.filename, range) end # @param node [Parser::AST::Node] # @return [String, nil] - def comments_for(node) + def comments_for node region.source.comments_for(node) end diff --git a/lib/solargraph/parser/parser_gem/class_methods.rb b/lib/solargraph/parser/parser_gem/class_methods.rb index 2daf22fc7..c376e565d 100644 --- a/lib/solargraph/parser/parser_gem/class_methods.rb +++ b/lib/solargraph/parser/parser_gem/class_methods.rb @@ -45,7 +45,7 @@ def map source # @param name [String] # @return [Array] def references source, name - if name.end_with?("=") + if name.end_with?('=') reg = /#{Regexp.escape name[0..-2]}\s*=/ # @param code [String] # @param offset [Integer] @@ -86,17 +86,17 @@ def inner_node_references name, top # @return [Source::Chain] def chain *args - NodeChainer.chain *args + NodeChainer.chain(*args) end # @return [Source::Chain] def chain_string *args - NodeChainer.load_string *args + NodeChainer.load_string(*args) end # @return [Array(Array, Array)] def process_node *args - Solargraph::Parser::NodeProcessor.process *args + Solargraph::Parser::NodeProcessor.process(*args) end # @param node [Parser::AST::Node] diff --git a/lib/solargraph/parser/parser_gem/flawed_builder.rb b/lib/solargraph/parser/parser_gem/flawed_builder.rb index acf665e16..341042f22 100644 --- a/lib/solargraph/parser/parser_gem/flawed_builder.rb +++ b/lib/solargraph/parser/parser_gem/flawed_builder.rb @@ -10,7 +10,7 @@ class FlawedBuilder < ::Parser::Builders::Default # @param token [::Parser::AST::Node] # @return [String] # @sg-ignore - def string_value(token) + def string_value token value(token) end end diff --git a/lib/solargraph/parser/parser_gem/node_chainer.rb b/lib/solargraph/parser/parser_gem/node_chainer.rb index d8d46319b..188fa7142 100644 --- a/lib/solargraph/parser/parser_gem/node_chainer.rb +++ b/lib/solargraph/parser/parser_gem/node_chainer.rb @@ -22,7 +22,7 @@ def initialize node, filename = nil, parent = nil # @return [Source::Chain] def chain links = generate_links(@node) - Chain.new(links, @node, (Parser.is_ast_node?(@node) && @node.type == :splat)) + Chain.new(links, @node, Parser.is_ast_node?(@node) && @node.type == :splat) end class << self @@ -36,7 +36,7 @@ def chain node, filename = nil, parent = nil # @param code [String] # @return [Source::Chain] - def load_string(code) + def load_string code node = Parser.parse(code.sub(/\.$/, '')) chain = NodeChainer.new(node).chain chain.links.push(Chain::Link.new) if code.end_with?('.') @@ -90,27 +90,29 @@ def generate_links n elsif n.type == :const const = unpack_name(n) result.push Chain::Constant.new(const) - elsif [:lvar, :lvasgn].include?(n.type) + elsif %i[lvar lvasgn].include?(n.type) result.push Chain::Call.new(n.children[0].to_s, Location.from_node(n)) - elsif [:ivar, :ivasgn].include?(n.type) + elsif %i[ivar ivasgn].include?(n.type) result.push Chain::InstanceVariable.new(n.children[0].to_s) - elsif [:cvar, :cvasgn].include?(n.type) + elsif %i[cvar cvasgn].include?(n.type) result.push Chain::ClassVariable.new(n.children[0].to_s) - elsif [:gvar, :gvasgn].include?(n.type) + elsif %i[gvar gvasgn].include?(n.type) result.push Chain::GlobalVariable.new(n.children[0].to_s) elsif n.type == :or_asgn new_node = n.updated(n.children[0].type, n.children[0].children + [n.children[1]]) result.concat generate_links new_node - elsif [:class, :module, :def, :defs].include?(n.type) + elsif %i[class module def defs].include?(n.type) # @todo Undefined or what? result.push Chain::UNDEFINED_CALL elsif n.type == :and result.concat generate_links(n.children.last) elsif n.type == :or - result.push Chain::Or.new([NodeChainer.chain(n.children[0], @filename), NodeChainer.chain(n.children[1], @filename, n)]) + result.push Chain::Or.new([NodeChainer.chain(n.children[0], @filename), + NodeChainer.chain(n.children[1], @filename, n)]) elsif n.type == :if - result.push Chain::If.new([NodeChainer.chain(n.children[1], @filename), NodeChainer.chain(n.children[2], @filename, n)]) - elsif [:begin, :kwbegin].include?(n.type) + result.push Chain::If.new([NodeChainer.chain(n.children[1], @filename), + NodeChainer.chain(n.children[2], @filename, n)]) + elsif %i[begin kwbegin].include?(n.type) result.concat generate_links(n.children.last) elsif n.type == :block_pass block_variable_name_node = n.children[0] @@ -118,12 +120,10 @@ def generate_links n # anonymous block forwarding (e.g., "&") # added in Ruby 3.1 - https://bugs.ruby-lang.org/issues/11256 result.push Chain::BlockVariable.new(nil) + elsif block_variable_name_node.type == :sym + result.push Chain::BlockSymbol.new("#{block_variable_name_node.children[0]}") else - if block_variable_name_node.type == :sym - result.push Chain::BlockSymbol.new("#{block_variable_name_node.children[0].to_s}") - else - result.push Chain::BlockVariable.new("&#{block_variable_name_node.children[0].to_s}") - end + result.push Chain::BlockVariable.new("&#{block_variable_name_node.children[0]}") end elsif n.type == :hash result.push Chain::Hash.new('::Hash', n, hash_is_splatted?(n)) @@ -132,7 +132,7 @@ def generate_links n result.push Source::Chain::Array.new(chained_children, n) else lit = infer_literal_node_type(n) - result.push (lit ? Chain::Literal.new(lit, n) : Chain::Link.new) + result.push(lit ? Chain::Literal.new(lit, n) : Chain::Link.new) end result end @@ -141,7 +141,9 @@ def generate_links n def hash_is_splatted? node return false unless Parser.is_ast_node?(node) && node.type == :hash return false unless Parser.is_ast_node?(node.children.last) && node.children.last.type == :kwsplat - return false if Parser.is_ast_node?(node.children.last.children[0]) && node.children.last.children[0].type == :hash + if Parser.is_ast_node?(node.children.last.children[0]) && node.children.last.children[0].type == :hash + return false + end true end diff --git a/lib/solargraph/parser/parser_gem/node_methods.rb b/lib/solargraph/parser/parser_gem/node_methods.rb index 02f790c00..9aad8526e 100644 --- a/lib/solargraph/parser/parser_gem/node_methods.rb +++ b/lib/solargraph/parser/parser_gem/node_methods.rb @@ -12,17 +12,17 @@ module NodeMethods # @param node [Parser::AST::Node] # @return [String] - def unpack_name(node) - pack_name(node).join("::") + def unpack_name node + pack_name(node).join('::') end # @param node [Parser::AST::Node] # @return [Array] - def pack_name(node) + def pack_name node # @type [Array] parts = [] if node.is_a?(AST::Node) - node.children.each { |n| + node.children.each do |n| if n.is_a?(AST::Node) if n.type == :cbase parts = [''] + pack_name(n) @@ -32,7 +32,7 @@ def pack_name(node) else parts.push n unless n.nil? end - } + end end parts end @@ -41,7 +41,7 @@ def pack_name(node) # @return [String, nil] def infer_literal_node_type node return nil unless node.is_a?(AST::Node) - if node.type == :str || node.type == :dstr + if %i[str dstr].include?(node.type) return '::String' elsif node.type == :array return '::Array' @@ -53,30 +53,30 @@ def infer_literal_node_type node return '::Integer' elsif node.type == :float return '::Float' - elsif node.type == :sym || node.type == :dsym + elsif %i[sym dsym].include?(node.type) return '::Symbol' elsif node.type == :regexp return '::Regexp' elsif node.type == :irange return '::Range' - elsif node.type == :true || node.type == :false + elsif %i[true false].include?(node.type) return '::Boolean' # @todo Support `nil` keyword in types - # elsif node.type == :nil - # return 'NilClass' + # elsif node.type == :nil + # return 'NilClass' end nil end # @param node [Parser::AST::Node] # @return [Position] - def get_node_start_position(node) + def get_node_start_position node Position.new(node.loc.line, node.loc.column) end # @param node [Parser::AST::Node] # @return [Position] - def get_node_end_position(node) + def get_node_end_position node Position.new(node.loc.last_line, node.loc.last_column) end @@ -86,19 +86,15 @@ def get_node_end_position(node) # @return [String] def drill_signature node, signature return signature unless node.is_a?(AST::Node) - if node.type == :const or node.type == :cbase - unless node.children[0].nil? - signature += drill_signature(node.children[0], signature) - end + if %i[const cbase].include?(node.type) + signature += drill_signature(node.children[0], signature) unless node.children[0].nil? signature += '::' unless signature.empty? signature += node.children[1].to_s - elsif node.type == :lvar or node.type == :ivar or node.type == :cvar + elsif %i[lvar ivar cvar].include?(node.type) signature += '.' unless signature.empty? signature += node.children[0].to_s elsif node.type == :send - unless node.children[0].nil? - signature += drill_signature(node.children[0], signature) - end + signature += drill_signature(node.children[0], signature) unless node.children[0].nil? signature += '.' unless signature.empty? signature += node.children[1].to_s end @@ -110,7 +106,9 @@ def drill_signature node, signature def convert_hash node return {} unless Parser.is_ast_node?(node) return convert_hash(node.children[0]) if node.type == :kwsplat - return convert_hash(node.children[0]) if Parser.is_ast_node?(node.children[0]) && node.children[0].type == :kwsplat + if Parser.is_ast_node?(node.children[0]) && node.children[0].type == :kwsplat + return convert_hash(node.children[0]) + end return {} unless node.type == :hash result = {} node.children.each do |pair| @@ -147,7 +145,7 @@ def splatted_call? node end # @param nodes [Enumerable] - def any_splatted_call?(nodes) + def any_splatted_call? nodes nodes.any? { |n| splatted_call?(n) } end @@ -167,7 +165,7 @@ def call_nodes_from node result.push node result.concat call_nodes_from(node.children.first) node.children[2..-1].each { |child| result.concat call_nodes_from(child) } - elsif [:super, :zsuper].include?(node.type) + elsif %i[super zsuper].include?(node.type) result.push node node.children.each { |child| result.concat call_nodes_from(child) } else @@ -198,27 +196,29 @@ def returns_from_method_body node # @return [Array] low-level value nodes in # value position. Does not include explicit return # statements - def value_position_nodes_only(node) + def value_position_nodes_only node DeepInference.value_position_nodes_only(node).map { |n| n || NIL_NODE } end # @param cursor [Solargraph::Source::Cursor] # @return [Parser::AST::Node, nil] def find_recipient_node cursor - return repaired_find_recipient_node(cursor) if cursor.source.repaired? && cursor.source.code[cursor.offset - 1] == '(' + if cursor.source.repaired? && cursor.source.code[cursor.offset - 1] == '(' + return repaired_find_recipient_node(cursor) + end source = cursor.source position = cursor.position offset = cursor.offset tree = if source.synchronized? - match = source.code[0..offset-1].match(/,\s*\z/) - if match - source.tree_at(position.line, position.column - match[0].length) - else - source.tree_at(position.line, position.column) - end - else - source.tree_at(position.line, position.column - 1) - end + match = source.code[0..offset - 1].match(/,\s*\z/) + if match + source.tree_at(position.line, position.column - match[0].length) + else + source.tree_at(position.line, position.column) + end + else + source.tree_at(position.line, position.column - 1) + end # @type [AST::Node, nil] prev = nil tree.each do |node| @@ -226,12 +226,10 @@ def find_recipient_node cursor args = node.children[2..-1] if !args.empty? return node if prev && args.include?(prev) - else - if source.synchronized? - return node if source.code[0..offset-1] =~ /\(\s*\z/ && source.code[offset..-1] =~ /^\s*\)/ - else - return node if source.code[0..offset-1] =~ /\([^(]*\z/ - end + elsif source.synchronized? + return node if source.code[0..offset - 1] =~ /\(\s*\z/ && source.code[offset..-1] =~ /^\s*\)/ + elsif source.code[0..offset - 1] =~ /\([^(]*\z/ + return node end end prev = node @@ -244,7 +242,7 @@ def find_recipient_node cursor def repaired_find_recipient_node cursor cursor = cursor.source.cursor_at([cursor.position.line, cursor.position.column - 1]) node = cursor.source.tree_at(cursor.position.line, cursor.position.column).first - return node if node && node.type == :send + node if node && node.type == :send end # @@ -301,12 +299,12 @@ def repaired_find_recipient_node cursor # statements in value positions. module DeepInference class << self - CONDITIONAL_ALL_BUT_FIRST = [:if, :unless] + CONDITIONAL_ALL_BUT_FIRST = %i[if unless] CONDITIONAL_ALL = [:or] ONLY_ONE_CHILD = [:return] FIRST_TWO_CHILDREN = [:rescue] - COMPOUND_STATEMENTS = [:begin, :kwbegin] - SKIPPABLE = [:def, :defs, :class, :sclass, :module] + COMPOUND_STATEMENTS = %i[begin kwbegin] + SKIPPABLE = %i[def defs class sclass module] FUNCTION_VALUE = [:block] CASE_STATEMENT = [:case] @@ -326,7 +324,7 @@ def from_method_body node # @return [Array] low-level value nodes in # value position. Does not include explicit return # statements - def value_position_nodes_only(node) + def value_position_nodes_only node from_value_position_statement(node, include_explicit_returns: false) end @@ -361,7 +359,9 @@ def from_value_position_statement node, include_explicit_returns: true # @todo any explicit returns actually return from # scope in which the proc is run. This asssumes # that the function is executed here. - result.concat explicit_return_values_from_compound_statement(node.children[2]) if include_explicit_returns + if include_explicit_returns + result.concat explicit_return_values_from_compound_statement(node.children[2]) + end elsif CASE_STATEMENT.include?(node.type) node.children[1..-1].each do |cc| if cc.nil? @@ -396,7 +396,7 @@ def from_value_position_statement node, include_explicit_returns: true # @return [Array] def from_value_position_compound_statement parent result = [] - nodes = parent.children.select{|n| n.is_a?(AST::Node)} + nodes = parent.children.select { |n| n.is_a?(AST::Node) } nodes.each_with_index do |node, idx| if node.type == :block result.concat explicit_return_values_from_compound_statement(node.children[2]) @@ -421,7 +421,10 @@ def from_value_position_compound_statement parent # value position. we already have the explicit values # from above; now we need to also gather the value # position nodes - result.concat from_value_position_statement(nodes.last, include_explicit_returns: false) if idx == nodes.length - 1 + if idx == nodes.length - 1 + result.concat from_value_position_statement(nodes.last, + include_explicit_returns: false) + end end result end @@ -437,7 +440,7 @@ def from_value_position_compound_statement parent def explicit_return_values_from_compound_statement parent return [] unless parent.is_a?(::Parser::AST::Node) result = [] - nodes = parent.children.select{|n| n.is_a?(::Parser::AST::Node)} + nodes = parent.children.select { |n| n.is_a?(::Parser::AST::Node) } nodes.each do |node| next if SKIPPABLE.include?(node.type) if node.type == :return diff --git a/lib/solargraph/parser/parser_gem/node_processors/and_node.rb b/lib/solargraph/parser/parser_gem/node_processors/and_node.rb index d3485af7c..d3986f2d4 100644 --- a/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +++ b/lib/solargraph/parser/parser_gem/node_processors/and_node.rb @@ -11,7 +11,9 @@ def process process_children position = get_node_start_position(node) - enclosing_breakable_pin = pins.select{|pin| pin.is_a?(Pin::Breakable) && pin.location.range.contain?(position)}.last + enclosing_breakable_pin = pins.select do |pin| + pin.is_a?(Pin::Breakable) && pin.location.range.contain?(position) + end.last FlowSensitiveTyping.new(locals, enclosing_breakable_pin).process_and(node) end end diff --git a/lib/solargraph/parser/parser_gem/node_processors/args_node.rb b/lib/solargraph/parser/parser_gem/node_processors/args_node.rb index 8d601bf6e..c33aa1ca4 100644 --- a/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +++ b/lib/solargraph/parser/parser_gem/node_processors/args_node.rb @@ -14,16 +14,16 @@ def process node.children.each do |u| loc = get_node_location(u) locals.push Solargraph::Pin::Parameter.new( - location: loc, - closure: callable, - comments: comments_for(node), - name: u.children[0].to_s, - assignment: u.children[1], - asgn_code: u.children[1] ? region.code_for(u.children[1]) : nil, - presence: callable.location.range, - decl: get_decl(u), - source: :parser - ) + location: loc, + closure: callable, + comments: comments_for(node), + name: u.children[0].to_s, + assignment: u.children[1], + asgn_code: u.children[1] ? region.code_for(u.children[1]) : nil, + presence: callable.location.range, + decl: get_decl(u), + source: :parser + ) callable.parameters.push locals.last end end @@ -35,7 +35,7 @@ def process # @param callable [Pin::Callable] # @return [void] - def forward(callable) + def forward callable loc = get_node_location(node) locals.push Solargraph::Pin::Parameter.new( location: loc, diff --git a/lib/solargraph/parser/parser_gem/node_processors/block_node.rb b/lib/solargraph/parser/parser_gem/node_processors/block_node.rb index d773e8e50..b2a9d3c2d 100644 --- a/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +++ b/lib/solargraph/parser/parser_gem/node_processors/block_node.rb @@ -10,15 +10,15 @@ class BlockNode < Parser::NodeProcessor::Base def process location = get_node_location(node) parent = if other_class_eval? - Solargraph::Pin::Namespace.new( - location: location, - type: :class, - name: unpack_name(node.children[0].children[0]), - source: :parser, - ) - else - region.closure - end + Solargraph::Pin::Namespace.new( + location: location, + type: :class, + name: unpack_name(node.children[0].children[0]), + source: :parser + ) + else + region.closure + end block_pin = Solargraph::Pin::Block.new( location: location, closure: parent, @@ -37,7 +37,7 @@ def process def other_class_eval? node.children[0].type == :send && node.children[0].children[1] == :class_eval && - [:cbase, :const].include?(node.children[0].children[0]&.type) + %i[cbase const].include?(node.children[0].children[0]&.type) end end end diff --git a/lib/solargraph/parser/parser_gem/node_processors/def_node.rb b/lib/solargraph/parser/parser_gem/node_processors/def_node.rb index 47c01e728..25c124423 100644 --- a/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +++ b/lib/solargraph/parser/parser_gem/node_processors/def_node.rb @@ -16,7 +16,7 @@ def process scope: scope, visibility: scope == :instance && name == 'initialize' ? :private : region.visibility, node: node, - source: :parser, + source: :parser ) if region.visibility == :module_function pins.push Solargraph::Pin::Method.new( @@ -28,7 +28,7 @@ def process visibility: :public, parameters: methpin.parameters, node: methpin.node, - source: :parser, + source: :parser ) pins.push Solargraph::Pin::Method.new( location: methpin.location, @@ -39,7 +39,7 @@ def process visibility: :private, parameters: methpin.parameters, node: methpin.node, - source: :parser, + source: :parser ) else pins.push methpin diff --git a/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb b/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb index 5f40457e9..6c9c1d7e2 100644 --- a/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +++ b/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb @@ -11,13 +11,13 @@ def process s_visi = region.visibility s_visi = :public if s_visi == :module_function || region.scope != :class loc = get_node_location(node) - if node.children[0].is_a?(AST::Node) && node.children[0].type == :self - closure = region.closure - else - closure = Solargraph::Pin::Namespace.new( - name: unpack_name(node.children[0]) - ) - end + closure = if node.children[0].is_a?(AST::Node) && node.children[0].type == :self + region.closure + else + Solargraph::Pin::Namespace.new( + name: unpack_name(node.children[0]) + ) + end pins.push Solargraph::Pin::Method.new( location: loc, closure: closure, @@ -26,7 +26,7 @@ def process scope: :class, visibility: s_visi, node: node, - source: :parser, + source: :parser ) process_children region.update(closure: pins.last, scope: :class) end diff --git a/lib/solargraph/parser/parser_gem/node_processors/if_node.rb b/lib/solargraph/parser/parser_gem/node_processors/if_node.rb index 2452b9cc5..4b5d9c1c6 100644 --- a/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +++ b/lib/solargraph/parser/parser_gem/node_processors/if_node.rb @@ -13,7 +13,9 @@ def process position = get_node_start_position(node) # @sg-ignore # @type [Solargraph::Pin::Breakable, nil] - enclosing_breakable_pin = pins.select{|pin| pin.is_a?(Pin::Breakable) && pin.location.range.contain?(position)}.last + enclosing_breakable_pin = pins.select do |pin| + pin.is_a?(Pin::Breakable) && pin.location.range.contain?(position) + end.last FlowSensitiveTyping.new(locals, enclosing_breakable_pin).process_if(node) end end diff --git a/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb b/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb index 021ae0ab1..67b79108d 100644 --- a/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +++ b/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb @@ -23,7 +23,8 @@ def process if named_path.is_a?(Pin::Method) pins.push Solargraph::Pin::InstanceVariable.new( location: loc, - closure: Pin::Namespace.new(type: :module, closure: region.closure.closure, name: region.closure.name), + closure: Pin::Namespace.new(type: :module, closure: region.closure.closure, + name: region.closure.name), name: node.children[0].to_s, comments: comments_for(node), assignment: node.children[1], diff --git a/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb b/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb index 0e4d7b26a..bf70cd554 100644 --- a/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +++ b/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb @@ -86,7 +86,7 @@ def process_vasgn_target asgn, operator, argument argument ] send_node = node.updated(:send, send_children) - new_asgn = node.updated(asgn.type, [variable_name, send_node]) + new_asgn = node.updated(asgn.type, [variable_name, send_node]) NodeProcessor.process(new_asgn, region, pins, locals) end end diff --git a/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb b/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb index 1b573ed93..526a9ba51 100644 --- a/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +++ b/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb @@ -30,9 +30,7 @@ def process elsif sclass.is_a?(::Parser::AST::Node) && sclass.type == :const names = [region.closure.namespace, region.closure.name] also = NodeMethods.unpack_name(sclass) - if also != region.closure.name - names << also - end + names << also if also != region.closure.name name = names.reject(&:empty?).join('::') closure = Solargraph::Pin::Namespace.new(name: name, location: region.closure.location, source: :parser) else @@ -41,7 +39,7 @@ def process pins.push Solargraph::Pin::Singleton.new( location: get_node_location(node), closure: closure, - source: :parser, + source: :parser ) process_children region.update(visibility: :public, scope: :class, closure: pins.last) end diff --git a/lib/solargraph/parser/parser_gem/node_processors/send_node.rb b/lib/solargraph/parser/parser_gem/node_processors/send_node.rb index 645baf00f..854cb9740 100644 --- a/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +++ b/lib/solargraph/parser/parser_gem/node_processors/send_node.rb @@ -13,16 +13,17 @@ def process method_name = node.children[1] # :nocov: unless method_name.instance_of?(Symbol) - Solargraph.assert_or_log(:parser_method_name, "Expected method name to be a Symbol, got #{method_name.class} for node #{node.inspect}") + Solargraph.assert_or_log(:parser_method_name, + "Expected method name to be a Symbol, got #{method_name.class} for node #{node.inspect}") return process_children end # :nocov: if node.children[0].nil? - if [:private, :public, :protected].include?(method_name) + if %i[private public protected].include?(method_name) process_visibility elsif method_name == :module_function process_module_function - elsif [:attr_reader, :attr_writer, :attr_accessor].include?(method_name) + elsif %i[attr_reader attr_writer attr_accessor].include?(method_name) process_attribute elsif method_name == :include process_include @@ -46,7 +47,10 @@ def process end # @sg-ignore elsif method_name == :require && node.children[0].to_s == '(const nil :Bundler)' - pins.push Pin::Reference::Require.new(Solargraph::Location.new(region.filename, Solargraph::Range.from_to(0, 0, 0, 0)), 'bundler/require', source: :parser) + pins.push Pin::Reference::Require.new( + Solargraph::Location.new(region.filename, + Solargraph::Range.from_to(0, 0, 0, 0)), 'bundler/require', source: :parser + ) end process_children end @@ -55,20 +59,21 @@ def process # @return [void] def process_visibility - if (node.children.length > 2) + if node.children.length > 2 node.children[2..-1].each do |child| # @sg-ignore Variable type could not be inferred for method_name # @type [Symbol] visibility = node.children[1] # :nocov: unless visibility.instance_of?(Symbol) - Solargraph.assert_or_log(:parser_visibility, "Expected visibility name to be a Symbol, got #{visibility.class} for node #{node.inspect}") + Solargraph.assert_or_log(:parser_visibility, + "Expected visibility name to be a Symbol, got #{visibility.class} for node #{node.inspect}") return process_children end # :nocov: - if child.is_a?(::Parser::AST::Node) && (child.type == :sym || child.type == :str) + if child.is_a?(::Parser::AST::Node) && %i[sym str].include?(child.type) name = child.children[0].to_s - matches = pins.select{ |pin| pin.is_a?(Pin::Method) && pin.name == name && pin.namespace == region.closure.full_context.namespace && pin.context.scope == (region.scope || :instance)} + matches = pins.select { |pin| pin.is_a?(Pin::Method) && pin.name == name && pin.namespace == region.closure.full_context.namespace && pin.context.scope == (region.scope || :instance) } matches.each do |pin| # @todo Smelly instance variable access pin.instance_variable_set(:@visibility, visibility) @@ -89,7 +94,7 @@ def process_attribute loc = get_node_location(node) clos = region.closure cmnt = comments_for(node) - if node.children[1] == :attr_reader || node.children[1] == :attr_accessor + if %i[attr_reader attr_accessor].include?(node.children[1]) pins.push Solargraph::Pin::Method.new( location: loc, closure: clos, @@ -101,54 +106,53 @@ def process_attribute source: :parser ) end - if node.children[1] == :attr_writer || node.children[1] == :attr_accessor - method_pin = Solargraph::Pin::Method.new( - location: loc, - closure: clos, - name: "#{a.children[0]}=", - comments: cmnt, - scope: region.scope || :instance, - visibility: region.visibility, - attribute: true, - source: :parser - ) - pins.push method_pin - method_pin.parameters.push Pin::Parameter.new(name: 'value', decl: :arg, closure: pins.last, source: :parser) - if method_pin.return_type.defined? - pins.last.docstring.add_tag YARD::Tags::Tag.new(:param, '', pins.last.return_type.items.map(&:rooted_tags), 'value') - end + next unless %i[attr_writer attr_accessor].include?(node.children[1]) + method_pin = Solargraph::Pin::Method.new( + location: loc, + closure: clos, + name: "#{a.children[0]}=", + comments: cmnt, + scope: region.scope || :instance, + visibility: region.visibility, + attribute: true, + source: :parser + ) + pins.push method_pin + method_pin.parameters.push Pin::Parameter.new(name: 'value', decl: :arg, closure: pins.last, + source: :parser) + if method_pin.return_type.defined? + pins.last.docstring.add_tag YARD::Tags::Tag.new(:param, '', + pins.last.return_type.items.map(&:rooted_tags), 'value') end end end # @return [void] def process_include - if node.children[2].is_a?(AST::Node) && node.children[2].type == :const - cp = region.closure - node.children[2..-1].each do |i| - type = region.scope == :class ? Pin::Reference::Extend : Pin::Reference::Include - pins.push type.new( - location: get_node_location(i), - closure: cp, - name: unpack_name(i), - source: :parser - ) - end + return unless node.children[2].is_a?(AST::Node) && node.children[2].type == :const + cp = region.closure + node.children[2..-1].each do |i| + type = region.scope == :class ? Pin::Reference::Extend : Pin::Reference::Include + pins.push type.new( + location: get_node_location(i), + closure: cp, + name: unpack_name(i), + source: :parser + ) end end # @return [void] def process_prepend - if node.children[2].is_a?(AST::Node) && node.children[2].type == :const - cp = region.closure - node.children[2..-1].each do |i| - pins.push Pin::Reference::Prepend.new( - location: get_node_location(i), - closure: cp, - name: unpack_name(i), - source: :parser - ) - end + return unless node.children[2].is_a?(AST::Node) && node.children[2].type == :const + cp = region.closure + node.children[2..-1].each do |i| + pins.push Pin::Reference::Prepend.new( + location: get_node_location(i), + closure: cp, + name: unpack_name(i), + source: :parser + ) end end @@ -176,18 +180,16 @@ def process_extend # @return [void] def process_require - if node.children[2].is_a?(AST::Node) && node.children[2].type == :str - path = node.children[2].children[0].to_s - pins.push Pin::Reference::Require.new(get_node_location(node), path, source: :parser) - end + return unless node.children[2].is_a?(AST::Node) && node.children[2].type == :str + path = node.children[2].children[0].to_s + pins.push Pin::Reference::Require.new(get_node_location(node), path, source: :parser) end # @return [void] def process_autoload - if node.children[3].is_a?(AST::Node) && node.children[3].type == :str - path = node.children[3].children[0].to_s - pins.push Pin::Reference::Require.new(get_node_location(node), path, source: :parser) - end + return unless node.children[3].is_a?(AST::Node) && node.children[3].type == :str + path = node.children[3].children[0].to_s + pins.push Pin::Reference::Require.new(get_node_location(node), path, source: :parser) end # @return [void] @@ -195,54 +197,54 @@ def process_module_function if node.children[2].nil? # @todo Smelly instance variable access region.instance_variable_set(:@visibility, :module_function) - elsif node.children[2].type == :sym || node.children[2].type == :str + elsif %i[sym str].include?(node.children[2].type) node.children[2..-1].each do |x| cn = x.children[0].to_s # @type [Pin::Method, nil] ref = pins.find { |p| p.is_a?(Pin::Method) && p.namespace == region.closure.full_context.namespace && p.name == cn } - unless ref.nil? - pins.delete ref - mm = Solargraph::Pin::Method.new( - location: ref.location, - closure: ref.closure, - name: ref.name, - parameters: ref.parameters, - comments: ref.comments, - scope: :class, - visibility: :public, - node: ref.node, + next if ref.nil? + pins.delete ref + mm = Solargraph::Pin::Method.new( + location: ref.location, + closure: ref.closure, + name: ref.name, + parameters: ref.parameters, + comments: ref.comments, + scope: :class, + visibility: :public, + node: ref.node, + source: :parser + ) + cm = Solargraph::Pin::Method.new( + location: ref.location, + closure: ref.closure, + name: ref.name, + parameters: ref.parameters, + comments: ref.comments, + scope: :instance, + visibility: :private, + node: ref.node, + source: :parser + ) + pins.push mm, cm + pins.select { |pin| pin.is_a?(Pin::InstanceVariable) && pin.closure.path == ref.path }.each do |ivar| + pins.delete ivar + pins.push Solargraph::Pin::InstanceVariable.new( + location: ivar.location, + closure: cm, + name: ivar.name, + comments: ivar.comments, + assignment: ivar.assignment, + source: :parser + ) + pins.push Solargraph::Pin::InstanceVariable.new( + location: ivar.location, + closure: mm, + name: ivar.name, + comments: ivar.comments, + assignment: ivar.assignment, source: :parser ) - cm = Solargraph::Pin::Method.new( - location: ref.location, - closure: ref.closure, - name: ref.name, - parameters: ref.parameters, - comments: ref.comments, - scope: :instance, - visibility: :private, - node: ref.node, - source: :parser) - pins.push mm, cm - pins.select{|pin| pin.is_a?(Pin::InstanceVariable) && pin.closure.path == ref.path}.each do |ivar| - pins.delete ivar - pins.push Solargraph::Pin::InstanceVariable.new( - location: ivar.location, - closure: cm, - name: ivar.name, - comments: ivar.comments, - assignment: ivar.assignment, - source: :parser - ) - pins.push Solargraph::Pin::InstanceVariable.new( - location: ivar.location, - closure: mm, - name: ivar.name, - comments: ivar.comments, - assignment: ivar.assignment, - source: :parser - ) - end end end elsif node.children[2].type == :def @@ -252,17 +254,19 @@ def process_module_function # @return [void] def process_private_constant - if node.children[2] && (node.children[2].type == :sym || node.children[2].type == :str) - cn = node.children[2].children[0].to_s - ref = pins.select{|p| [Solargraph::Pin::Namespace, Solargraph::Pin::Constant].include?(p.class) && p.namespace == region.closure.full_context.namespace && p.name == cn}.first - # HACK: Smelly instance variable access - ref.instance_variable_set(:@visibility, :private) unless ref.nil? - end + return unless node.children[2] && %i[sym str].include?(node.children[2].type) + cn = node.children[2].children[0].to_s + ref = pins.select do |p| + [Solargraph::Pin::Namespace, + Solargraph::Pin::Constant].include?(p.class) && p.namespace == region.closure.full_context.namespace && p.name == cn + end.first + # HACK: Smelly instance variable access + ref.instance_variable_set(:@visibility, :private) unless ref.nil? end # @return [void] def process_alias_method - loc = get_node_location(node) + get_node_location(node) pins.push Solargraph::Pin::MethodAlias.new( location: get_node_location(node), closure: region.closure, @@ -275,8 +279,10 @@ def process_alias_method # @return [Boolean] def process_private_class_method - if node.children[2].type == :sym || node.children[2].type == :str - ref = pins.select { |p| p.is_a?(Pin::Method) && p.namespace == region.closure.full_context.namespace && p.name == node.children[2].children[0].to_s }.first + if %i[sym str].include?(node.children[2].type) + ref = pins.select do |p| + p.is_a?(Pin::Method) && p.namespace == region.closure.full_context.namespace && p.name == node.children[2].children[0].to_s + end.first # HACK: Smelly instance variable access ref.instance_variable_set(:@visibility, :private) unless ref.nil? false diff --git a/lib/solargraph/parser/parser_gem/node_processors/until_node.rb b/lib/solargraph/parser/parser_gem/node_processors/until_node.rb index bcfae287d..2e091f41d 100644 --- a/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +++ b/lib/solargraph/parser/parser_gem/node_processors/until_node.rb @@ -18,7 +18,7 @@ def process closure: region.closure, node: node, comments: comments_for(node), - source: :parser, + source: :parser ) process_children region end diff --git a/lib/solargraph/parser/parser_gem/node_processors/while_node.rb b/lib/solargraph/parser/parser_gem/node_processors/while_node.rb index c9211448e..303942c81 100644 --- a/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +++ b/lib/solargraph/parser/parser_gem/node_processors/while_node.rb @@ -18,7 +18,7 @@ def process closure: region.closure, node: node, comments: comments_for(node), - source: :parser, + source: :parser ) process_children region end diff --git a/lib/solargraph/pin/base.rb b/lib/solargraph/pin/base.rb index 511c7deb7..1e0d9adbc 100644 --- a/lib/solargraph/pin/base.rb +++ b/lib/solargraph/pin/base.rb @@ -46,7 +46,8 @@ def presence_certain? # @param docstring [YARD::Docstring, nil] # @param directives [::Array, nil] # @param combine_priority [::Numeric, nil] See attr_reader for combine_priority - def initialize location: nil, type_location: nil, closure: nil, source: nil, name: '', comments: '', docstring: nil, directives: nil, combine_priority: nil + def initialize location: nil, type_location: nil, closure: nil, source: nil, name: '', comments: '', + docstring: nil, directives: nil, combine_priority: nil @location = location @type_location = type_location @closure = closure @@ -66,12 +67,16 @@ def initialize location: nil, type_location: nil, closure: nil, source: nil, nam def assert_location_provided return unless best_location.nil? && %i[yardoc source rbs].include?(source) - Solargraph.assert_or_log(:best_location, "Neither location nor type_location provided - #{path} #{source} #{self.class}") + Solargraph.assert_or_log(:best_location, + "Neither location nor type_location provided - #{path} #{source} #{self.class}") end # @return [Pin::Closure, nil] def closure - Solargraph.assert_or_log(:closure, "Closure not set on #{self.class} #{name.inspect} from #{source.inspect}") unless @closure + unless @closure + Solargraph.assert_or_log(:closure, + "Closure not set on #{self.class} #{name.inspect} from #{source.inspect}") + end # @type [Pin::Closure, nil] @closure end @@ -80,7 +85,7 @@ def closure # @param attrs [Hash{::Symbol => Object}] # # @return [self] - def combine_with(other, attrs={}) + def combine_with other, attrs = {} raise "tried to combine #{other.class} with #{self.class}" unless other.class == self.class priority_choice = choose_priority(other) return priority_choice unless priority_choice.nil? @@ -100,7 +105,9 @@ def combine_with(other, attrs={}) combine_priority: combine_priority }.merge(attrs) assert_same_macros(other) - logger.debug { "Base#combine_with(path=#{path}) - other.comments=#{other.comments.inspect}, self.comments = #{self.comments}" } + logger.debug do + "Base#combine_with(path=#{path}) - other.comments=#{other.comments.inspect}, self.comments = #{comments}" + end out = self.class.new(**new_attrs) out.reset_generated! out @@ -109,7 +116,7 @@ def combine_with(other, attrs={}) # @param other [self] # @return [self, nil] Returns either the pin chosen based on priority or nil # A nil return means that the combination process must proceed - def choose_priority(other) + def choose_priority other if combine_priority.nil? && !other.combine_priority.nil? return other elsif other.combine_priority.nil? && !combine_priority.nil? @@ -129,7 +136,7 @@ def choose_priority(other) # @param attr [::Symbol] # @sg-ignore # @return [undefined] - def choose_longer(other, attr) + def choose_longer other, attr # @type [undefined] val1 = send(attr) # @type [undefined] @@ -141,15 +148,15 @@ def choose_longer(other, attr) # @param other [self] # @return [::Array, nil] - def combine_directives(other) - return self.directives if other.directives.empty? + def combine_directives other + return directives if other.directives.empty? return other.directives if directives.empty? [directives + other.directives].uniq end # @param other [self] # @return [String] - def combine_name(other) + def combine_name other if needs_consistent_name? || other.needs_consistent_name? assert_same(other, :name) else @@ -184,7 +191,7 @@ def needs_consistent_name? # @param other [self] # @return [ComplexType] - def combine_return_type(other) + def combine_return_type other if return_type.undefined? other.return_type elsif other.return_type.undefined? @@ -195,7 +202,9 @@ def combine_return_type(other) return_type else all_items = return_type.items + other.return_type.items - if all_items.any? { |item| item.selfy? } && all_items.any? { |item| item.rooted_tag == context.reduce_class_type.rooted_tag } + if all_items.any? { |item| item.selfy? } && all_items.any? do |item| + item.rooted_tag == context.reduce_class_type.rooted_tag + end # assume this was a declaration that should have said 'self' all_items.delete_if { |item| item.rooted_tag == context.reduce_class_type.rooted_tag } end @@ -214,13 +223,13 @@ def dodgy_return_type_source? # @param attr [::Symbol] # # @return [Object, nil] - def choose(other, attr) + def choose other, attr results = [self, other].map(&attr).compact # true and false are different classes and can't be sorted - return true if results.any? { |r| r == true || r == false } + return true if results.any? { |r| [true, false].include?(r) } results.min - rescue - STDERR.puts("Problem handling #{attr} for \n#{self.inspect}\n and \n#{other.inspect}\n\n#{self.send(attr).inspect} vs #{other.send(attr).inspect}") + rescue StandardError + warn("Problem handling #{attr} for \n#{inspect}\n and \n#{other.inspect}\n\n#{send(attr).inspect} vs #{other.send(attr).inspect}") raise end @@ -228,7 +237,7 @@ def choose(other, attr) # @param attr [::Symbol] # @sg-ignore # @return [undefined] - def choose_node(other, attr) + def choose_node other, attr if other.object_id < attr.object_id other.send(attr) else @@ -240,9 +249,9 @@ def choose_node(other, attr) # @param attr [::Symbol] # @sg-ignore # @return [undefined] - def prefer_rbs_location(other, attr) + def prefer_rbs_location other, attr if rbs_location? && !other.rbs_location? - self.send(attr) + send(attr) elsif !rbs_location? && other.rbs_location? other.send(attr) else @@ -256,8 +265,8 @@ def rbs_location? # @param other [self] # @return [void] - def assert_same_macros(other) - return unless self.source == :yardoc && other.source == :yardoc + def assert_same_macros other + return unless source == :yardoc && other.source == :yardoc assert_same_count(other, :macros) assert_same_array_content(other, :macros) { |macro| macro.tag.name } end @@ -266,7 +275,7 @@ def assert_same_macros(other) # @param attr [::Symbol] # @return [void] # @todo strong typechecking should complain when there are no block-related tags - def assert_same_array_content(other, attr, &block) + def assert_same_array_content other, attr, &block arr1 = send(attr) raise "Expected #{attr} on #{self} to be an Enumerable, got #{arr1.class}" unless arr1.is_a?(::Enumerable) # @type arr1 [::Enumerable] @@ -280,7 +289,7 @@ def assert_same_array_content(other, attr, &block) values2 = arr2.map(&block) # @sg-ignore return arr1 if values1 == values2 - Solargraph.assert_or_log("combine_with_#{attr}".to_sym, + Solargraph.assert_or_log(:"combine_with_#{attr}", "Inconsistent #{attr.inspect} values between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self values = #{values1}\nother values =#{attr} = #{values2}") arr1 end @@ -289,15 +298,15 @@ def assert_same_array_content(other, attr, &block) # @param attr [::Symbol] # # @return [::Enumerable] - def assert_same_count(other, attr) + def assert_same_count other, attr # @type [::Enumerable] - arr1 = self.send(attr) + arr1 = send(attr) raise "Expected #{attr} on #{self} to be an Enumerable, got #{arr1.class}" unless arr1.is_a?(::Enumerable) # @type [::Enumerable] arr2 = other.send(attr) raise "Expected #{attr} on #{other} to be an Enumerable, got #{arr2.class}" unless arr2.is_a?(::Enumerable) return arr1 if arr1.count == arr2.count - Solargraph.assert_or_log("combine_with_#{attr}".to_sym, + Solargraph.assert_or_log(:"combine_with_#{attr}", "Inconsistent #{attr.inspect} count value between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self.#{attr} = #{arr1.inspect}\nother.#{attr} = #{arr2.inspect}") arr1 end @@ -307,12 +316,12 @@ def assert_same_count(other, attr) # # @sg-ignore # @return [undefined] - def assert_same(other, attr) + def assert_same other, attr return false if other.nil? val1 = send(attr) val2 = other.send(attr) return val1 if val1 == val2 - Solargraph.assert_or_log("combine_with_#{attr}".to_sym, + Solargraph.assert_or_log(:"combine_with_#{attr}", "Inconsistent #{attr.inspect} values between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self.#{attr} = #{val1.inspect}\nother.#{attr} = #{val2.inspect}") val1 end @@ -321,15 +330,17 @@ def assert_same(other, attr) # @param attr [::Symbol] # @sg-ignore # @return [undefined] - def choose_pin_attr_with_same_name(other, attr) + def choose_pin_attr_with_same_name other, attr # @type [Pin::Base, nil] val1 = send(attr) # @type [Pin::Base, nil] val2 = other.send(attr) - raise "Expected pin for #{attr} on\n#{self.inspect},\ngot #{val1.inspect}" unless val1.nil? || val1.is_a?(Pin::Base) - raise "Expected pin for #{attr} on\n#{other.inspect},\ngot #{val2.inspect}" unless val2.nil? || val2.is_a?(Pin::Base) + raise "Expected pin for #{attr} on\n#{inspect},\ngot #{val1.inspect}" unless val1.nil? || val1.is_a?(Pin::Base) + unless val2.nil? || val2.is_a?(Pin::Base) + raise "Expected pin for #{attr} on\n#{other.inspect},\ngot #{val2.inspect}" + end if val1&.name != val2&.name - Solargraph.assert_or_log("combine_with_#{attr}_name".to_sym, + Solargraph.assert_or_log(:"combine_with_#{attr}_name", "Inconsistent #{attr.inspect} name values between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self.#{attr} = #{val1.inspect}\nother.#{attr} = #{val2.inspect}") end choose_pin_attr(other, attr) @@ -340,14 +351,14 @@ def choose_pin_attr_with_same_name(other, attr) # # @sg-ignore Missing @return tag for Solargraph::Pin::Base#choose_pin_attr # @return [undefined] - def choose_pin_attr(other, attr) + def choose_pin_attr other, attr # @type [Pin::Base, nil] val1 = send(attr) # @type [Pin::Base, nil] val2 = other.send(attr) if val1.class != val2.class # :nocov: - Solargraph.assert_or_log("combine_with_#{attr}_class".to_sym, + Solargraph.assert_or_log(:"combine_with_#{attr}_class", "Inconsistent #{attr.inspect} class values between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self.#{attr} = #{val1.inspect}\nother.#{attr} = #{val2.inspect}") return val1 # :nocov: @@ -379,7 +390,7 @@ def comments # @param context [ComplexType] # @param resolved_generic_values [Hash{String => ComplexType}] # @return [self] - def resolve_generics_from_context(generics_to_resolve, return_type_context = nil, resolved_generic_values: {}) + def resolve_generics_from_context generics_to_resolve, return_type_context = nil, resolved_generic_values: {} proxy return_type.resolve_generics_from_context(generics_to_resolve, return_type_context, resolved_generic_values: resolved_generic_values) @@ -388,7 +399,7 @@ def resolve_generics_from_context(generics_to_resolve, return_type_context = nil # @yieldparam [ComplexType] # @yieldreturn [ComplexType] # @return [self] - def transform_types(&transform) + def transform_types &transform proxy return_type.transform(&transform) end @@ -409,7 +420,7 @@ def all_rooted? # @param generics_to_erase [::Array] # @return [self] - def erase_generics(generics_to_erase) + def erase_generics generics_to_erase return self if generics_to_erase.empty? transform_types { |t| t.erase_generics(generics_to_erase) } end @@ -455,7 +466,8 @@ def nearly? other name == other.name && (closure == other.closure || (closure && closure.nearly?(other.closure))) && (comments == other.comments || - (((maybe_directives? == false && other.maybe_directives? == false) || compare_directives(directives, other.directives)) && + (((maybe_directives? == false && other.maybe_directives? == false) || compare_directives(directives, + other.directives)) && compare_docstring_tags(docstring, other.docstring)) ) end @@ -535,7 +547,7 @@ def probe api_map # @param api_map [ApiMap] # @return [ComplexType] def infer api_map - Solargraph::Logging.logger.warn "WARNING: Pin #infer methods are deprecated. Use #typify or #probe instead." + Solargraph::Logging.logger.warn 'WARNING: Pin #infer methods are deprecated. Use #typify or #probe instead.' type = typify(api_map) return type unless type.undefined? probe api_map @@ -628,7 +640,7 @@ def desc # @return [String] def inspect - "#<#{self.class} `#{self.inner_desc}`#{all_location_text} via #{source.inspect}>" + "#<#{self.class} `#{inner_desc}`#{all_location_text} via #{source.inspect}>" end # @return [String] @@ -645,8 +657,7 @@ def all_location_text end # @return [void] - def reset_generated! - end + def reset_generated!; end protected @@ -659,9 +670,7 @@ def reset_generated! # @return [ComplexType] attr_writer :return_type - attr_writer :docstring - - attr_writer :directives + attr_writer :docstring, :directives private @@ -720,7 +729,7 @@ def compare_tags tag1, tag2 def collect_macros return [] unless maybe_directives? parse = Solargraph::Source.parse_docstring(comments) - parse.directives.select{ |d| d.tag.tag_name == 'macro' } + parse.directives.select { |d| d.tag.tag_name == 'macro' } end end end diff --git a/lib/solargraph/pin/base_variable.rb b/lib/solargraph/pin/base_variable.rb index 764c1fb39..9feabfc3e 100644 --- a/lib/solargraph/pin/base_variable.rb +++ b/lib/solargraph/pin/base_variable.rb @@ -13,6 +13,7 @@ class BaseVariable < Base # @param return_type [ComplexType, nil] # @param assignment [Parser::AST::Node, nil] + # @param [Hash{Symbol => Object}] splat def initialize assignment: nil, return_type: nil, **splat super(**splat) @assignment = assignment @@ -21,12 +22,12 @@ def initialize assignment: nil, return_type: nil, **splat @return_type = return_type end - def combine_with(other, attrs={}) + def combine_with other, attrs = {} attrs.merge({ - assignment: assert_same(other, :assignment), - mass_assignment: assert_same(other, :mass_assignment), - return_type: combine_return_type(other), - }) + assignment: assert_same(other, :assignment), + mass_assignment: assert_same(other, :mass_assignment), + return_type: combine_return_type(other) + }) super(other, attrs) end @@ -56,7 +57,7 @@ def variable? # @param parent_node [Parser::AST::Node] # @param api_map [ApiMap] # @return [::Array] - def return_types_from_node(parent_node, api_map) + def return_types_from_node parent_node, api_map types = [] value_position_nodes_only(parent_node).each do |node| # Nil nodes may not have a location diff --git a/lib/solargraph/pin/block.rb b/lib/solargraph/pin/block.rb index 227bc0873..5cf4f189c 100644 --- a/lib/solargraph/pin/block.rb +++ b/lib/solargraph/pin/block.rb @@ -15,6 +15,7 @@ class Block < Callable # @param node [Parser::AST::Node, nil] # @param context [ComplexType, nil] # @param args [::Array] + # @param [Hash{Symbol => Object}] splat def initialize receiver: nil, args: [], context: nil, node: nil, **splat super(**splat, parameters: args) @receiver = receiver @@ -37,7 +38,7 @@ def binder # @param parameters [::Array] # # @return [::Array] - def destructure_yield_types(yield_types, parameters) + def destructure_yield_types yield_types, parameters # yielding a tuple into a block will destructure the tuple if yield_types.length == 1 yield_type = yield_types.first @@ -48,7 +49,7 @@ def destructure_yield_types(yield_types, parameters) # @param api_map [ApiMap] # @return [::Array] - def typify_parameters(api_map) + def typify_parameters api_map chain = Parser.chain(receiver, filename, node) clip = api_map.clip_at(location.filename, location.range.start) locals = clip.locals - [self] diff --git a/lib/solargraph/pin/callable.rb b/lib/solargraph/pin/callable.rb index 207c2619b..6c3166ce3 100644 --- a/lib/solargraph/pin/callable.rb +++ b/lib/solargraph/pin/callable.rb @@ -14,6 +14,7 @@ class Callable < Closure # @param block [Signature, nil] # @param return_type [ComplexType, nil] # @param parameters [::Array] + # @param [Hash{Symbol => Object}] splat def initialize block: nil, return_type: nil, parameters: [], **splat super(**splat) @block = block @@ -29,7 +30,7 @@ def method_namespace # @param other [self] # # @return [Pin::Signature, nil] - def combine_blocks(other) + def combine_blocks other if block.nil? other.block elsif other.block.nil? @@ -44,10 +45,10 @@ def combine_blocks(other) # @param attrs [Hash{Symbol => Object}] # # @return [self] - def combine_with(other, attrs={}) + def combine_with other, attrs = {} new_attrs = { block: combine_blocks(other), - return_type: combine_return_type(other), + return_type: combine_return_type(other) }.merge(attrs) new_attrs[:parameters] = choose_parameters(other).clone.freeze unless new_attrs.key?(:parameters) super(other, new_attrs) @@ -65,8 +66,10 @@ def generics # @param other [self] # # @return [Array] - def choose_parameters(other) - raise "Trying to combine two pins with different arities - \nself =#{inspect}, \nother=#{other.inspect}, \n\n self.arity=#{self.arity}, \nother.arity=#{other.arity}" if other.arity != arity + def choose_parameters other + if other.arity != arity + raise "Trying to combine two pins with different arities - \nself =#{inspect}, \nother=#{other.inspect}, \n\n self.arity=#{arity}, \nother.arity=#{other.arity}" + end parameters.zip(other.parameters).map do |param, other_param| if param.nil? && other_param.block? other_param @@ -100,12 +103,12 @@ def arity # @param context [ComplexType, nil] # @param resolved_generic_values [Hash{String => ComplexType}] # @return [self] - def resolve_generics_from_context(generics_to_resolve, + def resolve_generics_from_context generics_to_resolve, arg_types = nil, return_type_context = nil, yield_arg_types = nil, yield_return_type_context = nil, - resolved_generic_values: {}) + resolved_generic_values: {} callable = super(generics_to_resolve, return_type_context, resolved_generic_values: resolved_generic_values) callable.parameters = callable.parameters.each_with_index.map do |param, i| if arg_types.nil? @@ -116,10 +119,12 @@ def resolve_generics_from_context(generics_to_resolve, resolved_generic_values: resolved_generic_values) end end - callable.block = block.resolve_generics_from_context(generics_to_resolve, - yield_arg_types, - yield_return_type_context, - resolved_generic_values: resolved_generic_values) if callable.block? + if callable.block? + callable.block = block.resolve_generics_from_context(generics_to_resolve, + yield_arg_types, + yield_return_type_context, + resolved_generic_values: resolved_generic_values) + end callable end @@ -137,7 +142,7 @@ def typify api_map # @return [String] def method_name - raise "closure was nil in #{self.inspect}" if closure.nil? + raise "closure was nil in #{inspect}" if closure.nil? @method_name ||= closure.name end @@ -149,12 +154,12 @@ def method_name # @param context [ComplexType, nil] # @param resolved_generic_values [Hash{String => ComplexType}] # @return [self] - def resolve_generics_from_context_until_complete(generics_to_resolve, + def resolve_generics_from_context_until_complete generics_to_resolve, arg_types = nil, return_type_context = nil, yield_arg_types = nil, yield_return_type_context = nil, - resolved_generic_values: {}) + resolved_generic_values: {} # See # https://github.com/soutaro/steep/tree/master/lib/steep/type_inference # and @@ -172,7 +177,7 @@ def resolve_generics_from_context_until_complete(generics_to_resolve, resolved_generic_values: resolved_generic_values) if last_resolved_generic_values == resolved_generic_values # erase anything unresolved - return new_pin.erase_generics(self.generics) + return new_pin.erase_generics(generics) end new_pin.resolve_generics_from_context_until_complete(generics_to_resolve, arg_types, @@ -186,7 +191,7 @@ def resolve_generics_from_context_until_complete(generics_to_resolve, # @yieldparam [ComplexType] # @yieldreturn [ComplexType] # @return [self] - def transform_types(&transform) + def transform_types &transform # @todo 'super' alone should work here I think, but doesn't typecheck at level typed callable = super(&transform) callable.block = block.transform_types(&transform) if block? @@ -214,7 +219,9 @@ def mandatory_positional_param_count end def to_rbs - rbs_generics + '(' + parameters.map { |param| param.to_rbs }.join(', ') + ') ' + (block.nil? ? '' : '{ ' + block.to_rbs + ' } ') + '-> ' + return_type.to_rbs + rbs_generics + '(' + parameters.map { |param| + param.to_rbs + }.join(', ') + ') ' + (block.nil? ? '' : '{ ' + block.to_rbs + ' } ') + '-> ' + return_type.to_rbs end def block? diff --git a/lib/solargraph/pin/closure.rb b/lib/solargraph/pin/closure.rb index a7b37e01b..3960c52a2 100644 --- a/lib/solargraph/pin/closure.rb +++ b/lib/solargraph/pin/closure.rb @@ -9,7 +9,8 @@ class Closure < Base # @param scope [::Symbol] :class or :instance # @param generics [::Array, nil] # @param generic_defaults [Hash{String => ComplexType}] - def initialize scope: :class, generics: nil, generic_defaults: {}, **splat + # @param [Hash{Symbol => Object}] splat + def initialize scope: :class, generics: nil, generic_defaults: {}, **splat super(**splat) @scope = scope @generics = generics @@ -25,10 +26,10 @@ def generic_defaults # @param attrs [Hash{Symbol => Object}] # # @return [self] - def combine_with(other, attrs={}) + def combine_with other, attrs = {} new_attrs = { scope: assert_same(other, :scope), - generics: generics.empty? ? other.generics : generics, + generics: generics.empty? ? other.generics : generics }.merge(attrs) super(other, new_attrs) end diff --git a/lib/solargraph/pin/common.rb b/lib/solargraph/pin/common.rb index 062099ee4..92f0e003e 100644 --- a/lib/solargraph/pin/common.rb +++ b/lib/solargraph/pin/common.rb @@ -14,7 +14,10 @@ module Common # @sg-ignore Solargraph::Pin::Common#closure return type could not be inferred # @return [Pin::Closure, nil] def closure - Solargraph.assert_or_log(:closure, "Closure not set on #{self.class} #{name.inspect} from #{source.inspect}") unless @closure + unless @closure + Solargraph.assert_or_log(:closure, + "Closure not set on #{self.class} #{name.inspect} from #{source.inspect}") + end @closure end diff --git a/lib/solargraph/pin/constant.rb b/lib/solargraph/pin/constant.rb index 94a968e7e..8da79f682 100644 --- a/lib/solargraph/pin/constant.rb +++ b/lib/solargraph/pin/constant.rb @@ -34,11 +34,9 @@ def path # @return [ComplexType] def generate_complex_type tags = docstring.tags(:return).map(&:types).flatten.reject(&:nil?) - if tags.empty? - tags = docstring.tags(:type).map(&:types).flatten.reject(&:nil?) - end + tags = docstring.tags(:type).map(&:types).flatten.reject(&:nil?) if tags.empty? return ComplexType::UNDEFINED if tags.empty? - ComplexType.try_parse *tags + ComplexType.try_parse(*tags) end end end diff --git a/lib/solargraph/pin/conversions.rb b/lib/solargraph/pin/conversions.rb index e40cc8990..e50a27b8d 100644 --- a/lib/solargraph/pin/conversions.rb +++ b/lib/solargraph/pin/conversions.rb @@ -72,7 +72,13 @@ def detail # This property is not cached in an instance variable because it can # change when pins get proxied. detail = String.new - detail += "=#{probed? ? '~' : (proxied? ? '^' : '>')} #{return_type.to_s}" unless return_type.undefined? + unless return_type.undefined? + detail += "=#{if probed? + '~' + else + (proxied? ? '^' : '>') + end} #{return_type}" + end detail.strip! return nil if detail.empty? detail @@ -116,7 +122,7 @@ def generate_link # @return [String] def escape_brackets text # text.gsub(/(\<|\>)/, "\\#{$1}") - text.gsub("<", '\<').gsub(">", '\>') + text.gsub('<', '\<').gsub('>', '\>') end end end diff --git a/lib/solargraph/pin/delegated_method.rb b/lib/solargraph/pin/delegated_method.rb index 9483fb058..db3b38cfd 100644 --- a/lib/solargraph/pin/delegated_method.rb +++ b/lib/solargraph/pin/delegated_method.rb @@ -15,6 +15,7 @@ class DelegatedMethod < Pin::Method # @param receiver [Source::Chain, nil] the source code used to resolve the receiver for this delegated method. # @param name [String] # @param receiver_method_name [String] the method name that will be called on the receiver (defaults to :name). + # @param [Hash{Symbol => Object}] splat def initialize(method: nil, receiver: nil, name: method&.name, receiver_method_name: name, **splat) raise ArgumentError, 'either :method or :receiver is required' if (method && receiver) || (!method && !receiver) super(name: name, **splat) @@ -34,7 +35,6 @@ def location @resolved_method&.send(:location) end - def type_location return super if super @@ -59,7 +59,7 @@ def type_location end # @param api_map [ApiMap] - def resolvable?(api_map) + def resolvable? api_map resolve_method(api_map) !!@resolved_method end @@ -102,7 +102,7 @@ def resolve_method api_map # # @param chain [Source::Chain] # @return [String] - def print_chain(chain) + def print_chain chain out = +'' chain.links.each_with_index do |link, index| if index > 0 diff --git a/lib/solargraph/pin/documenting.rb b/lib/solargraph/pin/documenting.rb index bd8b1fe9a..e44c78d9c 100644 --- a/lib/solargraph/pin/documenting.rb +++ b/lib/solargraph/pin/documenting.rb @@ -62,7 +62,7 @@ def to_s # @return [String] def to_code - "\n```ruby\n#{Documenting.normalize_indentation(@plaintext)}#{@plaintext.end_with?("\n") ? '' : "\n"}```\n\n" + "\n```ruby\n#{Documenting.normalize_indentation(@plaintext)}#{"\n" unless @plaintext.end_with?("\n")}```\n\n" end # @return [String] @@ -78,7 +78,8 @@ def documentation # line and at least two spaces of indentation. This is a common # convention in Ruby core documentation, e.g., String#split. sections = [DocSection.new(false)] - Documenting.normalize_indentation(Documenting.strip_html_comments(docstring.to_s.gsub("\t", ' '))).lines.each do |l| + Documenting.normalize_indentation(Documenting.strip_html_comments(docstring.to_s.gsub("\t", + ' '))).lines.each do |l| if l.start_with?(' ') # Code block sections.push DocSection.new(true) unless sections.last.code? diff --git a/lib/solargraph/pin/keyword.rb b/lib/solargraph/pin/keyword.rb index 089d0a417..46a9f1fb3 100644 --- a/lib/solargraph/pin/keyword.rb +++ b/lib/solargraph/pin/keyword.rb @@ -12,9 +12,7 @@ def closure @closure ||= Pin::ROOT_PIN end - def name - @name - end + attr_reader :name end end end diff --git a/lib/solargraph/pin/local_variable.rb b/lib/solargraph/pin/local_variable.rb index 9eae6cc6f..f5d1c6cdb 100644 --- a/lib/solargraph/pin/local_variable.rb +++ b/lib/solargraph/pin/local_variable.rb @@ -21,10 +21,10 @@ def initialize assignment: nil, presence: nil, presence_certain: false, **splat @presence_certain = presence_certain end - def combine_with(other, attrs={}) + def combine_with other, attrs = {} new_attrs = { assignment: assert_same(other, :assignment), - presence_certain: assert_same(other, :presence_certain?), + presence_certain: assert_same(other, :presence_certain?) }.merge(attrs) # @sg-ignore Wrong argument type for # Solargraph::Pin::Base#assert_same: other expected @@ -36,7 +36,7 @@ def combine_with(other, attrs={}) # @param other_closure [Pin::Closure] # @param other_loc [Location] - def visible_at?(other_closure, other_loc) + def visible_at? other_closure, other_loc location.filename == other_loc.filename && presence.include?(other_loc.range.start) && match_named_closure(other_closure, closure) diff --git a/lib/solargraph/pin/method.rb b/lib/solargraph/pin/method.rb index 011f096f6..7d7adb4b3 100644 --- a/lib/solargraph/pin/method.rb +++ b/lib/solargraph/pin/method.rb @@ -22,6 +22,7 @@ class Method < Callable # @param attribute [Boolean] # @param signatures [::Array, nil] # @param anon_splat [Boolean] + # @param [Hash{Symbol => Object}] splat def initialize visibility: :public, explicit: true, block: :undefined, node: nil, attribute: false, signatures: nil, anon_splat: false, **splat super(**splat) @@ -52,7 +53,7 @@ def combine_all_signature_pins(*signature_pins) # @param other [Pin::Method] # @return [::Symbol] - def combine_visibility(other) + def combine_visibility other if dodgy_visibility_source? && !other.dodgy_visibility_source? other.visibility elsif other.dodgy_visibility_source? && !dodgy_visibility_source? @@ -64,7 +65,7 @@ def combine_visibility(other) # @param other [Pin::Method] # @return [Array] - def combine_signatures(other) + def combine_signatures other all_undefined = signatures.all? { |sig| sig.return_type.undefined? } other_all_undefined = other.signatures.all? { |sig| sig.return_type.undefined? } if all_undefined && !other_all_undefined @@ -76,16 +77,16 @@ def combine_signatures(other) end end - def combine_with(other, attrs = {}) + def combine_with other, attrs = {} priority_choice = choose_priority(other) return priority_choice unless priority_choice.nil? sigs = combine_signatures(other) parameters = if sigs.length > 0 - [].freeze - else - choose(other, :parameters).clone.freeze - end + [].freeze + else + choose(other, :parameters).clone.freeze + end new_attrs = { visibility: combine_visibility(other), explicit: explicit? || other.explicit?, @@ -105,7 +106,7 @@ def == other super && other.node == node end - def transform_types(&transform) + def transform_types &transform # @todo 'super' alone should work here I think, but doesn't typecheck at level typed m = super(&transform) m.signatures = m.signatures.map do |sig| @@ -120,14 +121,12 @@ def transform_types(&transform) def reset_generated! super unless signatures.empty? - return_type = nil @block = :undefined - parameters = [] + [] end block&.reset_generated! @signatures&.each(&:reset_generated!) - signature_help = nil - documentation = nil + nil end def all_rooted? @@ -136,7 +135,7 @@ def all_rooted? # @param signature [Pin::Signature] # @return [Pin::Method] - def with_single_signature(signature) + def with_single_signature signature m = proxy signature.return_type m.reset_generated! # @todo populating the single parameters/return_type/block @@ -176,7 +175,7 @@ def return_type # @param parameters [::Array] # @param return_type [ComplexType] # @return [Signature] - def generate_signature(parameters, return_type) + def generate_signature parameters, return_type block = nil yieldparam_tags = docstring.tags(:yieldparam) yieldreturn_tags = docstring.tags(:yieldreturn) @@ -218,7 +217,11 @@ def signatures top_type = generate_complex_type result = [] result.push generate_signature(parameters, top_type) if top_type.defined? - result.concat(overloads.map { |meth| generate_signature(meth.parameters, meth.return_type) }) unless overloads.empty? + unless overloads.empty? + result.concat(overloads.map do |meth| + generate_signature(meth.parameters, meth.return_type) + end) + end result.push generate_signature(parameters, @return_type || ComplexType::UNDEFINED) if result.empty? result end @@ -238,11 +241,17 @@ def detail # change when pins get proxied. detail = String.new detail += if signatures.length > 1 - "(*) " - else - "(#{signatures.first.parameters.map(&:full).join(', ')}) " unless signatures.first.parameters.empty? - end.to_s - detail += "=#{probed? ? '~' : (proxied? ? '^' : '>')} #{return_type.to_s}" unless return_type.undefined? + '(*) ' + else + "(#{signatures.first.parameters.map(&:full).join(', ')}) " unless signatures.first.parameters.empty? + end.to_s + unless return_type.undefined? + detail += "=#{if probed? + '~' + else + (proxied? ? '^' : '>') + end} #{return_type}" + end detail.strip! return nil if detail.empty? detail @@ -280,7 +289,7 @@ def to_rbs end def path - @path ||= "#{namespace}#{(scope == :instance ? '#' : '.')}#{name}" + @path ||= "#{namespace}#{scope == :instance ? '#' : '.'}#{name}" end # @return [String] @@ -289,10 +298,14 @@ def method_name end def typify api_map - logger.debug { "Method#typify(self=#{self}, binder=#{binder}, closure=#{closure}, context=#{context.rooted_tags}, return_type=#{return_type.rooted_tags}) - starting" } + logger.debug do + "Method#typify(self=#{self}, binder=#{binder}, closure=#{closure}, context=#{context.rooted_tags}, return_type=#{return_type.rooted_tags}) - starting" + end decl = super unless decl.undefined? - logger.debug { "Method#typify(self=#{self}, binder=#{binder}, closure=#{closure}, context=#{context}) => #{decl.rooted_tags.inspect} - decl found" } + logger.debug do + "Method#typify(self=#{self}, binder=#{binder}, closure=#{closure}, context=#{context}) => #{decl.rooted_tags.inspect} - decl found" + end return decl end type = see_reference(api_map) || typify_from_super(api_map) @@ -340,7 +353,7 @@ def documentation method_docs += "Block Returns:\n" lines = [] yieldreturn_tags.each do |r| - l = "*" + l = '*' l += " [#{escape_brackets(r.types.join(', '))}]" unless r.types.nil? or r.types.empty? l += " #{r.text}" lines.push l @@ -353,7 +366,7 @@ def documentation method_docs += "Returns:\n" lines = [] return_tags.each do |r| - l = "*" + l = '*' l += " [#{escape_brackets(r.types.join(', '))}]" unless r.types.nil? or r.types.empty? l += " #{r.text}" lines.push l @@ -410,7 +423,7 @@ def overloads end, closure: self, return_type: ComplexType.try_parse(*tag.docstring.tags(:return).flat_map(&:types)), - source: :overloads, + source: :overloads ) end @overloads @@ -429,13 +442,13 @@ def resolve_ref_tag api_map return self unless docstring.ref_tags.any? docstring.ref_tags.each do |tag| ref = if tag.owner.to_s.start_with?(/[#.]/) - api_map.get_methods(namespace) - .select { |pin| pin.path.end_with?(tag.owner.to_s) } - .first - else - # @todo Resolve relative namespaces - api_map.get_path_pins(tag.owner.to_s).first - end + api_map.get_methods(namespace) + .select { |pin| pin.path.end_with?(tag.owner.to_s) } + .first + else + # @todo Resolve relative namespaces + api_map.get_path_pins(tag.owner.to_s).first + end next unless ref docstring.add_tag(*ref.docstring.tags(:param)) @@ -451,25 +464,21 @@ def rest_of_stack api_map protected - attr_writer :block - - attr_writer :signature_help - - attr_writer :documentation + attr_writer :block, :signature_help, :documentation, :return_type def dodgy_visibility_source? # as of 2025-03-12, the RBS generator used for # e.g. activesupport did not understand 'private' markings # inside 'class << self' blocks, but YARD did OK at it - source == :rbs && scope == :class && type_location&.filename&.include?('generated') && return_type.undefined? || + (source == :rbs && scope == :class && type_location&.filename&.include?('generated') && return_type.undefined?) || # YARD's RBS generator seems to miss a lot of should-be protected instance methods - source == :rbs && scope == :instance && namespace.start_with?('YARD::') || + (source == :rbs && scope == :instance && namespace.start_with?('YARD::')) || # private on attr_readers seems to be broken in Prism's auto-generator script - source == :rbs && scope == :instance && namespace.start_with?('Prism::') || + (source == :rbs && scope == :instance && namespace.start_with?('Prism::')) || # The RBS for the RBS gem itself seems to use private as a # 'is this a public API' concept, more aggressively than the # actual code. Let's respect that and ignore the actual .rb file. - source == :yardoc && scope == :instance && namespace.start_with?('RBS::') + (source == :yardoc && scope == :instance && namespace.start_with?('RBS::')) end private @@ -506,7 +515,7 @@ def clean_param name # @param name [String] # # @return [ComplexType] - def param_type_from_name(tag, name) + def param_type_from_name tag, name param = tag.tags(:param).select { |t| t.name == name }.first return ComplexType::UNDEFINED unless param ComplexType.try_parse(*param.types) @@ -516,7 +525,7 @@ def param_type_from_name(tag, name) def generate_complex_type tags = docstring.tags(:return).map(&:types).flatten.compact return ComplexType::UNDEFINED if tags.empty? - ComplexType.try_parse *tags + ComplexType.try_parse(*tags) end # @param api_map [ApiMap] @@ -573,7 +582,7 @@ def method_body_node return nil if node.nil? return node.children[1].children.last if node.type == :DEFN return node.children[2].children.last if node.type == :DEFS - return node.children[2] if node.type == :def || node.type == :DEFS + return node.children[2] if %i[def DEFS].include?(node.type) return node.children[3] if node.type == :defs nil end @@ -586,7 +595,7 @@ def infer_from_return_nodes api_map has_nil = false return ComplexType::NIL if method_body_node.nil? returns_from_method_body(method_body_node).each do |n| - if n.nil? || [:NIL, :nil].include?(n.type) + if n.nil? || %i[NIL nil].include?(n.type) has_nil = true next end @@ -624,7 +633,7 @@ def infer_from_iv api_map # # @param name [String] # @return [::Array(String, ::Symbol)] - def parse_overload_param(name) + def parse_overload_param name # @todo this needs to handle mandatory vs not args, kwargs, blocks, etc if name.start_with?('**') [name[2..-1], :kwrestarg] @@ -647,10 +656,6 @@ def concat_example_tags .join("\n") .concat("```\n") end - - protected - - attr_writer :return_type end end end diff --git a/lib/solargraph/pin/namespace.rb b/lib/solargraph/pin/namespace.rb index 95bd1089a..a28a721ce 100644 --- a/lib/solargraph/pin/namespace.rb +++ b/lib/solargraph/pin/namespace.rb @@ -20,6 +20,7 @@ class Namespace < Closure # @param visibility [::Symbol] :public or :private # @param gates [::Array] # @param name [String] + # @param [Hash{Symbol => Object}] splat def initialize type: :class, visibility: :public, gates: [''], name: '', **splat # super(location, namespace, name, comments) super(**splat, name: name) @@ -37,10 +38,10 @@ def initialize type: :class, visibility: :public, gates: [''], name: '', **splat parts = name.split('::') name = parts.pop closure_name = if [Solargraph::Pin::ROOT_PIN, nil].include?(closure) - '' - else - closure.full_context.namespace + '::' - end + '' + else + closure.full_context.namespace + '::' + end closure_name += parts.join('::') @closure = Pin::Namespace.new(name: closure_name, gates: [parts.join('::')], source: :namespace) @context = nil @@ -49,7 +50,7 @@ def initialize type: :class, visibility: :public, gates: [''], name: '', **splat end def to_rbs - "#{@type.to_s} #{return_type.all_params.first.to_rbs}#{rbs_generics}".strip + "#{@type} #{return_type.all_params.first.to_rbs}#{rbs_generics}".strip end def inner_desc @@ -91,7 +92,7 @@ def path end def return_type - @return_type ||= ComplexType.try_parse( (type == :class ? '::Class' : '::Module') + "<::#{path}>") + @return_type ||= ComplexType.try_parse((type == :class ? '::Class' : '::Module') + "<::#{path}>") end # @return [Array] @@ -105,10 +106,10 @@ def typify api_map def gates @gates ||= if path.empty? - @open_gates - else - [path] + @open_gates - end + @open_gates + else + [path] + @open_gates + end end end end diff --git a/lib/solargraph/pin/parameter.rb b/lib/solargraph/pin/parameter.rb index 947513689..d3af9a1a8 100644 --- a/lib/solargraph/pin/parameter.rb +++ b/lib/solargraph/pin/parameter.rb @@ -15,6 +15,7 @@ class Parameter < LocalVariable # @param decl [::Symbol] :arg, :optarg, :kwarg, :kwoptarg, :restarg, :kwrestarg, :block, :blockarg # @param asgn_code [String, nil] + # @param [Hash{Symbol => Object}] splat def initialize decl: :arg, asgn_code: nil, **splat super(**splat) @asgn_code = asgn_code @@ -29,21 +30,21 @@ def location super || closure&.type_location end - def combine_with(other, attrs={}) + def combine_with other, attrs = {} new_attrs = { decl: assert_same(other, :decl), presence: choose(other, :presence), - asgn_code: choose(other, :asgn_code), + asgn_code: choose(other, :asgn_code) }.merge(attrs) super(other, new_attrs) end def keyword? - [:kwarg, :kwoptarg].include?(decl) + %i[kwarg kwoptarg].include?(decl) end def kwrestarg? - decl == :kwrestarg || (assignment && [:HASH, :hash].include?(assignment.type)) + decl == :kwrestarg || (assignment && %i[HASH hash].include?(assignment.type)) end def needs_consistent_name? @@ -52,21 +53,21 @@ def needs_consistent_name? # @return [String] def arity_decl - name = (self.name || '(anon)') - type = (return_type&.to_rbs || 'untyped') + name = self.name || '(anon)' + return_type&.to_rbs || 'untyped' case decl when :arg - "" + '' when :optarg - "?" + '?' when :kwarg "#{name}:" when :kwoptarg "?#{name}:" when :restarg - "*" + '*' when :kwrestarg - "**" + '**' else "(unknown decl: #{decl})" end @@ -81,11 +82,11 @@ def restarg? end def rest? - decl == :restarg || decl == :kwrestarg + %i[restarg kwrestarg].include?(decl) end def block? - [:block, :blockarg].include?(decl) + %i[block blockarg].include?(decl) end def to_rbs @@ -172,7 +173,7 @@ def typify api_map # @param atype [ComplexType] # @param api_map [ApiMap] - def compatible_arg?(atype, api_map) + def compatible_arg? atype, api_map # make sure we get types from up the method # inheritance chain if we don't have them on this pin ptype = typify api_map @@ -200,9 +201,7 @@ def param_tag # @return [ComplexType] def typify_block_param api_map block_pin = closure - if block_pin.is_a?(Pin::Block) && block_pin.receiver - return block_pin.typify_parameters(api_map)[index] - end + return block_pin.typify_parameters(api_map)[index] if block_pin.is_a?(Pin::Block) && block_pin.receiver ComplexType::UNDEFINED end @@ -219,10 +218,13 @@ def typify_method_param api_map found = p break end - if found.nil? and !index.nil? - found = params[index] if params[index] && (params[index].name.nil? || params[index].name.empty?) + if found.nil? and !index.nil? && params[index] && (params[index].name.nil? || params[index].name.empty?) + found = params[index] + end + unless found.nil? || found.types.nil? + return ComplexType.try_parse(*found.types).qualify(api_map, + *meth.closure.gates) end - return ComplexType.try_parse(*found.types).qualify(api_map, *meth.closure.gates) unless found.nil? || found.types.nil? end ComplexType::UNDEFINED end diff --git a/lib/solargraph/pin/proxy_type.rb b/lib/solargraph/pin/proxy_type.rb index 2323489a7..8dcfbd353 100644 --- a/lib/solargraph/pin/proxy_type.rb +++ b/lib/solargraph/pin/proxy_type.rb @@ -5,6 +5,7 @@ module Pin class ProxyType < Base # @param return_type [ComplexType] # @param binder [ComplexType, ComplexType::UniqueType, nil] + # @param [Hash{Symbol => Object}] splat def initialize return_type: ComplexType::UNDEFINED, binder: nil, **splat super(**splat) @return_type = return_type @@ -19,6 +20,7 @@ def context # @param closure [Pin::Namespace, nil] Used as the closure for this pin # @param binder [ComplexType, ComplexType::UniqueType, nil] # @return [ProxyType] + # @param [Hash{Symbol => Object}] kwargs def self.anonymous context, closure: nil, binder: nil, **kwargs unless closure parts = context.namespace.split('::') diff --git a/lib/solargraph/pin/reference.rb b/lib/solargraph/pin/reference.rb index d678ab7b7..b429d4631 100644 --- a/lib/solargraph/pin/reference.rb +++ b/lib/solargraph/pin/reference.rb @@ -13,6 +13,7 @@ class Reference < Base attr_reader :generic_values # @param generic_values [Array] + # @param [Hash{Symbol => Object}] splat def initialize generic_values: [], **splat super(**splat) @generic_values = generic_values diff --git a/lib/solargraph/pin/search.rb b/lib/solargraph/pin/search.rb index f92978a35..ee223edb3 100644 --- a/lib/solargraph/pin/search.rb +++ b/lib/solargraph/pin/search.rb @@ -43,7 +43,7 @@ def do_query end .compact .sort { |a, b| b.match <=> a.match } - .map(&:pin) + .map(&:pin) end # @param str1 [String] diff --git a/lib/solargraph/pin/signature.rb b/lib/solargraph/pin/signature.rb index 4c25e028b..2f0b6bafb 100644 --- a/lib/solargraph/pin/signature.rb +++ b/lib/solargraph/pin/signature.rb @@ -44,13 +44,12 @@ def typify api_map method_stack = closure.rest_of_stack api_map logger.debug { "Signature#typify(self=#{self}) - method_stack: #{method_stack}" } method_stack.each do |pin| - sig = pin.signatures.find { |s| s.arity == self.arity } + sig = pin.signatures.find { |s| s.arity == arity } next unless sig - unless sig.return_type.undefined? - qualified = sig.return_type.qualify(api_map, closure.namespace) - logger.debug { "Signature#typify(self=#{self}) => #{qualified.rooted_tags.inspect}" } - return qualified - end + next if sig.return_type.undefined? + qualified = sig.return_type.qualify(api_map, closure.namespace) + logger.debug { "Signature#typify(self=#{self}) => #{qualified.rooted_tags.inspect}" } + return qualified end out = super logger.debug { "Signature#typify(self=#{self}) => #{out}" } diff --git a/lib/solargraph/pin/symbol.rb b/lib/solargraph/pin/symbol.rb index 294363f5f..721c5cb3b 100644 --- a/lib/solargraph/pin/symbol.rb +++ b/lib/solargraph/pin/symbol.rb @@ -5,6 +5,7 @@ module Pin class Symbol < Base # @param location [Solargraph::Location] # @param name [String] + # @param [Hash{Symbol => Object}] kwargs def initialize(location, name, **kwargs) # @sg-ignore "Unrecognized keyword argument kwargs to Solargraph::Pin::Base#initialize" super(location: location, name: name, **kwargs) diff --git a/lib/solargraph/pin_cache.rb b/lib/solargraph/pin_cache.rb index b3c162a15..6e014d122 100644 --- a/lib/solargraph/pin_cache.rb +++ b/lib/solargraph/pin_cache.rb @@ -84,40 +84,40 @@ def yard_gem_path gemspec # @param gemspec [Gem::Specification] # @return [Array, nil] - def deserialize_yard_gem(gemspec) + def deserialize_yard_gem gemspec load(yard_gem_path(gemspec)) end # @param gemspec [Gem::Specification] # @param pins [Array] # @return [void] - def serialize_yard_gem(gemspec, pins) + def serialize_yard_gem gemspec, pins save(yard_gem_path(gemspec), pins) end # @param gemspec [Gem::Specification] # @return [Boolean] - def has_yard?(gemspec) + def has_yard? gemspec exist?(yard_gem_path(gemspec)) end # @param gemspec [Gem::Specification] # @param hash [String, nil] # @return [String] - def rbs_collection_path(gemspec, hash) + def rbs_collection_path gemspec, hash File.join(work_dir, 'rbs', "#{gemspec.name}-#{gemspec.version}-#{hash || 0}.ser") end # @param gemspec [Gem::Specification] # @return [String] - def rbs_collection_path_prefix(gemspec) + def rbs_collection_path_prefix gemspec File.join(work_dir, 'rbs', "#{gemspec.name}-#{gemspec.version}-") end # @param gemspec [Gem::Specification] # @param hash [String, nil] # @return [Array, nil] - def deserialize_rbs_collection_gem(gemspec, hash) + def deserialize_rbs_collection_gem gemspec, hash load(rbs_collection_path(gemspec, hash)) end @@ -125,20 +125,20 @@ def deserialize_rbs_collection_gem(gemspec, hash) # @param hash [String, nil] # @param pins [Array]n # @return [void] - def serialize_rbs_collection_gem(gemspec, hash, pins) + def serialize_rbs_collection_gem gemspec, hash, pins save(rbs_collection_path(gemspec, hash), pins) end # @param gemspec [Gem::Specification] # @param hash [String, nil] # @return [String] - def combined_path(gemspec, hash) + def combined_path gemspec, hash File.join(work_dir, 'combined', "#{gemspec.name}-#{gemspec.version}-#{hash || 0}.ser") end # @param gemspec [Gem::Specification] # @return [String] - def combined_path_prefix(gemspec) + def combined_path_prefix gemspec File.join(work_dir, 'combined', "#{gemspec.name}-#{gemspec.version}-") end @@ -146,7 +146,7 @@ def combined_path_prefix(gemspec) # @param hash [String, nil] # @param pins [Array] # @return [void] - def serialize_combined_gem(gemspec, hash, pins) + def serialize_combined_gem gemspec, hash, pins save(combined_path(gemspec, hash), pins) end @@ -160,7 +160,7 @@ def deserialize_combined_gem gemspec, hash # @param gemspec [Gem::Specification] # @param hash [String, nil] # @return [Boolean] - def has_rbs_collection?(gemspec, hash) + def has_rbs_collection? gemspec, hash exist?(rbs_collection_path(gemspec, hash)) end @@ -177,7 +177,7 @@ def uncache_stdlib # @param gemspec [Gem::Specification] # @param out [IO, nil] # @return [void] - def uncache_gem(gemspec, out: nil) + def uncache_gem gemspec, out: nil uncache(yardoc_path(gemspec), out: out) uncache_by_prefix(rbs_collection_path_prefix(gemspec), out: out) uncache(yard_gem_path(gemspec), out: out) @@ -220,16 +220,17 @@ def save file, pins # @param path_segments [Array] # @return [void] + # @param [Object, nil] out def uncache *path_segments, out: nil path = File.join(*path_segments) - if File.exist?(path) - FileUtils.rm_rf path, secure: true - out.puts "Clearing pin cache in #{path}" unless out.nil? - end + return unless File.exist?(path) + FileUtils.rm_rf path, secure: true + out.puts "Clearing pin cache in #{path}" unless out.nil? end # @return [void] # @param path_segments [Array] + # @param [Object, nil] out def uncache_by_prefix *path_segments, out: nil path = File.join(*path_segments) glob = "#{path}*" diff --git a/lib/solargraph/position.rb b/lib/solargraph/position.rb index 2faa0a99b..5f2f4f282 100644 --- a/lib/solargraph/position.rb +++ b/lib/solargraph/position.rb @@ -27,7 +27,7 @@ def initialize line, character end # @param other [Position] - def <=>(other) + def <=> other return nil unless other.is_a?(Position) if line == other.line character <=> other.character diff --git a/lib/solargraph/range.rb b/lib/solargraph/range.rb index 7a9bc0e30..ed05043b5 100644 --- a/lib/solargraph/range.rb +++ b/lib/solargraph/range.rb @@ -25,7 +25,7 @@ def initialize start, ending end # @param other [BasicObject] - def <=>(other) + def <=> other return nil unless other.is_a?(Range) if start == other.start ending <=> other.ending @@ -37,7 +37,7 @@ def <=>(other) # Get a hash of the range. This representation is suitable for use in # the language server protocol. # - # @return [Hash] + # @return [Hash{Symbol => Position}] def to_hash { start: start.to_hash, @@ -82,9 +82,8 @@ def self.from_to l1, c1, l2, c2 # @param node [Parser::AST::Node] # @return [Range, nil] def self.from_node node - if node&.loc && node.loc.expression - from_expr(node.loc.expression) - end + return unless node&.loc && node.loc.expression + from_expr(node.loc.expression) end # Get a range from a Parser range, usually found in diff --git a/lib/solargraph/rbs_map.rb b/lib/solargraph/rbs_map.rb index 803e3677a..85f99baa9 100644 --- a/lib/solargraph/rbs_map.rb +++ b/lib/solargraph/rbs_map.rb @@ -16,11 +16,7 @@ class RbsMap # @type [Hash{String => RbsMap}] @@rbs_maps_hash = {} - attr_reader :library - - attr_reader :rbs_collection_paths - - attr_reader :rbs_collection_config_path + attr_reader :library, :rbs_collection_paths, :rbs_collection_config_path # @param library [String] # @param version [String, nil] @@ -146,13 +142,13 @@ def conversions # @return [Boolean] true if adding the library succeeded def add_library loader, library, version @resolved = if loader.has_library?(library: library, version: version) - loader.add library: library, version: version - logger.debug { "#{short_name} successfully loaded library #{library}:#{version}" } - true - else - logger.info { "#{short_name} did not find data for library #{library}:#{version}" } - false - end + loader.add library: library, version: version + logger.debug { "#{short_name} successfully loaded library #{library}:#{version}" } + true + else + logger.info { "#{short_name} did not find data for library #{library}:#{version}" } + false + end end # @return [String] diff --git a/lib/solargraph/rbs_map/conversions.rb b/lib/solargraph/rbs_map/conversions.rb index 3e777f726..4dc3f67be 100644 --- a/lib/solargraph/rbs_map/conversions.rb +++ b/lib/solargraph/rbs_map/conversions.rb @@ -23,7 +23,7 @@ def initialize visibility = :public end # @param loader [RBS::EnvironmentLoader] - def initialize(loader:) + def initialize loader: @loader = loader @pins = [] load_environment_to_pins(loader) @@ -44,9 +44,9 @@ def type_aliases # @param loader [RBS::EnvironmentLoader] # @return [void] - def load_environment_to_pins(loader) + def load_environment_to_pins loader environment = RBS::Environment.from_loader(loader).resolve_type_names - cursor = pins.length + pins.length if environment.declarations.empty? Solargraph.logger.info "No RBS declarations found in environment for core_root #{loader.core_root.inspect}, libraries #{loader.libs} and directories #{loader.dirs}" return @@ -85,7 +85,7 @@ def convert_decl_to_pin decl, closure # @param module_pin [Pin::Namespace] # @return [void] def convert_self_types_to_pins decl, module_pin - decl.self_types.each { |self_type| context = convert_self_type_to_pins(self_type, module_pin) } + decl.self_types.each { |self_type| convert_self_type_to_pins(self_type, module_pin) } end # @param decl [RBS::AST::Declarations::Module::Self] @@ -241,7 +241,7 @@ def module_decl_to_pin decl # @param base [String, nil] Optional conversion of tag to base # # @return [Solargraph::Pin::Constant] - def create_constant(name, tag, comments, decl, base = nil) + def create_constant name, tag, comments, decl, base = nil parts = name.split('::') if parts.length > 1 name = parts.last @@ -280,7 +280,7 @@ def module_alias_decl_to_pin decl new_name = decl.new_name.relative!.to_s old_name = decl.old_name.relative!.to_s - pins.push create_constant(new_name, old_name, decl.comment&.string, decl, 'Module') + pins.push create_constant(new_name, old_name, decl.comment&.string, decl, 'Module') end # @param decl [RBS::AST::Declarations::Constant] @@ -307,7 +307,6 @@ def global_decl_to_pin decl pins.push pin end - # Visibility overrides that will allow the Solargraph project # and plugins to pass typechecking using SOLARGRAPH_ASSERTS=on, # so that we can detect any regressions/issues elsewhere in the @@ -323,27 +322,27 @@ def global_decl_to_pin decl # allow that to be extended via .solargraph.yml # @type [Hash{Array(String, Symbol, String) => Symbol} VISIBILITY_OVERRIDE = { - ["Rails::Engine", :instance, "run_tasks_blocks"] => :protected, + ['Rails::Engine', :instance, 'run_tasks_blocks'] => :protected, # Should have been marked as both instance and class method in module -e.g., 'module_function' - ["Kernel", :instance, "pretty_inspect"] => :private, + ['Kernel', :instance, 'pretty_inspect'] => :private, # marked incorrectly in RBS - ["WEBrick::HTTPUtils::FormData", :instance, "next_data"] => :protected, - ["Rails::Command", :class, "command_type"] => :private, - ["Rails::Command", :class, "lookup_paths"] => :private, - ["Rails::Command", :class, "file_lookup_paths"] => :private, - ["Rails::Railtie", :instance, "run_console_blocks"] => :protected, - ["Rails::Railtie", :instance, "run_generators_blocks"] => :protected, - ["Rails::Railtie", :instance, "run_runner_blocks"] => :protected, - ["Rails::Railtie", :instance, "run_tasks_blocks"] => :protected, - ["ActionController::Base", :instance, "_protected_ivars"] => :private, - ["ActionView::Template", :instance, "method_name"] => :public, - ["Module", :instance, "ruby2_keywords"] => :private, - ["Nokogiri::XML::Node", :instance, "coerce"] => :protected, - ["Nokogiri::XML::Document", :class, "empty_doc?"] => :private, - ["Nokogiri::Decorators::Slop", :instance, "respond_to_missing?"] => :public, - ["RuboCop::Cop::RangeHelp", :instance, "source_range"] => :private, - ["AST::Node", :instance, "original_dup"] => :private, - ["Rainbow::Presenter", :instance, "wrap_with_sgr"] => :private, + ['WEBrick::HTTPUtils::FormData', :instance, 'next_data'] => :protected, + ['Rails::Command', :class, 'command_type'] => :private, + ['Rails::Command', :class, 'lookup_paths'] => :private, + ['Rails::Command', :class, 'file_lookup_paths'] => :private, + ['Rails::Railtie', :instance, 'run_console_blocks'] => :protected, + ['Rails::Railtie', :instance, 'run_generators_blocks'] => :protected, + ['Rails::Railtie', :instance, 'run_runner_blocks'] => :protected, + ['Rails::Railtie', :instance, 'run_tasks_blocks'] => :protected, + ['ActionController::Base', :instance, '_protected_ivars'] => :private, + ['ActionView::Template', :instance, 'method_name'] => :public, + ['Module', :instance, 'ruby2_keywords'] => :private, + ['Nokogiri::XML::Node', :instance, 'coerce'] => :protected, + ['Nokogiri::XML::Document', :class, 'empty_doc?'] => :private, + ['Nokogiri::Decorators::Slop', :instance, 'respond_to_missing?'] => :public, + ['RuboCop::Cop::RangeHelp', :instance, 'source_range'] => :private, + ['AST::Node', :instance, 'original_dup'] => :private, + ['Rainbow::Presenter', :instance, 'wrap_with_sgr'] => :private } # @param decl [RBS::AST::Members::MethodDefinition, RBS::AST::Members::AttrReader, RBS::AST::Members::AttrAccessor] @@ -353,12 +352,14 @@ def global_decl_to_pin decl # @param name [String] The name of the method # @sg-ignore # @return [Symbol] - def calculate_method_visibility(decl, context, closure, scope, name) + def calculate_method_visibility decl, context, closure, scope, name override_key = [closure.path, scope, name] visibility = VISIBILITY_OVERRIDE[override_key] simple_override_key = [closure.path, scope] visibility ||= VISIBILITY_OVERRIDE[simple_override_key] - visibility ||= :private if closure.path == 'Kernel' && Kernel.private_instance_methods(false).include?(decl.name) + if closure.path == 'Kernel' && Kernel.private_instance_methods(false).include?(decl.name) + visibility ||= :private + end if decl.kind == :singleton_instance # this is a 'module function' visibility ||= :private @@ -402,24 +403,23 @@ def method_def_to_pin decl, closure, context pin.instance_variable_set(:@return_type, ComplexType::VOID) end end - if decl.singleton? - final_scope = :class - name = decl.name.to_s - visibility = calculate_method_visibility(decl, context, closure, final_scope, name) - pin = Solargraph::Pin::Method.new( - name: name, - closure: closure, - comments: decl.comment&.string, - type_location: location_decl_to_pin_location(decl.location), - visibility: visibility, - scope: final_scope, - signatures: [], - generics: generics, - source: :rbs - ) - pin.signatures.concat method_def_to_sigs(decl, pin) - pins.push pin - end + return unless decl.singleton? + final_scope = :class + name = decl.name.to_s + visibility = calculate_method_visibility(decl, context, closure, final_scope, name) + pin = Solargraph::Pin::Method.new( + name: name, + closure: closure, + comments: decl.comment&.string, + type_location: location_decl_to_pin_location(decl.location), + visibility: visibility, + scope: final_scope, + signatures: [], + generics: generics, + source: :rbs + ) + pin.signatures.concat method_def_to_sigs(decl, pin) + pins.push pin end # @param decl [RBS::AST::Members::MethodDefinition] @@ -442,7 +442,7 @@ def method_def_to_sigs decl, pin # @param location [RBS::Location, nil] # @return [Solargraph::Location, nil] - def location_decl_to_pin_location(location) + def location_decl_to_pin_location location return nil if location&.name.nil? start_pos = Position.new(location.start_line - 1, location.start_column) @@ -458,7 +458,8 @@ def parts_of_function type, pin type_location = pin.type_location if defined?(RBS::Types::UntypedFunction) && type.type.is_a?(RBS::Types::UntypedFunction) return [ - [Solargraph::Pin::Parameter.new(decl: :restarg, name: 'arg', closure: pin, source: :rbs, type_location: type_location)], + [Solargraph::Pin::Parameter.new(decl: :restarg, name: 'arg', closure: pin, source: :rbs, + type_location: type_location)], ComplexType.try_parse(method_type_to_tag(type)).force_rooted ] end @@ -467,7 +468,8 @@ def parts_of_function type, pin arg_num = -1 type.type.required_positionals.each do |param| name = param.name ? param.name.to_s : "arg_#{arg_num += 1}" - parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin, return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted, source: :rbs, type_location: type_location) + parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin, + return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted, source: :rbs, type_location: type_location) end type.type.optional_positionals.each do |param| name = param.name ? param.name.to_s : "arg_#{arg_num += 1}" @@ -486,11 +488,12 @@ def parts_of_function type, pin rooted: true, parameters_type: :list) parameters.push Solargraph::Pin::Parameter.new(decl: :restarg, name: name, closure: pin, source: :rbs, type_location: type_location, - return_type: rest_positional_type,) + return_type: rest_positional_type) end type.type.trailing_positionals.each do |param| name = param.name ? param.name.to_s : "arg_#{arg_num += 1}" - parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin, source: :rbs, type_location: type_location) + parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin, source: :rbs, + type_location: type_location) end type.type.required_keywords.each do |orig, param| name = orig ? orig.to_s : "arg_#{arg_num += 1}" @@ -520,7 +523,7 @@ def parts_of_function type, pin # @param closure [Pin::Namespace] # @param context [Context] # @return [void] - def attr_reader_to_pin(decl, closure, context) + def attr_reader_to_pin decl, closure, context name = decl.name.to_s final_scope = decl.kind == :instance ? :instance : :class visibility = calculate_method_visibility(decl, context, closure, final_scope, name) @@ -536,7 +539,9 @@ def attr_reader_to_pin(decl, closure, context) ) rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', rooted_tag)) - logger.debug { "Conversions#attr_reader_to_pin(name=#{name.inspect}, visibility=#{visibility.inspect}) => #{pin.inspect}" } + logger.debug do + "Conversions#attr_reader_to_pin(name=#{name.inspect}, visibility=#{visibility.inspect}) => #{pin.inspect}" + end pins.push pin end @@ -544,9 +549,9 @@ def attr_reader_to_pin(decl, closure, context) # @param closure [Pin::Namespace] # @param context [Context] # @return [void] - def attr_writer_to_pin(decl, closure, context) + def attr_writer_to_pin decl, closure, context final_scope = decl.kind == :instance ? :instance : :class - name = "#{decl.name.to_s}=" + name = "#{decl.name}=" visibility = calculate_method_visibility(decl, context, closure, final_scope, name) type_location = location_decl_to_pin_location(decl.location) pin = Solargraph::Pin::Method.new( @@ -577,7 +582,7 @@ def attr_writer_to_pin(decl, closure, context) # @param closure [Pin::Namespace] # @param context [Context] # @return [void] - def attr_accessor_to_pin(decl, closure, context) + def attr_accessor_to_pin decl, closure, context attr_reader_to_pin(decl, closure, context) attr_writer_to_pin(decl, closure, context) end @@ -585,7 +590,7 @@ def attr_accessor_to_pin(decl, closure, context) # @param decl [RBS::AST::Members::InstanceVariable] # @param closure [Pin::Namespace] # @return [void] - def ivar_to_pin(decl, closure) + def ivar_to_pin decl, closure pin = Solargraph::Pin::InstanceVariable.new( name: decl.name.to_s, closure: closure, @@ -601,7 +606,7 @@ def ivar_to_pin(decl, closure) # @param decl [RBS::AST::Members::ClassVariable] # @param closure [Pin::Namespace] # @return [void] - def cvar_to_pin(decl, closure) + def cvar_to_pin decl, closure name = decl.name.to_s pin = Solargraph::Pin::ClassVariable.new( name: name, @@ -618,7 +623,7 @@ def cvar_to_pin(decl, closure) # @param decl [RBS::AST::Members::ClassInstanceVariable] # @param closure [Pin::Namespace] # @return [void] - def civar_to_pin(decl, closure) + def civar_to_pin decl, closure name = decl.name.to_s pin = Solargraph::Pin::InstanceVariable.new( name: name, @@ -682,7 +687,7 @@ def alias_to_pin decl, closure original: decl.old_name.to_s, closure: closure, scope: final_scope, - source: :rbs, + source: :rbs ) end @@ -707,7 +712,7 @@ def method_type_to_tag type # @param type_name [RBS::TypeName] # @param type_args [Enumerable] # @return [ComplexType::UniqueType] - def build_type(type_name, type_args = []) + def build_type type_name, type_args = [] base = RBS_TO_YARD_TYPE[type_name.relative!.to_s] || type_name.relative!.to_s params = type_args.map { |a| other_type_to_tag(a) }.map do |t| ComplexType.try_parse(t).force_rooted @@ -722,7 +727,7 @@ def build_type(type_name, type_args = []) # @param type_name [RBS::TypeName] # @param type_args [Enumerable] # @return [String] - def type_tag(type_name, type_args = []) + def type_tag type_name, type_args = [] build_type(type_name, type_args).tags end @@ -752,7 +757,7 @@ def other_type_to_tag type 'void' elsif type.is_a?(RBS::Types::Variable) "#{Solargraph::ComplexType::GENERIC_TAG_NAME}<#{type.name}>" - elsif type.is_a?(RBS::Types::ClassInstance) #&& !type.args.empty? + elsif type.is_a?(RBS::Types::ClassInstance) # && !type.args.empty? type_tag(type.name, type.args) elsif type.is_a?(RBS::Types::Bases::Instance) 'self' diff --git a/lib/solargraph/rbs_map/core_fills.rb b/lib/solargraph/rbs_map/core_fills.rb index 3bb32a0da..809e802a1 100644 --- a/lib/solargraph/rbs_map/core_fills.rb +++ b/lib/solargraph/rbs_map/core_fills.rb @@ -38,7 +38,7 @@ module CoreFills source: :core_fill), # RBS does not define Class with a generic, so all calls to # generic() return an 'untyped'. We can do better: - Override.method_return('Class#allocate', 'self', source: :core_fill), + Override.method_return('Class#allocate', 'self', source: :core_fill) ] # @todo I don't see any direct link in RBS to build this from - @@ -46,26 +46,32 @@ module CoreFills # against concrete classes INCLUDES = [ Solargraph::Pin::Reference::Include.new(name: '_ToAry', - closure: Solargraph::Pin::Namespace.new(name: 'Array', source: :core_fill), + closure: Solargraph::Pin::Namespace.new(name: 'Array', + source: :core_fill), generic_values: ['generic'], source: :core_fill), Solargraph::Pin::Reference::Include.new(name: '_ToAry', - closure: Solargraph::Pin::Namespace.new(name: 'Set', source: :core_fill), + closure: Solargraph::Pin::Namespace.new(name: 'Set', + source: :core_fill), generic_values: ['generic'], source: :core_fill), Solargraph::Pin::Reference::Include.new(name: '_Each', - closure: Solargraph::Pin::Namespace.new(name: 'Array', source: :core_fill), + closure: Solargraph::Pin::Namespace.new(name: 'Array', + source: :core_fill), generic_values: ['generic'], source: :core_fill), Solargraph::Pin::Reference::Include.new(name: '_Each', - closure: Solargraph::Pin::Namespace.new(name: 'Set', source: :core_fill), + closure: Solargraph::Pin::Namespace.new(name: 'Set', + source: :core_fill), generic_values: ['generic'], source: :core_fill), Solargraph::Pin::Reference::Include.new(name: '_ToS', - closure: Solargraph::Pin::Namespace.new(name: 'Object', source: :core_fill), + closure: Solargraph::Pin::Namespace.new(name: 'Object', + source: :core_fill), source: :core_fill), Solargraph::Pin::Reference::Include.new(name: '_ToS', - closure: Solargraph::Pin::Namespace.new(name: 'String', source: :core_fill), + closure: Solargraph::Pin::Namespace.new(name: 'String', + source: :core_fill), source: :core_fill) ] @@ -74,7 +80,8 @@ module CoreFills errnos = [] Errno.constants.each do |const| errnos.push Solargraph::Pin::Namespace.new(type: :class, name: const.to_s, closure: errno, source: :core_fill) - errnos.push Solargraph::Pin::Reference::Superclass.new(closure: errnos.last, name: 'SystemCallError', source: :core_fill) + errnos.push Solargraph::Pin::Reference::Superclass.new(closure: errnos.last, name: 'SystemCallError', + source: :core_fill) end ERRNOS = errnos diff --git a/lib/solargraph/server_methods.rb b/lib/solargraph/server_methods.rb index bdac3f19c..86cd107d0 100644 --- a/lib/solargraph/server_methods.rb +++ b/lib/solargraph/server_methods.rb @@ -7,7 +7,7 @@ module ServerMethods # @return [Integer] def available_port socket = Socket.new(:INET, :STREAM, 0) - socket.bind(Addrinfo.tcp("127.0.0.1", 0)) + socket.bind(Addrinfo.tcp('127.0.0.1', 0)) port = socket.local_address.ip_port socket.close port diff --git a/lib/solargraph/shell.rb b/lib/solargraph/shell.rb index a005f600b..c28bb4d0b 100755 --- a/lib/solargraph/shell.rb +++ b/lib/solargraph/shell.rb @@ -15,7 +15,7 @@ def self.exit_on_failure? map %w[--version -v] => :version - desc "--version, -v", "Print the version" + desc '--version, -v', 'Print the version' # @return [void] def version puts Solargraph::VERSION @@ -30,15 +30,15 @@ def socket port = options[:port] port = available_port if port.zero? Backport.run do - Signal.trap("INT") do + Signal.trap('INT') do Backport.stop end - Signal.trap("TERM") do + Signal.trap('TERM') do Backport.stop end # @sg-ignore Wrong argument type for Backport.prepare_tcp_server: adapter expected Backport::Adapter, received Module Backport.prepare_tcp_server host: options[:host], port: port, adapter: Solargraph::LanguageServer::Transport::Adapter - STDERR.puts "Solargraph is listening PORT=#{port} PID=#{Process.pid}" + warn "Solargraph is listening PORT=#{port} PID=#{Process.pid}" end end @@ -47,15 +47,15 @@ def socket def stdio require 'backport' Backport.run do - Signal.trap("INT") do + Signal.trap('INT') do Backport.stop end - Signal.trap("TERM") do + Signal.trap('TERM') do Backport.stop end # @sg-ignore Wrong argument type for Backport.prepare_stdio_server: adapter expected Backport::Adapter, received Module Backport.prepare_stdio_server adapter: Solargraph::LanguageServer::Transport::Adapter - STDERR.puts "Solargraph is listening on stdio PID=#{Process.pid}" + warn "Solargraph is listening on stdio PID=#{Process.pid}" end end @@ -63,11 +63,11 @@ def stdio option :extensions, type: :boolean, aliases: :e, desc: 'Add installed extensions', default: true # @param directory [String] # @return [void] - def config(directory = '.') + def config directory = '.' matches = [] if options[:extensions] Gem::Specification.each do |g| - if g.name.match(/^solargraph\-[A-Za-z0-9_\-]*?\-ext/) + if g.name.match(/^solargraph-[A-Za-z0-9_-]*?-ext/) require g.name matches.push g.name end @@ -82,7 +82,7 @@ def config(directory = '.') File.open(File.join(directory, '.solargraph.yml'), 'w') do |file| file.puts conf.to_yaml end - STDOUT.puts "Configuration file initialized." + STDOUT.puts 'Configuration file initialized.' end desc 'clear', 'Delete all cached documentation' @@ -91,7 +91,7 @@ def config(directory = '.') ) # @return [void] def clear - puts "Deleting all cached documentation (gems, core and stdlib)" + puts 'Deleting all cached documentation (gems, core and stdlib)' Solargraph::PinCache.clear end map 'clear-cache' => :clear @@ -108,7 +108,7 @@ def cache gem, version = nil api_map.cache_gem(spec, rebuild: options[:rebuild], out: $stdout) end - desc 'uncache GEM [...GEM]', "Delete specific cached gem documentation" + desc 'uncache GEM [...GEM]', 'Delete specific cached gem documentation' long_desc %( Specify one or more gem names to clear. 'core' or 'stdlib' may also be specified to clear cached system documentation. @@ -142,7 +142,7 @@ def gems *names api_map = ApiMap.load('.') if names.empty? Gem::Specification.to_a.each { |spec| do_cache spec, api_map } - STDERR.puts "Documentation cached for all #{Gem::Specification.count} gems." + warn "Documentation cached for all #{Gem::Specification.count} gems." else names.each do |name| spec = Gem::Specification.find_by_name(*name.split('=')) @@ -150,7 +150,7 @@ def gems *names rescue Gem::MissingSpecError warn "Gem '#{name}' not found" end - STDERR.puts "Documentation cached for #{names.count} gems." + warn "Documentation cached for #{names.count} gems." end end @@ -167,7 +167,7 @@ def reporters Type checking levels are normal, typed, strict, and strong. ) - option :level, type: :string, aliases: [:mode, :m, :l], desc: 'Type checking level', default: 'normal' + option :level, type: :string, aliases: %i[mode m l], desc: 'Type checking level', default: 'normal' option :directory, type: :string, aliases: :d, desc: 'The workspace directory', default: '.' # @return [void] def typecheck *files @@ -181,20 +181,22 @@ def typecheck *files end filecount = 0 - time = Benchmark.measure { + time = Benchmark.measure do files.each do |file| checker = TypeChecker.new(file, api_map: api_map, level: options[:level].to_sym) problems = checker.problems next if problems.empty? problems.sort! { |a, b| a.location.range.start.line <=> b.location.range.start.line } - puts problems.map { |prob| "#{prob.location.filename}:#{prob.location.range.start.line + 1} - #{prob.message}" }.join("\n") + puts problems.map { |prob| + "#{prob.location.filename}:#{prob.location.range.start.line + 1} - #{prob.message}" + }.join("\n") filecount += 1 probcount += problems.length end # " - } + end puts "Typecheck finished in #{time.real} seconds." - puts "#{probcount} problem#{probcount != 1 ? 's' : ''} found#{files.length != 1 ? " in #{filecount} of #{files.length} files" : ''}." + puts "#{probcount} problem#{'s' if probcount != 1} found#{" in #{filecount} of #{files.length} files" if files.length != 1}." # " exit 1 if probcount > 0 end @@ -213,21 +215,21 @@ def scan directory = File.realpath(options[:directory]) # @type [Solargraph::ApiMap, nil] api_map = nil - time = Benchmark.measure { + time = Benchmark.measure do api_map = Solargraph::ApiMap.load_with_cache(directory, $stdout) api_map.pins.each do |pin| - begin - puts pin_description(pin) if options[:verbose] - pin.typify api_map - pin.probe api_map - rescue StandardError => e - STDERR.puts "Error testing #{pin_description(pin)} #{pin.location ? "at #{pin.location.filename}:#{pin.location.range.start.line + 1}" : ''}" - STDERR.puts "[#{e.class}]: #{e.message}" - STDERR.puts e.backtrace.join("\n") - exit 1 - end + puts pin_description(pin) if options[:verbose] + pin.typify api_map + pin.probe api_map + rescue StandardError => e + warn "Error testing #{pin_description(pin)} #{if pin.location + "at #{pin.location.filename}:#{pin.location.range.start.line + 1}" + end}" + warn "[#{e.class}]: #{e.message}" + warn e.backtrace.join("\n") + exit 1 end - } + end puts "Scanned #{directory} (#{api_map.pins.length} pins) in #{time.real} seconds." end @@ -247,14 +249,14 @@ def list # @return [String] def pin_description pin desc = if pin.path.nil? || pin.path.empty? - if pin.closure - "#{pin.closure.path} | #{pin.name}" - else - "#{pin.context.namespace} | #{pin.name}" - end - else - pin.path - end + if pin.closure + "#{pin.closure.path} | #{pin.name}" + else + "#{pin.context.namespace} | #{pin.name}" + end + else + pin.path + end desc += " (#{pin.location.filename} #{pin.location.range.start.line})" if pin.location desc end diff --git a/lib/solargraph/source.rb b/lib/solargraph/source.rb index ae5b08d3b..36339c78c 100644 --- a/lib/solargraph/source.rb +++ b/lib/solargraph/source.rb @@ -64,7 +64,7 @@ def at range def from_to l1, c1, l2, c2 b = Solargraph::Position.line_char_to_offset(code, l1, c1) e = Solargraph::Position.line_char_to_offset(code, l2, c2) - code[b..e-1] + code[b..e - 1] end # Get the nearest node that contains the specified index. @@ -72,7 +72,7 @@ def from_to l1, c1, l2, c2 # @param line [Integer] # @param column [Integer] # @return [AST::Node] - def node_at(line, column) + def node_at line, column tree_at(line, column).first end @@ -82,7 +82,7 @@ def node_at(line, column) # @param line [Integer] # @param column [Integer] # @return [Array] - def tree_at(line, column) + def tree_at line, column position = Position.new(line, column) stack = [] inner_tree_at node, position, stack @@ -134,7 +134,7 @@ def string_at? position next if range.ending.line < position.line break if range.ending.line > position.line return true if node.type == :str && range.include?(position) && range.start != position - return true if [:STR, :str].include?(node.type) && range.include?(position) && range.start != position + return true if %i[STR str].include?(node.type) && range.include?(position) && range.start != position if node.type == :dstr inner = node_at(position.line, position.column) next if inner.nil? @@ -142,7 +142,7 @@ def string_at? position next unless range.include?(inner_range.ending) return true if inner.type == :str inner_code = at(Solargraph::Range.new(inner_range.start, position)) - return true if (inner.type == :dstr && inner_range.ending.character <= position.character) && !inner_code.end_with?('}') || + return true if (inner.type == :dstr && inner_range.ending.character <= position.character && !inner_code.end_with?('}')) || (inner.type != :dstr && inner_range.ending.line == position.line && position.character <= inner_range.ending.character && inner_code.end_with?('}')) end break if range.ending.line > position.line @@ -160,7 +160,7 @@ def string_ranges def comment_at? position comment_ranges.each do |range| return true if range.include?(position) || - (range.ending.line == position.line && range.ending.column < position.column) + (range.ending.line == position.line && range.ending.column < position.column) break if range.ending.line > position.line end false @@ -179,11 +179,11 @@ def error_ranges # @param node [Parser::AST::Node] # @return [String] - def code_for(node) + def code_for node rng = Range.from_node(node) b = Position.line_char_to_offset(code, rng.start.line, rng.start.column) e = Position.line_char_to_offset(code, rng.ending.line, rng.ending.column) - frag = code[b..e-1].to_s + frag = code[b..e - 1].to_s frag.strip.gsub(/,$/, '') end @@ -208,8 +208,8 @@ def location end FOLDING_NODE_TYPES = %i[ - class sclass module def defs if str dstr array while unless kwbegin hash block - ].freeze + class sclass module def defs if str dstr array while unless kwbegin hash block + ].freeze # Get an array of ranges that can be folded, e.g., the range of a class # definition or an if condition. @@ -273,8 +273,8 @@ def inner_folding_ranges top, result = [], parent = nil return unless Parser.is_ast_node?(top) if FOLDING_NODE_TYPES.include?(top.type) range = Range.from_node(top) - if result.empty? || range.start.line > result.last.start.line - result.push range unless range.ending.line - range.start.line < 2 + if (result.empty? || range.start.line > result.last.start.line) && !(range.ending.line - range.start.line < 2) + result.push range end end top.children.each do |child| @@ -290,7 +290,7 @@ def stringify_comment_array comments ctxt = String.new('') started = false skip = nil - comments.lines.each { |l| + comments.lines.each do |l| # Trim the comment and minimum leading whitespace p = l.force_encoding('UTF-8').encode('UTF-8', invalid: :replace, replace: '?').gsub(/^#+/, '') if p.strip.empty? @@ -302,7 +302,7 @@ def stringify_comment_array comments ctxt.concat p[skip..-1] end started = true - } + end ctxt end @@ -348,10 +348,10 @@ def foldable_comment_block_ranges def string_nodes_in n result = [] if Parser.is_ast_node?(n) - if n.type == :str || n.type == :dstr || n.type == :STR || n.type == :DSTR + if %i[str dstr STR DSTR].include?(n.type) result.push n else - n.children.each{ |c| result.concat string_nodes_in(c) } + n.children.each { |c| result.concat string_nodes_in(c) } end end result @@ -364,13 +364,12 @@ def string_nodes_in n def inner_tree_at node, position, stack return if node.nil? here = Range.from_node(node) - if here.contain?(position) - stack.unshift node - node.children.each do |c| - next unless Parser.is_ast_node?(c) - next if c.loc.expression.nil? - inner_tree_at(c, position, stack) - end + return unless here.contain?(position) + stack.unshift node + node.children.each do |c| + next unless Parser.is_ast_node?(c) + next if c.loc.expression.nil? + inner_tree_at(c, position, stack) end end @@ -399,7 +398,7 @@ def finalize @node, @comments = Solargraph::Parser.parse_with_comments(@code, filename) @parsed = true @repaired = @code - rescue Parser::SyntaxError, EncodingError => e + rescue Parser::SyntaxError, EncodingError @node = nil @comments = {} @parsed = false @@ -414,7 +413,7 @@ def finalize begin @node, @comments = Solargraph::Parser.parse_with_comments(@repaired, filename) @parsed = true - rescue Parser::SyntaxError, EncodingError => e + rescue Parser::SyntaxError, EncodingError @node = nil @comments = {} @parsed = false @@ -427,7 +426,7 @@ def finalize # @param val [String] # @return [String] - def code=(val) + def code= val @code_lines = nil @finalized = false @code = val diff --git a/lib/solargraph/source/chain.rb b/lib/solargraph/source/chain.rb index c08d04878..629fc3ab8 100644 --- a/lib/solargraph/source/chain.rb +++ b/lib/solargraph/source/chain.rb @@ -117,7 +117,9 @@ def define api_map, name_pin, locals pins = link.resolve(api_map, working_pin, locals) type = infer_from_definitions(pins, working_pin, api_map, locals) if type.undefined? - logger.debug { "Chain#define(links=#{links.map(&:desc)}, name_pin=#{name_pin.inspect}, locals=#{locals}) => [] - undefined type from #{link.desc}" } + logger.debug do + "Chain#define(links=#{links.map(&:desc)}, name_pin=#{name_pin.inspect}, locals=#{locals}) => [] - undefined type from #{link.desc}" + end return [] end # We continue to use the context from the head pin, in case @@ -126,7 +128,9 @@ def define api_map, name_pin, locals # for the binder, as this is chaining off of it, and the # binder is now the lhs of the rhs we are evaluating. working_pin = Pin::ProxyType.anonymous(name_pin.context, binder: type, closure: name_pin, source: :chain) - logger.debug { "Chain#define(links=#{links.map(&:desc)}, name_pin=#{name_pin.inspect}, locals=#{locals}) - after processing #{link.desc}, new working_pin=#{working_pin} with binder #{working_pin.binder}" } + logger.debug do + "Chain#define(links=#{links.map(&:desc)}, name_pin=#{name_pin.inspect}, locals=#{locals}) - after processing #{link.desc}, new working_pin=#{working_pin} with binder #{working_pin.binder}" + end end links.last.last_context = working_pin links.last.resolve(api_map, working_pin, locals) @@ -147,7 +151,9 @@ def infer api_map, name_pin, locals @@inference_cache = {} end out = infer_uncached(api_map, name_pin, locals).downcast_to_literal_if_possible - logger.debug { "Chain#infer() - caching result - cache_key_hash=#{cache_key.hash}, links.map(&:hash)=#{links.map(&:hash)}, links=#{links}, cache_key.map(&:hash) = #{cache_key.map(&:hash)}, cache_key=#{cache_key}" } + logger.debug do + "Chain#infer() - caching result - cache_key_hash=#{cache_key.hash}, links.map(&:hash)=#{links.map(&:hash)}, links=#{links}, cache_key.map(&:hash) = #{cache_key.map(&:hash)}, cache_key=#{cache_key}" + end @@inference_cache[cache_key] = out end @@ -158,12 +164,16 @@ def infer api_map, name_pin, locals def infer_uncached api_map, name_pin, locals pins = define(api_map, name_pin, locals) if pins.empty? - logger.debug { "Chain#infer_uncached(links=#{links.map(&:desc)}, locals=#{locals.map(&:desc)}) => undefined - no pins" } + logger.debug do + "Chain#infer_uncached(links=#{links.map(&:desc)}, locals=#{locals.map(&:desc)}) => undefined - no pins" + end return ComplexType::UNDEFINED end type = infer_from_definitions(pins, links.last.last_context, api_map, locals) out = maybe_nil(type) - logger.debug { "Chain#infer_uncached(links=#{self.links.map(&:desc)}, locals=#{locals.map(&:desc)}, name_pin=#{name_pin}, name_pin.closure=#{name_pin.closure.inspect}, name_pin.binder=#{name_pin.binder}) => #{out.rooted_tags.inspect}" } + logger.debug do + "Chain#infer_uncached(links=#{links.map(&:desc)}, locals=#{locals.map(&:desc)}, name_pin=#{name_pin}, name_pin.closure=#{name_pin.closure.inspect}, name_pin.binder=#{name_pin.binder}) => #{out.rooted_tags.inspect}" + end out end @@ -241,17 +251,13 @@ def infer_from_definitions pins, context, api_map, locals end # Limit method inference recursion - if @@inference_depth >= 10 && pins.first.is_a?(Pin::Method) - return ComplexType::UNDEFINED - end + return ComplexType::UNDEFINED if @@inference_depth >= 10 && pins.first.is_a?(Pin::Method) @@inference_depth += 1 # @param pin [Pin::Base] unresolved_pins.each do |pin| # Avoid infinite recursion - if @@inference_stack.include?(pin.identity) - next - end + next if @@inference_stack.include?(pin.identity) @@inference_stack.push(pin.identity) type = pin.probe(api_map) diff --git a/lib/solargraph/source/chain/call.rb b/lib/solargraph/source/chain/call.rb index 24d10656d..2e2b1273b 100644 --- a/lib/solargraph/source/chain/call.rb +++ b/lib/solargraph/source/chain/call.rb @@ -51,10 +51,10 @@ def resolve api_map, name_pin, locals return super_pins(api_map, name_pin) if word == 'super' return yield_pins(api_map, name_pin) if word == 'yield' found = if head? - api_map.visible_pins(locals, word, name_pin, location) - else - [] - end + api_map.visible_pins(locals, word, name_pin, location) + else + [] + end return inferred_pins(found, api_map, name_pin, locals) unless found.empty? pins = name_pin.binder.each_unique_type.flat_map do |context| ns_tag = context.namespace == '' ? '' : context.namespace_type.tag @@ -98,7 +98,8 @@ def inferred_pins pins, api_map, name_pin, locals match = ol.parameters.any?(&:restarg?) break end - atype = atypes[idx] ||= arg.infer(api_map, Pin::ProxyType.anonymous(name_pin.context, source: :chain), locals) + atype = atypes[idx] ||= arg.infer(api_map, Pin::ProxyType.anonymous(name_pin.context, source: :chain), + locals) unless param.compatible_arg?(atype, api_map) || param.restarg? match = false break @@ -107,37 +108,41 @@ def inferred_pins pins, api_map, name_pin, locals if match if ol.block && with_block? block_atypes = ol.block.parameters.map(&:return_type) - if block.links.map(&:class) == [BlockSymbol] - # like the bar in foo(&:bar) - blocktype = block_symbol_call_type(api_map, name_pin.context, block_atypes, locals) - else - blocktype = block_call_type(api_map, name_pin, locals) - end + blocktype = if block.links.map(&:class) == [BlockSymbol] + # like the bar in foo(&:bar) + block_symbol_call_type(api_map, name_pin.context, block_atypes, locals) + else + block_call_type(api_map, name_pin, locals) + end end # @type new_signature_pin [Pin::Signature] - new_signature_pin = ol.resolve_generics_from_context_until_complete(ol.generics, atypes, nil, nil, blocktype) + new_signature_pin = ol.resolve_generics_from_context_until_complete(ol.generics, atypes, nil, nil, + blocktype) new_return_type = new_signature_pin.return_type - if head? - # If we're at the head of the chain, we called a - # method somewhere that marked itself as returning - # self. Given we didn't invoke this on an object, - # this must be a method in this same class - so we - # use our own self type - self_type = name_pin.context - else - # if we're past the head in the chain, whatever the - # type of the lhs side is what 'self' will be in its - # declaration - we can't just use the type of the - # method pin, as this might be a subclass of the - # place where the method is defined - self_type = name_pin.binder - end + self_type = if head? + # If we're at the head of the chain, we called a + # method somewhere that marked itself as returning + # self. Given we didn't invoke this on an object, + # this must be a method in this same class - so we + # use our own self type + name_pin.context + else + # if we're past the head in the chain, whatever the + # type of the lhs side is what 'self' will be in its + # declaration - we can't just use the type of the + # method pin, as this might be a subclass of the + # place where the method is defined + name_pin.binder + end # This same logic applies to the YARD work done by # 'with_params()'. # # qualify(), however, happens in the namespace where # the docs were written - from the method pin. - type = with_params(new_return_type.self_to_type(self_type), self_type).qualify(api_map, *p.gates) if new_return_type.defined? + if new_return_type.defined? + type = with_params(new_return_type.self_to_type(self_type), self_type).qualify(api_map, + *p.gates) + end type ||= ComplexType::UNDEFINED end break if type.defined? @@ -153,8 +158,10 @@ def inferred_pins pins, api_map, name_pin, locals end p end - logger.debug { "Call#inferred_pins(name_pin.binder=#{name_pin.binder}, word=#{word}, pins=#{pins.map(&:desc)}, name_pin=#{name_pin}) - result=#{result}" } - out = result.map do |pin| + logger.debug do + "Call#inferred_pins(name_pin.binder=#{name_pin.binder}, word=#{word}, pins=#{pins.map(&:desc)}, name_pin=#{name_pin}) - result=#{result}" + end + result.map do |pin| if pin.path == 'Class#new' && name_pin.binder.tag != 'Class' reduced_context = name_pin.binder.reduce_class_type pin.proxy(reduced_context) @@ -207,7 +214,7 @@ def process_directive pin, api_map, context, locals # @param locals [::Array] # @return [Pin::ProxyType] def inner_process_macro pin, macro, api_map, context, locals - vals = arguments.map{ |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals), source: :chain) } + vals = arguments.map { |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals), source: :chain) } txt = macro.tag.text.clone if txt.empty? && macro.tag.name named = api_map.named_macro(macro.tag.name) @@ -230,7 +237,7 @@ def inner_process_macro pin, macro, api_map, context, locals # @param context [ComplexType] # @return [ComplexType, nil] def extra_return_type docstring, context - if docstring.has_tag?('return_single_parameter') #&& context.subtypes.one? + if docstring.has_tag?('return_single_parameter') # && context.subtypes.one? return context.subtypes.first || ComplexType::UNDEFINED elsif docstring.has_tag?('return_value_parameter') && context.value_types.one? return context.value_types.first @@ -240,7 +247,7 @@ def extra_return_type docstring, context # @param name_pin [Pin::Base] # @return [Pin::Method, nil] - def find_method_pin(name_pin) + def find_method_pin name_pin method_pin = name_pin until method_pin.is_a?(Pin::Method) method_pin = method_pin.closure @@ -256,7 +263,7 @@ def super_pins api_map, name_pin method_pin = find_method_pin(name_pin) return [] if method_pin.nil? pins = api_map.get_method_stack(method_pin.namespace, method_pin.name, scope: method_pin.context.scope) - pins.reject{|p| p.path == name_pin.path} + pins.reject { |p| p.path == name_pin.path } end # @param api_map [ApiMap] @@ -291,7 +298,7 @@ def fix_block_pass # @param block_parameter_types [::Array] # @param locals [::Array] # @return [ComplexType, nil] - def block_symbol_call_type(api_map, context, block_parameter_types, locals) + def block_symbol_call_type api_map, context, block_parameter_types, locals # Ruby's shorthand for sending the passed in method name # to the first yield parameter with no arguments block_symbol_name = block.links.first.word @@ -307,7 +314,7 @@ def block_symbol_call_type(api_map, context, block_parameter_types, locals) # @param api_map [ApiMap] # @return [Pin::Block, nil] - def find_block_pin(api_map) + def find_block_pin api_map node_location = Solargraph::Location.from_node(block.node) return if node_location.nil? block_pins = api_map.get_block_pins @@ -319,7 +326,7 @@ def find_block_pin(api_map) # @param block_parameter_types [::Array] # @param locals [::Array] # @return [ComplexType, nil] - def block_call_type(api_map, name_pin, locals) + def block_call_type api_map, name_pin, locals return nil unless with_block? block_context_pin = name_pin diff --git a/lib/solargraph/source/chain/class_variable.rb b/lib/solargraph/source/chain/class_variable.rb index a804d89e5..f50028ffa 100644 --- a/lib/solargraph/source/chain/class_variable.rb +++ b/lib/solargraph/source/chain/class_variable.rb @@ -5,7 +5,7 @@ class Source class Chain class ClassVariable < Link def resolve api_map, name_pin, locals - api_map.get_class_variable_pins(name_pin.context.namespace).select{|p| p.name == word} + api_map.get_class_variable_pins(name_pin.context.namespace).select { |p| p.name == word } end end end diff --git a/lib/solargraph/source/chain/global_variable.rb b/lib/solargraph/source/chain/global_variable.rb index 0842803a9..335b8e42c 100644 --- a/lib/solargraph/source/chain/global_variable.rb +++ b/lib/solargraph/source/chain/global_variable.rb @@ -5,7 +5,7 @@ class Source class Chain class GlobalVariable < Link def resolve api_map, name_pin, locals - api_map.get_global_variable_pins.select{|p| p.name == word} + api_map.get_global_variable_pins.select { |p| p.name == word } end end end diff --git a/lib/solargraph/source/chain/if.rb b/lib/solargraph/source/chain/if.rb index c14d00ddf..6c85d42e9 100644 --- a/lib/solargraph/source/chain/if.rb +++ b/lib/solargraph/source/chain/if.rb @@ -20,7 +20,8 @@ def initialize links def resolve api_map, name_pin, locals types = @links.map { |link| link.infer(api_map, name_pin, locals) } - [Solargraph::Pin::ProxyType.anonymous(Solargraph::ComplexType.try_parse(types.map(&:tag).uniq.join(', ')), source: :chain)] + [Solargraph::Pin::ProxyType.anonymous(Solargraph::ComplexType.try_parse(types.map(&:tag).uniq.join(', ')), + source: :chain)] end end end diff --git a/lib/solargraph/source/chain/instance_variable.rb b/lib/solargraph/source/chain/instance_variable.rb index ea09f5578..ac622bdcc 100644 --- a/lib/solargraph/source/chain/instance_variable.rb +++ b/lib/solargraph/source/chain/instance_variable.rb @@ -5,7 +5,9 @@ class Source class Chain class InstanceVariable < Link def resolve api_map, name_pin, locals - api_map.get_instance_variable_pins(name_pin.binder.namespace, name_pin.binder.scope).select{|p| p.name == word} + api_map.get_instance_variable_pins(name_pin.binder.namespace, name_pin.binder.scope).select do |p| + p.name == word + end end end end diff --git a/lib/solargraph/source/chain/link.rb b/lib/solargraph/source/chain/link.rb index bcd9eb196..14b4ae77b 100644 --- a/lib/solargraph/source/chain/link.rb +++ b/lib/solargraph/source/chain/link.rb @@ -55,7 +55,7 @@ def to_s end def inspect - "#<#{self.class} - `#{self.desc}`>" + "#<#{self.class} - `#{desc}`>" end def head? @@ -88,7 +88,7 @@ def desc end def inspect - "#<#{self.class} - `#{self.desc}`>" + "#<#{self.class} - `#{desc}`>" end include Logging diff --git a/lib/solargraph/source/chain/literal.rb b/lib/solargraph/source/chain/literal.rb index 2e0d65c9e..c7220e95f 100644 --- a/lib/solargraph/source/chain/literal.rb +++ b/lib/solargraph/source/chain/literal.rb @@ -20,7 +20,7 @@ def initialize type, node @value = true elsif node.type == :false @value = false - elsif [:int, :sym].include?(node.type) + elsif %i[int sym].include?(node.type) @value = node.children.first end end diff --git a/lib/solargraph/source/chain/variable.rb b/lib/solargraph/source/chain/variable.rb index 975fbf6f5..8bf424e3b 100644 --- a/lib/solargraph/source/chain/variable.rb +++ b/lib/solargraph/source/chain/variable.rb @@ -5,7 +5,9 @@ class Source class Chain class Variable < Link def resolve api_map, name_pin, locals - api_map.get_instance_variable_pins(name_pin.context.namespace, name_pin.context.scope).select{|p| p.name == word} + api_map.get_instance_variable_pins(name_pin.context.namespace, name_pin.context.scope).select do |p| + p.name == word + end end end end diff --git a/lib/solargraph/source/chain/z_super.rb b/lib/solargraph/source/chain/z_super.rb index 5b0106c92..0021c4dbf 100644 --- a/lib/solargraph/source/chain/z_super.rb +++ b/lib/solargraph/source/chain/z_super.rb @@ -22,7 +22,7 @@ def initialize word, with_block = false # @param name_pin [Pin::Base] # @param locals [::Array] def resolve api_map, name_pin, locals - return super_pins(api_map, name_pin) + super_pins(api_map, name_pin) end end end diff --git a/lib/solargraph/source/change.rb b/lib/solargraph/source/change.rb index 65c47c7e0..cca35128d 100644 --- a/lib/solargraph/source/change.rb +++ b/lib/solargraph/source/change.rb @@ -60,9 +60,7 @@ def repair text result = commit text, fixed off = Position.to_offset(text, range.start) match = result[0, off].match(/[.:]+\z/) - if match - result = result[0, off].sub(/#{match[0]}\z/, ' ' * match[0].length) + result[off..-1] - end + result = result[0, off].sub(/#{match[0]}\z/, ' ' * match[0].length) + result[off..-1] if match result end end @@ -75,7 +73,7 @@ def repair text def commit text, insert start_offset = Position.to_offset(text, range.start) end_offset = Position.to_offset(text, range.ending) - (start_offset == 0 ? '' : text[0..start_offset-1].to_s) + normalize(insert) + text[end_offset..-1].to_s + (start_offset == 0 ? '' : text[0..start_offset - 1].to_s) + normalize(insert) + text[end_offset..-1].to_s end end end diff --git a/lib/solargraph/source/cursor.rb b/lib/solargraph/source/cursor.rb index a8226eb07..4af119369 100644 --- a/lib/solargraph/source/cursor.rb +++ b/lib/solargraph/source/cursor.rb @@ -38,10 +38,12 @@ def word # @return [String] def start_of_word @start_of_word ||= begin - match = source.code[0..offset-1].to_s.match(start_word_pattern) + match = source.code[0..offset - 1].to_s.match(start_word_pattern) result = (match ? match[0] : '') # Including the preceding colon if the word appears to be a symbol - result = ":#{result}" if source.code[0..offset-result.length-1].end_with?(':') and !source.code[0..offset-result.length-1].end_with?('::') + if source.code[0..offset - result.length - 1].end_with?(':') and !source.code[0..offset - result.length - 1].end_with?('::') + result = ":#{result}" + end result end end @@ -59,7 +61,7 @@ def end_of_word # @return [Boolean] def start_of_constant? - source.code[offset-2, 2] == '::' + source.code[offset - 2, 2] == '::' end # The range of the word at the current position. @@ -122,18 +124,16 @@ def node # @return [Position] def node_position - @node_position ||= begin - if start_of_word.empty? - match = source.code[0, offset].match(/\s*(\.|:+)\s*$/) - if match - Position.from_offset(source.code, offset - match[0].length) - else - position - end - else - position - end - end + @node_position ||= if start_of_word.empty? + match = source.code[0, offset].match(/\s*(\.|:+)\s*$/) + if match + Position.from_offset(source.code, offset - match[0].length) + else + position + end + else + position + end end # @return [Parser::AST::Node, nil] diff --git a/lib/solargraph/source/encoding_fixes.rb b/lib/solargraph/source/encoding_fixes.rb index 8c5d081b0..0bb8d7f7e 100644 --- a/lib/solargraph/source/encoding_fixes.rb +++ b/lib/solargraph/source/encoding_fixes.rb @@ -1,23 +1,22 @@ -# frozen_string_literal: true - -module Solargraph - class Source - module EncodingFixes - module_function - - # Convert strings to normalized UTF-8. - # - # @param string [String] - # @return [String] - def normalize string - begin - string.dup.force_encoding('UTF-8') - rescue ::Encoding::CompatibilityError, ::Encoding::UndefinedConversionError, ::Encoding::InvalidByteSequenceError => e - # @todo Improve error handling - Solargraph::Logging.logger.warn "Normalize error: #{e.message}" - string - end - end - end - end -end +# frozen_string_literal: true + +module Solargraph + class Source + module EncodingFixes + module_function + + # Convert strings to normalized UTF-8. + # + # @param string [String] + # @return [String] + def normalize string + string.dup.force_encoding('UTF-8') + rescue ::Encoding::CompatibilityError, ::Encoding::UndefinedConversionError, + ::Encoding::InvalidByteSequenceError => e + # @todo Improve error handling + Solargraph::Logging.logger.warn "Normalize error: #{e.message}" + string + end + end + end +end diff --git a/lib/solargraph/source/source_chainer.rb b/lib/solargraph/source/source_chainer.rb index 5758a9d35..15a880d7e 100644 --- a/lib/solargraph/source/source_chainer.rb +++ b/lib/solargraph/source/source_chainer.rb @@ -32,9 +32,21 @@ def initialize source, position # @return [Source::Chain] def chain # Special handling for files that end with an integer and a period - return Chain.new([Chain::Literal.new('Integer', Integer(phrase[0..-2])), Chain::UNDEFINED_CALL]) if phrase =~ /^[0-9]+\.$/ - return Chain.new([Chain::Literal.new('Symbol', phrase[1..].to_sym)]) if phrase.start_with?(':') && !phrase.start_with?('::') - return SourceChainer.chain(source, Position.new(position.line, position.character + 1)) if end_of_phrase.strip == '::' && source.code[Position.to_offset(source.code, position)].to_s.match?(/[a-z]/i) + if phrase =~ /^[0-9]+\.$/ + return Chain.new([Chain::Literal.new('Integer', Integer(phrase[0..-2])), + Chain::UNDEFINED_CALL]) + end + if phrase.start_with?(':') && !phrase.start_with?('::') + return Chain.new([Chain::Literal.new('Symbol', + phrase[1..].to_sym)]) + end + if end_of_phrase.strip == '::' && source.code[Position.to_offset( + source.code, position + )].to_s.match?(/[a-z]/i) + return SourceChainer.chain(source, + Position.new(position.line, + position.character + 1)) + end begin return Chain.new([]) if phrase.end_with?('..') node = nil @@ -48,7 +60,12 @@ def chain elsif source.repaired? node = Parser.parse(fixed_phrase) else - node, parent = source.tree_at(fixed_position.line, fixed_position.column)[0..2] unless source.error_ranges.any?{|r| r.nil? || r.include?(fixed_position)} + unless source.error_ranges.any? do |r| + r.nil? || r.include?(fixed_position) + end + node, parent = source.tree_at(fixed_position.line, + fixed_position.column)[0..2] + end # Exception for positions that chain literal nodes in unsynchronized sources node = nil unless source.synchronized? || !Parser.infer_literal_node_type(node).nil? node = Parser.parse(fixed_phrase) if node.nil? @@ -81,12 +98,12 @@ def chain # @return [String] def phrase - @phrase ||= source.code[signature_data..offset-1] + @phrase ||= source.code[signature_data..offset - 1] end # @return [String] def fixed_phrase - @fixed_phrase ||= phrase[0..-(end_of_phrase.length+1)] + @fixed_phrase ||= phrase[0..-(end_of_phrase.length + 1)] end # @return [Position] @@ -137,7 +154,7 @@ def get_signature_data_at index brackets = 0 squares = 0 parens = 0 - index -=1 + index -= 1 in_whitespace = false while index >= 0 pos = Position.from_offset(@source.code, index) @@ -148,18 +165,16 @@ def get_signature_data_at index if brackets.zero? and parens.zero? and squares.zero? and [' ', "\r", "\n", "\t"].include?(char) in_whitespace = true else - if brackets.zero? and parens.zero? and squares.zero? and in_whitespace - unless char == '.' or @source.code[index+1..-1].strip.start_with?('.') - old = @source.code[index+1..-1] - nxt = @source.code[index+1..-1].lstrip - index += (@source.code[index+1..-1].length - @source.code[index+1..-1].lstrip.length) - break - end + if brackets.zero? and parens.zero? and squares.zero? and in_whitespace && !(char == '.' or @source.code[index + 1..-1].strip.start_with?('.')) + @source.code[index + 1..-1] + @source.code[index + 1..-1].lstrip + index += (@source.code[index + 1..-1].length - @source.code[index + 1..-1].lstrip.length) + break end if char == ')' - parens -=1 + parens -= 1 elsif char == ']' - squares -=1 + squares -= 1 elsif char == '}' brackets -= 1 elsif char == '(' @@ -175,9 +190,7 @@ def get_signature_data_at index break if char == '$' if char == '@' index -= 1 - if @source.code[index, 1] == '@' - index -= 1 - end + index -= 1 if @source.code[index, 1] == '@' break end elsif parens == 1 || brackets == 1 || squares == 1 diff --git a/lib/solargraph/source_map.rb b/lib/solargraph/source_map.rb index d7b6fb4fc..815a019d0 100644 --- a/lib/solargraph/source_map.rb +++ b/lib/solargraph/source_map.rb @@ -58,7 +58,9 @@ def pins_by_class klass # # @return [Integer] def api_hash - @api_hash ||= (pins_by_class(Pin::Constant) + pins_by_class(Pin::Namespace).select { |pin| pin.namespace.to_s > '' } + pins_by_class(Pin::Reference) + pins_by_class(Pin::Method).map(&:node) + locals).hash + @api_hash ||= (pins_by_class(Pin::Constant) + pins_by_class(Pin::Namespace).select do |pin| + pin.namespace.to_s > '' + end + pins_by_class(Pin::Reference) + pins_by_class(Pin::Method).map(&:node) + locals).hash end # @return [String] @@ -139,7 +141,7 @@ def references name # @param location [Location] # @return [Array] - def locals_at(location) + def locals_at location return [] if location.filename != filename closure = locate_named_path_pin(location.range.start.line, location.range.start.character) locals.select { |pin| pin.visible_at?(closure, location) } @@ -200,7 +202,9 @@ def _locate_pin line, character, *klasses # @todo Attribute pins should not be treated like closures, but # there's probably a better way to handle it next if pin.is_a?(Pin::Method) && pin.attribute? - found = pin if (klasses.empty? || klasses.any? { |kls| pin.is_a?(kls) } ) && pin.location.range.contain?(position) + found = pin if (klasses.empty? || klasses.any? do |kls| + pin.is_a?(kls) + end) && pin.location.range.contain?(position) break if pin.location.range.start.line > line end # Assuming the root pin is always valid diff --git a/lib/solargraph/source_map/clip.rb b/lib/solargraph/source_map/clip.rb index 3d198ac1e..325c6f380 100644 --- a/lib/solargraph/source_map/clip.rb +++ b/lib/solargraph/source_map/clip.rb @@ -12,7 +12,9 @@ def initialize api_map, cursor @api_map = api_map @cursor = cursor closure_pin = closure - closure_pin.rebind(api_map) if closure_pin.is_a?(Pin::Block) && !Solargraph::Range.from_node(closure_pin.receiver).contain?(cursor.range.start) + if closure_pin.is_a?(Pin::Block) && !Solargraph::Range.from_node(closure_pin.receiver).contain?(cursor.range.start) + closure_pin.rebind(api_map) + end end # @return [Array] Relevant pins for infering the type of the Cursor's position @@ -20,7 +22,11 @@ def define return [] if cursor.comment? || cursor.chain.literal? result = cursor.chain.define(api_map, closure, locals) result.concat file_global_methods - result.concat((source_map.pins + source_map.locals).select{ |p| p.name == cursor.word && p.location.range.contain?(cursor.position) }) if result.empty? + if result.empty? + result.concat((source_map.pins + source_map.locals).select do |p| + p.name == cursor.word && p.location.range.contain?(cursor.position) + end) + end result end @@ -32,7 +38,9 @@ def types # @return [Completion] def complete return package_completions([]) if !source_map.source.parsed? || cursor.string? - return package_completions(api_map.get_symbols) if cursor.chain.literal? && cursor.chain.links.last.word == '' + if cursor.chain.literal? && cursor.chain.links.last.word == '' + return package_completions(api_map.get_symbols) + end return Completion.new([], cursor.range) if cursor.chain.literal? if cursor.comment? tag_complete @@ -125,12 +133,11 @@ def complete_keyword_parameters next unless param.keyword? result.push Pin::KeywordParam.new(pin.location, "#{param.name}:") end - if !pin.parameters.empty? && pin.parameters.last.kwrestarg? - pin.docstring.tags(:param).each do |tag| - next if done.include?(tag.name) - done.push tag.name - result.push Pin::KeywordParam.new(pin.location, "#{tag.name}:") - end + next unless !pin.parameters.empty? && pin.parameters.last.kwrestarg? + pin.docstring.tags(:param).each do |tag| + next if done.include?(tag.name) + done.push tag.name + result.push Pin::KeywordParam.new(pin.location, "#{tag.name}:") end end result @@ -140,17 +147,17 @@ def complete_keyword_parameters # @return [Completion] def package_completions result frag_start = cursor.start_of_word.to_s.downcase - filtered = result.uniq(&:name).select { |s| + filtered = result.uniq(&:name).select do |s| s.name.downcase.start_with?(frag_start) && - (!s.is_a?(Pin::Method) || s.name.match(/^[a-z0-9_]+(\!|\?|=)?$/i)) - } + (!s.is_a?(Pin::Method) || s.name.match(/^[a-z0-9_]+(!|\?|=)?$/i)) + end Completion.new(filtered, cursor.range) end # @return [Completion] def tag_complete result = [] - match = source_map.code[0..cursor.offset-1].match(/[\[<, ]([a-z0-9_:]*)\z/i) + match = source_map.code[0..cursor.offset - 1].match(/[\[<, ]([a-z0-9_:]*)\z/i) if match full = match[1] if full.include?('::') @@ -160,7 +167,7 @@ def tag_complete result.concat api_map.get_constants(full.split('::')[0..-2].join('::'), *gates) end else - result.concat api_map.get_constants('', full.end_with?('::') ? '' : context_pin.full_context.namespace, *gates) #.select { |pin| pin.name.start_with?(full) } + result.concat api_map.get_constants('', full.end_with?('::') ? '' : context_pin.full_context.namespace, *gates) # .select { |pin| pin.name.start_with?(full) } end end package_completions(result) @@ -173,24 +180,23 @@ def code_complete if cursor.chain.constant? || cursor.start_of_constant? full = cursor.chain.links.first.word type = if cursor.chain.undefined? - cursor.chain.base.infer(api_map, context_pin, locals) - else - if full.include?('::') && cursor.chain.links.length == 1 - ComplexType.try_parse(full.split('::')[0..-2].join('::')) - elsif cursor.chain.links.length > 1 - ComplexType.try_parse(full) - else - ComplexType::UNDEFINED - end - end + cursor.chain.base.infer(api_map, context_pin, locals) + elsif full.include?('::') && cursor.chain.links.length == 1 + ComplexType.try_parse(full.split('::')[0..-2].join('::')) + elsif cursor.chain.links.length > 1 + ComplexType.try_parse(full) + else + ComplexType::UNDEFINED + end if type.undefined? if full.include?('::') result.concat api_map.get_constants(full, *gates) else - result.concat api_map.get_constants('', cursor.start_of_constant? ? '' : context_pin.full_context.namespace, *gates) #.select { |pin| pin.name.start_with?(full) } + result.concat api_map.get_constants('', cursor.start_of_constant? ? '' : context_pin.full_context.namespace, *gates) # .select { |pin| pin.name.start_with?(full) } end else - result.concat api_map.get_constants(type.namespace, cursor.start_of_constant? ? '' : context_pin.full_context.namespace, *gates) + result.concat api_map.get_constants(type.namespace, + cursor.start_of_constant? ? '' : context_pin.full_context.namespace, *gates) end else type = cursor.chain.base.infer(api_map, closure, locals) @@ -199,14 +205,16 @@ def code_complete if cursor.word.start_with?('@@') return package_completions(api_map.get_class_variable_pins(context_pin.full_context.namespace)) elsif cursor.word.start_with?('@') - return package_completions(api_map.get_instance_variable_pins(closure.binder.namespace, closure.binder.scope)) + return package_completions(api_map.get_instance_variable_pins(closure.binder.namespace, + closure.binder.scope)) elsif cursor.word.start_with?('$') return package_completions(api_map.get_global_variable_pins) end result.concat locals result.concat file_global_methods unless closure.binder.namespace.empty? result.concat api_map.get_constants(context_pin.context.namespace, *gates) - result.concat api_map.get_methods(closure.binder.namespace, scope: closure.binder.scope, visibility: [:public, :private, :protected]) + result.concat api_map.get_methods(closure.binder.namespace, scope: closure.binder.scope, + visibility: %i[public private protected]) result.concat api_map.get_methods('Kernel') result.concat api_map.keyword_pins.to_a end diff --git a/lib/solargraph/source_map/mapper.rb b/lib/solargraph/source_map/mapper.rb index 18fdf1f88..1e29cadcb 100644 --- a/lib/solargraph/source_map/mapper.rb +++ b/lib/solargraph/source_map/mapper.rb @@ -12,7 +12,7 @@ class Mapper private_class_method :new - DIRECTIVE_REGEXP = /(@\!method|@\!attribute|@\!visibility|@\!domain|@\!macro|@\!parse|@\!override)/.freeze + DIRECTIVE_REGEXP = /(@!method|@!attribute|@!visibility|@!domain|@!macro|@!parse|@!override)/ # Generate the data. # @@ -28,10 +28,10 @@ def map source @locals.each { |l| l.source = :code } process_comment_directives [@pins, @locals] - # rescue Exception => e - # Solargraph.logger.warn "Error mapping #{source.filename}: [#{e.class}] #{e.message}" - # Solargraph.logger.warn e.backtrace.join("\n") - # [[], []] + # rescue Exception => e + # Solargraph.logger.warn "Error mapping #{source.filename}: [#{e.class}] #{e.message}" + # Solargraph.logger.warn e.backtrace.join("\n") + # [[], []] end # @param filename [String] @@ -61,8 +61,8 @@ def pins # @param position [Solargraph::Position] # @return [Solargraph::Pin::Closure] - def closure_at(position) - pins.select{|pin| pin.is_a?(Pin::Closure) and pin.location.range.contain?(position)}.last + def closure_at position + pins.select { |pin| pin.is_a?(Pin::Closure) and pin.location.range.contain?(position) }.last end # @param source_position [Position] @@ -109,9 +109,7 @@ def process_directive source_position, comment_position, directive case directive.tag.tag_name when 'method' namespace = closure_at(source_position) || @pins.first - if namespace.location.range.start.line < comment_position.line - namespace = closure_at(comment_position) - end + namespace = closure_at(comment_position) if namespace.location.range.start.line < comment_position.line begin src = Solargraph::Source.load_string("def #{directive.tag.name};end", @source.filename) region = Parser::Region.new(source: src, closure: namespace) @@ -120,19 +118,20 @@ def process_directive source_position, comment_position, directive return if gen_pin.nil? # Move the location to the end of the line so it gets recognized # as originating from a comment - shifted = Solargraph::Position.new(comment_position.line, @code.lines[comment_position.line].to_s.chomp.length) + shifted = Solargraph::Position.new(comment_position.line, + @code.lines[comment_position.line].to_s.chomp.length) # @todo: Smelly instance variable access gen_pin.instance_variable_set(:@comments, docstring.all.to_s) gen_pin.instance_variable_set(:@location, Solargraph::Location.new(@filename, Range.new(shifted, shifted))) gen_pin.instance_variable_set(:@explicit, false) @pins.push gen_pin - rescue Parser::SyntaxError => e + rescue Parser::SyntaxError # @todo Handle error in directive end when 'attribute' return if directive.tag.name.nil? namespace = closure_at(source_position) - t = (directive.tag.types.nil? || directive.tag.types.empty?) ? nil : directive.tag.types.flatten.join('') + t = directive.tag.types.nil? || directive.tag.types.empty? ? nil : directive.tag.types.flatten.join('') if t.nil? || t.include?('r') pins.push Solargraph::Pin::Method.new( location: location, @@ -158,31 +157,33 @@ def process_directive source_position, comment_position, directive source: :source_map ) pins.push method_pin - method_pin.parameters.push Pin::Parameter.new(name: 'value', decl: :arg, closure: pins.last, source: :source_map) + method_pin.parameters.push Pin::Parameter.new(name: 'value', decl: :arg, closure: pins.last, + source: :source_map) if pins.last.return_type.defined? - pins.last.docstring.add_tag YARD::Tags::Tag.new(:param, '', pins.last.return_type.to_s.split(', '), 'value') + pins.last.docstring.add_tag YARD::Tags::Tag.new(:param, '', pins.last.return_type.to_s.split(', '), + 'value') end end when 'visibility' - kind = directive.tag.text&.to_sym - return unless [:private, :protected, :public].include?(kind) + kind = directive.tag.text&.to_sym + return unless %i[private protected public].include?(kind) - name = directive.tag.name - closure = closure_at(source_position) || @pins.first - if closure.location.range.start.line < comment_position.line - closure = closure_at(comment_position) + name = directive.tag.name + closure = closure_at(source_position) || @pins.first + closure = closure_at(comment_position) if closure.location.range.start.line < comment_position.line + if closure.is_a?(Pin::Method) && no_empty_lines?(comment_position.line, source_position.line) + # @todo Smelly instance variable access + closure.instance_variable_set(:@visibility, kind) + else + matches = pins.select do |pin| + pin.is_a?(Pin::Method) && pin.name == name && pin.namespace == namespace && pin.context.scope == namespace.is_a?(Pin::Singleton) ? :class : :instance end - if closure.is_a?(Pin::Method) && no_empty_lines?(comment_position.line, source_position.line) + matches.each do |pin| # @todo Smelly instance variable access - closure.instance_variable_set(:@visibility, kind) - else - matches = pins.select{ |pin| pin.is_a?(Pin::Method) && pin.name == name && pin.namespace == namespace && pin.context.scope == namespace.is_a?(Pin::Singleton) ? :class : :instance } - matches.each do |pin| - # @todo Smelly instance variable access - pin.instance_variable_set(:@visibility, kind) - end + pin.instance_variable_set(:@visibility, kind) end + end when 'parse' begin @@ -192,17 +193,17 @@ def process_directive source_position, comment_position, directive # @todo These pins may need to be marked not explicit index = @pins.length loff = if @code.lines[comment_position.line].strip.end_with?('@!parse') - comment_position.line + 1 - else - comment_position.line - end + comment_position.line + 1 + else + comment_position.line + end Parser.process_node(src.node, region, @pins) @pins[index..-1].each do |p| # @todo Smelly instance variable access p.location.range.start.instance_variable_set(:@line, p.location.range.start.line + loff) p.location.range.ending.instance_variable_set(:@line, p.location.range.ending.line + loff) end - rescue Parser::SyntaxError => e + rescue Parser::SyntaxError # @todo Handle parser errors in !parse directives end when 'domain' @@ -218,7 +219,7 @@ def process_directive source_position, comment_position, directive # @param line1 [Integer] # @param line2 [Integer] - def no_empty_lines?(line1, line2) + def no_empty_lines? line1, line2 @code.lines[line1..line2].none? { |line| line.strip.empty? } end @@ -228,7 +229,7 @@ def remove_inline_comment_hashes comment ctxt = '' num = nil started = false - comment.lines.each { |l| + comment.lines.each do |l| # Trim the comment and minimum leading whitespace p = l.encode('UTF-8', invalid: :replace, replace: '?').gsub(/^#+/, '') if num.nil? && !p.strip.empty? @@ -239,7 +240,7 @@ def remove_inline_comment_hashes comment num = cur if cur < num end ctxt += "#{p[num..-1]}" if started - } + end ctxt end @@ -249,7 +250,14 @@ def process_comment_directives return unless @code.encode('UTF-8', invalid: :replace, replace: '?') =~ DIRECTIVE_REGEXP code_lines = @code.lines @source.associated_comments.each do |line, comments| - src_pos = line ? Position.new(line, code_lines[line].to_s.chomp.index(/[^\s]/) || 0) : Position.new(code_lines.length, 0) + src_pos = if line + Position.new(line, + code_lines[line].to_s.chomp.index(/[^\s]/) || 0) + else + Position.new( + code_lines.length, 0 + ) + end com_pos = Position.new(line + 1 - comments.lines.length, 0) process_comment(src_pos, com_pos, comments) end diff --git a/lib/solargraph/type_checker.rb b/lib/solargraph/type_checker.rb index 4600767b5..71343b697 100644 --- a/lib/solargraph/type_checker.rb +++ b/lib/solargraph/type_checker.rb @@ -46,12 +46,12 @@ def source # @return [Array] def problems @problems ||= begin - all = method_tag_problems - .concat(variable_type_tag_problems) - .concat(const_problems) - .concat(call_problems) - unignored = without_ignored(all) - unignored.concat(unneeded_sgignore_problems) + all = method_tag_problems + .concat(variable_type_tag_problems) + .concat(const_problems) + .concat(call_problems) + unignored = without_ignored(all) + unignored.concat(unneeded_sgignore_problems) end end @@ -101,7 +101,10 @@ def method_return_type_problems_for pin if pin.return_type.undefined? && rules.require_type_tags? if pin.attribute? inferred = pin.probe(api_map).self_to_type(pin.full_context) - result.push Problem.new(pin.location, "Missing @return tag for #{pin.path}", pin: pin) unless inferred.defined? + unless inferred.defined? + result.push Problem.new(pin.location, "Missing @return tag for #{pin.path}", + pin: pin) + end else result.push Problem.new(pin.location, "Missing @return tag for #{pin.path}", pin: pin) end @@ -118,8 +121,16 @@ def method_return_type_problems_for pin result.push Problem.new(pin.location, "#{pin.path} return type could not be inferred", pin: pin) end else - unless (rules.require_all_return_types_match_inferred? ? all_types_match?(api_map, inferred, declared) : any_types_match?(api_map, declared, inferred)) - result.push Problem.new(pin.location, "Declared return type #{declared.rooted_tags} does not match inferred type #{inferred.rooted_tags} for #{pin.path}", pin: pin) + unless if rules.require_all_return_types_match_inferred? + all_types_match?(api_map, inferred, + declared) + else + any_types_match?( + api_map, declared, inferred + ) + end + result.push Problem.new(pin.location, + "Declared return type #{declared.rooted_tags} does not match inferred type #{inferred.rooted_tags} for #{pin.path}", pin: pin) end end end @@ -135,7 +146,7 @@ def method_return_type_problems_for pin def resolved_constant? pin return true if pin.typify(api_map).defined? constant_pins = api_map.get_constants('', *pin.closure.gates) - .select { |p| p.name == pin.return_type.namespace } + .select { |p| p.name == pin.return_type.namespace } return true if constant_pins.find { |p| p.typify(api_map).defined? } # will need to probe when a constant name is assigned to a # class/module (alias) @@ -156,19 +167,19 @@ def method_param_type_problems_for pin pin.signatures.each do |sig| params = param_details_from_stack(sig, stack) if rules.require_type_tags? - sig.parameters.each do |par| - break if par.decl == :restarg || par.decl == :kwrestarg || par.decl == :blockarg - unless params[par.name] - if pin.attribute? - inferred = pin.probe(api_map).self_to_type(pin.full_context) - if inferred.undefined? - result.push Problem.new(pin.location, "Missing @param tag for #{par.name} on #{pin.path}", pin: pin) - end - else + sig.parameters.each do |par| + break if %i[restarg kwrestarg blockarg].include?(par.decl) + unless params[par.name] + if pin.attribute? + inferred = pin.probe(api_map).self_to_type(pin.full_context) + if inferred.undefined? result.push Problem.new(pin.location, "Missing @param tag for #{par.name} on #{pin.path}", pin: pin) end + else + result.push Problem.new(pin.location, "Missing @param tag for #{par.name} on #{pin.path}", pin: pin) end end + end end # @param name [String] # @param data [Hash{Symbol => BasicObject}] @@ -176,7 +187,8 @@ def method_param_type_problems_for pin # @type [ComplexType] type = data[:qualified] if type.undefined? - result.push Problem.new(pin.location, "Unresolved type #{data[:tagged]} for #{name} param on #{pin.path}", pin: pin) + result.push Problem.new(pin.location, "Unresolved type #{data[:tagged]} for #{name} param on #{pin.path}", + pin: pin) end end end @@ -207,20 +219,20 @@ def variable_type_tag_problems end else unless any_types_match?(api_map, declared, inferred) - result.push Problem.new(pin.location, "Declared type #{declared} does not match inferred type #{inferred} for variable #{pin.name}", pin: pin) + result.push Problem.new(pin.location, + "Declared type #{declared} does not match inferred type #{inferred} for variable #{pin.name}", pin: pin) end end elsif declared_externally?(pin) ignored_pins.push pin end elsif !pin.is_a?(Pin::Parameter) && !resolved_constant?(pin) - result.push Problem.new(pin.location, "Unresolved type #{pin.return_type} for variable #{pin.name}", pin: pin) + result.push Problem.new(pin.location, "Unresolved type #{pin.return_type} for variable #{pin.name}", + pin: pin) end else inferred = pin.probe(api_map) - if inferred.undefined? && declared_externally?(pin) - ignored_pins.push pin - end + ignored_pins.push pin if inferred.undefined? && declared_externally?(pin) end end result @@ -259,7 +271,6 @@ def call_problems next if @marked_ranges.any? { |d| d.contain?(rng.start) } chain = Solargraph::Parser.chain(call, filename) closure_pin = source_map.locate_closure_pin(rng.start.line, rng.start.column) - namespace_pin = closure_pin if call.type == :block # blocks in the AST include the method call as well, so the # node returned by #call_nodes_from needs to be backed out @@ -283,15 +294,13 @@ def call_problems end closest = found.typify(api_map) if found # @todo remove the internal_or_core? check at a higher-than-strict level - if !found || found.is_a?(Pin::BaseVariable) || (closest.defined? && internal_or_core?(found)) - unless closest.generic? || ignored_pins.include?(found) - if closest.defined? - result.push Problem.new(location, "Unresolved call to #{missing.links.last.word} on #{closest}") - else - result.push Problem.new(location, "Unresolved call to #{missing.links.last.word}") - end - @marked_ranges.push rng + if (!found || found.is_a?(Pin::BaseVariable) || (closest.defined? && internal_or_core?(found))) && !(closest.generic? || ignored_pins.include?(found)) + if closest.defined? + result.push Problem.new(location, "Unresolved call to #{missing.links.last.word} on #{closest}") + else + result.push Problem.new(location, "Unresolved call to #{missing.links.last.word}") end + @marked_ranges.push rng end end result.concat argument_problems_for(chain, api_map, closure_pin, locals, location) @@ -373,7 +382,7 @@ def signature_argument_problems_for location, locals, closure_pin, params, argum # when possible, and when not, ensure provably # incorrect situations are detected. sig.parameters.each_with_index do |par, idx| - return errors if par.decl == :restarg # bail out and assume the rest is valid pending better arg processing + return errors if par.decl == :restarg # bail out and assume the rest is valid pending better arg processing argchain = arguments[idx] if argchain.nil? if par.decl == :arg @@ -386,18 +395,13 @@ def signature_argument_problems_for location, locals, closure_pin, params, argum end else final_arg = arguments.last - argchain = final_arg if final_arg && [:kwsplat, :hash].include?(final_arg.node.type) + argchain = final_arg if final_arg && %i[kwsplat hash].include?(final_arg.node.type) end end if argchain - if par.decl != :arg - errors.concat kwarg_problems_for sig, argchain, api_map, closure_pin, locals, location, pin, params, idx - next - else - if argchain.node.type == :splat && argchain == arguments.last - final_arg = argchain - end - if (final_arg && final_arg.node.type == :splat) + if par.decl == :arg + final_arg = argchain if argchain.node.type == :splat && argchain == arguments.last + if final_arg && final_arg.node.type == :splat # The final argument given has been seen and was a # splat, which doesn't give us useful types or # arities against positional parameters, so let's @@ -421,10 +425,14 @@ def signature_argument_problems_for location, locals, closure_pin, params, argum else argtype = argchain.infer(api_map, closure_pin, locals) if argtype.defined? && ptype.defined? && !any_types_match?(api_map, ptype, argtype) - errors.push Problem.new(location, "Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}") + errors.push Problem.new(location, + "Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}") return errors end end + else + errors.concat kwarg_problems_for sig, argchain, api_map, closure_pin, locals, location, pin, params, idx + next end elsif par.decl == :kwarg errors.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}") @@ -452,23 +460,22 @@ def kwarg_problems_for sig, argchain, api_map, closure_pin, locals, location, pi argchain = kwargs[par.name.to_sym] if par.decl == :kwrestarg || (par.decl == :optarg && idx == pin.parameters.length - 1 && par.asgn_code == '{}') result.concat kwrestarg_problems_for(api_map, closure_pin, locals, location, pin, params, kwargs) - else - if argchain - data = params[par.name] - if data.nil? - # @todo Some level (strong, I guess) should require the param here - else - ptype = data[:qualified] - unless ptype.undefined? - argtype = argchain.infer(api_map, closure_pin, locals) - if argtype.defined? && ptype && !any_types_match?(api_map, ptype, argtype) - result.push Problem.new(location, "Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}") - end + elsif argchain + data = params[par.name] + if data.nil? + # @todo Some level (strong, I guess) should require the param here + else + ptype = data[:qualified] + unless ptype.undefined? + argtype = argchain.infer(api_map, closure_pin, locals) + if argtype.defined? && ptype && !any_types_match?(api_map, ptype, argtype) + result.push Problem.new(location, + "Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}") end end - elsif par.decl == :kwarg - result.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}") end + elsif par.decl == :kwarg + result.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}") end result end @@ -481,14 +488,15 @@ def kwarg_problems_for sig, argchain, api_map, closure_pin, locals, location, pi # @param params [Hash{String => [nil, Hash]}] # @param kwargs [Hash{Symbol => Source::Chain}] # @return [Array] - def kwrestarg_problems_for(api_map, closure_pin, locals, location, pin, params, kwargs) + def kwrestarg_problems_for api_map, closure_pin, locals, location, pin, params, kwargs result = [] kwargs.each_pair do |pname, argchain| next unless params.key?(pname.to_s) ptype = params[pname.to_s][:qualified] argtype = argchain.infer(api_map, closure_pin, locals) if argtype.defined? && ptype && !any_types_match?(api_map, ptype, argtype) - result.push Problem.new(location, "Wrong argument type for #{pin.path}: #{pname} expected #{ptype}, received #{argtype}") + result.push Problem.new(location, + "Wrong argument type for #{pin.path}: #{pname} expected #{ptype}, received #{argtype}") end end result @@ -498,7 +506,7 @@ def kwrestarg_problems_for(api_map, closure_pin, locals, location, pin, params, # @param pin [Pin::Method, Pin::Signature] # @param relevant_pin [Pin::Method, Pin::Signature] the pin which is under inspection # @return [void] - def add_restkwarg_param_tag_details(param_details, pin, relevant_pin) + def add_restkwarg_param_tag_details param_details, pin, relevant_pin # see if we have additional tags to pay attention to from YARD - # e.g., kwargs in a **restkwargs splat tags = pin.docstring.tags(:param) @@ -519,7 +527,7 @@ def add_restkwarg_param_tag_details(param_details, pin, relevant_pin) # @param pin [Pin::Signature] # @return [Hash{String => Hash{Symbol => String, ComplexType}}] - def signature_param_details(pin) + def signature_param_details pin # @type [Hash{String => Hash{Symbol => String, ComplexType}}] result = {} pin.parameters.each do |param| @@ -552,7 +560,7 @@ def signature_param_details(pin) # @param new_param_details [Hash{String => Hash{Symbol => String, ComplexType}}] # # @return [void] - def add_to_param_details(param_details, param_names, new_param_details) + def add_to_param_details param_details, param_names, new_param_details new_param_details.each do |param_name, details| next unless param_names.include?(param_name) @@ -565,7 +573,7 @@ def add_to_param_details(param_details, param_names, new_param_details) # @param signature [Pin::Signature] # @param method_pin_stack [Array] # @return [Hash{String => Hash{Symbol => String, ComplexType}}] - def param_details_from_stack(signature, method_pin_stack) + def param_details_from_stack signature, method_pin_stack signature_type = signature.typify(api_map) signature = signature.proxy signature_type param_details = signature_param_details(signature) @@ -613,19 +621,15 @@ def declared_externally? pin type = chain.infer(api_map, closure_pin, locals) if type.undefined? && !rules.ignore_all_undefined? base = chain - missing = chain found = nil closest = ComplexType::UNDEFINED until base.links.first.undefined? found = base.define(api_map, closure_pin, locals).first break if found - missing = base base = base.base end closest = found.typify(api_map) if found - if !found || closest.defined? || internal?(found) - return false - end + return false if !found || closest.defined? || internal?(found) end true end @@ -648,7 +652,7 @@ def arity_problems_for pin, arguments, location # @param arguments [Array] # @param location [Location] # @return [Array] - def parameterized_arity_problems_for(pin, parameters, arguments, location) + def parameterized_arity_problems_for pin, parameters, arguments, location return [] unless pin.explicit? return [] if parameters.empty? && arguments.empty? return [] if pin.anon_splat? @@ -663,7 +667,7 @@ def parameterized_arity_problems_for(pin, parameters, arguments, location) settled_kwargs = parameters.count(&:keyword?) else kwargs = convert_hash(unchecked.last.node) - if parameters.any? { |param| [:kwarg, :kwoptarg].include?(param.decl) || param.kwrestarg? } + if parameters.any? { |param| %i[kwarg kwoptarg].include?(param.decl) || param.kwrestarg? } if kwargs.empty? add_params += 1 else @@ -692,10 +696,12 @@ def parameterized_arity_problems_for(pin, parameters, arguments, location) return [] if parameters.any?(&:rest?) opt = optional_param_count(parameters) return [] if unchecked.length <= req + opt - if req + add_params + 1 == unchecked.length && any_splatted_call?(unchecked.map(&:node)) && (parameters.map(&:decl) & [:kwarg, :kwoptarg, :kwrestarg]).any? + if req + add_params + 1 == unchecked.length && any_splatted_call?(unchecked.map(&:node)) && (parameters.map(&:decl) & %i[ + kwarg kwoptarg kwrestarg + ]).any? return [] end - return [] if arguments.length - req == parameters.select { |p| [:optarg, :kwoptarg].include?(p.decl) }.length + return [] if arguments.length - req == parameters.select { |p| %i[optarg kwoptarg].include?(p.decl) }.length return [Problem.new(location, "Too many arguments to #{pin.path}")] elsif unchecked.length < req - settled_kwargs && (arguments.empty? || (!arguments.last.splat? && !arguments.last.links.last.is_a?(Solargraph::Source::Chain::Hash))) # HACK: Kernel#raise signature is incorrect in Ruby 2.7 core docs. @@ -711,14 +717,14 @@ def parameterized_arity_problems_for(pin, parameters, arguments, location) # @todo need to use generic types in method to choose correct # signature and generate Integer as return type # @return [Integer] - def required_param_count(parameters) + def required_param_count parameters parameters.sum { |param| %i[arg kwarg].include?(param.decl) ? 1 : 0 } end # @param parameters [Enumerable] # @param pin [Pin::Method] # @return [Integer] - def optional_param_count(parameters) + def optional_param_count parameters parameters.select { |p| p.decl == :optarg }.length end @@ -730,12 +736,12 @@ def abstract? pin # @param pin [Pin::Method] # @return [Array] - def fake_args_for(pin) + def fake_args_for pin args = [] with_opts = false with_block = false pin.parameters.each do |pin| - if [:kwarg, :kwoptarg, :kwrestarg].include?(pin.decl) + if %i[kwarg kwoptarg kwrestarg].include?(pin.decl) with_opts = true elsif pin.decl == :block with_block = true diff --git a/lib/solargraph/type_checker/checks.rb b/lib/solargraph/type_checker/checks.rb index de402978b..664c023b3 100644 --- a/lib/solargraph/type_checker/checks.rb +++ b/lib/solargraph/type_checker/checks.rb @@ -22,11 +22,10 @@ def types_match? api_map, expected, inferred found = false inferred.each do |inf| # if api_map.super_and_sub?(fuzz(inf), fuzz(exp)) - if either_way?(api_map, inf, exp) - found = true - matches.push inf - break - end + next unless either_way?(api_map, inf, exp) + found = true + matches.push inf + break end return false unless found end @@ -111,7 +110,7 @@ def fuzz type # @param cls1 [ComplexType::UniqueType] # @param cls2 [ComplexType::UniqueType] # @return [Boolean] - def either_way?(api_map, cls1, cls2) + def either_way? api_map, cls1, cls2 # @todo there should be a level of typechecking which uses the # full tag with parameters to determine compatibility f1 = cls1.name diff --git a/lib/solargraph/type_checker/rules.rb b/lib/solargraph/type_checker/rules.rb index a27fcbefa..7fa7aff3f 100644 --- a/lib/solargraph/type_checker/rules.rb +++ b/lib/solargraph/type_checker/rules.rb @@ -22,11 +22,11 @@ class Rules # @param level [Symbol] def initialize level @rank = if LEVELS.key?(level) - LEVELS[level] - else - Solargraph.logger.warn "Unrecognized TypeChecker level #{level}, assuming normal" - 0 - end + LEVELS[level] + else + Solargraph.logger.warn "Unrecognized TypeChecker level #{level}, assuming normal" + 0 + end @level = LEVELS[LEVELS.values.index(@rank)] end diff --git a/lib/solargraph/workspace.rb b/lib/solargraph/workspace.rb index 07cf26f09..a8176b33f 100644 --- a/lib/solargraph/workspace.rb +++ b/lib/solargraph/workspace.rb @@ -58,7 +58,7 @@ def merge *sources includes_any = false sources.each do |source| - if directory == "*" || config.calculated.include?(source.filename) + if directory == '*' || config.calculated.include?(source.filename) source_hash[source.filename] = source includes_any = true end @@ -109,7 +109,7 @@ def source filename def would_require? path require_paths.each do |rp| full = File.join rp, path - return true if File.file?(full) || File.file?(full << ".rb") + return true if File.file?(full) || File.file?(full << '.rb') end false end @@ -121,12 +121,10 @@ def rbs_collection_path # @return [String, nil] def rbs_collection_config_path - @rbs_collection_config_path ||= begin - unless directory.empty? || directory == '*' - yaml_file = File.join(directory, 'rbs_collection.yaml') - yaml_file if File.file?(yaml_file) - end - end + @rbs_collection_config_path ||= unless directory.empty? || directory == '*' + yaml_file = File.join(directory, 'rbs_collection.yaml') + yaml_file if File.file?(yaml_file) + end end # Synchronize the workspace from the provided updater. @@ -172,27 +170,25 @@ def source_hash # @return [void] def load_sources source_hash.clear - unless directory.empty? || directory == '*' - size = config.calculated.length - raise WorkspaceTooLargeError, "The workspace is too large to index (#{size} files, #{config.max_files} max)" if config.max_files > 0 and size > config.max_files - config.calculated.each do |filename| - begin - source_hash[filename] = Solargraph::Source.load(filename) - rescue Errno::ENOENT => e - Solargraph.logger.warn("Error loading #{filename}: [#{e.class}] #{e.message}") - end - end + return if directory.empty? || directory == '*' + size = config.calculated.length + if config.max_files > 0 and size > config.max_files + raise WorkspaceTooLargeError, + "The workspace is too large to index (#{size} files, #{config.max_files} max)" + end + config.calculated.each do |filename| + source_hash[filename] = Solargraph::Source.load(filename) + rescue Errno::ENOENT => e + Solargraph.logger.warn("Error loading #{filename}: [#{e.class}] #{e.message}") end end # @return [void] def require_plugins config.plugins.each do |plugin| - begin - require plugin - rescue LoadError - Solargraph.logger.warn "Failed to load plugin '#{plugin}'" - end + require plugin + rescue LoadError + Solargraph.logger.warn "Failed to load plugin '#{plugin}'" end end diff --git a/lib/solargraph/workspace/config.rb b/lib/solargraph/workspace/config.rb index d1e6c27b5..ea72dd9f4 100644 --- a/lib/solargraph/workspace/config.rb +++ b/lib/solargraph/workspace/config.rb @@ -54,7 +54,9 @@ def allow? filename # # @return [Array] def calculated - Solargraph.logger.info "Indexing workspace files in #{directory}" unless @calculated || directory.empty? || directory == '*' + unless @calculated || directory.empty? || directory == '*' + Solargraph.logger.info "Indexing workspace files in #{directory}" + end @calculated ||= included - excluded end @@ -129,7 +131,7 @@ def config_data global_config = read_config(global_config_path) defaults = default_config - defaults.merge({'exclude' => []}) unless workspace_config.nil? + defaults.merge({ 'exclude' => [] }) unless workspace_config.nil? defaults .merge(global_config || {}) @@ -143,7 +145,7 @@ def config_data def read_config config_path = '' return nil if config_path.empty? return nil unless File.file?(config_path) - YAML.safe_load(File.read(config_path)) + YAML.safe_load_file(config_path) end # @return [Hash{String => Array, Hash, Integer}] @@ -159,7 +161,7 @@ def default_config 'cops' => 'safe', 'except' => [], 'only' => [], - 'extra_args' =>[] + 'extra_args' => [] } }, 'require_paths' => [], @@ -173,12 +175,11 @@ def default_config # @param globs [Array] # @return [Array] def process_globs globs - result = globs.flat_map do |glob| + globs.flat_map do |glob| Dir[File.absolute_path(glob, directory)] - .map{ |f| f.gsub(/\\/, '/') } + .map { |f| f.gsub('\\', '/') } .select { |f| File.file?(f) } end - result end # Modify the included files based on excluded directories and get an @@ -221,7 +222,7 @@ def glob_is_directory? glob # @param glob [String] # @return [String] def glob_to_directory glob - glob.gsub(/(\/\*|\/\*\*\/\*\*?)$/, '') + glob.gsub(%r{(/\*|/\*\*/\*\*?)$}, '') end # @return [Array] diff --git a/lib/solargraph/yard_map/helpers.rb b/lib/solargraph/yard_map/helpers.rb index 96bc454b5..a94f80327 100644 --- a/lib/solargraph/yard_map/helpers.rb +++ b/lib/solargraph/yard_map/helpers.rb @@ -21,10 +21,12 @@ def object_location code_object, spec # @param code_object [YARD::CodeObjects::Base] # @param spec [Gem::Specification, nil] # @return [Solargraph::Pin::Namespace] - def create_closure_namespace_for(code_object, spec) + def create_closure_namespace_for code_object, spec code_object_for_location = code_object # code_object.namespace is sometimes a YARD proxy object pointing to a method path ("Object#new") - code_object_for_location = code_object.namespace if code_object.namespace.is_a?(YARD::CodeObjects::NamespaceObject) + if code_object.namespace.is_a?(YARD::CodeObjects::NamespaceObject) + code_object_for_location = code_object.namespace + end namespace_location = object_location(code_object_for_location, spec) ns_name = code_object.namespace.to_s if ns_name.empty? diff --git a/lib/solargraph/yard_map/mapper.rb b/lib/solargraph/yard_map/mapper.rb index 592b3805e..3d48e7ae1 100644 --- a/lib/solargraph/yard_map/mapper.rb +++ b/lib/solargraph/yard_map/mapper.rb @@ -43,10 +43,10 @@ def generate_pins code_object # the superclass is a Proxy, it is assumed to be undefined in its # yardoc and converted to a fully qualified namespace. superclass = if code_object.superclass.is_a?(YARD::CodeObjects::Proxy) - "::#{code_object.superclass}" - else - code_object.superclass.to_s - end + "::#{code_object.superclass}" + else + code_object.superclass.to_s + end result.push Solargraph::Pin::Reference::Superclass.new(name: superclass, closure: nspin, source: :yard_map) end code_object.class_mixins.each do |m| diff --git a/lib/solargraph/yard_map/mapper/to_method.rb b/lib/solargraph/yard_map/mapper/to_method.rb index d8e3b8b43..a9b3247f6 100644 --- a/lib/solargraph/yard_map/mapper/to_method.rb +++ b/lib/solargraph/yard_map/mapper/to_method.rb @@ -8,7 +8,7 @@ module ToMethod VISIBILITY_OVERRIDE = { # YARD pays attention to 'private' statements prior to class methods but shouldn't - ["Rails::Engine", :class, "find_root_with_flag"] => :public + ['Rails::Engine', :class, 'find_root_with_flag'] => :public } # @param code_object [YARD::CodeObjects::Base] @@ -28,7 +28,9 @@ def self.make code_object, name = nil, scope = nil, visibility = nil, closure = override_key = [closure.path, final_scope, name] final_visibility = VISIBILITY_OVERRIDE[override_key] final_visibility ||= VISIBILITY_OVERRIDE[[closure.path, final_scope]] - final_visibility ||= :private if closure.path == 'Kernel' && Kernel.private_instance_methods(false).include?(name.to_sym) + if closure.path == 'Kernel' && Kernel.private_instance_methods(false).include?(name.to_sym) + final_visibility ||= :private + end final_visibility ||= visibility final_visibility ||= :private if code_object.module_function? && final_scope == :instance final_visibility ||= :public if code_object.module_function? && final_scope == :class @@ -46,7 +48,7 @@ def self.make code_object, name = nil, scope = nil, visibility = nil, closure = explicit: code_object.is_explicit?, return_type: return_type, parameters: [], - source: :yardoc, + source: :yardoc ) else pin = Pin::Method.new( @@ -61,7 +63,7 @@ def self.make code_object, name = nil, scope = nil, visibility = nil, closure = return_type: return_type, attribute: code_object.is_attribute?, parameters: [], - source: :yardoc, + source: :yardoc ) pin.parameters.concat get_parameters(code_object, location, comments, pin) pin.parameters.freeze @@ -94,7 +96,7 @@ def get_parameters code_object, location, comments, pin presence: nil, decl: arg_type(a), asgn_code: a[1], - source: :yardoc, + source: :yardoc ) end end diff --git a/lib/solargraph/yard_map/mapper/to_namespace.rb b/lib/solargraph/yard_map/mapper/to_namespace.rb index f7063e3d6..e1c9215d6 100644 --- a/lib/solargraph/yard_map/mapper/to_namespace.rb +++ b/lib/solargraph/yard_map/mapper/to_namespace.rb @@ -22,7 +22,7 @@ def self.make code_object, spec, closure = nil visibility: code_object.visibility, closure: closure, gates: closure.gates, - source: :yardoc, + source: :yardoc ) end end diff --git a/lib/solargraph/yard_tags.rb b/lib/solargraph/yard_tags.rb index c34710b63..462138f9c 100644 --- a/lib/solargraph/yard_tags.rb +++ b/lib/solargraph/yard_tags.rb @@ -14,7 +14,7 @@ def call; end end # Define a @type tag for documenting variables -YARD::Tags::Library.define_tag("Type", :type, :with_types_and_name) +YARD::Tags::Library.define_tag('Type', :type, :with_types_and_name) # Define an @!override directive for overriding method tags -YARD::Tags::Library.define_directive("override", :with_name, Solargraph::DomainDirective) +YARD::Tags::Library.define_directive('override', :with_name, Solargraph::DomainDirective) diff --git a/lib/solargraph/yardoc.rb b/lib/solargraph/yardoc.rb index 2d709f778..2e0c20cf6 100644 --- a/lib/solargraph/yardoc.rb +++ b/lib/solargraph/yardoc.rb @@ -14,7 +14,7 @@ module Yardoc # @param yard_plugins [Array] The names of YARD plugins to use. # @param gemspec [Gem::Specification] # @return [String] The path to the cached yardoc. - def cache(yard_plugins, gemspec) + def cache yard_plugins, gemspec path = PinCache.yardoc_path gemspec return path if cached?(gemspec) @@ -34,7 +34,7 @@ def cache(yard_plugins, gemspec) # True if the gem yardoc is cached. # # @param gemspec [Gem::Specification] - def cached?(gemspec) + def cached? gemspec yardoc = File.join(PinCache.yardoc_path(gemspec), 'complete') File.exist?(yardoc) end @@ -42,7 +42,7 @@ def cached?(gemspec) # True if another process is currently building the yardoc cache. # # @param gemspec [Gem::Specification] - def processing?(gemspec) + def processing? gemspec yardoc = File.join(PinCache.yardoc_path(gemspec), 'processing') File.exist?(yardoc) end @@ -53,7 +53,7 @@ def processing?(gemspec) # # @param gemspec [Gem::Specification] # @return [Array] - def load!(gemspec) + def load! gemspec YARD::Registry.load! PinCache.yardoc_path gemspec YARD::Registry.all end diff --git a/solargraph.gemspec b/solargraph.gemspec index 49265f9c6..c426c63a9 100755 --- a/solargraph.gemspec +++ b/solargraph.gemspec @@ -1,74 +1,73 @@ -$LOAD_PATH.unshift File.dirname(__FILE__) + '/lib' -require 'solargraph/version' -require 'date' - -Gem::Specification.new do |s| - s.name = 'solargraph' - s.version = Solargraph::VERSION - s.date = Date.today.strftime("%Y-%m-%d") - s.summary = "A Ruby language server" - s.description = "IDE tools for code completion, inline documentation, and static analysis" - s.authors = ["Fred Snyder"] - s.email = 'admin@castwide.com' - s.files = Dir.chdir(File.expand_path('..', __FILE__)) do - # @sg-ignore Need backtick support - # @type [String] - all_files = `git ls-files -z` - all_files.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } - end - s.homepage = 'https://solargraph.org' - s.license = 'MIT' - s.executables = ['solargraph'] - s.metadata["funding_uri"] = "https://www.patreon.com/castwide" - s.metadata["bug_tracker_uri"] = "https://github.com/castwide/solargraph/issues" - s.metadata["changelog_uri"] = "https://github.com/castwide/solargraph/blob/master/CHANGELOG.md" - s.metadata["source_code_uri"] = "https://github.com/castwide/solargraph" - s.metadata["rubygems_mfa_required"] = "true" - - s.required_ruby_version = '>= 3.0' - - s.add_runtime_dependency 'ast', '~> 2.4.3' - s.add_runtime_dependency 'backport', '~> 1.2' - s.add_runtime_dependency 'benchmark', '~> 0.4' - s.add_runtime_dependency 'bundler', '~> 2.0' - s.add_runtime_dependency 'diff-lcs', '~> 1.4' - s.add_runtime_dependency 'jaro_winkler', '~> 1.6', '>= 1.6.1' - s.add_runtime_dependency 'kramdown', '~> 2.3' - s.add_runtime_dependency 'kramdown-parser-gfm', '~> 1.1' - s.add_runtime_dependency 'logger', '~> 1.6' - s.add_runtime_dependency 'observer', '~> 0.1' - s.add_runtime_dependency 'ostruct', '~> 0.6' - s.add_runtime_dependency 'open3', '~> 0.2.1' - s.add_runtime_dependency 'parser', '~> 3.0' - s.add_runtime_dependency 'prism', '~> 1.4' - s.add_runtime_dependency 'rbs', ['>= 3.6.1', '<= 4.0.0.dev.4'] - s.add_runtime_dependency 'reverse_markdown', '~> 3.0' - s.add_runtime_dependency 'rubocop', '~> 1.76' - s.add_runtime_dependency 'thor', '~> 1.0' - s.add_runtime_dependency 'tilt', '~> 2.0' - s.add_runtime_dependency 'yard', '~> 0.9', '>= 0.9.24' - s.add_runtime_dependency 'yard-solargraph', '~> 0.1' - s.add_runtime_dependency 'yard-activesupport-concern', '~> 0.0' - - s.add_development_dependency 'pry', '~> 0.15' - s.add_development_dependency 'public_suffix', '~> 3.1' - s.add_development_dependency 'rake', '~> 13.2' - s.add_development_dependency 'rspec', '~> 3.5' - # - # very specific development-time RuboCop version patterns for CI - # stability - feel free to update in an isolated PR - # - # even more specific on RuboCop itself, which is written into _todo - # file. - s.add_development_dependency 'rubocop', '~> 1.80.0.0' - s.add_development_dependency 'rubocop-rake', '~> 0.7.1' - s.add_development_dependency 'rubocop-rspec', '~> 3.6.0' - s.add_development_dependency 'rubocop-yard', '~> 1.0.0' - s.add_development_dependency 'simplecov', '~> 0.21' - s.add_development_dependency 'simplecov-lcov', '~> 0.8' - s.add_development_dependency 'undercover', '~> 0.7' - s.add_development_dependency 'overcommit', '~> 0.68.0' - s.add_development_dependency 'webmock', '~> 3.6' - # work around missing yard dependency needed as of Ruby 3.5 - s.add_development_dependency 'irb', '~> 1.15' -end +$LOAD_PATH.unshift File.dirname(__FILE__) + '/lib' +require 'solargraph/version' +require 'date' + +Gem::Specification.new do |s| + s.name = 'solargraph' + s.version = Solargraph::VERSION + s.summary = 'A Ruby language server' + s.description = 'IDE tools for code completion, inline documentation, and static analysis' + s.authors = ['Fred Snyder'] + s.email = 'admin@castwide.com' + s.files = Dir.chdir(File.expand_path(__dir__)) do + # @sg-ignore Need backtick support + # @type [String] + all_files = `git ls-files -z` + all_files.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } + end + s.homepage = 'https://solargraph.org' + s.license = 'MIT' + s.executables = ['solargraph'] + s.metadata['funding_uri'] = 'https://www.patreon.com/castwide' + s.metadata['bug_tracker_uri'] = 'https://github.com/castwide/solargraph/issues' + s.metadata['changelog_uri'] = 'https://github.com/castwide/solargraph/blob/master/CHANGELOG.md' + s.metadata['source_code_uri'] = 'https://github.com/castwide/solargraph' + s.metadata['rubygems_mfa_required'] = 'true' + + s.required_ruby_version = '>= 3.0' + + s.add_dependency 'ast', '~> 2.4.3' + s.add_dependency 'backport', '~> 1.2' + s.add_dependency 'benchmark', '~> 0.4' + s.add_dependency 'bundler', '~> 2.0' + s.add_dependency 'diff-lcs', '~> 1.4' + s.add_dependency 'jaro_winkler', '~> 1.6', '>= 1.6.1' + s.add_dependency 'kramdown', '~> 2.3' + s.add_dependency 'kramdown-parser-gfm', '~> 1.1' + s.add_dependency 'logger', '~> 1.6' + s.add_dependency 'observer', '~> 0.1' + s.add_dependency 'open3', '~> 0.2.1' + s.add_dependency 'ostruct', '~> 0.6' + s.add_dependency 'parser', '~> 3.0' + s.add_dependency 'prism', '~> 1.4' + s.add_dependency 'rbs', ['>= 3.6.1', '<= 4.0.0.dev.4'] + s.add_dependency 'reverse_markdown', '~> 3.0' + s.add_dependency 'rubocop', '~> 1.76' + s.add_dependency 'thor', '~> 1.0' + s.add_dependency 'tilt', '~> 2.0' + s.add_dependency 'yard', '~> 0.9', '>= 0.9.24' + s.add_dependency 'yard-activesupport-concern', '~> 0.0' + s.add_dependency 'yard-solargraph', '~> 0.1' + + s.add_development_dependency 'pry', '~> 0.15' + s.add_development_dependency 'public_suffix', '~> 3.1' + s.add_development_dependency 'rake', '~> 13.2' + s.add_development_dependency 'rspec', '~> 3.5' + # + # very specific development-time RuboCop version patterns for CI + # stability - feel free to update in an isolated PR + # + # even more specific on RuboCop itself, which is written into _todo + # file. + s.add_development_dependency 'overcommit', '~> 0.68.0' + s.add_development_dependency 'rubocop', '~> 1.80.0.0' + s.add_development_dependency 'rubocop-rake', '~> 0.7.1' + s.add_development_dependency 'rubocop-rspec', '~> 3.6.0' + s.add_development_dependency 'rubocop-yard', '~> 1.0.0' + s.add_development_dependency 'simplecov', '~> 0.21' + s.add_development_dependency 'simplecov-lcov', '~> 0.8' + s.add_development_dependency 'undercover', '~> 0.7' + s.add_development_dependency 'webmock', '~> 3.6' + # work around missing yard dependency needed as of Ruby 3.5 + s.add_development_dependency 'irb', '~> 1.15' +end diff --git a/spec/api_map/cache_spec.rb b/spec/api_map/cache_spec.rb index 20e5b9df1..0a8d002de 100644 --- a/spec/api_map/cache_spec.rb +++ b/spec/api_map/cache_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::ApiMap::Cache do - it "recognizes empty caches" do + it 'recognizes empty caches' do cache = Solargraph::ApiMap::Cache.new expect(cache).to be_empty cache.set_methods('', :class, [:public], true, []) diff --git a/spec/api_map/config_spec.rb b/spec/api_map/config_spec.rb index 5790265cd..936d05e27 100644 --- a/spec/api_map/config_spec.rb +++ b/spec/api_map/config_spec.rb @@ -5,62 +5,62 @@ let(:workspace_path) { File.realpath(Dir.mktmpdir) } let(:global_path) { @global_path } - before(:each) do + before do @global_path = File.realpath(Dir.mktmpdir) - @orig_env = ENV['SOLARGRAPH_GLOBAL_CONFIG'] + @orig_env = ENV.fetch('SOLARGRAPH_GLOBAL_CONFIG', nil) ENV['SOLARGRAPH_GLOBAL_CONFIG'] = File.join(@global_path, '.solargraph.yml') end - after(:each) do + after do ENV['SOLARGRAPH_GLOBAL_CONFIG'] = @orig_env FileUtils.remove_entry(workspace_path) FileUtils.remove_entry(global_path) end - it "reads workspace files from config" do + it 'reads workspace files from config' do File.write(File.join(workspace_path, 'foo.rb'), 'test') File.write(File.join(workspace_path, 'bar.rb'), 'test') File.open(File.join(workspace_path, '.solargraph.yml'), 'w') do |file| - file.puts "include:" - file.puts " - foo.rb" - file.puts "exclude:" - file.puts " - bar.rb" + file.puts 'include:' + file.puts ' - foo.rb' + file.puts 'exclude:' + file.puts ' - bar.rb' end expect(config.included).to eq([File.join(workspace_path, 'foo.rb')]) expect(config.excluded).to eq([File.join(workspace_path, 'bar.rb')]) end - it "reads workspace files from global config" do + it 'reads workspace files from global config' do File.write(File.join(workspace_path, 'foo.rb'), 'test') File.write(File.join(workspace_path, 'bar.rb'), 'test') File.open(File.join(global_path, '.solargraph.yml'), 'w') do |file| - file.puts "include:" - file.puts " - foo.rb" - file.puts "exclude:" - file.puts " - bar.rb" + file.puts 'include:' + file.puts ' - foo.rb' + file.puts 'exclude:' + file.puts ' - bar.rb' end expect(config.included).to eq([File.join(workspace_path, 'foo.rb')]) expect(config.excluded).to eq([File.join(workspace_path, 'bar.rb')]) end - it "overrides global config with workspace config" do + it 'overrides global config with workspace config' do File.write(File.join(workspace_path, 'foo.rb'), 'test') File.write(File.join(workspace_path, 'bar.rb'), 'test') - + File.open(File.join(workspace_path, '.solargraph.yml'), 'w') do |file| - file.puts "include:" - file.puts " - foo.rb" - file.puts "max_files: 8000" + file.puts 'include:' + file.puts ' - foo.rb' + file.puts 'max_files: 8000' end File.open(File.join(global_path, '.solargraph.yml'), 'w') do |file| - file.puts "include:" - file.puts " - include.rb" - file.puts "exclude:" - file.puts " - bar.rb" - file.puts "max_files: 1000" + file.puts 'include:' + file.puts ' - include.rb' + file.puts 'exclude:' + file.puts ' - bar.rb' + file.puts 'max_files: 1000' end expect(config.included).to eq([File.join(workspace_path, 'foo.rb')]) diff --git a/spec/api_map/source_to_yard_spec.rb b/spec/api_map/source_to_yard_spec.rb index 88be54c64..e7dcf3d0d 100644 --- a/spec/api_map/source_to_yard_spec.rb +++ b/spec/api_map/source_to_yard_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::ApiMap::SourceToYard do - it "rakes sources" do + it 'rakes sources' do source = Solargraph::SourceMap.load_string(%( module Foo class Bar @@ -17,7 +17,7 @@ def baz expect(object.code_object_paths).to include('Foo::Bar#baz') end - it "generates docstrings" do + it 'generates docstrings' do source = Solargraph::SourceMap.load_string(%( # My foo class 描述 class Foo @@ -40,7 +40,7 @@ def self.baz expect(class_method_object.tag(:return).types).to eq(['Foo']) end - it "generates instance mixins" do + it 'generates instance mixins' do source = Solargraph::SourceMap.load_string(%( module Foo def bar @@ -58,7 +58,7 @@ class Baz expect(class_object.instance_mixins).to include(module_object) end - it "generates class mixins" do + it 'generates class mixins' do source = Solargraph::SourceMap.load_string(%( module Foo def bar; end @@ -75,7 +75,7 @@ class Baz expect(class_object.class_mixins).to include(module_object) end - it "generates methods for attributes" do + it 'generates methods for attributes' do source = Solargraph::SourceMap.load_string(%( class Foo attr_reader :bar @@ -86,15 +86,15 @@ class Foo object = Object.new object.extend Solargraph::ApiMap::SourceToYard object.rake_yard Solargraph::ApiMap::Store.new(source.pins) - expect(object.code_object_at('Foo#bar')).not_to be(nil) - expect(object.code_object_at('Foo#bar=')).to be(nil) - expect(object.code_object_at('Foo#baz')).to be(nil) - expect(object.code_object_at('Foo#baz=')).not_to be(nil) - expect(object.code_object_at('Foo#boo')).not_to be(nil) - expect(object.code_object_at('Foo#boo=')).not_to be(nil) + expect(object.code_object_at('Foo#bar')).not_to be_nil + expect(object.code_object_at('Foo#bar=')).to be_nil + expect(object.code_object_at('Foo#baz')).to be_nil + expect(object.code_object_at('Foo#baz=')).not_to be_nil + expect(object.code_object_at('Foo#boo')).not_to be_nil + expect(object.code_object_at('Foo#boo=')).not_to be_nil end - it "generates method parameters" do + it 'generates method parameters' do source = Solargraph::SourceMap.load_string(%( class Foo def bar baz, boo = 'boo' @@ -110,7 +110,7 @@ def bar baz, boo = 'boo' expect(method_object.parameters[1]).to eq(['boo', "'boo'"]) end - it "generates method keyword parameters" do + it 'generates method keyword parameters' do source = Solargraph::SourceMap.load_string(%( class Foo def bar baz, boo: 'boo' diff --git a/spec/api_map_spec.rb b/spec/api_map_spec.rb index 1e0130c14..880c52ece 100755 --- a/spec/api_map_spec.rb +++ b/spec/api_map_spec.rb @@ -436,7 +436,7 @@ class Sup xit 'understands tuples inherit from regular arrays' do method_pins = @api_map.get_method_stack("Array(1, 2, 'a')", 'include?') method_pin = method_pins.first - expect(method_pin).to_not be_nil + expect(method_pin).not_to be_nil expect(method_pin.path).to eq('Array#include?') parameter_type = method_pin.signatures.first.parameters.first.return_type expect(parameter_type.rooted_tags).to eq("1, 2, 'a'") diff --git a/spec/complex_type_spec.rb b/spec/complex_type_spec.rb index ba2a1ac7c..f88b708f4 100644 --- a/spec/complex_type_spec.rb +++ b/spec/complex_type_spec.rb @@ -159,7 +159,6 @@ expect(types.to_rbs).to eq('Array[Symbol, String]') end - # Note that parametrized types are typically not order-dependent, in # other words, a list of parametrized types can occur in any order # inside of a type. An array specified as Array can @@ -538,13 +537,13 @@ let(:complex_type) { Solargraph::ComplexType.parse(tag) } let(:unique_type) { complex_type.first } + let(:context_type) { Solargraph::ComplexType.parse(context_type_tag) } + let(:generic_value) { unfrozen_input_map.transform_values! { |tag| Solargraph::ComplexType.parse(tag) } } + it '#{tag} is a unique type' do expect(complex_type.length).to eq(1) end - let(:generic_value) { unfrozen_input_map.transform_values! { |tag| Solargraph::ComplexType.parse(tag) } } - let(:context_type) { Solargraph::ComplexType.parse(context_type_tag) } - it "resolves to #{expected_tag} with updated map #{expected_output_map}" do resolved_generic_values = unfrozen_input_map.transform_values { |tag| Solargraph::ComplexType.parse(tag) } resolved_type = unique_type.resolve_generics_from_context(expected_output_map.keys, context_type, @@ -602,7 +601,22 @@ end end - context "supports arbitrary combinations of the above syntax and features" do + context 'supports arbitrary combinations of the above syntax and features' do + let(:foo_bar_api_map) do + api_map = Solargraph::ApiMap.new + source = Solargraph::Source.load_string(%( + module Foo + class Bar + # @return [Bar] + def make_bar + end + end + end + )) + api_map.map source + api_map + end + it 'returns string representations of the entire type array' do type = Solargraph::ComplexType.parse('String', 'Array') expect(type.to_s).to eq('String, Array') @@ -630,21 +644,6 @@ expect(types.to_rbs).to eq('(Array[String] | Hash[String, Symbol] | [String, Integer])') end - let(:foo_bar_api_map) do - api_map = Solargraph::ApiMap.new - source = Solargraph::Source.load_string(%( - module Foo - class Bar - # @return [Bar] - def make_bar - end - end - end - )) - api_map.map source - api_map - end - it 'qualifies types with list parameters' do original = Solargraph::ComplexType.parse('Class').first expect(original).not_to be_rooted diff --git a/spec/convention/struct_definition_spec.rb b/spec/convention/struct_definition_spec.rb index 5c3fc5211..51a71f673 100644 --- a/spec/convention/struct_definition_spec.rb +++ b/spec/convention/struct_definition_spec.rb @@ -103,7 +103,7 @@ expect(params.map(&:name)).to eql(%w[bar baz]) expect(params.map(&:return_type).map(&:tag)).to eql(%w[Integer String]) - expect(params[1].documentation).to eql("Some text") + expect(params[1].documentation).to eql('Some text') end [true, false].each do |kw_args| @@ -116,21 +116,21 @@ Foo = Struct.new(:bar, :baz, keyword_init: #{kw_args}) ), 'test.rb') - params_bar = source.pins.find { |p| p.path == "Foo#bar=" }.parameters + params_bar = source.pins.find { |p| p.path == 'Foo#bar=' }.parameters expect(params_bar.length).to be(1) - expect(params_bar.first.return_type.tag).to eql("String") + expect(params_bar.first.return_type.tag).to eql('String') expect(params_bar.first.arg?).to be(true) - params_baz = source.pins.find { |p| p.path == "Foo#baz=" }.parameters + params_baz = source.pins.find { |p| p.path == 'Foo#baz=' }.parameters expect(params_baz.length).to be(1) - expect(params_baz.first.return_type.tag).to eql("Integer") + expect(params_baz.first.return_type.tag).to eql('Integer') expect(params_baz.first.arg?).to be(true) - iv_bar = source.pins.find { |p| p.name == "@bar" } - expect(iv_bar.return_type.tag).to eql("String") + iv_bar = source.pins.find { |p| p.name == '@bar' } + expect(iv_bar.return_type.tag).to eql('String') - iv_baz = source.pins.find { |p| p.name == "@baz" } - expect(iv_baz.return_type.tag).to eql("Integer") + iv_baz = source.pins.find { |p| p.name == '@baz' } + expect(iv_baz.return_type.tag).to eql('Integer') end end end diff --git a/spec/diagnostics/base_spec.rb b/spec/diagnostics/base_spec.rb index d2068caf1..42fbb097e 100644 --- a/spec/diagnostics/base_spec.rb +++ b/spec/diagnostics/base_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::Diagnostics::Base do - it "returns empty diagnostics" do + it 'returns empty diagnostics' do reporter = Solargraph::Diagnostics::Base.new expect(reporter.diagnose(nil, nil)).to be_empty end diff --git a/spec/diagnostics/require_not_found_spec.rb b/spec/diagnostics/require_not_found_spec.rb index 6ecfdcae9..53b375d7e 100644 --- a/spec/diagnostics/require_not_found_spec.rb +++ b/spec/diagnostics/require_not_found_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::Diagnostics::RequireNotFound do - before :each do + before do @source = Solargraph::Source.new(%( require 'rexml/document' require 'not_valid' @@ -11,7 +11,7 @@ @api_map.catalog Solargraph::Bench.new(source_maps: [@source_map], external_requires: ['not_valid']) end - it "reports unresolved requires" do + it 'reports unresolved requires' do reporter = Solargraph::Diagnostics::RequireNotFound.new result = reporter.diagnose(@source, @api_map) expect(result.length).to eq(1) diff --git a/spec/diagnostics/rubocop_helpers_spec.rb b/spec/diagnostics/rubocop_helpers_spec.rb index d59dac4ae..bccfeb9d6 100644 --- a/spec/diagnostics/rubocop_helpers_spec.rb +++ b/spec/diagnostics/rubocop_helpers_spec.rb @@ -2,7 +2,7 @@ context do around do |example| old_gem_path = Gem.paths.path - custom_gem_path = File.absolute_path('spec/fixtures/rubocop-custom-version').gsub(/\\/, '/') + custom_gem_path = File.absolute_path('spec/fixtures/rubocop-custom-version').gsub('\\', '/') # Remove a post_reset hook set by bundler to restore cached specs # Source: https://github.com/ruby/ruby/blob/master/lib/bundler/rubygems_integration.rb#L487-L489 old_post_reset_hooks = Gem.post_reset_hooks.dup @@ -18,7 +18,7 @@ let(:custom_version) { '0.0.0' } - it "requires the specified version of rubocop" do + it 'requires the specified version of rubocop' do input = custom_version Solargraph::Diagnostics::RubocopHelpers.require_rubocop(input) output = RuboCop::Version::STRING @@ -29,7 +29,7 @@ context do let(:default_version) { Gem::Specification.find_by_name('rubocop').full_gem_path[/[^-]+$/] } - it "requires the default version of rubocop" do + it 'requires the default version of rubocop' do input = nil Solargraph::Diagnostics::RubocopHelpers.require_rubocop(input) output = RuboCop::Version::STRING @@ -37,13 +37,13 @@ end end - it "converts lower-case drive letters to upper-case" do + it 'converts lower-case drive letters to upper-case' do input = 'c:/one/two' output = Solargraph::Diagnostics::RubocopHelpers.fix_drive_letter(input) expect(output).to eq('C:/one/two') end - it "ignores paths without drive letters" do + it 'ignores paths without drive letters' do input = 'one/two' output = Solargraph::Diagnostics::RubocopHelpers.fix_drive_letter(input) expect(output).to eq('one/two') diff --git a/spec/diagnostics/rubocop_spec.rb b/spec/diagnostics/rubocop_spec.rb index aa279f66c..4926a458f 100644 --- a/spec/diagnostics/rubocop_spec.rb +++ b/spec/diagnostics/rubocop_spec.rb @@ -15,17 +15,17 @@ def bar expect(result).to be_a(Array) end - context "with validation error" do + context 'with validation error' do let(:fixture_path) do - File.absolute_path('spec/fixtures/rubocop-validation-error').gsub(/\\/, '/') + File.absolute_path('spec/fixtures/rubocop-validation-error').gsub('\\', '/') end around do |example| config_file = File.join(fixture_path, '.rubocop.yml') File.write(config_file, <<~YAML) - inherit_from: - - file_not_found.yml - YAML + inherit_from: + - file_not_found.yml + YAML example.run ensure File.delete(config_file) if File.exist?(config_file) @@ -35,9 +35,9 @@ def bar file = File.realpath(File.join(fixture_path, 'app.rb')) source = Solargraph::Source.load(file) rubocop = Solargraph::Diagnostics::Rubocop.new - expect { + expect do rubocop.diagnose(source, nil) - }.to raise_error(Solargraph::DiagnosticsError) + end.to raise_error(Solargraph::DiagnosticsError) end end diff --git a/spec/diagnostics/type_check_spec.rb b/spec/diagnostics/type_check_spec.rb index e343d6598..c140f9593 100644 --- a/spec/diagnostics/type_check_spec.rb +++ b/spec/diagnostics/type_check_spec.rb @@ -1,7 +1,7 @@ describe Solargraph::Diagnostics::TypeCheck do let(:api_map) { Solargraph::ApiMap.new } - it "detects defined return types" do + it 'detects defined return types' do source = Solargraph::Source.load_string(%( # @return [String] def foo @@ -12,7 +12,7 @@ def foo expect(result).to be_empty end - it "detects missing return types" do + it 'detects missing return types' do source = Solargraph::Source.load_string(%( def foo end @@ -23,7 +23,7 @@ def foo expect(result[0][:message]).to include('foo') end - it "detects defined parameter types" do + it 'detects defined parameter types' do source = Solargraph::Source.load_string(%( # @param bar [String] # @return [String] @@ -35,7 +35,7 @@ def foo(bar) expect(result).to be_empty end - it "detects missing parameter types" do + it 'detects missing parameter types' do source = Solargraph::Source.load_string(%( # @return [String] def foo(bar) @@ -48,7 +48,7 @@ def foo(bar) expect(result[0][:message]).to include('bar') end - it "detects return types from superclasses" do + it 'detects return types from superclasses' do source = Solargraph::Source.load_string(%( class First # @return [String] @@ -65,7 +65,7 @@ def foo expect(result).to be_empty end - it "detects parameter types from superclasses" do + it 'detects parameter types from superclasses' do source = Solargraph::Source.load_string(%( class First # @param bar [String] @@ -83,7 +83,7 @@ def foo bar expect(result).to be_empty end - it "works with optional and keyword arguments" do + it 'works with optional and keyword arguments' do source = Solargraph::Source.load_string(%( # @param bar [String] # @param baz [String] diff --git a/spec/diagnostics/update_errors_spec.rb b/spec/diagnostics/update_errors_spec.rb index 11b8c6f8f..1a05f93d5 100644 --- a/spec/diagnostics/update_errors_spec.rb +++ b/spec/diagnostics/update_errors_spec.rb @@ -1,16 +1,16 @@ describe Solargraph::Diagnostics::UpdateErrors do - it "detects repaired lines" do + it 'detects repaired lines' do api_map = Solargraph::ApiMap.new orig = Solargraph::Source.load_string('foo', 'test.rb') diagnoser = Solargraph::Diagnostics::UpdateErrors.new result = diagnoser.diagnose(orig, api_map) expect(result.length).to eq(0) updater = Solargraph::Source::Updater.new('test.rb', 2, [ - Solargraph::Source::Change.new( - Solargraph::Range.from_to(0, 3, 0, 3), - '.' - ) - ]) + Solargraph::Source::Change.new( + Solargraph::Range.from_to(0, 3, 0, 3), + '.' + ) + ]) source = orig.synchronize(updater) diagnoser = Solargraph::Diagnostics::UpdateErrors.new result = diagnoser.diagnose(source, api_map) diff --git a/spec/diagnostics_spec.rb b/spec/diagnostics_spec.rb index ba689692d..628341f2a 100644 --- a/spec/diagnostics_spec.rb +++ b/spec/diagnostics_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::Diagnostics do - it "registers reporters" do + it 'registers reporters' do Solargraph::Diagnostics.register 'base', Solargraph::Diagnostics::Base expect(Solargraph::Diagnostics.reporters).to include('base') expect(Solargraph::Diagnostics.reporter('base')).to be(Solargraph::Diagnostics::Base) diff --git a/spec/doc_map_spec.rb b/spec/doc_map_spec.rb index 1315f6c90..9cd65c747 100644 --- a/spec/doc_map_spec.rb +++ b/spec/doc_map_spec.rb @@ -61,9 +61,9 @@ it 'includes convention requires from environ' do dummy_convention = Class.new(Solargraph::Convention::Base) do - def global(doc_map) + def global doc_map Solargraph::Environ.new( - requires: ['convention_gem1', 'convention_gem2'] + requires: %w[convention_gem1 convention_gem2] ) end end diff --git a/spec/language_server/host/diagnoser_spec.rb b/spec/language_server/host/diagnoser_spec.rb index d59a843f1..c04e9f58d 100644 --- a/spec/language_server/host/diagnoser_spec.rb +++ b/spec/language_server/host/diagnoser_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::LanguageServer::Host::Diagnoser do - it "diagnoses on ticks" do + it 'diagnoses on ticks' do host = double(Solargraph::LanguageServer::Host, options: { 'diagnostics' => true }, synchronizing?: false) diagnoser = Solargraph::LanguageServer::Host::Diagnoser.new(host) diagnoser.schedule 'file.rb' diff --git a/spec/language_server/host/dispatch_spec.rb b/spec/language_server/host/dispatch_spec.rb index 9b314c403..1ecd49c9b 100644 --- a/spec/language_server/host/dispatch_spec.rb +++ b/spec/language_server/host/dispatch_spec.rb @@ -5,12 +5,12 @@ @dispatch.extend Solargraph::LanguageServer::Host::Dispatch end - after :each do + after do @dispatch.libraries.clear @dispatch.sources.clear end - it "finds an explicit library" do + it 'finds an explicit library' do @dispatch.libraries.push Solargraph::Library.load('*') src = @dispatch.sources.open('file:///file.rb', 'a=b', 0) @dispatch.libraries.first.merge src @@ -18,7 +18,7 @@ expect(lib).to be(@dispatch.libraries.first) end - it "finds an implicit library" do + it 'finds an implicit library' do dir = File.realpath(File.join('spec', 'fixtures', 'workspace')) file = File.join(dir, 'new.rb') uri = Solargraph::LanguageServer::UriHelpers.file_to_uri(file) @@ -28,7 +28,7 @@ expect(lib).to be(@dispatch.libraries.first) end - it "finds a generic library" do + it 'finds a generic library' do dir = File.realpath(File.join('spec', 'fixtures', 'workspace')) file = '/external.rb' uri = Solargraph::LanguageServer::UriHelpers.file_to_uri(file) diff --git a/spec/language_server/host/message_worker_spec.rb b/spec/language_server/host/message_worker_spec.rb index b9ce2a41f..0b8558556 100644 --- a/spec/language_server/host/message_worker_spec.rb +++ b/spec/language_server/host/message_worker_spec.rb @@ -1,7 +1,7 @@ describe Solargraph::LanguageServer::Host::MessageWorker do - it "handle requests on queue" do + it 'handle requests on queue' do host = double(Solargraph::LanguageServer::Host) - message = {'method' => '$/example'} + message = { 'method' => '$/example' } expect(host).to receive(:receive).with(message).and_return(nil) worker = Solargraph::LanguageServer::Host::MessageWorker.new(host) diff --git a/spec/language_server/host_spec.rb b/spec/language_server/host_spec.rb index 5635680e3..3eb4d52f3 100644 --- a/spec/language_server/host_spec.rb +++ b/spec/language_server/host_spec.rb @@ -1,15 +1,15 @@ require 'tmpdir' describe Solargraph::LanguageServer::Host do - it "prepares a workspace" do + it 'prepares a workspace' do host = Solargraph::LanguageServer::Host.new Dir.mktmpdir do |dir| - host.prepare (dir) - expect(host.libraries.first).not_to be(nil) + host.prepare(dir) + expect(host.libraries.first).not_to be_nil end end - it "processes responses to message requests" do + it 'processes responses to message requests' do host = Solargraph::LanguageServer::Host.new done_somethings = 0 host.send_request 'window/showMessageRequest', { @@ -20,13 +20,13 @@ end expect(host.pending_requests.length).to eq(1) host.receive({ - 'id' => host.pending_requests.first, - 'result' => 'Do something' - }) + 'id' => host.pending_requests.first, + 'result' => 'Do something' + }) expect(done_somethings).to eq(1) end - it "creates files from disk" do + it 'creates files from disk' do Dir.mktmpdir do |dir| host = Solargraph::LanguageServer::Host.new host.prepare dir @@ -38,26 +38,26 @@ end end - it "deletes files" do + it 'deletes files' do Dir.mktmpdir do |dir| - expect { + expect do host = Solargraph::LanguageServer::Host.new file = File.join(dir, 'test.rb') File.write(file, "foo = 'foo'") host.prepare dir uri = Solargraph::LanguageServer::UriHelpers.file_to_uri(file) host.delete(uri) - }.not_to raise_error + end.not_to raise_error end end - it "cancels requests" do + it 'cancels requests' do host = Solargraph::LanguageServer::Host.new host.cancel 1 expect(host.cancel?(1)).to be(true) end - it "runs diagnostics on opened files" do + it 'runs diagnostics on opened files' do Dir.mktmpdir do |dir| host = Solargraph::LanguageServer::Host.new host.configure({ 'diagnostics' => true }) @@ -65,7 +65,7 @@ File.write(file, "foo = 'foo'") host.start host.prepare dir - uri = Solargraph::LanguageServer::UriHelpers.file_to_uri(file) + Solargraph::LanguageServer::UriHelpers.file_to_uri(file) host.open(file, File.read(file), 1) buffer = host.flush times = 0 @@ -81,7 +81,7 @@ end end - it "handles DiagnosticsErrors" do + it 'handles DiagnosticsErrors' do host = Solargraph::LanguageServer::Host.new library = double(:Library) allow(library).to receive(:diagnose).and_raise(Solargraph::DiagnosticsError) @@ -94,17 +94,17 @@ # @todo Smelly instance variable access host.instance_variable_set(:@libraries, [library]) host.open('file:///test.rb', '', 0) - expect { + expect do host.diagnose 'file:///test.rb' - }.not_to raise_error + end.not_to raise_error result = host.flush expect(result).to include('Error in diagnostics') end - it "opens multiple folders" do + it 'opens multiple folders' do host = Solargraph::LanguageServer::Host.new - app1_folder = File.absolute_path('spec/fixtures/workspace_folders/folder1').gsub(/\\/, '/') - app2_folder = File.absolute_path('spec/fixtures/workspace_folders/folder2').gsub(/\\/, '/') + app1_folder = File.absolute_path('spec/fixtures/workspace_folders/folder1').gsub('\\', '/') + app2_folder = File.absolute_path('spec/fixtures/workspace_folders/folder2').gsub('\\', '/') host.prepare(app1_folder) host.prepare(app2_folder) file1_uri = Solargraph::LanguageServer::UriHelpers.file_to_uri("#{app1_folder}/app.rb") @@ -119,13 +119,13 @@ expect(app2_map).not_to include('Folder1App') end - it "stops" do + it 'stops' do host = Solargraph::LanguageServer::Host.new host.stop expect(host.stopped?).to be(true) end - it "retains orphaned sources" do + it 'retains orphaned sources' do dir = File.absolute_path('spec/fixtures/workspace') file = File.join(dir, 'lib', 'thing.rb') file_uri = Solargraph::LanguageServer::UriHelpers.uri_to_file(file) @@ -133,12 +133,12 @@ host.prepare(dir) host.open(file_uri, File.read(file), 1) host.remove(dir) - expect{ + expect do host.document_symbols(file_uri) - }.not_to raise_error + end.not_to raise_error end - it "responds with empty diagnostics for unopened files" do + it 'responds with empty diagnostics for unopened files' do host = Solargraph::LanguageServer::Host.new host.diagnose 'file:///file.rb' response = host.flush @@ -147,28 +147,28 @@ expect(json['params']['diagnostics']).to be_empty end - it "rescues runtime errors from messages" do + it 'rescues runtime errors from messages' do host = Solargraph::LanguageServer::Host.new message_class = Class.new(Solargraph::LanguageServer::Message::Base) do def process - raise RuntimeError, 'Always raise an error from this message' + raise 'Always raise an error from this message' end end Solargraph::LanguageServer::Message.register('raiseRuntimeError', message_class) - expect { + expect do host.receive({ - 'id' => 1, - 'method' => 'raiseRuntimeError', - 'params' => {} - }) - }.not_to raise_error + 'id' => 1, + 'method' => 'raiseRuntimeError', + 'params' => {} + }) + end.not_to raise_error end - it "ignores invalid messages" do + it 'ignores invalid messages' do host = Solargraph::LanguageServer::Host.new - expect { + expect do host.receive({ 'bad' => 'message' }) - }.not_to raise_error + end.not_to raise_error end it 'repairs simple breaking changes without incremental sync' do @@ -179,16 +179,16 @@ def process host.open uri, 'Foo::Bar', 1 sleep 0.1 until host.libraries.all?(&:mapped?) host.change({ - "textDocument" => { - "uri" => uri, - 'version' => 2 - }, - "contentChanges" => [ - { - "text" => "Foo::Bar." - } - ] - }) + 'textDocument' => { + 'uri' => uri, + 'version' => 2 + }, + 'contentChanges' => [ + { + 'text' => 'Foo::Bar.' + } + ] + }) source = host.sources.find(uri) # @todo Smelly private method access expect(source.send(:repaired)).to eq('Foo::Bar ') @@ -211,23 +211,23 @@ def initialize(foo); end host.open uri, code, 1 sleep 0.1 until host.libraries.all?(&:mapped?) result = host.locate_pins({ - "data" => { - "uri" => uri, - "location" => { - "range" => { - "start" => { - "line" => 5, - "character" => 12 - }, - "end" => { - "line" => 5, - "character" => 15 - } - } - }, - "path" => "Example.new" - } - }) + 'data' => { + 'uri' => uri, + 'location' => { + 'range' => { + 'start' => { + 'line' => 5, + 'character' => 12 + }, + 'end' => { + 'line' => 5, + 'character' => 15 + } + } + }, + 'path' => 'Example.new' + } + }) expect(result.map(&:path)).to include('Example.new') end end @@ -260,22 +260,22 @@ def initialize(foo); end end end - describe "Workspace variations" do - before :each do + describe 'Workspace variations' do + before do @host = Solargraph::LanguageServer::Host.new end - after :each do + after do @host.stop end - it "creates a library for a file without a workspace" do + it 'creates a library for a file without a workspace' do @host.open('file:///file.rb', 'class Foo; end', 1) symbols = @host.document_symbols('file:///file.rb') expect(symbols).not_to be_empty end - it "opens a file outside of prepared libraries" do + it 'opens a file outside of prepared libraries' do @host.prepare(File.absolute_path(File.join('spec', 'fixtures', 'workspace'))) @host.open('file:///file.rb', 'class Foo; end', 1) symbols = @host.document_symbols('file:///file.rb') diff --git a/spec/language_server/message/completion_item/resolve_spec.rb b/spec/language_server/message/completion_item/resolve_spec.rb index 3ae66dbda..7cf980377 100644 --- a/spec/language_server/message/completion_item/resolve_spec.rb +++ b/spec/language_server/message/completion_item/resolve_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::LanguageServer::Message::CompletionItem::Resolve do - it "returns MarkupContent for documentation" do + it 'returns MarkupContent for documentation' do pin = Solargraph::Pin::Method.new( location: nil, closure: Solargraph::Pin::Namespace.new(name: 'Foo'), @@ -9,16 +9,17 @@ visibility: :public, parameters: [] ) - host = double(Solargraph::LanguageServer::Host, locate_pins: [pin], probe: pin, detail: nil, options: { 'enablePages' => true }) + host = double(Solargraph::LanguageServer::Host, locate_pins: [pin], probe: pin, detail: nil, + options: { 'enablePages' => true }) resolve = Solargraph::LanguageServer::Message::CompletionItem::Resolve.new(host, { - 'params' => pin.completion_item - }) + 'params' => pin.completion_item + }) resolve.process expect(resolve.result[:documentation][:kind]).to eq('markdown') expect(resolve.result[:documentation][:value]).to include('A method') end - it "returns nil documentation for empty strings" do + it 'returns nil documentation for empty strings' do pin = Solargraph::Pin::InstanceVariable.new( location: nil, closure: Solargraph::Pin::Namespace.new(name: 'Foo'), @@ -27,8 +28,8 @@ ) host = double(Solargraph::LanguageServer::Host, locate_pins: [pin], probe: pin, detail: nil) resolve = Solargraph::LanguageServer::Message::CompletionItem::Resolve.new(host, { - 'params' => pin.completion_item - }) + 'params' => pin.completion_item + }) resolve.process expect(resolve.result[:documentation]).to be_nil end diff --git a/spec/language_server/message/extended/check_gem_version_spec.rb b/spec/language_server/message/extended/check_gem_version_spec.rb index 935917442..cd64c5af8 100644 --- a/spec/language_server/message/extended/check_gem_version_spec.rb +++ b/spec/language_server/message/extended/check_gem_version_spec.rb @@ -1,38 +1,39 @@ describe Solargraph::LanguageServer::Message::Extended::CheckGemVersion do - before :each do + before do version = double(:GemVersion, version: Gem::Version.new('1.0.0')) - Solargraph::LanguageServer::Message::Extended::CheckGemVersion.fetcher = double(:fetcher, search_for_dependency: [version]) + Solargraph::LanguageServer::Message::Extended::CheckGemVersion.fetcher = double(:fetcher, + search_for_dependency: [version]) end - after :each do + after do Solargraph::LanguageServer::Message::Extended::CheckGemVersion.fetcher = nil end - it "checks the gem source" do + it 'checks the gem source' do host = Solargraph::LanguageServer::Host.new message = described_class.new(host, {}) expect { message.process }.not_to raise_error end - it "performs a verbose check" do + it 'performs a verbose check' do host = Solargraph::LanguageServer::Host.new message = described_class.new(host, { 'params' => { 'verbose' => true } }) expect { message.process }.not_to raise_error end - it "detects available updates" do + it 'detects available updates' do host = Solargraph::LanguageServer::Host.new message = described_class.new(host, {}, current: Gem::Version.new('0.0.1')) expect { message.process }.not_to raise_error end - it "performs a verbose check with an available update" do + it 'performs a verbose check with an available update' do host = Solargraph::LanguageServer::Host.new message = described_class.new(host, { 'params' => { 'verbose' => true } }, current: Gem::Version.new('0.0.1')) expect { message.process }.not_to raise_error end - it "responds to update actions" do + it 'responds to update actions' do host = Solargraph::LanguageServer::Host.new message = Solargraph::LanguageServer::Message::Extended::CheckGemVersion.new(host, {}, current: Gem::Version.new('0.0.1')) message.process @@ -42,18 +43,18 @@ response = data end reader.receive host.flush - expect { + expect do action = { - "id" => response['id'], - "result" => response['params']['actions'].first + 'id' => response['id'], + 'result' => response['params']['actions'].first } host.receive action - }.not_to raise_error + end.not_to raise_error end it 'uses bundler' do host = Solargraph::LanguageServer::Host.new - host.configure({'useBundler' => true}) + host.configure({ 'useBundler' => true }) message = Solargraph::LanguageServer::Message::Extended::CheckGemVersion.new(host, {}, current: Gem::Version.new('0.0.1')) message.process response = nil @@ -62,12 +63,12 @@ response = data end reader.receive host.flush - expect { + expect do action = { - "id" => response['id'], - "result" => response['params']['actions'].first + 'id' => response['id'], + 'result' => response['params']['actions'].first } host.receive action - }.not_to raise_error + end.not_to raise_error end end diff --git a/spec/language_server/message/initialize_spec.rb b/spec/language_server/message/initialize_spec.rb index 3ab54e2de..877add68f 100644 --- a/spec/language_server/message/initialize_spec.rb +++ b/spec/language_server/message/initialize_spec.rb @@ -1,56 +1,56 @@ describe Solargraph::LanguageServer::Message::Initialize do - it "prepares workspace folders" do + it 'prepares workspace folders' do host = Solargraph::LanguageServer::Host.new dir = File.realpath(File.join('spec', 'fixtures', 'workspace')) init = Solargraph::LanguageServer::Message::Initialize.new(host, { - 'params' => { - 'capabilities' => { - 'workspace' => { - 'workspaceFolders' => true - } - }, - 'workspaceFolders' => [ - { - 'uri' => Solargraph::LanguageServer::UriHelpers.file_to_uri(dir), - 'name' => 'workspace' - } - ] - } - }) + 'params' => { + 'capabilities' => { + 'workspace' => { + 'workspaceFolders' => true + } + }, + 'workspaceFolders' => [ + { + 'uri' => Solargraph::LanguageServer::UriHelpers.file_to_uri(dir), + 'name' => 'workspace' + } + ] + } + }) init.process expect(host.folders.length).to eq(1) end - it "prepares rootUri as a workspace" do + it 'prepares rootUri as a workspace' do host = Solargraph::LanguageServer::Host.new dir = File.realpath(File.join('spec', 'fixtures', 'workspace')) init = Solargraph::LanguageServer::Message::Initialize.new(host, { - 'params' => { - 'capabilities' => { - 'workspace' => { - 'workspaceFolders' => true - } - }, - 'rootUri' => Solargraph::LanguageServer::UriHelpers.file_to_uri(dir) - } - }) + 'params' => { + 'capabilities' => { + 'workspace' => { + 'workspaceFolders' => true + } + }, + 'rootUri' => Solargraph::LanguageServer::UriHelpers.file_to_uri(dir) + } + }) init.process expect(host.folders.length).to eq(1) end - it "prepares rootPath as a workspace" do + it 'prepares rootPath as a workspace' do host = Solargraph::LanguageServer::Host.new dir = File.realpath(File.join('spec', 'fixtures', 'workspace')) init = Solargraph::LanguageServer::Message::Initialize.new(host, { - 'params' => { - 'capabilities' => { - 'workspace' => { - 'workspaceFolders' => true - } - }, - 'rootPath' => dir - } - }) + 'params' => { + 'capabilities' => { + 'workspace' => { + 'workspaceFolders' => true + } + }, + 'rootPath' => dir + } + }) init.process expect(host.folders.length).to eq(1) end @@ -62,33 +62,35 @@ result = init.result expect(result).to include(:capabilities) expect(result[:capabilities]).to eq({ - textDocumentSync: 2, - workspace: { workspaceFolders: { supported: true, changeNotifications: true } }, - completionProvider: { resolveProvider: true, triggerCharacters: ['.', ':', '@'] }, - signatureHelpProvider: { triggerCharacters: ['(', ','] }, - hoverProvider: true, - documentSymbolProvider: true, - definitionProvider: true, - typeDefinitionProvider: true, - renameProvider: { prepareProvider: true }, - referencesProvider: true, - workspaceSymbolProvider: true, - foldingRangeProvider: true, - documentHighlightProvider: true - }) + textDocumentSync: 2, + workspace: { workspaceFolders: { supported: true, + changeNotifications: true } }, + completionProvider: { resolveProvider: true, + triggerCharacters: ['.', ':', '@'] }, + signatureHelpProvider: { triggerCharacters: ['(', ','] }, + hoverProvider: true, + documentSymbolProvider: true, + definitionProvider: true, + typeDefinitionProvider: true, + renameProvider: { prepareProvider: true }, + referencesProvider: true, + workspaceSymbolProvider: true, + foldingRangeProvider: true, + documentHighlightProvider: true + }) end it 'returns all capabilities when all options are enabled' do host = Solargraph::LanguageServer::Host.new init = Solargraph::LanguageServer::Message::Initialize.new(host, { - 'params' => { - 'initializationOptions' => { - 'completion' => true, - 'autoformat' => true, - 'formatting' => true - } - } - }) + 'params' => { + 'initializationOptions' => { + 'completion' => true, + 'autoformat' => true, + 'formatting' => true + } + } + }) init.process result = init.result diff --git a/spec/language_server/message/text_document/definition_spec.rb b/spec/language_server/message/text_document/definition_spec.rb index 72ff77f1e..5840d6092 100644 --- a/spec/language_server/message/text_document/definition_spec.rb +++ b/spec/language_server/message/text_document/definition_spec.rb @@ -7,16 +7,16 @@ file_uri = Solargraph::LanguageServer::UriHelpers.file_to_uri(File.absolute_path('spec/fixtures/workspace/lib/other.rb')) other_uri = Solargraph::LanguageServer::UriHelpers.file_to_uri(File.absolute_path('spec/fixtures/workspace/lib/thing.rb')) message = Solargraph::LanguageServer::Message::TextDocument::Definition.new(host, { - 'params' => { - 'textDocument' => { - 'uri' => file_uri - }, - 'position' => { - 'line' => 4, - 'character' => 10 - } - } - }) + 'params' => { + 'textDocument' => { + 'uri' => file_uri + }, + 'position' => { + 'line' => 4, + 'character' => 10 + } + } + }) message.process expect(message.result.first[:uri]).to eq(other_uri) end @@ -28,17 +28,20 @@ sleep 0.1 until host.libraries.all?(&:mapped?) host.catalog message = Solargraph::LanguageServer::Message::TextDocument::Definition.new(host, { - 'params' => { - 'textDocument' => { - 'uri' => Solargraph::LanguageServer::UriHelpers.file_to_uri(File.join(path, 'lib', 'other.rb')) - }, - 'position' => { - 'line' => 0, - 'character' => 10 - } - } - }) + 'params' => { + 'textDocument' => { + 'uri' => Solargraph::LanguageServer::UriHelpers.file_to_uri(File.join( + path, 'lib', 'other.rb' + )) + }, + 'position' => { + 'line' => 0, + 'character' => 10 + } + } + }) message.process - expect(message.result.first[:uri]).to eq(Solargraph::LanguageServer::UriHelpers.file_to_uri(File.join(path, 'lib', 'thing.rb'))) + expect(message.result.first[:uri]).to eq(Solargraph::LanguageServer::UriHelpers.file_to_uri(File.join(path, 'lib', + 'thing.rb'))) end end diff --git a/spec/language_server/message/text_document/formatting_spec.rb b/spec/language_server/message/text_document/formatting_spec.rb index 10797e8db..a174a2361 100644 --- a/spec/language_server/message/text_document/formatting_spec.rb +++ b/spec/language_server/message/text_document/formatting_spec.rb @@ -3,7 +3,7 @@ host = double(:Host, read_text: '', formatter_config: {}) request = { 'params' => { - 'textDocument' => { + 'textDocument' => { 'uri' => 'test.rb' } } diff --git a/spec/language_server/message/text_document/hover_spec.rb b/spec/language_server/message/text_document/hover_spec.rb index 74eaee597..93f05c127 100644 --- a/spec/language_server/message/text_document/hover_spec.rb +++ b/spec/language_server/message/text_document/hover_spec.rb @@ -5,16 +5,16 @@ sleep 0.1 until host.libraries.all?(&:mapped?) host.catalog message = Solargraph::LanguageServer::Message::TextDocument::Hover.new(host, { - 'params' => { - 'textDocument' => { - 'uri' => 'file://spec/fixtures/workspace/lib/other.rb' - }, - 'position' => { - 'line' => 5, - 'character' => 0 - } - } - }) + 'params' => { + 'textDocument' => { + 'uri' => 'file://spec/fixtures/workspace/lib/other.rb' + }, + 'position' => { + 'line' => 5, + 'character' => 0 + } + } + }) message.process expect(message.result).to be_nil end @@ -30,16 +30,16 @@ def foo host.open('file:///test.rb', code, 1) host.catalog message = Solargraph::LanguageServer::Message::TextDocument::Hover.new(host, { - 'params' => { - 'textDocument' => { - 'uri' => 'file:///test.rb' - }, - 'position' => { - 'line' => 4, - 'character' => 6 - } - } - }) + 'params' => { + 'textDocument' => { + 'uri' => 'file:///test.rb' + }, + 'position' => { + 'line' => 4, + 'character' => 6 + } + } + }) message.process expect(message.result[:contents][:value]).to eq("x\n\n`=~ String`") end diff --git a/spec/language_server/message/text_document/rename_spec.rb b/spec/language_server/message/text_document/rename_spec.rb index b16110455..900752e63 100644 --- a/spec/language_server/message/text_document/rename_spec.rb +++ b/spec/language_server/message/text_document/rename_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true describe Solargraph::LanguageServer::Message::TextDocument::Rename do - it "renames a symbol" do + it 'renames a symbol' do host = Solargraph::LanguageServer::Host.new host.start host.open('file:///file.rb', %( @@ -11,24 +11,24 @@ class Foo ), 1) sleep 0.01 until host.libraries.all?(&:mapped?) rename = Solargraph::LanguageServer::Message::TextDocument::Rename.new(host, { - 'id' => 1, - 'method' => 'textDocument/rename', - 'params' => { - 'textDocument' => { - 'uri' => 'file:///file.rb' - }, - 'position' => { - 'line' => 1, - 'character' => 12 - }, - 'newName' => 'Bar' - } - }) + 'id' => 1, + 'method' => 'textDocument/rename', + 'params' => { + 'textDocument' => { + 'uri' => 'file:///file.rb' + }, + 'position' => { + 'line' => 1, + 'character' => 12 + }, + 'newName' => 'Bar' + } + }) rename.process expect(rename.result[:changes]['file:///file.rb'].length).to eq(2) end - it "renames an argument symbol from method signature" do + it 'renames an argument symbol from method signature' do host = Solargraph::LanguageServer::Host.new host.start host.open('file:///file.rb', %( @@ -41,24 +41,24 @@ def foo(bar) ), 1) rename = Solargraph::LanguageServer::Message::TextDocument::Rename.new(host, { - 'id' => 1, - 'method' => 'textDocument/rename', - 'params' => { - 'textDocument' => { - 'uri' => 'file:///file.rb' - }, - 'position' => { - 'line' => 2, - 'character' => 14 - }, - 'newName' => 'baz' - } - }) + 'id' => 1, + 'method' => 'textDocument/rename', + 'params' => { + 'textDocument' => { + 'uri' => 'file:///file.rb' + }, + 'position' => { + 'line' => 2, + 'character' => 14 + }, + 'newName' => 'baz' + } + }) rename.process expect(rename.result[:changes]['file:///file.rb'].length).to eq(3) end - it "renames an argument symbol from method body" do + it 'renames an argument symbol from method body' do host = Solargraph::LanguageServer::Host.new host.start host.open('file:///file.rb', %( @@ -70,24 +70,24 @@ def foo(bar) end ), 1) rename = Solargraph::LanguageServer::Message::TextDocument::Rename.new(host, { - 'id' => 1, - 'method' => 'textDocument/rename', - 'params' => { - 'textDocument' => { - 'uri' => 'file:///file.rb' - }, - 'position' => { - 'line' => 3, - 'character' => 6 - }, - 'newName' => 'baz' - } - }) + 'id' => 1, + 'method' => 'textDocument/rename', + 'params' => { + 'textDocument' => { + 'uri' => 'file:///file.rb' + }, + 'position' => { + 'line' => 3, + 'character' => 6 + }, + 'newName' => 'baz' + } + }) rename.process expect(rename.result[:changes]['file:///file.rb'].length).to eq(3) end - it "renames namespace symbol with proper range" do + it 'renames namespace symbol with proper range' do host = Solargraph::LanguageServer::Host.new host.start host.open('file:///file.rb', %( @@ -97,19 +97,19 @@ class Namespace::ExampleClass obj = Namespace::ExampleClass.new ), 1) rename = Solargraph::LanguageServer::Message::TextDocument::Rename.new(host, { - 'id' => 1, - 'method' => 'textDocument/rename', - 'params' => { - 'textDocument' => { - 'uri' => 'file:///file.rb' - }, - 'position' => { - 'line' => 2, - 'character' => 12 - }, - 'newName' => 'Nameplace' - } - }) + 'id' => 1, + 'method' => 'textDocument/rename', + 'params' => { + 'textDocument' => { + 'uri' => 'file:///file.rb' + }, + 'position' => { + 'line' => 2, + 'character' => 12 + }, + 'newName' => 'Nameplace' + } + }) rename.process changes = rename.result[:changes]['file:///file.rb'] expect(changes.length).to eq(3) diff --git a/spec/language_server/message/text_document/type_definition_spec.rb b/spec/language_server/message/text_document/type_definition_spec.rb index 2f7ec3668..7fdd9ce6f 100644 --- a/spec/language_server/message/text_document/type_definition_spec.rb +++ b/spec/language_server/message/text_document/type_definition_spec.rb @@ -7,16 +7,16 @@ file_uri = Solargraph::LanguageServer::UriHelpers.file_to_uri(File.absolute_path('spec/fixtures/workspace/lib/other.rb')) something_uri = Solargraph::LanguageServer::UriHelpers.file_to_uri(File.absolute_path('spec/fixtures/workspace/lib/something.rb')) message = Solargraph::LanguageServer::Message::TextDocument::TypeDefinition.new(host, { - 'params' => { - 'textDocument' => { - 'uri' => file_uri - }, - 'position' => { - 'line' => 4, - 'character' => 10 - } - } - }) + 'params' => { + 'textDocument' => { + 'uri' => file_uri + }, + 'position' => { + 'line' => 4, + 'character' => 10 + } + } + }) message.process expect(message.result.first[:uri]).to eq(something_uri) end diff --git a/spec/language_server/message/workspace/did_change_watched_files_spec.rb b/spec/language_server/message/workspace/did_change_watched_files_spec.rb index b78aa06d3..504947855 100644 --- a/spec/language_server/message/workspace/did_change_watched_files_spec.rb +++ b/spec/language_server/message/workspace/did_change_watched_files_spec.rb @@ -9,16 +9,16 @@ File.write file, 'class Foo; end' uri = Solargraph::LanguageServer::UriHelpers.file_to_uri(file) changed = Solargraph::LanguageServer::Message::Workspace::DidChangeWatchedFiles.new(host, { - 'method' => 'workspace/didChangeWatchedFiles', - 'params' => { - 'changes' => [ - { - 'type' => Solargraph::LanguageServer::Message::Workspace::DidChangeWatchedFiles::CREATED, - 'uri' => uri - } - ] - } - }) + 'method' => 'workspace/didChangeWatchedFiles', + 'params' => { + 'changes' => [ + { + 'type' => Solargraph::LanguageServer::Message::Workspace::DidChangeWatchedFiles::CREATED, + 'uri' => uri + } + ] + } + }) changed.process expect(host.synchronizing?).to be(false) expect(host.library_for(uri)).to be_a(Solargraph::Library) @@ -34,21 +34,21 @@ host = Solargraph::LanguageServer::Host.new host.prepare dir changed = Solargraph::LanguageServer::Message::Workspace::DidChangeWatchedFiles.new(host, { - 'method' => 'workspace/didChangeWatchedFiles', - 'params' => { - 'changes' => [ - { - 'type' => Solargraph::LanguageServer::Message::Workspace::DidChangeWatchedFiles::DELETED, - 'uri' => uri - } - ] - } - }) + 'method' => 'workspace/didChangeWatchedFiles', + 'params' => { + 'changes' => [ + { + 'type' => Solargraph::LanguageServer::Message::Workspace::DidChangeWatchedFiles::DELETED, + 'uri' => uri + } + ] + } + }) changed.process expect(host.synchronizing?).to be(false) - expect { + expect do host.library_for(uri) - }.to raise_error(Solargraph::FileNotFoundError) + end.to raise_error(Solargraph::FileNotFoundError) end end @@ -61,16 +61,16 @@ host.prepare dir File.write file, 'class FooBar; end' changed = Solargraph::LanguageServer::Message::Workspace::DidChangeWatchedFiles.new(host, { - 'method' => 'workspace/didChangeWatchedFiles', - 'params' => { - 'changes' => [ - { - 'type' => Solargraph::LanguageServer::Message::Workspace::DidChangeWatchedFiles::CHANGED, - 'uri' => uri - } - ] - } - }) + 'method' => 'workspace/didChangeWatchedFiles', + 'params' => { + 'changes' => [ + { + 'type' => Solargraph::LanguageServer::Message::Workspace::DidChangeWatchedFiles::CHANGED, + 'uri' => uri + } + ] + } + }) changed.process expect(host.synchronizing?).to be(false) library = host.library_for(uri) @@ -85,16 +85,16 @@ allow(host).to receive(:create) allow(host).to receive(:delete) changed = Solargraph::LanguageServer::Message::Workspace::DidChangeWatchedFiles.new(host, { - 'method' => 'workspace/didChangeWatchedFiles', - 'params' => { - 'changes' => [ - { - 'type' => -1, - 'uri' => 'file:///foo.rb' - } - ] - } - }) + 'method' => 'workspace/didChangeWatchedFiles', + 'params' => { + 'changes' => [ + { + 'type' => -1, + 'uri' => 'file:///foo.rb' + } + ] + } + }) changed.process expect(changed.error).not_to be_nil end diff --git a/spec/language_server/message_spec.rb b/spec/language_server/message_spec.rb index 9a8c26328..4dca484d5 100644 --- a/spec/language_server/message_spec.rb +++ b/spec/language_server/message_spec.rb @@ -1,10 +1,10 @@ describe Solargraph::LanguageServer::Message do - it "returns MethodNotFound for unregistered methods" do + it 'returns MethodNotFound for unregistered methods' do msg = Solargraph::LanguageServer::Message.select 'notARealMethod' expect(msg).to be(Solargraph::LanguageServer::Message::MethodNotFound) end - it "returns MethodNotImplemented for unregistered $ methods" do + it 'returns MethodNotImplemented for unregistered $ methods' do msg = Solargraph::LanguageServer::Message.select '$/notARealMethod' expect(msg).to be(Solargraph::LanguageServer::Message::MethodNotImplemented) end diff --git a/spec/language_server/protocol_spec.rb b/spec/language_server/protocol_spec.rb index e88fb9c05..a8a97cb2f 100644 --- a/spec/language_server/protocol_spec.rb +++ b/spec/language_server/protocol_spec.rb @@ -1,5 +1,3 @@ -require 'thread' - class Protocol attr_reader :response @@ -43,16 +41,17 @@ def stop @protocol.stop end - before :each do + before do version = double(:GemVersion, version: Gem::Version.new('1.0.0')) - Solargraph::LanguageServer::Message::Extended::CheckGemVersion.fetcher = double(:fetcher, search_for_dependency: [version]) + Solargraph::LanguageServer::Message::Extended::CheckGemVersion.fetcher = double(:fetcher, + search_for_dependency: [version]) end - after :each do + after do Solargraph::LanguageServer::Message::Extended::CheckGemVersion.fetcher = nil end - it "handles initialize" do + it 'handles initialize' do @protocol.request 'initialize', { 'capabilities' => { 'textDocument' => { @@ -69,27 +68,27 @@ def stop expect(response['result'].keys).to include('capabilities') end - it "is not stopped after initialization" do + it 'is not stopped after initialization' do expect(@protocol.host.stopped?).to be(false) end - it "configured dynamic registration capabilities from initialize" do + it 'configured dynamic registration capabilities from initialize' do expect(@protocol.host.can_register?('textDocument/completion')).to be(true) expect(@protocol.host.can_register?('textDocument/hover')).to be(false) expect(@protocol.host.can_register?('workspace/symbol')).to be(false) end - it "handles initialized" do + it 'handles initialized' do @protocol.request 'initialized', nil response = @protocol.response expect(response['error']).to be_nil end - it "configured default dynamic registration capabilities from initialized" do + it 'configured default dynamic registration capabilities from initialized' do expect(@protocol.host.registered?('textDocument/completion')).to be(true) end - it "handles textDocument/didOpen" do + it 'handles textDocument/didOpen' do @protocol.request 'textDocument/didOpen', { 'textDocument' => { 'uri' => 'file:///file.rb', @@ -107,7 +106,7 @@ def bar baz 'version' => 0 } } - response = @protocol.response + @protocol.response expect(@protocol.host.open?('file:///file.rb')).to be(true) end @@ -126,7 +125,7 @@ def bar baz expect(response['result'].length).to eq(2) end - it "handles textDocument/didChange" do + it 'handles textDocument/didChange' do @protocol.request 'textDocument/didChange', { 'textDocument' => { 'uri' => 'file:///file.rb', @@ -148,11 +147,11 @@ def bar baz } ] } - response = @protocol.response + @protocol.response # @todo What to expect? end - it "handles textDocument/completion" do + it 'handles textDocument/completion' do @protocol.request 'textDocument/completion', { 'textDocument' => { 'uri' => 'file:///file.rb' @@ -167,10 +166,10 @@ def bar baz expect(response['result']['items'].length > 0).to be(true) end - it "handles completionItem/resolve" do + it 'handles completionItem/resolve' do # Reuse the response from textDocument/completion response = @protocol.response - item = response['result']['items'].select{|h| h['label'] == 'bar'}.first + item = response['result']['items'].select { |h| h['label'] == 'bar' }.first @protocol.request 'completionItem/resolve', item response = @protocol.response expect(response['result']['documentation']['value']).to include('bar method') @@ -189,7 +188,7 @@ def bar baz expect(@protocol.response['error']).to be_nil end - it "documents YARD pins" do + it 'documents YARD pins' do @protocol.request 'textDocument/completion', { 'textDocument' => { 'uri' => 'file:///file.rb' @@ -200,14 +199,14 @@ def bar baz } } response = @protocol.response - item = response['result']['items'].select{|i| i['data']['path'] == 'File.absolute_path'}.first + item = response['result']['items'].select { |i| i['data']['path'] == 'File.absolute_path' }.first expect(item).not_to be_nil @protocol.request 'completionItem/resolve', item response = @protocol.response expect(response['result']['documentation']).not_to be_empty end - it "handles workspace/symbol" do + it 'handles workspace/symbol' do @protocol.request 'workspace/symbol', { 'query' => 'test' } @@ -215,7 +214,7 @@ def bar baz expect(response['error']).to be_nil end - it "handles textDocument/definition" do + it 'handles textDocument/definition' do sleep 0.5 # HACK: Give the Host::Sources thread time to work @protocol.request 'textDocument/definition', { 'textDocument' => { @@ -231,7 +230,7 @@ def bar baz expect(response['result']).not_to be_empty end - it "handles textDocument/definition on undefined symbols" do + it 'handles textDocument/definition on undefined symbols' do @protocol.request 'textDocument/definition', { 'textDocument' => { 'uri' => 'file:///file.rb' @@ -246,7 +245,7 @@ def bar baz expect(response['result']).to be_empty end - it "handles textDocument/documentSymbol" do + it 'handles textDocument/documentSymbol' do @protocol.request 'textDocument/documentSymbol', { 'textDocument' => { 'uri' => 'file:///file.rb' @@ -256,7 +255,7 @@ def bar baz expect(response['error']).to be_nil end - it "handles textDocument/hover" do + it 'handles textDocument/hover' do @protocol.request 'textDocument/hover', { 'textDocument' => { 'uri' => 'file:///file.rb' @@ -285,7 +284,7 @@ def bar baz expect(@protocol.response['error']).to be_nil end - it "handles textDocument/signatureHelp" do + it 'handles textDocument/signatureHelp' do @protocol.request 'textDocument/signatureHelp', { 'textDocument' => { 'uri' => 'file:///file.rb' @@ -300,7 +299,7 @@ def bar baz expect(response['result']['signatures']).not_to be_empty end - it "handles workspace/symbol" do + it 'handles workspace/symbol' do @protocol.request 'workspace/symbol', { 'query' => 'Foo' } @@ -309,7 +308,7 @@ def bar baz expect(response['result']).not_to be_empty end - it "handles textDocument/references for namespaces" do + it 'handles textDocument/references for namespaces' do @protocol.request 'textDocument/references', { 'textDocument' => { 'uri' => 'file:///file.rb' @@ -324,7 +323,7 @@ def bar baz expect(response['result']).not_to be_empty end - it "handles textDocument/references for methods" do + it 'handles textDocument/references for methods' do @protocol.request 'textDocument/references', { 'textDocument' => { 'uri' => 'file:///file.rb' @@ -339,7 +338,7 @@ def bar baz expect(response['result']).not_to be_empty end - it "handles textDocument/rename" do + it 'handles textDocument/rename' do @protocol.request 'textDocument/rename', { 'textDocument' => { 'uri' => 'file:///file.rb' @@ -355,7 +354,7 @@ def bar baz expect(response['result']['changes']['file:///file.rb']).to be_a(Array) end - it "handles textDocument/prepareRename" do + it 'handles textDocument/prepareRename' do @protocol.request 'textDocument/prepareRename', { 'textDocument' => { 'uri' => 'file:///file.rb' @@ -371,7 +370,7 @@ def bar baz expect(response['result']).to be_a(Hash) end - it "handles textDocument/foldingRange" do + it 'handles textDocument/foldingRange' do @protocol.request 'textDocument/foldingRange', { 'textDocument' => { 'uri' => 'file:///file.rb' @@ -382,17 +381,17 @@ def bar baz expect(response['result'].length).not_to be_zero end - it "handles textDocument/didClose" do + it 'handles textDocument/didClose' do @protocol.request 'textDocument/didClose', { 'textDocument' => { 'uri' => 'file:///file.rb' } } - response = @protocol.response + @protocol.response expect(@protocol.host.open?('file:///file.rb')).to be(false) end - it "handles $/solargraph/search" do + it 'handles $/solargraph/search' do @protocol.request '$/solargraph/search', { 'query' => 'Foo#bar' } @@ -401,7 +400,7 @@ def bar baz expect(response['result']['content']).not_to be_empty end - it "handles $/solargraph/document" do + it 'handles $/solargraph/document' do @protocol.request '$/solargraph/document', { 'query' => 'String' } @@ -410,7 +409,7 @@ def bar baz expect(response['result']['content']).not_to be_empty end - it "handles workspace/didChangeConfiguration" do + it 'handles workspace/didChangeConfiguration' do @protocol.request 'workspace/didChangeConfiguration', { 'settings' => { 'solargraph' => { @@ -423,7 +422,7 @@ def bar baz expect(@protocol.host.registered?('textDocument/completion')).to be(false) end - it "handles $/solargraph/checkGemVersion" do + it 'handles $/solargraph/checkGemVersion' do @protocol.request '$/solargraph/checkGemVersion', { verbose: false } response = @protocol.response expect(response['error']).to be_nil @@ -431,13 +430,13 @@ def bar baz expect(response['result']['available']).to be_a(String) end - it "handles $/solargraph/documentGems" do + it 'handles $/solargraph/documentGems' do @protocol.request '$/solargraph/documentGems', {} response = @protocol.response expect(response['error']).to be_nil end - it "handles textDocument/formatting" do + it 'handles textDocument/formatting' do @protocol.request 'textDocument/didOpen', { 'textDocument' => { 'uri' => Solargraph::LanguageServer::UriHelpers.file_to_uri(File.realpath('spec/fixtures/formattable.rb')), @@ -455,7 +454,7 @@ def bar baz expect(response['result'].first['newText']).to be_a(String) end - it "can format file without file extension" do + it 'can format file without file extension' do @protocol.request 'textDocument/didOpen', { 'textDocument' => { 'uri' => Solargraph::LanguageServer::UriHelpers.file_to_uri(File.realpath('spec/fixtures/formattable')), @@ -474,13 +473,13 @@ def bar baz # expect(response['result'].first['newText']).to include('def barbaz(parameter); end') end - it "handles MethodNotFound errors" do + it 'handles MethodNotFound errors' do @protocol.request 'notamethod', {} response = @protocol.response expect(response['error']['code']).to be(Solargraph::LanguageServer::ErrorCodes::METHOD_NOT_FOUND) end - it "handles didChangeWatchedFiles for created files" do + it 'handles didChangeWatchedFiles for created files' do @protocol.request 'workspace/didChangeWatchedFiles', { 'changes' => [ { @@ -493,7 +492,7 @@ def bar baz expect(response['error']).to be_nil end - it "handles didChangeWatchedFiles for changed files" do + it 'handles didChangeWatchedFiles for changed files' do @protocol.request 'workspace/didChangeWatchedFiles', { 'changes' => [ { @@ -506,7 +505,7 @@ def bar baz expect(response['error']).to be_nil end - it "handles didChangeWatchedFiles for deleted files" do + it 'handles didChangeWatchedFiles for deleted files' do @protocol.request 'workspace/didChangeWatchedFiles', { 'changes' => [ { @@ -519,11 +518,11 @@ def bar baz expect(response['error']).to be_nil end - it "handles didChangeWatchedFiles for invalid change types" do + it 'handles didChangeWatchedFiles for invalid change types' do @protocol.request 'workspace/didChangeWatchedFiles', { 'changes' => [ { - 'type' => -99999, + 'type' => -99_999, 'uri' => 'file:///watched-file.rb' } ] @@ -532,7 +531,7 @@ def bar baz expect(response['error']).not_to be_nil end - it "adds folders to the workspace" do + it 'adds folders to the workspace' do dir = File.absolute_path('spec/fixtures/workspace_folders/folder1') uri = Solargraph::LanguageServer::UriHelpers.file_to_uri(dir) @protocol.request 'workspace/didChangeWorkspaceFolders', { @@ -549,7 +548,7 @@ def bar baz expect(@protocol.host.folders).to include(dir) end - it "removes folders from the workspace" do + it 'removes folders from the workspace' do dir = File.absolute_path('spec/fixtures/workspace_folders/folder1') uri = Solargraph::LanguageServer::UriHelpers.file_to_uri(dir) @protocol.request 'workspace/didChangeWorkspaceFolders', { @@ -566,27 +565,27 @@ def bar baz expect(@protocol.host.folders).not_to include(dir) end - it "handles $/cancelRequest" do - expect { + it 'handles $/cancelRequest' do + expect do @protocol.request '$/cancelRequest', { 'id' => 0 } - }.not_to raise_error + end.not_to raise_error end - it "handles $/solargraph/environment" do + it 'handles $/solargraph/environment' do @protocol.request '$/solargraph/environment', {} response = @protocol.response expect(response['result']['content']).not_to be_nil end - it "handles shutdown" do + it 'handles shutdown' do @protocol.request 'shutdown', {} response = @protocol.response expect(response['error']).to be_nil end - it "handles exit" do + it 'handles exit' do @protocol.request 'exit', {} response = @protocol.response expect(response['error']).to be_nil diff --git a/spec/language_server/transport/adapter_spec.rb b/spec/language_server/transport/adapter_spec.rb index 3d30dd4e6..6ec360395 100644 --- a/spec/language_server/transport/adapter_spec.rb +++ b/spec/language_server/transport/adapter_spec.rb @@ -15,21 +15,21 @@ def flush end describe Solargraph::LanguageServer::Transport::Adapter do - it "creates a host on open" do + it 'creates a host on open' do tester = AdapterTester.new tester.opening expect(tester.host).to be_a(Solargraph::LanguageServer::Host) expect(tester.host).not_to be_stopped end - it "stops a host on close" do + it 'stops a host on close' do tester = AdapterTester.new tester.opening tester.closing expect(tester.host).to be_stopped end - it "stops Backport when the host stops" do + it 'stops Backport when the host stops' do tester = AdapterTester.new Backport.run do tester.opening @@ -40,13 +40,13 @@ def flush expect(tester.host).to be_stopped end - it "processes sent data" do + it 'processes sent data' do tester = AdapterTester.new tester.opening message = '{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {}}' - expect { + expect do tester.receiving "Content-Length: #{message.length}\r\n\r\n#{message}" - }.not_to raise_error + end.not_to raise_error tester.closing end end diff --git a/spec/language_server/transport/data_reader_spec.rb b/spec/language_server/transport/data_reader_spec.rb index c035d2b2c..bf9bbcc15 100644 --- a/spec/language_server/transport/data_reader_spec.rb +++ b/spec/language_server/transport/data_reader_spec.rb @@ -1,8 +1,8 @@ describe Solargraph::LanguageServer::Transport::DataReader do - it "rescues exceptions for invalid JSON" do + it 'rescues exceptions for invalid JSON' do reader = Solargraph::LanguageServer::Transport::DataReader.new handled = 0 - reader.set_message_handler do |msg| + reader.set_message_handler do |_msg| handled += 1 end msg = { @@ -10,9 +10,9 @@ method: 'test' }.to_json msg += '}' - expect { + expect do reader.receive "Content-Length:#{msg.bytesize}\r\n\r\n#{msg}" - }.not_to raise_error + end.not_to raise_error expect(handled).to eq(0) end end diff --git a/spec/library_spec.rb b/spec/library_spec.rb index 34de9e1f0..41c6102e7 100644 --- a/spec/library_spec.rb +++ b/spec/library_spec.rb @@ -2,7 +2,7 @@ require 'yard' describe Solargraph::Library do - it "does not open created files in the workspace" do + it 'does not open created files in the workspace' do Dir.mktmpdir do |temp_dir_path| # Ensure we resolve any symlinks to their real path workspace_path = File.realpath(temp_dir_path) @@ -15,7 +15,7 @@ end end - it "returns a Completion" do + it 'returns a Completion' do library = Solargraph::Library.new library.attach Solargraph::Source.load_string(%( x = 1 @@ -31,7 +31,7 @@ Solargraph::Shell.new.gems('backport') end - it "returns a Completion" do + it 'returns a Completion' do library = Solargraph::Library.new(Solargraph::Workspace.new(Dir.pwd, Solargraph::Workspace::Config.new)) library.attach Solargraph::Source.load_string(%( @@ -48,7 +48,7 @@ def foo(adapter) end end - it "gets definitions from a file" do + it 'gets definitions from a file' do library = Solargraph::Library.new src = Solargraph::Source.load_string %( class Foo @@ -61,7 +61,7 @@ def bar expect(paths).to include('Foo#bar') end - it "gets type definitions from a file" do + it 'gets type definitions from a file' do library = Solargraph::Library.new src = Solargraph::Source.load_string %( class Bar; end @@ -77,7 +77,7 @@ def self.bar expect(paths).to include('Bar') end - it "signifies method arguments" do + it 'signifies method arguments' do library = Solargraph::Library.new src = Solargraph::Source.load_string %( class Foo @@ -92,14 +92,14 @@ def bar baz, key: '' expect(pins.first.path).to eq('Foo#bar') end - it "ignores invalid filenames in create_from_disk" do + it 'ignores invalid filenames in create_from_disk' do library = Solargraph::Library.new filename = 'not_a_real_file.rb' expect(library.create_from_disk(filename)).to be(false) expect(library.contain?(filename)).to be(false) end - it "adds mergeable files to the workspace in create_from_disk" do + it 'adds mergeable files to the workspace in create_from_disk' do Dir.mktmpdir do |temp_dir_path| # Ensure we resolve any symlinks to their real path workspace_path = File.realpath(temp_dir_path) @@ -111,7 +111,7 @@ def bar baz, key: '' end end - it "ignores non-mergeable files in create_from_disk" do + it 'ignores non-mergeable files in create_from_disk' do Dir.mktmpdir do |dir| library = Solargraph::Library.load(dir) filename = File.join(dir, 'created.txt') @@ -121,7 +121,7 @@ def bar baz, key: '' end end - it "diagnoses files" do + it 'diagnoses files' do library = Solargraph::Library.new src = Solargraph::Source.load_string(%( puts 'hello' @@ -146,7 +146,7 @@ def bar baz, key: '' expect(result.to_s).to include('rubocop') end - it "documents symbols" do + it 'documents symbols' do library = Solargraph::Library.new src = Solargraph::Source.load_string(%( class Foo @@ -161,7 +161,7 @@ def bar expect(pins.map(&:path)).to include('Foo#bar') end - it "collects references to an instance method symbol" do + it 'collects references to an instance method symbol' do workspace = Solargraph::Workspace.new('*') library = Solargraph::Library.new(workspace) src1 = Solargraph::Source.load_string(%( @@ -185,10 +185,10 @@ def bar; end library.catalog locs = library.references_from('file2.rb', 2, 11) expect(locs.length).to eq(3) - expect(locs.select{|l| l.filename == 'file2.rb' && l.range.start.line == 6}).to be_empty + expect(locs.select { |l| l.filename == 'file2.rb' && l.range.start.line == 6 }).to be_empty end - it "collects references to a class method symbol" do + it 'collects references to a class method symbol' do workspace = Solargraph::Workspace.new('*') library = Solargraph::Library.new(workspace) src1 = Solargraph::Source.load_string(%( @@ -218,12 +218,12 @@ def bar; end library.catalog locs = library.references_from('file2.rb', 1, 11) expect(locs.length).to eq(3) - expect(locs.select{|l| l.filename == 'file1.rb' && l.range.start.line == 2}).not_to be_empty - expect(locs.select{|l| l.filename == 'file1.rb' && l.range.start.line == 9}).not_to be_empty - expect(locs.select{|l| l.filename == 'file2.rb' && l.range.start.line == 1}).not_to be_empty + expect(locs.select { |l| l.filename == 'file1.rb' && l.range.start.line == 2 }).not_to be_empty + expect(locs.select { |l| l.filename == 'file1.rb' && l.range.start.line == 9 }).not_to be_empty + expect(locs.select { |l| l.filename == 'file2.rb' && l.range.start.line == 1 }).not_to be_empty end - it "collects stripped references to constant symbols" do + it 'collects stripped references to constant symbols' do workspace = Solargraph::Workspace.new('*') library = Solargraph::Library.new(workspace) src1 = Solargraph::Source.load_string(%( @@ -248,7 +248,7 @@ class Other code = library.read_text(l.filename) o1 = Solargraph::Position.to_offset(code, l.range.start) o2 = Solargraph::Position.to_offset(code, l.range.ending) - expect(code[o1..o2-1]).to eq('Foo') + expect(code[o1..o2 - 1]).to eq('Foo') end end @@ -271,20 +271,20 @@ def bar expect(obj_new_locs).to eq([Solargraph::Location.new('test.rb', Solargraph::Range.from_to(6, 12, 6, 15))]) end - it "searches the core for queries" do + it 'searches the core for queries' do library = Solargraph::Library.new result = library.search('String') expect(result).not_to be_empty end - it "returns YARD documentation from the core" do + it 'returns YARD documentation from the core' do library = Solargraph::Library.new - api_map, result = library.document('String') + _, result = library.document('String') expect(result).not_to be_empty expect(result.first).to be_a(Solargraph::Pin::Base) end - it "returns YARD documentation from sources" do + it 'returns YARD documentation from sources' do library = Solargraph::Library.new src = Solargraph::Source.load_string(%( class Foo @@ -293,12 +293,12 @@ def bar; end end ), 'test.rb', 0) library.attach src - api_map, result = library.document('Foo#bar') + _, result = library.document('Foo#bar') expect(result).not_to be_empty expect(result.first).to be_a(Solargraph::Pin::Base) end - it "synchronizes sources from updaters" do + it 'synchronizes sources from updaters' do library = Solargraph::Library.new src = Solargraph::Source.load_string(%( class Foo @@ -319,7 +319,7 @@ def bar; end expect(library.current.code).to eq(repl) end - it "finds unique references" do + it 'finds unique references' do library = Solargraph::Library.new(Solargraph::Workspace.new('*')) src1 = Solargraph::Source.load_string(%( class Foo @@ -335,7 +335,7 @@ class Foo expect(refs.length).to eq(2) end - it "includes method parameters in references" do + it 'includes method parameters in references' do library = Solargraph::Library.new(Solargraph::Workspace.new('*')) source = Solargraph::Source.load_string(%( class Foo @@ -351,7 +351,7 @@ def bar(baz) expect(from_ref.length).to eq(2) end - it "includes block parameters in references" do + it 'includes block parameters in references' do library = Solargraph::Library.new(Solargraph::Workspace.new('*')) source = Solargraph::Source.load_string(%( 100.times do |foo| @@ -542,29 +542,29 @@ def bar; end describe 'Library#completions_at' do it 'gracefully handles unmapped sources' do - expect { + expect do library.completions_at(good_file, 0, 0) - }.not_to raise_error + end.not_to raise_error end it 'raises errors for nonexistent sources' do - expect { + expect do library.completions_at(bad_file, 0, 0) - }.to raise_error(Solargraph::FileNotFoundError) + end.to raise_error(Solargraph::FileNotFoundError) end end describe 'Library#definitions_at' do it 'gracefully handles unmapped sources' do - expect { + expect do library.definitions_at(good_file, 0, 0) - }.not_to raise_error + end.not_to raise_error end it 'raises errors for nonexistent sources' do - expect { + expect do library.definitions_at(bad_file, 0, 0) - }.to raise_error(Solargraph::FileNotFoundError) + end.to raise_error(Solargraph::FileNotFoundError) end end end diff --git a/spec/logging_spec.rb b/spec/logging_spec.rb index eee59e606..1913bc81e 100644 --- a/spec/logging_spec.rb +++ b/spec/logging_spec.rb @@ -1,10 +1,10 @@ require 'tempfile' describe Solargraph::Logging do - it "logs messages with levels" do + it 'logs messages with levels' do file = Tempfile.new('log') Solargraph::Logging.logger.reopen file - Solargraph::Logging.logger.warn "Test" + Solargraph::Logging.logger.warn 'Test' file.rewind msg = file.read file.close diff --git a/spec/parser/node_chainer_spec.rb b/spec/parser/node_chainer_spec.rb index e92431aae..51badf296 100644 --- a/spec/parser/node_chainer_spec.rb +++ b/spec/parser/node_chainer_spec.rb @@ -1,29 +1,29 @@ describe 'NodeChainer' do - it "recognizes self keywords" do + it 'recognizes self keywords' do chain = Solargraph::Parser.chain_string('self.foo') expect(chain.links.first.word).to eq('self') expect(chain.links.first).to be_a(Solargraph::Source::Chain::Head) end - it "recognizes super keywords" do + it 'recognizes super keywords' do chain = Solargraph::Parser.chain_string('super.foo') expect(chain.links.first.word).to eq('super') expect(chain.links.first).to be_a(Solargraph::Source::Chain::ZSuper) end - it "recognizes constants" do + it 'recognizes constants' do chain = Solargraph::Parser.chain_string('Foo::Bar') expect(chain.links.length).to eq(1) expect(chain.links.first).to be_a(Solargraph::Source::Chain::Constant) expect(chain.links.map(&:word)).to eq(['Foo::Bar']) end - it "splits method calls with arguments and blocks" do + it 'splits method calls with arguments and blocks' do chain = Solargraph::Parser.chain_string('var.meth1(1, 2).meth2 do; end') - expect(chain.links.map(&:word)).to eq(['var', 'meth1', 'meth2']) + expect(chain.links.map(&:word)).to eq(%w[var meth1 meth2]) end - it "recognizes literals" do + it 'recognizes literals' do chain = Solargraph::Parser.chain_string('"string"') expect(chain).to be_literal chain = Solargraph::Parser.chain_string('100') @@ -34,22 +34,22 @@ expect(chain).to be_literal end - it "recognizes instance variables" do + it 'recognizes instance variables' do chain = Solargraph::Parser.chain_string('@foo') expect(chain.links.first).to be_a(Solargraph::Source::Chain::InstanceVariable) end - it "recognizes class variables" do + it 'recognizes class variables' do chain = Solargraph::Parser.chain_string('@@foo') expect(chain.links.first).to be_a(Solargraph::Source::Chain::ClassVariable) end - it "recognizes global variables" do + it 'recognizes global variables' do chain = Solargraph::Parser.chain_string('$foo') expect(chain.links.first).to be_a(Solargraph::Source::Chain::GlobalVariable) end - it "operates on nodes" do + it 'operates on nodes' do source = Solargraph::Source.load_string(%( class Foo Bar.meth1(1, 2).meth2{} @@ -57,7 +57,7 @@ class Foo )) node = source.node_at(2, 26) chain = Solargraph::Parser.chain(node) - expect(chain.links.map(&:word)).to eq(['Bar', 'meth1', 'meth2']) + expect(chain.links.map(&:word)).to eq(%w[Bar meth1 meth2]) end it 'chains and/or nodes' do diff --git a/spec/parser/node_methods_spec.rb b/spec/parser/node_methods_spec.rb index f9504b584..63a5ed04d 100644 --- a/spec/parser/node_methods_spec.rb +++ b/spec/parser/node_methods_spec.rb @@ -1,64 +1,64 @@ # These tests are deliberately generic because they apply to both the Legacy # and Rubyvm node methods. describe Solargraph::Parser::NodeMethods do - it "unpacks constant nodes into strings" do - ast = Solargraph::Parser.parse("Foo::Bar") - expect(Solargraph::Parser::NodeMethods.unpack_name(ast)).to eq "Foo::Bar" + it 'unpacks constant nodes into strings' do + ast = Solargraph::Parser.parse('Foo::Bar') + expect(Solargraph::Parser::NodeMethods.unpack_name(ast)).to eq 'Foo::Bar' end - it "infers literal strings" do + it 'infers literal strings' do ast = Solargraph::Parser.parse("x = 'string'") expect(Solargraph::Parser::NodeMethods.infer_literal_node_type(ast.children[1])).to eq '::String' end - it "infers literal hashes" do - ast = Solargraph::Parser.parse("x = {}") + it 'infers literal hashes' do + ast = Solargraph::Parser.parse('x = {}') expect(Solargraph::Parser::NodeMethods.infer_literal_node_type(ast.children[1])).to eq '::Hash' end - it "infers literal arrays" do - ast = Solargraph::Parser.parse("x = []") + it 'infers literal arrays' do + ast = Solargraph::Parser.parse('x = []') expect(Solargraph::Parser::NodeMethods.infer_literal_node_type(ast.children[1])).to eq '::Array' end - it "infers literal integers" do - ast = Solargraph::Parser.parse("x = 100") + it 'infers literal integers' do + ast = Solargraph::Parser.parse('x = 100') expect(Solargraph::Parser::NodeMethods.infer_literal_node_type(ast.children[1])).to eq '::Integer' end - it "infers literal floats" do - ast = Solargraph::Parser.parse("x = 10.1") + it 'infers literal floats' do + ast = Solargraph::Parser.parse('x = 10.1') expect(Solargraph::Parser::NodeMethods.infer_literal_node_type(ast.children[1])).to eq '::Float' end - it "infers literal symbols" do - ast = Solargraph::Parser.parse(":symbol") + it 'infers literal symbols' do + ast = Solargraph::Parser.parse(':symbol') expect(Solargraph::Parser::NodeMethods.infer_literal_node_type(ast)).to eq '::Symbol' end - it "infers double quoted symbols" do + it 'infers double quoted symbols' do ast = Solargraph::Parser.parse(':"symbol"') expect(Solargraph::Parser::NodeMethods.infer_literal_node_type(ast)).to eq '::Symbol' end - it "infers interpolated double quoted symbols" do + it 'infers interpolated double quoted symbols' do ast = Solargraph::Parser.parse(':"#{Object}"') expect(Solargraph::Parser::NodeMethods.infer_literal_node_type(ast)).to eq '::Symbol' end - it "infers single quoted symbols" do + it 'infers single quoted symbols' do ast = Solargraph::Parser.parse(":'symbol'") expect(Solargraph::Parser::NodeMethods.infer_literal_node_type(ast)).to eq '::Symbol' end it 'infers literal booleans' do - true_ast = Solargraph::Parser.parse("true") + true_ast = Solargraph::Parser.parse('true') expect(Solargraph::Parser::NodeMethods.infer_literal_node_type(true_ast)).to eq '::Boolean' - false_ast = Solargraph::Parser.parse("false") + false_ast = Solargraph::Parser.parse('false') expect(Solargraph::Parser::NodeMethods.infer_literal_node_type(false_ast)).to eq '::Boolean' end - it "handles return nodes with implicit nil values" do + it 'handles return nodes with implicit nil values' do node = Solargraph::Parser.parse(%( return if true )) @@ -68,7 +68,7 @@ expect(rets.length).to eq(2) end - it "handles return nodes with implicit nil values" do + it 'handles return nodes with implicit nil values' do node = Solargraph::Parser.parse(%( return bla if true )) @@ -126,7 +126,7 @@ expect(returns.length).to eq(2) end - it "handles return nodes in reduceable (begin) nodes" do + it 'handles return nodes in reduceable (begin) nodes' do # @todo Temporarily disabled. Result is 3 nodes instead of 2. # node = Solargraph::Parser.parse(%( # begin @@ -137,7 +137,7 @@ # expect(rets.length).to eq(2) end - it "handles return nodes after other nodes" do + it 'handles return nodes after other nodes' do node = Solargraph::Parser.parse(%( x = 1 return x @@ -146,7 +146,7 @@ expect(rets.length).to eq(1) end - it "handles return nodes with unreachable code" do + it 'handles return nodes with unreachable code' do node = Solargraph::Parser.parse(%( x = 1 return x @@ -156,7 +156,7 @@ expect(rets.length).to eq(1) end - it "handles conditional returns with following code" do + it 'handles conditional returns with following code' do node = Solargraph::Parser.parse(%( x = 1 return x if foo @@ -166,7 +166,7 @@ expect(rets.length).to eq(2) end - it "handles return nodes with reduceable code" do + it 'handles return nodes with reduceable code' do node = Solargraph::Parser.parse(%( return begin x if foo @@ -214,7 +214,7 @@ end )) rets = Solargraph::Parser::NodeMethods.returns_from_method_body(node) - expect(rets.map(&:type)).to eq([:block, :lvar]) + expect(rets.map(&:type)).to eq(%i[block lvar]) end it 'finds correct return node line in begin expressions' do @@ -238,10 +238,10 @@ nil )) rets = Solargraph::Parser::NodeMethods.returns_from_method_body(node) - expect(rets.map(&:type)).to eq([:lvar, :nil]) + expect(rets.map(&:type)).to eq(%i[lvar nil]) end - it "handles return nodes with implicit nil values" do + it 'handles return nodes with implicit nil values' do node = Solargraph::Parser.parse(%( return if true )) @@ -251,15 +251,15 @@ expect(rets.length).to eq(2) end - it "handles return nodes with implicit nil values" do + it 'handles return nodes with implicit nil values' do node = Solargraph::Parser.parse(%( return bla if true )) rets = Solargraph::Parser::NodeMethods.returns_from_method_body(node) - expect(rets.map(&:type)).to eq([:send, :nil]) + expect(rets.map(&:type)).to eq(%i[send nil]) end - it "handles return nodes in reduceable (begin) nodes" do + it 'handles return nodes in reduceable (begin) nodes' do # @todo Temporarily disabled. Result is 3 nodes instead of 2 in legacy. # node = Solargraph::Parser.parse(%( # begin @@ -270,7 +270,7 @@ # expect(rets.length).to eq(2) end - it "handles return nodes after other nodes" do + it 'handles return nodes after other nodes' do node = Solargraph::Parser.parse(%( x = 1 return x @@ -279,7 +279,7 @@ expect(rets.map(&:type)).to eq([:lvar]) end - it "handles return nodes with unreachable code" do + it 'handles return nodes with unreachable code' do node = Solargraph::Parser.parse(%( x = 1 return x @@ -289,7 +289,7 @@ expect(rets.length).to eq(1) end - xit "short-circuits return node finding after a raise statement in a begin expressiona" do + xit 'short-circuits return node finding after a raise statement in a begin expressiona' do node = Solargraph::Parser.parse(%( raise "Error" y @@ -298,7 +298,7 @@ expect(rets.length).to eq(0) end - it "does not short circuit return node finding after a raise statement in a conditional" do + it 'does not short circuit return node finding after a raise statement in a conditional' do node = Solargraph::Parser.parse(%( x = 1 raise "Error" if foo @@ -308,7 +308,7 @@ expect(rets.length).to eq(1) end - it "does not short circuit return node finding after a return statement in a conditional" do + it 'does not short circuit return node finding after a return statement in a conditional' do node = Solargraph::Parser.parse(%( x = 1 return "Error" if foo @@ -318,7 +318,7 @@ expect(rets.length).to eq(2) end - it "handles return nodes with reduceable code" do + it 'handles return nodes with reduceable code' do node = Solargraph::Parser.parse(%( return begin x if foo @@ -338,7 +338,7 @@ it "handles top 'or' nodes" do node = Solargraph::Parser.parse('1 || "2"') rets = Solargraph::Parser::NodeMethods.returns_from_method_body(node) - expect(rets.map(&:type)).to eq([:int, :str]) + expect(rets.map(&:type)).to eq(%i[int str]) end it "handles nested 'and' nodes from return" do @@ -350,7 +350,7 @@ it "handles nested 'or' nodes from return" do node = Solargraph::Parser.parse('return 1 || "2"') rets = Solargraph::Parser::NodeMethods.returns_from_method_body(node) - expect(rets.map(&:type)).to eq([:int, :str]) + expect(rets.map(&:type)).to eq(%i[int str]) end it 'finds return nodes in blocks' do @@ -360,7 +360,7 @@ end )) rets = Solargraph::Parser::NodeMethods.returns_from_method_body(node) - expect(rets.map(&:type)).to eq([:block, :lvar]) + expect(rets.map(&:type)).to eq(%i[block lvar]) # expect(rets[1].type).to eq(:DVAR) end @@ -374,7 +374,7 @@ nil )) rets = Solargraph::Parser::NodeMethods.returns_from_method_body(node) - expect(rets.map(&:type)).to eq([:lvar, :nil]) + expect(rets.map(&:type)).to eq(%i[lvar nil]) # expect(rets[0].type).to eq(:DVAR) end @@ -387,7 +387,7 @@ end )) rets = Solargraph::Parser::NodeMethods.returns_from_method_body(node) - expect(rets.map(&:type)).to eq([:str, :str]) + expect(rets.map(&:type)).to eq(%i[str str]) end it 'handles return nodes from case statements without else' do @@ -398,7 +398,7 @@ end )) rets = Solargraph::Parser::NodeMethods.returns_from_method_body(node) - expect(rets.map(&:type)).to eq([:str, :nil]) + expect(rets.map(&:type)).to eq(%i[str nil]) end it 'handles return nodes from case statements with super' do @@ -411,7 +411,7 @@ end )) rets = Solargraph::Parser::NodeMethods.returns_from_method_body(node) - expect(rets.map(&:type)).to eq([:send, :zsuper]) + expect(rets.map(&:type)).to eq(%i[send zsuper]) end describe 'convert_hash' do diff --git a/spec/parser/node_processor_spec.rb b/spec/parser/node_processor_spec.rb index 5b8d7cd40..fcea4e825 100644 --- a/spec/parser/node_processor_spec.rb +++ b/spec/parser/node_processor_spec.rb @@ -5,9 +5,9 @@ class Foo private_constant end )) - expect { + expect do Solargraph::Parser::NodeProcessor.process(node) - }.not_to raise_error + end.not_to raise_error end it 'orders optional args correctly' do diff --git a/spec/parser_spec.rb b/spec/parser_spec.rb index 267f412f4..becfbe4a9 100644 --- a/spec/parser_spec.rb +++ b/spec/parser_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::Parser do - it "parses nodes" do + it 'parses nodes' do node = Solargraph::Parser.parse('class Foo; end', 'test.rb') expect(Solargraph::Parser.is_ast_node?(node)).to be(true) end diff --git a/spec/pin/base_spec.rb b/spec/pin/base_spec.rb index 1a6cfd1e8..97de966df 100644 --- a/spec/pin/base_spec.rb +++ b/spec/pin/base_spec.rb @@ -2,7 +2,7 @@ let(:zero_location) { Solargraph::Location.new('test.rb', Solargraph::Range.from_to(0, 0, 0, 0)) } let(:one_location) { Solargraph::Location.new('test.rb', Solargraph::Range.from_to(0, 0, 1, 0)) } - it "will not combine pins with directive changes" do + it 'does not combine pins with directive changes' do pin1 = Solargraph::Pin::Base.new(location: zero_location, name: 'Foo', comments: 'A Foo class', source: :yardoc, closure: Solargraph::Pin::ROOT_PIN) pin2 = Solargraph::Pin::Base.new(location: zero_location, name: 'Foo', comments: '@!macro my_macro', @@ -14,7 +14,7 @@ end end - it "will not combine pins with different directives" do + it 'does not combine pins with different directives' do pin1 = Solargraph::Pin::Base.new(location: zero_location, name: 'Foo', comments: '@!macro my_macro', source: :yardoc, closure: Solargraph::Pin::ROOT_PIN) pin2 = Solargraph::Pin::Base.new(location: zero_location, name: 'Foo', comments: '@!macro other', @@ -25,26 +25,26 @@ end end - it "sees tag differences as not near or equal" do + it 'sees tag differences as not near or equal' do pin1 = Solargraph::Pin::Base.new(location: zero_location, name: 'Foo', comments: '@return [Foo]') pin2 = Solargraph::Pin::Base.new(location: zero_location, name: 'Foo', comments: '@return [Bar]') expect(pin1.nearly?(pin2)).to be(false) expect(pin1 == pin2).to be(false) end - it "sees comment differences as nearly but not equal" do + it 'sees comment differences as nearly but not equal' do pin1 = Solargraph::Pin::Base.new(location: zero_location, name: 'Foo', comments: 'A Foo class') pin2 = Solargraph::Pin::Base.new(location: zero_location, name: 'Foo', comments: 'A different Foo') expect(pin1.nearly?(pin2)).to be(true) expect(pin1 == pin2).to be(false) end - it "recognizes deprecated tags" do + it 'recognizes deprecated tags' do pin = Solargraph::Pin::Base.new(location: zero_location, name: 'Foo', comments: '@deprecated Use Bar instead.') expect(pin).to be_deprecated end - it "does not link documentation for undefined return types" do + it 'does not link documentation for undefined return types' do pin = Solargraph::Pin::Base.new(name: 'Foo', comments: '@return [undefined]') expect(pin.link_documentation).to eq('Foo') end @@ -56,8 +56,8 @@ expect(pins.length).to eq(1) parser_method_pin = pins.first return_type = parser_method_pin.typify(api_map) - expect(parser_method_pin.closure.name).to eq("Docstring") - expect(parser_method_pin.closure.gates).to eq(["YARD::Docstring", "YARD", '']) + expect(parser_method_pin.closure.name).to eq('Docstring') + expect(parser_method_pin.closure.gates).to eq(['YARD::Docstring', 'YARD', '']) expect(return_type).to be_defined expect(parser_method_pin.typify(api_map).rooted_tags).to eq('::YARD::DocstringParser') end diff --git a/spec/pin/base_variable_spec.rb b/spec/pin/base_variable_spec.rb index 8c462bff3..7990ab691 100644 --- a/spec/pin/base_variable_spec.rb +++ b/spec/pin/base_variable_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::Pin::BaseVariable do - it "checks assignments for equality" do + it 'checks assignments for equality' do smap = Solargraph::SourceMap.load_string('foo = "foo"') pin1 = smap.locals.first smap = Solargraph::SourceMap.load_string('foo = "foo"') diff --git a/spec/pin/constant_spec.rb b/spec/pin/constant_spec.rb index 7a7fdb0c9..124c36174 100644 --- a/spec/pin/constant_spec.rb +++ b/spec/pin/constant_spec.rb @@ -1,23 +1,23 @@ describe Solargraph::Pin::Constant do - it "resolves constant paths" do + it 'resolves constant paths' do source = Solargraph::Source.new(%( class Foo BAR = 'bar' end )) map = Solargraph::SourceMap.map(source) - pin = map.pins.select{|pin| pin.name == 'BAR'}.first + pin = map.pins.select { |pin| pin.name == 'BAR' }.first expect(pin.path).to eq('Foo::BAR') end - it "is a constant kind" do + it 'is a constant kind' do source = Solargraph::Source.new(%( class Foo BAR = 'bar' end )) map = Solargraph::SourceMap.map(source) - pin = map.pins.select{|pin| pin.name == 'BAR'}.first + pin = map.pins.select { |pin| pin.name == 'BAR' }.first expect(pin.completion_item_kind).to eq(Solargraph::LanguageServer::CompletionItemKinds::CONSTANT) expect(pin.symbol_kind).to eq(Solargraph::LanguageServer::SymbolKinds::CONSTANT) end diff --git a/spec/pin/documenting_spec.rb b/spec/pin/documenting_spec.rb index 1fdf9b8de..42da36dd1 100644 --- a/spec/pin/documenting_spec.rb +++ b/spec/pin/documenting_spec.rb @@ -1,11 +1,11 @@ describe Solargraph::Pin::Documenting do - let(:object) { + let(:object) do Class.new do include Solargraph::Pin::Documenting attr_accessor :docstring end.new - } + end it 'parses indented code blocks' do object.docstring = YARD::Docstring.new(%(Method overview diff --git a/spec/pin/instance_variable_spec.rb b/spec/pin/instance_variable_spec.rb index fd6203398..c9fd036d7 100644 --- a/spec/pin/instance_variable_spec.rb +++ b/spec/pin/instance_variable_spec.rb @@ -1,13 +1,13 @@ describe Solargraph::Pin::InstanceVariable do - it "is a kind of variable" do + it 'is a kind of variable' do source = Solargraph::Source.load_string("@foo = 'foo'", 'file.rb') map = Solargraph::SourceMap.map(source) - pin = map.pins.select{ |p| p.is_a?(Solargraph::Pin::InstanceVariable) }.first + pin = map.pins.select { |p| p.is_a?(Solargraph::Pin::InstanceVariable) }.first expect(pin.completion_item_kind).to eq(Solargraph::LanguageServer::CompletionItemKinds::VARIABLE) expect(pin.symbol_kind).to eq(Solargraph::LanguageServer::SymbolKinds::VARIABLE) end - it "does not link documentation for undefined return types" do + it 'does not link documentation for undefined return types' do pin = Solargraph::Pin::InstanceVariable.new(name: '@bar') expect(pin.link_documentation).to eq('@bar') end diff --git a/spec/pin/keyword_spec.rb b/spec/pin/keyword_spec.rb index 82bb373ef..99e51f287 100644 --- a/spec/pin/keyword_spec.rb +++ b/spec/pin/keyword_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::Pin::Keyword do - it "is a kind of keyword" do + it 'is a kind of keyword' do pin = Solargraph::Pin::Keyword.new('foo') expect(pin.completion_item_kind).to eq(Solargraph::LanguageServer::CompletionItemKinds::KEYWORD) end diff --git a/spec/pin/local_variable_spec.rb b/spec/pin/local_variable_spec.rb index 88075efb9..4a70c943b 100644 --- a/spec/pin/local_variable_spec.rb +++ b/spec/pin/local_variable_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::Pin::LocalVariable do - xit "merges presence changes so that [not currently used]" do + xit 'merges presence changes so that [not currently used]' do map1 = Solargraph::SourceMap.load_string(%( class Foo foo = 'foo' @@ -24,13 +24,12 @@ class Foo combined = pin1.combine_with(pin2) expect(combined).to be_a(Solargraph::Pin::LocalVariable) - expect(combined.source).to eq(:combined) # no choice behavior defined yet - if/when this is to be used, we # should indicate which one should override in the range situation end - it "asserts on attempt to merge namespace changes" do + it 'asserts on attempt to merge namespace changes' do map1 = Solargraph::SourceMap.load_string(%( class Foo foo = 'foo' diff --git a/spec/pin/method_spec.rb b/spec/pin/method_spec.rb index 283ef6d51..0b4e4e685 100644 --- a/spec/pin/method_spec.rb +++ b/spec/pin/method_spec.rb @@ -116,14 +116,14 @@ def bazzle; end expect(pin.return_type).to be_undefined end - it 'will not merge with changes in parameters' do + it 'does not merge with changes in parameters' do # @todo Method pin parameters are pins now pin1 = Solargraph::Pin::Method.new(name: 'bar', parameters: %w[one two]) pin2 = Solargraph::Pin::Method.new(name: 'bar', parameters: ['three']) expect(pin1.nearly?(pin2)).to be(false) end - it 'will not merge with changes in YARD return types' do + it 'does not merge with changes in YARD return types' do pin1 = Solargraph::Pin::Method.new(name: 'foo', comments: '@return [String]') pin2 = Solargraph::Pin::Method.new(name: 'foo', comments: '@return [Integer]') expect(pin1.nearly?(pin2)).to be(false) @@ -485,8 +485,8 @@ def bar param1, param2 api_map.map source pin = api_map.get_path_pins('Example#bar').first pin.resolve_ref_tag(api_map) - expect(pin.docstring.tags(:param).map(&:name)).to eq(['param1', 'param2']) - expect(pin.docstring.tags(:param).map(&:type)).to eq(['String', 'Integer']) + expect(pin.docstring.tags(:param).map(&:name)).to eq(%w[param1 param2]) + expect(pin.docstring.tags(:param).map(&:type)).to eq(%w[String Integer]) end it 'resolves ref tags with namespaces' do @@ -508,8 +508,8 @@ def bar param1, param2 api_map.map source pin = api_map.get_path_pins('Example2#bar').first pin.resolve_ref_tag(api_map) - expect(pin.docstring.tags(:param).map(&:name)).to eq(['param1', 'param2']) - expect(pin.docstring.tags(:param).map(&:type)).to eq(['String', 'Integer']) + expect(pin.docstring.tags(:param).map(&:name)).to eq(%w[param1 param2]) + expect(pin.docstring.tags(:param).map(&:type)).to eq(%w[String Integer]) end context 'as attribute' do diff --git a/spec/pin/namespace_spec.rb b/spec/pin/namespace_spec.rb index 3c94a526e..0421def05 100644 --- a/spec/pin/namespace_spec.rb +++ b/spec/pin/namespace_spec.rb @@ -1,11 +1,11 @@ describe Solargraph::Pin::Namespace do - it "handles long namespaces" do + it 'handles long namespaces' do pin = Solargraph::Pin::Namespace.new(closure: Solargraph::Pin::Namespace.new(name: 'Foo'), name: 'Bar') expect(pin.path).to eq('Foo::Bar') end - it "has class scope" do - source = Solargraph::Source.load_string(%( + it 'has class scope' do + Solargraph::Source.load_string(%( class Foo end )) @@ -13,7 +13,7 @@ class Foo expect(pin.context.scope).to eq(:class) end - it "is a kind of namespace/class/module" do + it 'is a kind of namespace/class/module' do pin1 = Solargraph::Pin::Namespace.new(name: 'Foo') expect(pin1.completion_item_kind).to eq(Solargraph::LanguageServer::CompletionItemKinds::CLASS) pin2 = Solargraph::Pin::Namespace.new(name: 'Foo', type: :module) diff --git a/spec/pin/symbol_spec.rb b/spec/pin/symbol_spec.rb index 16961cadc..141dbf463 100644 --- a/spec/pin/symbol_spec.rb +++ b/spec/pin/symbol_spec.rb @@ -1,53 +1,52 @@ describe Solargraph::Pin::Symbol do - context "as an unquoted literal" do - it "is a kind of keyword to the LSP" do + context 'as an unquoted literal' do + it 'is a kind of keyword to the LSP' do pin = Solargraph::Pin::Symbol.new(nil, ':symbol') expect(pin.completion_item_kind).to eq(Solargraph::LanguageServer::CompletionItemKinds::KEYWORD) end - it "has global closure" do + it 'has global closure' do pin = Solargraph::Pin::Symbol.new(nil, ':symbol') expect(pin.closure).to eq(Solargraph::Pin::ROOT_PIN) end - it "has a Symbol return type" do + it 'has a Symbol return type' do pin = Solargraph::Pin::Symbol.new(nil, ':symbol') expect(pin.return_type.tag).to eq('Symbol') end end - context "as a double quoted literal" do - it "is a kind of keyword" do + context 'as a double quoted literal' do + it 'is a kind of keyword' do pin = Solargraph::Pin::Symbol.new(nil, ':"symbol"') expect(pin.completion_item_kind).to eq(Solargraph::LanguageServer::CompletionItemKinds::KEYWORD) end - it "has a Symbol return type" do + it 'has a Symbol return type' do pin = Solargraph::Pin::Symbol.new(nil, ':"symbol"') expect(pin.return_type.tag).to eq('Symbol') end end - context "as a double quoted interpolatd literal" do - it "is a kind of keyword" do + context 'as a double quoted interpolatd literal' do + it 'is a kind of keyword' do pin = Solargraph::Pin::Symbol.new(nil, ':"symbol #{variable}"') expect(pin.completion_item_kind).to eq(Solargraph::LanguageServer::CompletionItemKinds::KEYWORD) end - it "has a Symbol return type" do + it 'has a Symbol return type' do pin = Solargraph::Pin::Symbol.new(nil, ':"symbol #{variable}"') expect(pin.return_type.tag).to eq('Symbol') end end - - context "as a single quoted literal" do - it "is a kind of keyword" do + context 'as a single quoted literal' do + it 'is a kind of keyword' do pin = Solargraph::Pin::Symbol.new(nil, ":'symbol'") expect(pin.completion_item_kind).to eq(Solargraph::LanguageServer::CompletionItemKinds::KEYWORD) end - it "has a Symbol return type" do + it 'has a Symbol return type' do pin = Solargraph::Pin::Symbol.new(nil, ":'symbol'") expect(pin.return_type.tag).to eq('Symbol') end diff --git a/spec/position_spec.rb b/spec/position_spec.rb index fa30cf7d9..b5e97d5f1 100644 --- a/spec/position_spec.rb +++ b/spec/position_spec.rb @@ -1,20 +1,20 @@ describe Solargraph::Position do - it "normalizes arrays into positions" do + it 'normalizes arrays into positions' do pos = Solargraph::Position.normalize([0, 1]) expect(pos).to be_a(Solargraph::Position) expect(pos.line).to eq(0) expect(pos.column).to eq(1) end - it "returns original positions when normalizing" do + it 'returns original positions when normalizing' do orig = Solargraph::Position.new(0, 1) norm = Solargraph::Position.normalize(orig) expect(orig).to be(norm) end - it "raises an error for objects that cannot be normalized" do - expect { + it 'raises an error for objects that cannot be normalized' do + expect do Solargraph::Position.normalize('0, 1') - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end end diff --git a/spec/rbs_map/conversions_spec.rb b/spec/rbs_map/conversions_spec.rb index 896a55f37..2435c08fc 100644 --- a/spec/rbs_map/conversions_spec.rb +++ b/spec/rbs_map/conversions_spec.rb @@ -3,7 +3,7 @@ # create a temporary directory with the scope of the spec around do |example| require 'tmpdir' - Dir.mktmpdir("rspec-solargraph-") do |dir| + Dir.mktmpdir('rspec-solargraph-') do |dir| @temp_dir = dir example.run end @@ -26,6 +26,8 @@ attr_reader :temp_dir context 'with self alias to self method' do + subject(:alias_pin) { api_map.get_method_stack('Foo', 'bar?', scope: :class).first } + let(:rbs) do <<~RBS class Foo @@ -37,11 +39,9 @@ def self.bar: () -> String let(:method_pin) { api_map.get_method_stack('Foo', 'bar', scope: :class).first } - subject(:alias_pin) { api_map.get_method_stack('Foo', 'bar?', scope: :class).first } - - it { should_not be_nil } + it { is_expected.not_to be_nil } - it { should be_instance_of(Solargraph::Pin::Method) } + it { is_expected.to be_instance_of(Solargraph::Pin::Method) } it 'finds the type' do expect(alias_pin.return_type.tag).to eq('String') @@ -49,6 +49,8 @@ def self.bar: () -> String end context 'with untyped response' do + subject(:method_pin) { conversions.pins.find { |pin| pin.path == 'Foo#bar' } } + let(:rbs) do <<~RBS class Foo @@ -57,13 +59,11 @@ def bar: () -> untyped RBS end - subject(:method_pin) { conversions.pins.find { |pin| pin.path == 'Foo#bar' } } - - it { should_not be_nil } + it { is_expected.not_to be_nil } - it { should be_a(Solargraph::Pin::Method) } + it { is_expected.to be_a(Solargraph::Pin::Method) } - it 'maps untyped in RBS to undefined in Solargraph 'do + it 'maps untyped in RBS to undefined in Solargraph' do expect(method_pin.return_type.tag).to eq('undefined') end end @@ -101,6 +101,8 @@ class Sub < Hash[Symbol, untyped] end context 'with overlapping module hierarchies and inheritance' do + subject(:method_pin) { api_map.get_method_stack('A::B::C', 'foo').first } + let(:rbs) do <<~RBS module B @@ -117,9 +119,7 @@ class C < ::B::C RBS end - subject(:method_pin) { api_map.get_method_stack('A::B::C', 'foo').first } - - it { should be_a(Solargraph::Pin::Method) } + it { is_expected.to be_a(Solargraph::Pin::Method) } end end diff --git a/spec/rbs_map/core_map_spec.rb b/spec/rbs_map/core_map_spec.rb index 7b5007529..7384a74da 100644 --- a/spec/rbs_map/core_map_spec.rb +++ b/spec/rbs_map/core_map_spec.rb @@ -16,12 +16,12 @@ store = Solargraph::ApiMap::Store.new(map.pins) # The core RBS contains: # class Mutex = Thread::Mutex - thread_mutex_pin = store.get_path_pins("Thread::Mutex").first + thread_mutex_pin = store.get_path_pins('Thread::Mutex').first expect(thread_mutex_pin).to be_a(Solargraph::Pin::Namespace) - mutex_pin = store.get_path_pins("Mutex").first + mutex_pin = store.get_path_pins('Mutex').first expect(mutex_pin).to be_a(Solargraph::Pin::Constant) - expect(mutex_pin.return_type.to_s).to eq("Class") + expect(mutex_pin.return_type.to_s).to eq('Class') end it 'understands RBS global variables' do @@ -39,10 +39,10 @@ it 'understands implied Enumerator#each method' do api_map = Solargraph::ApiMap.new methods = api_map.get_methods('Enumerable') - each_pins = methods.select{|pin| pin.path.end_with?('#each')} + each_pins = methods.select { |pin| pin.path.end_with?('#each') } # expect this to come from the _Each implied interface ("self # type") defined in the RBS - expect(each_pins.map(&:path)).to eq(["_Each#each"]) + expect(each_pins.map(&:path)).to eq(['_Each#each']) expect(each_pins.map(&:class)).to eq([Solargraph::Pin::Method]) each_pin = each_pins.first expect(each_pin.signatures.length).to eq(1) @@ -53,7 +53,7 @@ it 'populates types in block parameters from generics' do api_map = Solargraph::ApiMap.new methods = api_map.get_methods('Enumerable') - each_pins = methods.select{|pin| pin.path.end_with?('#each')} + each_pins = methods.select { |pin| pin.path.end_with?('#each') } each_pin = each_pins.first signature = each_pin.signatures.first expect(signature.block.parameters.map(&:return_type).map(&:to_s)).to eq(['String']) @@ -67,7 +67,7 @@ # api_map = Solargraph::ApiMap.new methods = api_map.get_methods('Enumerable') - each_pins = methods.select{|pin| pin.path.end_with?('#each')} + each_pins = methods.select { |pin| pin.path.end_with?('#each') } each_pin = each_pins.first signature = each_pin.signatures.first expect(signature.return_type.to_s).to eq('Enumerable') @@ -95,12 +95,12 @@ class Foo expect(clip.infer.to_s).to eq('Foo') end - it "generates rooted pins from RBS for core" do + it 'generates rooted pins from RBS for core' do map = Solargraph::RbsMap::CoreMap.new map.pins.each do |pin| expect(pin).to be_all_rooted unless pin.is_a?(Solargraph::Pin::Keyword) - expect(pin.closure).to_not be_nil, ->(){ "Pin #{pin.inspect} (#{pin.path}) has no closure" } + expect(pin.closure).not_to be_nil, -> { "Pin #{pin.inspect} (#{pin.path}) has no closure" } end end end diff --git a/spec/rbs_map/stdlib_map_spec.rb b/spec/rbs_map/stdlib_map_spec.rb index bc2a134c2..316f6dd67 100644 --- a/spec/rbs_map/stdlib_map_spec.rb +++ b/spec/rbs_map/stdlib_map_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::RbsMap::StdlibMap do - it "finds stdlib require paths" do + it 'finds stdlib require paths' do rbs_map = Solargraph::RbsMap::StdlibMap.load('fileutils') pin = rbs_map.path_pin('FileUtils#chdir') expect(pin).to be diff --git a/spec/shell_spec.rb b/spec/shell_spec.rb index 91f84b4c7..66ae96e84 100644 --- a/spec/shell_spec.rb +++ b/spec/shell_spec.rb @@ -6,10 +6,10 @@ before do File.open(File.join(temp_dir, 'Gemfile'), 'w') do |file| - file.puts "source 'https://rubygems.org'" - file.puts "gem 'solargraph', path: #{File.expand_path('..', __dir__)}" + file.puts "source 'https://rubygems.org'" + file.puts "gem 'solargraph', path: #{File.expand_path('..', __dir__)}" end - output, status = Open3.capture2e("bundle install", chdir: temp_dir) + output, status = Open3.capture2e('bundle install', chdir: temp_dir) raise "Failure installing bundle: #{output}" unless status.success? end @@ -25,18 +25,18 @@ def bundle_exec(*cmd) FileUtils.rm_rf(temp_dir) end - describe "--version" do - it "returns a version when run" do - output = bundle_exec("solargraph", "--version") + describe '--version' do + it 'returns a version when run' do + output = bundle_exec('solargraph', '--version') expect(output).not_to be_empty expect(output).to eq("#{Solargraph::VERSION}\n") end end - describe "uncache" do - it "uncaches without erroring out" do - output = bundle_exec("solargraph", "uncache", "solargraph") + describe 'uncache' do + it 'uncaches without erroring out' do + output = bundle_exec('solargraph', 'uncache', 'solargraph') expect(output).to include('Clearing pin cache in') end diff --git a/spec/source/chain/array_spec.rb b/spec/source/chain/array_spec.rb index b8ef9db23..34eeafe01 100644 --- a/spec/source/chain/array_spec.rb +++ b/spec/source/chain/array_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::Source::Chain::Array do - it "resolves an instance of an array" do + it 'resolves an instance of an array' do literal = described_class.new([], nil) pin = literal.resolve(nil, nil, nil).first expect(pin.return_type.tag).to eq('Array') diff --git a/spec/source/chain/call_spec.rb b/spec/source/chain/call_spec.rb index 8b67a3c66..26da1a4e3 100644 --- a/spec/source/chain/call_spec.rb +++ b/spec/source/chain/call_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::Source::Chain::Call do - it "recognizes core methods that return subtypes" do + it 'recognizes core methods that return subtypes' do api_map = Solargraph::ApiMap.new source = Solargraph::Source.load_string(%( # @type [Array] @@ -12,7 +12,7 @@ expect(type.tag).to eq('String') end - it "recognizes core methods that return self" do + it 'recognizes core methods that return self' do api_map = Solargraph::ApiMap.new source = Solargraph::Source.load_string(%( arr = [] @@ -24,7 +24,7 @@ expect(type.tag).to eq('Array') end - it "handles super calls to same method" do + it 'handles super calls to same method' do api_map = Solargraph::ApiMap.new source = Solargraph::Source.load_string(%( class Foo @@ -44,7 +44,7 @@ def my_method expect(type.tag).to eq('Integer') end - it "infers return types based on yield call and @yieldreturn" do + it 'infers return types based on yield call and @yieldreturn' do api_map = Solargraph::ApiMap.new source = Solargraph::Source.load_string(%( class Foo @@ -61,7 +61,7 @@ def my_method(&block) expect(type.tag).to eq('Integer') end - it "infers return types based only on yield call and @yieldreturn" do + it 'infers return types based only on yield call and @yieldreturn' do api_map = Solargraph::ApiMap.new source = Solargraph::Source.load_string(%( class Foo @@ -78,7 +78,7 @@ def my_method(&block) expect(type.tag).to eq('Integer') end - it "adds virtual constructors for .new calls with conflicting return types" do + it 'adds virtual constructors for .new calls with conflicting return types' do api_map = Solargraph::ApiMap.new source = Solargraph::Source.load_string(%( class Foo @@ -88,13 +88,13 @@ def self.new; end )) api_map.map source chain = Solargraph::Source::SourceChainer.chain(source, Solargraph::Position.new(4, 11)) - type = chain.infer(api_map, Solargraph::Pin::ROOT_PIN, api_map.source_map(nil).locals) + chain.infer(api_map, Solargraph::Pin::ROOT_PIN, api_map.source_map(nil).locals) # @todo This test looks invalid now. If `Foo.new` is an empty method, # shouldn't it return `nil` or `undefined`? # expect(type.tag).to eq('Foo') end - it "infers types from macros" do + it 'infers types from macros' do source = Solargraph::Source.load_string(%( class Foo # @!macro @@ -525,7 +525,7 @@ def d expect(type.rooted_tags).not_to eq('::A::C') end - it 'qualifies types in a second Array#+ ' do + it 'qualifies types in a second Array#+' do source = Solargraph::Source.load_string(%( module A1 class B1 diff --git a/spec/source/chain/class_variable_spec.rb b/spec/source/chain/class_variable_spec.rb index 4121e9948..65fcd0e5d 100644 --- a/spec/source/chain/class_variable_spec.rb +++ b/spec/source/chain/class_variable_spec.rb @@ -1,8 +1,8 @@ describe Solargraph::Source::Chain::ClassVariable do - it "resolves class variable pins" do + it 'resolves class variable pins' do foo_pin = Solargraph::Pin::ClassVariable.new(name: '@@foo') bar_pin = Solargraph::Pin::ClassVariable.new(name: '@@bar') - api_map = double(Solargraph::ApiMap, :get_class_variable_pins => [foo_pin, bar_pin]) + api_map = double(Solargraph::ApiMap, get_class_variable_pins: [foo_pin, bar_pin]) link = Solargraph::Source::Chain::ClassVariable.new('@@bar') pins = link.resolve(api_map, Solargraph::Pin::ROOT_PIN, []) expect(pins.length).to eq(1) diff --git a/spec/source/chain/constant_spec.rb b/spec/source/chain/constant_spec.rb index 4376650b3..f809783ef 100644 --- a/spec/source/chain/constant_spec.rb +++ b/spec/source/chain/constant_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::Source::Chain::Constant do - it "resolves constants in the current context" do + it 'resolves constants in the current context' do foo_pin = Solargraph::Pin::Constant.new(name: 'Foo', closure: Solargraph::Pin::ROOT_PIN) api_map = Solargraph::ApiMap.new api_map.index [foo_pin] diff --git a/spec/source/chain/global_variable_spec.rb b/spec/source/chain/global_variable_spec.rb index 4c5bd6bce..4d0ed4056 100644 --- a/spec/source/chain/global_variable_spec.rb +++ b/spec/source/chain/global_variable_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::Source::Chain::GlobalVariable do - it "resolves instance variable pins" do + it 'resolves instance variable pins' do closure = Solargraph::Pin::Namespace.new(name: 'Foo') foo_pin = Solargraph::Pin::GlobalVariable.new(closure: closure, name: '$foo') not_pin = Solargraph::Pin::InstanceVariable.new(closure: closure, name: '@bar') diff --git a/spec/source/chain/head_spec.rb b/spec/source/chain/head_spec.rb index cc63a54a3..7d4e5d9ea 100644 --- a/spec/source/chain/head_spec.rb +++ b/spec/source/chain/head_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::Source::Chain::Head do - it "returns self pins" do + it 'returns self pins' do head = Solargraph::Source::Chain::Head.new('self') npin = Solargraph::Pin::ProxyType.anonymous(Solargraph::ComplexType.parse('Foo')) ipin = head.resolve(nil, npin, []).first diff --git a/spec/source/chain/instance_variable_spec.rb b/spec/source/chain/instance_variable_spec.rb index 8326a66d2..75c8b6960 100644 --- a/spec/source/chain/instance_variable_spec.rb +++ b/spec/source/chain/instance_variable_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::Source::Chain::InstanceVariable do - it "resolves instance variable pins" do + it 'resolves instance variable pins' do closure = Solargraph::Pin::Namespace.new(name: 'Foo') methpin = Solargraph::Pin::Method.new(closure: closure, name: 'imeth', scope: :instance) foo_pin = Solargraph::Pin::InstanceVariable.new(closure: methpin, name: '@foo') diff --git a/spec/source/chain/link_spec.rb b/spec/source/chain/link_spec.rb index 39143dbbd..c492d0ba3 100644 --- a/spec/source/chain/link_spec.rb +++ b/spec/source/chain/link_spec.rb @@ -1,26 +1,26 @@ describe Solargraph::Source::Chain::Link do - it "is undefined by default" do + it 'is undefined by default' do link = described_class.new expect(link).to be_undefined end - it "is not a constant by default" do + it 'is not a constant by default' do link = described_class.new expect(link).not_to be_constant end - it "resolves empty arrays by default" do + it 'resolves empty arrays by default' do link = described_class.new expect(link.resolve(nil, nil, nil)).to be_empty end - it "recognizes equivalent links" do + it 'recognizes equivalent links' do l1 = described_class.new('foo') l2 = described_class.new('foo') expect(l1).to eq(l2) end - it "recognizes inequivalent links" do + it 'recognizes inequivalent links' do l1 = described_class.new('foo') l2 = described_class.new('bar') expect(l1).not_to eq(l2) diff --git a/spec/source/chain/literal_spec.rb b/spec/source/chain/literal_spec.rb index a1431ae07..d3f759ea0 100644 --- a/spec/source/chain/literal_spec.rb +++ b/spec/source/chain/literal_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::Source::Chain::Literal do - it "resolves an instance of a literal" do + it 'resolves an instance of a literal' do literal = described_class.new('String', nil) api_map = Solargraph::ApiMap.new pin = literal.resolve(api_map, nil, nil).first diff --git a/spec/source/chain/z_super_spec.rb b/spec/source/chain/z_super_spec.rb index aa412dda6..4739ee195 100644 --- a/spec/source/chain/z_super_spec.rb +++ b/spec/source/chain/z_super_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::Source::Chain::ZSuper do - it "resolves super" do + it 'resolves super' do head = Solargraph::Source::Chain::ZSuper.new('super') npin = Solargraph::Pin::Namespace.new(name: 'Substring') scpin = Solargraph::Pin::Reference::Superclass.new(closure: npin, name: 'String') diff --git a/spec/source/chain_spec.rb b/spec/source/chain_spec.rb index abc8c2b05..83c3773bd 100644 --- a/spec/source/chain_spec.rb +++ b/spec/source/chain_spec.rb @@ -1,25 +1,25 @@ describe Solargraph::Source::Chain do - it "gets empty definitions for undefined links" do + it 'gets empty definitions for undefined links' do chain = described_class.new([Solargraph::Source::Chain::Link.new]) expect(chain.define(nil, nil, nil)).to be_empty end - it "infers undefined types for undefined links" do + it 'infers undefined types for undefined links' do chain = described_class.new([Solargraph::Source::Chain::Link.new]) expect(chain.infer(nil, nil, nil)).to be_undefined end - it "calls itself undefined if any of its links are undefined" do + it 'calls itself undefined if any of its links are undefined' do chain = described_class.new([Solargraph::Source::Chain::Link.new]) expect(chain).to be_undefined end - it "returns undefined bases for single links" do + it 'returns undefined bases for single links' do chain = described_class.new([Solargraph::Source::Chain::Link.new]) expect(chain.base).to be_undefined end - it "defines constants from core classes" do + it 'defines constants from core classes' do api_map = Solargraph::ApiMap.new chain = described_class.new([Solargraph::Source::Chain::Constant.new('String')]) pins = chain.define(api_map, Solargraph::Pin::ROOT_PIN, []) @@ -27,7 +27,7 @@ expect(pins.first.path).to eq('String') end - it "infers types from core classes" do + it 'infers types from core classes' do api_map = Solargraph::ApiMap.new chain = described_class.new([Solargraph::Source::Chain::Constant.new('String')]) type = chain.infer(api_map, Solargraph::Pin::ROOT_PIN, []) @@ -35,25 +35,26 @@ expect(type.scope).to eq(:class) end - it "infers types from core methods" do + it 'infers types from core methods' do api_map = Solargraph::ApiMap.new - chain = described_class.new([Solargraph::Source::Chain::Constant.new('String'), Solargraph::Source::Chain::Call.new('new', nil)]) + chain = described_class.new([Solargraph::Source::Chain::Constant.new('String'), + Solargraph::Source::Chain::Call.new('new', nil)]) type = chain.infer(api_map, Solargraph::Pin::ROOT_PIN, []) expect(type.namespace).to eq('String') expect(type.scope).to eq(:instance) end - it "recognizes literals" do + it 'recognizes literals' do chain = described_class.new([Solargraph::Source::Chain::Literal.new('String', nil)]) expect(chain.literal?).to be(true) end - it "recognizes constants" do + it 'recognizes constants' do chain = described_class.new([Solargraph::Source::Chain::Constant.new('String')]) expect(chain.constant?).to be(true) end - it "recognizes unfinished constants" do + it 'recognizes unfinished constants' do chain = described_class.new([Solargraph::Source::Chain::Constant.new('String'), Solargraph::Source::Chain::Constant.new('')]) expect(chain.constant?).to be(true) expect(chain.base.constant?).to be(true) @@ -61,7 +62,7 @@ expect(chain.base.undefined?).to be(false) end - it "infers types from new subclass calls without a subclass initialize method" do + it 'infers types from new subclass calls without a subclass initialize method' do code = %( class Sup def initialize; end @@ -80,7 +81,7 @@ def meth; end expect(type.name).to eq('Sub') end - it "follows constant chains" do + it 'follows constant chains' do source = Solargraph::Source.load_string(%( module Mixin; end module Container @@ -95,7 +96,7 @@ class Foo; end expect(pins).to be_empty end - it "rebases inner constants chains" do + it 'rebases inner constants chains' do source = Solargraph::Source.load_string(%( class Foo class Bar; end @@ -105,11 +106,12 @@ class Bar; end api_map = Solargraph::ApiMap.new api_map.map source chain = Solargraph::Source::SourceChainer.chain(source, Solargraph::Position.new(3, 16)) - pins = chain.define(api_map, Solargraph::Pin::ProxyType.new(closure: Solargraph::Pin::Namespace.new(name: 'Foo'), return_type: Solargraph::ComplexType.parse('Class')), []) + pins = chain.define(api_map, + Solargraph::Pin::ProxyType.new(closure: Solargraph::Pin::Namespace.new(name: 'Foo'), return_type: Solargraph::ComplexType.parse('Class')), []) expect(pins.first.path).to eq('Foo::Bar') end - it "resolves relative constant paths" do + it 'resolves relative constant paths' do source = Solargraph::Source.load_string(%( class Foo class Bar @@ -123,11 +125,12 @@ module Other api_map = Solargraph::ApiMap.new api_map.map source chain = Solargraph::Source::SourceChainer.chain(source, Solargraph::Position.new(6, 16)) - pins = chain.define(api_map, Solargraph::Pin::ProxyType.anonymous(Solargraph::ComplexType.parse('Class')), []) + pins = chain.define(api_map, + Solargraph::Pin::ProxyType.anonymous(Solargraph::ComplexType.parse('Class')), []) expect(pins.first.path).to eq('Foo::Bar::Baz') end - it "avoids recursive variable assignments" do + it 'avoids recursive variable assignments' do source = Solargraph::Source.load_string(%( @foo = @bar @bar = @foo.quz @@ -135,12 +138,12 @@ module Other api_map = Solargraph::ApiMap.new api_map.map source chain = Solargraph::Source::SourceChainer.chain(source, Solargraph::Position.new(2, 18)) - expect { + expect do chain.define(api_map, Solargraph::Pin::ROOT_PIN, []) - }.not_to raise_error + end.not_to raise_error end - it "pulls types from multiple lines of code" do + it 'pulls types from multiple lines of code' do source = Solargraph::Source.load_string(%( 123 'abc' @@ -152,7 +155,7 @@ module Other expect(type.simple_tags).to eq('String') end - it "uses last line of a begin expression as return type" do + it 'uses last line of a begin expression as return type' do source = Solargraph::Source.load_string(%( begin 123 @@ -166,7 +169,7 @@ module Other expect(type.simple_tags).to eq('String') end - it "matches constants on complete symbols" do + it 'matches constants on complete symbols' do source = Solargraph::Source.load_string(%( class Correct; end class NotCorrect; end diff --git a/spec/source/change_spec.rb b/spec/source/change_spec.rb index 247c1e204..7ef02984a 100644 --- a/spec/source/change_spec.rb +++ b/spec/source/change_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::Source::Change do - it "inserts a character" do + it 'inserts a character' do text = 'var' range = Solargraph::Range.from_to(0, 3, 0, 3) new_text = '.' @@ -8,7 +8,7 @@ expect(updated).to eq('var.') end - it "repairs nullable characters" do + it 'repairs nullable characters' do text = 'var' range = Solargraph::Range.from_to(0, 3, 0, 3) new_text = '.' @@ -17,7 +17,7 @@ expect(updated).to eq('var ') end - it "repairs entire changes" do + it 'repairs entire changes' do text = 'var' range = Solargraph::Range.from_to(0, 3, 0, 3) new_text = '._(!' @@ -26,14 +26,14 @@ expect(updated).to eq('var ') end - it "repairs nil ranges" do + it 'repairs nil ranges' do text = 'original' change = Solargraph::Source::Change.new(nil, '...') updated = change.repair(text) expect(updated).to eq(' ') end - it "overwrites nil ranges" do + it 'overwrites nil ranges' do text = 'foo' new_text = 'bar' change = Solargraph::Source::Change.new(nil, new_text) @@ -41,7 +41,7 @@ expect(updated).to eq('bar') end - it "blanks single colons in nullable changes" do + it 'blanks single colons in nullable changes' do text = 'bar' new_text = ':' range = Solargraph::Range.from_to(0, 3, 0, 3) @@ -50,7 +50,7 @@ expect(updated).to eq('bar ') end - it "blanks double colons in nullable changes" do + it 'blanks double colons in nullable changes' do text = 'bar:' new_text = ':' range = Solargraph::Range.from_to(0, 4, 0, 4) @@ -59,7 +59,7 @@ expect(updated).to eq('bar ') end - it "repairs preceding periods" do + it 'repairs preceding periods' do text = 'bar.' new_text = ' ' range = Solargraph::Range.from_to(0, 4, 0, 4) @@ -68,7 +68,7 @@ expect(updated).to eq('bar ') end - it "repairs preceding colons" do + it 'repairs preceding colons' do text = 'bar:' new_text = 'x' range = Solargraph::Range.from_to(0, 4, 0, 4) diff --git a/spec/source/cursor_spec.rb b/spec/source/cursor_spec.rb index 150e99449..f221232cf 100644 --- a/spec/source/cursor_spec.rb +++ b/spec/source/cursor_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::Source::Cursor do - it "detects cursors in strings" do + it 'detects cursors in strings' do source = Solargraph::Source.load_string('str = "string"') cursor = described_class.new(source, Solargraph::Position.new(0, 6)) expect(cursor).not_to be_string @@ -7,7 +7,7 @@ expect(cursor).to be_string end - it "detects cursors in comments" do + it 'detects cursors in comments' do source = Solargraph::Source.load_string(%( # @type [String] var = make_a_string @@ -20,48 +20,48 @@ expect(cursor).not_to be_comment end - it "detects arguments inside parentheses" do + it 'detects arguments inside parentheses' do source = Solargraph::Source.load_string('a(1); b') - cur = described_class.new(source, Solargraph::Position.new(0,2)) + cur = described_class.new(source, Solargraph::Position.new(0, 2)) expect(cur).to be_argument - cur = described_class.new(source, Solargraph::Position.new(0,3)) + cur = described_class.new(source, Solargraph::Position.new(0, 3)) expect(cur).to be_argument - cur = described_class.new(source, Solargraph::Position.new(0,4)) + cur = described_class.new(source, Solargraph::Position.new(0, 4)) expect(cur).not_to be_argument - cur = described_class.new(source, Solargraph::Position.new(0,5)) + cur = described_class.new(source, Solargraph::Position.new(0, 5)) expect(cur).not_to be_argument - cur = described_class.new(source, Solargraph::Position.new(0,7)) + cur = described_class.new(source, Solargraph::Position.new(0, 7)) expect(cur).not_to be_argument end it 'detects arguments at opening parentheses' do source = Solargraph::Source.load_string('String.new', 'test.rb') - change = Solargraph::Source::Change.new(Solargraph::Range.from_to(0, 10, 0, 10) ,'(') + change = Solargraph::Source::Change.new(Solargraph::Range.from_to(0, 10, 0, 10), '(') updater = Solargraph::Source::Updater.new('test.rb', 1, [change]) source = source.synchronize(updater) cursor = source.cursor_at([0, 11]) expect(cursor).to be_argument end - it "detects class variables" do - source = double(:Source, :code => '@@foo') + it 'detects class variables' do + source = double(:Source, code: '@@foo') cur = described_class.new(source, Solargraph::Position.new(0, 2)) expect(cur.word).to eq('@@foo') end - it "detects instance variables" do - source = double(:Source, :code => '@foo') + it 'detects instance variables' do + source = double(:Source, code: '@foo') cur = described_class.new(source, Solargraph::Position.new(0, 1)) expect(cur.word).to eq('@foo') end - it "detects global variables" do - source = double(:Source, :code => '@foo') + it 'detects global variables' do + source = double(:Source, code: '@foo') cur = described_class.new(source, Solargraph::Position.new(0, 1)) expect(cur.word).to eq('@foo') end - it "generates word ranges" do + it 'generates word ranges' do source = Solargraph::Source.load_string(%( foo = bar )) @@ -69,26 +69,26 @@ expect(source.at(cur.range)).to eq('bar') end - it "generates chains" do + it 'generates chains' do source = Solargraph::Source.load_string('foo.bar(1,2).baz{}') cur = described_class.new(source, Solargraph::Position.new(0, 18)) expect(cur.chain).to be_a(Solargraph::Source::Chain) - expect(cur.chain.links.map(&:word)).to eq(['foo', 'bar', 'baz']) + expect(cur.chain.links.map(&:word)).to eq(%w[foo bar baz]) end - it "detects constant words" do - source = double(:Source, :code => 'Foo::Bar') + it 'detects constant words' do + source = double(:Source, code: 'Foo::Bar') cur = described_class.new(source, Solargraph::Position.new(0, 5)) expect(cur.word).to eq('Bar') end - it "detects cursors in dynamic strings" do + it 'detects cursors in dynamic strings' do source = Solargraph::Source.load_string('"#{100}"') cursor = source.cursor_at(Solargraph::Position.new(0, 7)) expect(cursor).to be_string end - it "detects cursors in embedded strings" do + it 'detects cursors in embedded strings' do source = Solargraph::Source.load_string('"#{100}..."') cursor = source.cursor_at(Solargraph::Position.new(0, 10)) expect(cursor).to be_string @@ -118,8 +118,8 @@ class Foo; end "#{[]}" ', 'test.rb') updater = Solargraph::Source::Updater.new('test.rb', 1, [ - Solargraph::Source::Change.new(Solargraph::Range.from_to(1, 12, 1, 12), '.') - ]) + Solargraph::Source::Change.new(Solargraph::Range.from_to(1, 12, 1, 12), '.') + ]) updated = source.synchronize(updater) cursor = updated.cursor_at(Solargraph::Position.new(1, 13)) expect(cursor).to be_string diff --git a/spec/source/source_chainer_spec.rb b/spec/source/source_chainer_spec.rb index 7a8eb9fb8..ae672b095 100644 --- a/spec/source/source_chainer_spec.rb +++ b/spec/source/source_chainer_spec.rb @@ -1,12 +1,12 @@ describe Solargraph::Source::SourceChainer do - it "handles trailing colons that are not namespace separators" do + it 'handles trailing colons that are not namespace separators' do source = Solargraph::Source.load_string('Foo:') map = Solargraph::SourceMap.map(source) cursor = map.cursor_at(Solargraph::Position.new(0, 4)) expect(cursor.chain.links.first).to be_undefined end - it "recognizes literal strings" do + it 'recognizes literal strings' do map = Solargraph::SourceMap.load_string("'string'") cursor = map.cursor_at(Solargraph::Position.new(0, 0)) expect(cursor.chain).not_to be_a(Solargraph::Source::Chain::Literal) @@ -15,8 +15,8 @@ expect(cursor.chain.links.first.word).to eq('<::String>') end - it "recognizes literal integers" do - map = Solargraph::SourceMap.load_string("100") + it 'recognizes literal integers' do + map = Solargraph::SourceMap.load_string('100') cursor = map.cursor_at(Solargraph::Position.new(0, 0)) expect(cursor.chain).not_to be_a(Solargraph::Source::Chain::Literal) cursor = map.cursor_at(Solargraph::Position.new(0, 1)) @@ -24,42 +24,42 @@ expect(cursor.chain.links.first.word).to eq('<::Integer>') end - it "recognizes literal regexps" do - map = Solargraph::SourceMap.load_string("/[a-z]/") + it 'recognizes literal regexps' do + map = Solargraph::SourceMap.load_string('/[a-z]/') cursor = map.cursor_at(Solargraph::Position.new(0, 0)) expect(cursor.chain.links.first).to be_a(Solargraph::Source::Chain::Literal) expect(cursor.chain.links.first.word).to eq('<::Regexp>') end - it "recognizes class variables" do + it 'recognizes class variables' do map = Solargraph::SourceMap.load_string('@@foo') cursor = map.cursor_at(Solargraph::Position.new(0, 0)) expect(cursor.chain.links.first).to be_a(Solargraph::Source::Chain::ClassVariable) expect(cursor.chain.links.first.word).to eq('@@foo') end - it "recognizes instance variables" do + it 'recognizes instance variables' do map = Solargraph::SourceMap.load_string('@foo') cursor = map.cursor_at(Solargraph::Position.new(0, 0)) expect(cursor.chain.links.first).to be_a(Solargraph::Source::Chain::InstanceVariable) expect(cursor.chain.links.first.word).to eq('@foo') end - it "recognizes global variables" do + it 'recognizes global variables' do map = Solargraph::SourceMap.load_string('$foo') cursor = map.cursor_at(Solargraph::Position.new(0, 0)) expect(cursor.chain.links.first).to be_a(Solargraph::Source::Chain::GlobalVariable) expect(cursor.chain.links.first.word).to eq('$foo') end - it "recognizes constants" do + it 'recognizes constants' do map = Solargraph::SourceMap.load_string('Foo::Bar') cursor = map.cursor_at(Solargraph::Position.new(0, 6)) expect(cursor.chain).to be_constant expect(cursor.chain.links.map(&:word)).to eq(['Foo::Bar']) end - it "recognizes unfinished constants" do + it 'recognizes unfinished constants' do map = Solargraph::SourceMap.load_string('Foo:: $something') cursor = map.cursor_at(Solargraph::Position.new(0, 5)) expect(cursor.chain).to be_constant @@ -67,11 +67,11 @@ expect(cursor.chain).to be_undefined end - it "recognizes unfinished calls" do + it 'recognizes unfinished calls' do orig = Solargraph::Source.load_string('foo.bar') updater = Solargraph::Source::Updater.new(nil, 1, [ - Solargraph::Source::Change.new(Solargraph::Range.from_to(0, 7, 0, 7), '.') - ]) + Solargraph::Source::Change.new(Solargraph::Range.from_to(0, 7, 0, 7), '.') + ]) source = orig.synchronize(updater) map = Solargraph::SourceMap.map(source) cursor = map.cursor_at(Solargraph::Position.new(0, 8)) @@ -80,25 +80,25 @@ expect(cursor.chain).to be_undefined end - it "chains signatures with square brackets" do + it 'chains signatures with square brackets' do map = Solargraph::SourceMap.load_string('foo[0].bar') cursor = map.cursor_at(Solargraph::Position.new(0, 8)) expect(cursor.chain.links.map(&:word)).to eq(['foo', '[]', 'bar']) end - it "chains signatures with curly brackets" do + it 'chains signatures with curly brackets' do map = Solargraph::SourceMap.load_string('foo{|x| x == y}.bar') cursor = map.cursor_at(Solargraph::Position.new(0, 16)) - expect(cursor.chain.links.map(&:word)).to eq(['foo', 'bar']) + expect(cursor.chain.links.map(&:word)).to eq(%w[foo bar]) end - it "chains signatures with parentheses" do + it 'chains signatures with parentheses' do map = Solargraph::SourceMap.load_string('foo(x, y).bar') cursor = map.cursor_at(Solargraph::Position.new(0, 10)) - expect(cursor.chain.links.map(&:word)).to eq(['foo', 'bar']) + expect(cursor.chain.links.map(&:word)).to eq(%w[foo bar]) end - it "chains from repaired sources with literal strings" do + it 'chains from repaired sources with literal strings' do orig = Solargraph::Source.load_string("''") updater = Solargraph::Source::Updater.new( nil, @@ -116,8 +116,8 @@ expect(chain.links.length).to eq(2) end - it "chains incomplete constants" do - source = Solargraph::Source.load_string("Foo::") + it 'chains incomplete constants' do + source = Solargraph::Source.load_string('Foo::') chain = Solargraph::Source::SourceChainer.chain(source, Solargraph::Position.new(0, 5)) expect(chain.links.length).to eq(2) expect(chain.links.first).to be_a(Solargraph::Source::Chain::Constant) @@ -125,18 +125,18 @@ expect(chain.links.last).to be_undefined end - it "works when source error ranges contain a nil range" do + it 'works when source error ranges contain a nil range' do orig = Solargraph::Source.load_string("msg = 'msg'\nmsg", 'test.rb') updater = Solargraph::Source::Updater.new('test.rb', 1, [ - Solargraph::Source::Change.new(nil, "msg = 'msg'\nmsg.") - ]) + Solargraph::Source::Change.new(nil, "msg = 'msg'\nmsg.") + ]) source = orig.synchronize(updater) - expect { + expect do Solargraph::Source::SourceChainer.chain(source, Solargraph::Position.new(1, 4)) - }.not_to raise_error + end.not_to raise_error end - it "stops phrases at opening brackets" do + it 'stops phrases at opening brackets' do source = Solargraph::Source.load_string(%( (aa1, 2, 3) [bb2, 2, 3] @@ -150,63 +150,61 @@ expect(chain.links.first.word).to eq('cc3') end - it "chains instance variables from unsynchronized sources" do + it 'chains instance variables from unsynchronized sources' do source = double(Solargraph::Source, - :synchronized? => false, - :code => '@foo.', - :filename => 'test.rb', - :string_at? => false, - :comment_at? => false, - :repaired? => false, - :parsed? => true, - :error_ranges => [], - :node_at => nil, - :tree_at => [] - ) + synchronized?: false, + code: '@foo.', + filename: 'test.rb', + string_at?: false, + comment_at?: false, + repaired?: false, + parsed?: true, + error_ranges: [], + node_at: nil, + tree_at: []) chain = Solargraph::Source::SourceChainer.chain(source, Solargraph::Position.new(0, 5)) expect(chain.links.first.word).to eq('@foo') expect(chain.links.last.word).to eq('') end - it "chains class variables from unsynchronized sources" do + it 'chains class variables from unsynchronized sources' do source = double(Solargraph::Source, - :synchronized? => false, - :code => '@@foo.', - :filename => 'test.rb', - :string_at? => false, - :comment_at? => false, - :repaired? => false, - :parsed? => true, - :error_ranges => [], - :node_at => nil, - :tree_at => [] - ) + synchronized?: false, + code: '@@foo.', + filename: 'test.rb', + string_at?: false, + comment_at?: false, + repaired?: false, + parsed?: true, + error_ranges: [], + node_at: nil, + tree_at: []) chain = Solargraph::Source::SourceChainer.chain(source, Solargraph::Position.new(0, 6)) expect(chain.links.first.word).to eq('@@foo') expect(chain.links.last.word).to eq('') end - it "detects literals from chains in unsynchronized sources" do + it 'detects literals from chains in unsynchronized sources' do source1 = Solargraph::Source.load_string(%( '' )) source2 = source1.synchronize(Solargraph::Source::Updater.new( - nil, - 2, - [ - Solargraph::Source::Change.new( - Solargraph::Range.from_to(1, 8, 1, 8), - '.' - ) - ] - )) + nil, + 2, + [ + Solargraph::Source::Change.new( + Solargraph::Range.from_to(1, 8, 1, 8), + '.' + ) + ] + )) chain = Solargraph::Source::SourceChainer.chain(source2, Solargraph::Position.new(1, 9)) expect(chain.links.first).to be_a(Solargraph::Source::Chain::Literal) expect(chain.links.first.word).to eq('<::String>') expect(chain.links.last.word).to eq('') end - it "ignores ? and ! that are not method suffixes" do + it 'ignores ? and ! that are not method suffixes' do source = Solargraph::Source.load_string(%( if !t ), 'test.rb') @@ -215,14 +213,14 @@ expect(chain.links.first.word).to eq('t') end - it "chains from fixed phrases in repaired sources with missing nodes" do + it 'chains from fixed phrases in repaired sources with missing nodes' do source = Solargraph::Source.load_string(%( x = [] ), 'test.rb') updater = Solargraph::Source::Updater.new('test.rb', 1, [ - Solargraph::Source::Change.new(Solargraph::Range.from_to(2, 6, 2, 6), 'x.') - ]) + Solargraph::Source::Change.new(Solargraph::Range.from_to(2, 6, 2, 6), 'x.') + ]) updated = source.synchronize(updater) cursor = updated.cursor_at(Solargraph::Position.new(2, 8)) expect(cursor.chain.links.first.word).to eq('x') @@ -331,8 +329,8 @@ def strings; end end ), 'test.rb') updater = Solargraph::Source::Updater.new('test.rb', 1, [ - Solargraph::Source::Change.new(Solargraph::Range.from_to(5, 10, 5, 10), 'if s') - ]) + Solargraph::Source::Change.new(Solargraph::Range.from_to(5, 10, 5, 10), 'if s') + ]) updated = source.synchronize(updater) api_map = Solargraph::ApiMap.new api_map.map updated diff --git a/spec/source/updater_spec.rb b/spec/source/updater_spec.rb index 0c5f1f4c6..580d41521 100644 --- a/spec/source/updater_spec.rb +++ b/spec/source/updater_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::Source::Updater do - it "applies changes" do + it 'applies changes' do text = 'foo' changes = [] range = Solargraph::Range.from_to(0, 3, 0, 3) @@ -13,7 +13,7 @@ expect(updated).to eq('foo.bar') end - it "applies repairs" do + it 'applies repairs' do text = 'foo' changes = [] range = Solargraph::Range.from_to(0, 3, 0, 3) @@ -27,7 +27,7 @@ expect(updated).to eq('foo ') end - it "handles nil ranges" do + it 'handles nil ranges' do text = 'foo' changes = [] range = nil diff --git a/spec/source_map/clip_spec.rb b/spec/source_map/clip_spec.rb index ee7e4bcfa..51c95c004 100644 --- a/spec/source_map/clip_spec.rb +++ b/spec/source_map/clip_spec.rb @@ -93,7 +93,7 @@ class Bar api_map = Solargraph::ApiMap.new api_map.map source clip = api_map.clip_at('test.rb', [6, 12]) - expect(clip.complete.pins.map(&:name)).to eq (['@foo']) + expect(clip.complete.pins.map(&:name)).to eq(['@foo']) end it 'completes instance variables' do @@ -648,7 +648,7 @@ def initialize clip = api_map.clip_at('test.rb', [7, 8]) # @todo expect(clip.infer.tags).to eq('""') expect(clip.infer.tags).to eq('String') - expect(clip.infer.simple_tags).to eq("String") + expect(clip.infer.simple_tags).to eq('String') end it 'completes instance variable methods in rebound blocks' do @@ -1645,7 +1645,7 @@ def foo; end api_map = Solargraph::ApiMap.new.map(source) array_names = api_map.clip_at('test.rb', [5, 22]).complete.pins.map(&:name) - expect(array_names).to eq(["byteindex", "byterindex", "bytes", "bytesize", "byteslice", "bytesplice"]) + expect(array_names).to eq(%w[byteindex byterindex bytes bytesize byteslice bytesplice]) string_names = api_map.clip_at('test.rb', [6, 22]).complete.pins.map(&:name) expect(string_names).to eq(['upcase', 'upcase!', 'upto']) @@ -2728,7 +2728,7 @@ def bar; end api_map = Solargraph::ApiMap.new.map(source) clip = api_map.clip_at('test.rb', [7, 6]) # The order of the types can vary between platforms - expect(clip.infer.items.map(&:to_s).sort).to eq(["123", ":foo", "String"]) + expect(clip.infer.items.map(&:to_s).sort).to eq(['123', ':foo', 'String']) end it 'does not map Module methods into an Object' do diff --git a/spec/source_map/mapper_spec.rb b/spec/source_map/mapper_spec.rb index 96d2bdab5..f6cc7279e 100644 --- a/spec/source_map/mapper_spec.rb +++ b/spec/source_map/mapper_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::SourceMap::Mapper do - it "ignores include calls that are not attached to the current namespace" do + it 'ignores include calls that are not attached to the current namespace' do source = Solargraph::Source.new(%( class Foo include Direct @@ -8,14 +8,14 @@ class Foo end )) map = Solargraph::SourceMap.map(source) - pins = map.pins.select{|pin| pin.is_a?(Solargraph::Pin::Reference::Include) && pin.namespace == 'Foo'} + pins = map.pins.select { |pin| pin.is_a?(Solargraph::Pin::Reference::Include) && pin.namespace == 'Foo' } names = pins.map(&:name) expect(names).to include('Direct') expect(names).not_to include('Indirect') expect(names).to include('Interior') end - it "ignores prepend calls that are not attached to the current namespace" do + it 'ignores prepend calls that are not attached to the current namespace' do source = Solargraph::Source.new(%( class Foo prepend Direct @@ -24,14 +24,14 @@ class Foo end )) map = Solargraph::SourceMap.map(source) - pins = map.pins.select{|pin| pin.is_a?(Solargraph::Pin::Reference::Prepend) && pin.namespace == 'Foo'} + pins = map.pins.select { |pin| pin.is_a?(Solargraph::Pin::Reference::Prepend) && pin.namespace == 'Foo' } names = pins.map(&:name) expect(names).to include('Direct') expect(names).not_to include('Indirect') expect(names).to include('Interior') end - it "ignores extend calls that are not attached to the current namespace" do + it 'ignores extend calls that are not attached to the current namespace' do source = Solargraph::Source.new(%( class Foo extend Direct @@ -40,17 +40,17 @@ class Foo end )) map = Solargraph::SourceMap.map(source) - foo_pin = map.pins.select{|pin| pin.path == 'Foo'}.first + map.pins.select { |pin| pin.path == 'Foo' }.first # expect(foo_pin.extend_references.map(&:name)).to include('Direct') # expect(foo_pin.extend_references.map(&:name)).not_to include('Indirect') - pins = map.pins.select{|pin| pin.is_a?(Solargraph::Pin::Reference::Extend) && pin.namespace == 'Foo'} + pins = map.pins.select { |pin| pin.is_a?(Solargraph::Pin::Reference::Extend) && pin.namespace == 'Foo' } names = pins.map(&:name) expect(names).to include('Direct') expect(names).not_to include('Indirect') expect(names).to include('Interior') end - it "sets scopes for attributes" do + it 'sets scopes for attributes' do source = Solargraph::Source.new(%( module Foo attr_reader :bar1 @@ -60,13 +60,13 @@ class << self end )) map = Solargraph::SourceMap.map(source) - bar1 = map.pins.select{|pin| pin.name == 'bar1'}.first + bar1 = map.pins.select { |pin| pin.name == 'bar1' }.first expect(bar1.scope).to eq(:instance) - bar2 = map.pins.select{|pin| pin.name == 'bar2'}.first + bar2 = map.pins.select { |pin| pin.name == 'bar2' }.first expect(bar2.scope).to eq(:class) end - it "sets attribute visibility" do + it 'sets attribute visibility' do map = Solargraph::SourceMap.load_string(%( module Foo attr_reader :default_public_method @@ -84,7 +84,7 @@ module Foo expect(map.first_pin('Foo#explicit_public_method').visibility).to eq(:public) end - it "processes method directives" do + it 'processes method directives' do map = Solargraph::SourceMap.load_string(%( class Foo # @!method bar(baz) @@ -119,7 +119,7 @@ class Foo expect(pin.scope).to eq(:class) end - it "processes attribute reader directives" do + it 'processes attribute reader directives' do map = Solargraph::SourceMap.load_string(%( class Foo # @!attribute [r] bar @@ -131,7 +131,7 @@ class Foo expect(pin.return_type.tag).to eq('String') end - it "processes attribute writer directives" do + it 'processes attribute writer directives' do map = Solargraph::SourceMap.load_string(%( class Foo # @!attribute [w] bar @@ -143,7 +143,7 @@ class Foo expect(pin.return_type.tag).to eq('String') end - it "processes attribute accessor directives" do + it 'processes attribute accessor directives' do map = Solargraph::SourceMap.load_string(%( class Foo # @!attribute [r,w] bar @@ -157,7 +157,7 @@ class Foo expect(pin.return_type.tag).to eq('String') end - it "processes default attribute directives" do + it 'processes default attribute directives' do map = Solargraph::SourceMap.load_string(%( class Foo # @!attribute bar @@ -171,7 +171,7 @@ class Foo expect(pin.return_type.tag).to eq('String') end - it "processes attribute directives attached to methods" do + it 'processes attribute directives attached to methods' do map = Solargraph::SourceMap.load_string(%( class Foo # @!attribute [r] bar @@ -184,7 +184,7 @@ def make_bar_attr expect(pin.return_type.tag).to eq('String') end - it "processes private visibility directives attached to methods" do + it 'processes private visibility directives attached to methods' do map = Solargraph::SourceMap.load_string(%( class Foo # @!visibility private @@ -195,7 +195,7 @@ def bar expect(map.first_pin('Foo#bar').visibility).to be(:private) end - it "processes protected visibility directives attached to methods" do + it 'processes protected visibility directives attached to methods' do map = Solargraph::SourceMap.load_string(%( class Foo # @!visibility protected @@ -206,7 +206,7 @@ def bar expect(map.first_pin('Foo#bar').visibility).to be(:protected) end - it "processes public visibility directives attached to methods" do + it 'processes public visibility directives attached to methods' do map = Solargraph::SourceMap.load_string(%( class Foo # @!visibility public @@ -217,7 +217,7 @@ def bar expect(map.first_pin('Foo#bar').visibility).to be(:public) end - it "does not process attached visibility directives on other methods" do + it 'does not process attached visibility directives on other methods' do map = Solargraph::SourceMap.load_string(%( class Example # @!visibility private @@ -232,7 +232,7 @@ def method2; end expect(method2.visibility).to be(:public) end - it "processes class-wide private visibility directives" do + it 'processes class-wide private visibility directives' do map = Solargraph::SourceMap.load_string(%( class Example # @!visibility private @@ -253,7 +253,7 @@ def method3; end expect(method3.visibility).to be(:public) end - it "processes attribute directives at class endings" do + it 'processes attribute directives at class endings' do map = Solargraph::SourceMap.load_string(%( class Foo # @!attribute [r] bar @@ -264,43 +264,43 @@ class Foo expect(pin.return_type.tag).to eq('String') end - it "finds assignment nodes for local variables using nil guards" do + it 'finds assignment nodes for local variables using nil guards' do map = Solargraph::SourceMap.load_string(%( x ||= [] )) pin = map.locals.first # @todo Dirty test - expect([:ZLIST, :ZARRAY, :array]).to include(pin.assignment.type) + expect(%i[ZLIST ZARRAY array]).to include(pin.assignment.type) end - it "finds assignment nodes for instance variables using nil guards" do + it 'finds assignment nodes for instance variables using nil guards' do map = Solargraph::SourceMap.load_string(%( @x ||= [] )) pin = map.pins.last # @todo Dirty test - expect([:ZLIST, :ZARRAY, :array]).to include(pin.assignment.type) + expect(%i[ZLIST ZARRAY array]).to include(pin.assignment.type) end - it "finds assignment nodes for class variables using nil guards" do + it 'finds assignment nodes for class variables using nil guards' do map = Solargraph::SourceMap.load_string(%( @@x ||= [] )) pin = map.pins.last # @todo Dirty test - expect([:ZLIST, :ZARRAY, :array]).to include(pin.assignment.type) + expect(%i[ZLIST ZARRAY array]).to include(pin.assignment.type) end - it "finds assignment nodes for global variables using nil guards" do + it 'finds assignment nodes for global variables using nil guards' do map = Solargraph::SourceMap.load_string(%( $x ||= [] )) pin = map.pins.last # @todo Dirty test - expect([:ZLIST, :ZARRAY, :array]).to include(pin.assignment.type) + expect(%i[ZLIST ZARRAY array]).to include(pin.assignment.type) end - it "requalifies namespace definitions with leading colons" do + it 'requalifies namespace definitions with leading colons' do map = Solargraph::SourceMap.load_string(%( class Foo class ::Bar; end @@ -311,7 +311,7 @@ class ::Bar; end expect(map.pins.map(&:path)).not_to include('Foo::Bar') end - it "maps method parameters" do + it 'maps method parameters' do map = Solargraph::SourceMap.load_string(%( class Foo def bar baz, boo = 'boo', key: 'value' @@ -319,16 +319,16 @@ def bar baz, boo = 'boo', key: 'value' end )) pin = map.first_pin('Foo#bar') - expect(pin.parameter_names).to eq(['baz', 'boo', 'key']) - pin = map.locals.select{|p| p.name == 'baz'}.first + expect(pin.parameter_names).to eq(%w[baz boo key]) + pin = map.locals.select { |p| p.name == 'baz' }.first expect(pin).to be_a(Solargraph::Pin::Parameter) - pin = map.locals.select{|p| p.name == 'boo'}.first + pin = map.locals.select { |p| p.name == 'boo' }.first expect(pin).to be_a(Solargraph::Pin::Parameter) - pin = map.locals.select{|p| p.name == 'key'}.first + pin = map.locals.select { |p| p.name == 'key' }.first expect(pin).to be_a(Solargraph::Pin::Parameter) end - it "maps method splat parameters" do + it 'maps method splat parameters' do map = Solargraph::SourceMap.load_string(%( class Foo def bar *baz @@ -340,7 +340,7 @@ def bar *baz expect(pin.parameters.first.name).to eq('baz') end - it "maps method block parameters" do + it 'maps method block parameters' do map = Solargraph::SourceMap.load_string(%( class Foo def bar &block @@ -352,18 +352,18 @@ def bar &block expect(pin.parameters.first.name).to eq('block') end - it "adds superclasses to class pins" do + it 'adds superclasses to class pins' do map = Solargraph::SourceMap.load_string(%( class Sub < Sup; end )) # pin = map.first_pin('Sub') # expect(pin.superclass_reference.name).to eq('Sup') - pin = map.pins.select{|p| p.is_a?(Solargraph::Pin::Reference::Superclass)}.first + pin = map.pins.select { |p| p.is_a?(Solargraph::Pin::Reference::Superclass) }.first expect(pin.namespace).to eq('Sub') expect(pin.name).to eq('Sup') end - it "modifies scope and visibility for module functions" do + it 'modifies scope and visibility for module functions' do map = Solargraph::SourceMap.load_string(%( module Functions module_function @@ -376,7 +376,7 @@ def foo; end expect(pin.visibility).to eq(:private) end - it "recognizes single module functions" do + it 'recognizes single module functions' do map = Solargraph::SourceMap.load_string(%( module Functions module_function def foo; end @@ -391,7 +391,7 @@ def bar; end expect(pin.visibility).to eq(:public) end - it "remaps methods for module_function symbol arguments" do + it 'remaps methods for module_function symbol arguments' do map = Solargraph::SourceMap.load_string(%( module Functions def foo @@ -409,13 +409,13 @@ def bar expect(pin.visibility).to eq(:private) pin = map.first_pin('Functions#bar') expect(pin.visibility).to eq(:public) - pin = map.pins.select{|p| p.name == '@foo' and p.context.scope == :class}.first + pin = map.pins.select { |p| p.name == '@foo' and p.context.scope == :class }.first expect(pin).to be_a(Solargraph::Pin::InstanceVariable) - pin = map.pins.select{|p| p.name == '@foo' and p.context.scope == :instance}.first + pin = map.pins.select { |p| p.name == '@foo' and p.context.scope == :instance }.first expect(pin).to be_a(Solargraph::Pin::InstanceVariable) end - it "modifies instance variables in module functions" do + it 'modifies instance variables in module functions' do map = Solargraph::SourceMap.load_string(%( module Functions module_function @@ -425,46 +425,46 @@ def foo end end )) - pin = map.pins.select{|p| p.name == '@foo' and p.context.scope == :class}.first + pin = map.pins.select { |p| p.name == '@foo' and p.context.scope == :class }.first expect(pin).to be_a(Solargraph::Pin::InstanceVariable) - pin = map.pins.select{|p| p.name == '@foo' and p.context.scope == :instance}.first + pin = map.pins.select { |p| p.name == '@foo' and p.context.scope == :instance }.first expect(pin).to be_a(Solargraph::Pin::InstanceVariable) - pin = map.pins.select{|p| p.name == '@bar' and p.context.scope == :class}.first + pin = map.pins.select { |p| p.name == '@bar' and p.context.scope == :class }.first expect(pin).to be_a(Solargraph::Pin::InstanceVariable) - pin = map.pins.select{|p| p.name == '@bar' and p.context.scope == :instance}.first + pin = map.pins.select { |p| p.name == '@bar' and p.context.scope == :instance }.first expect(pin).to be_a(Solargraph::Pin::InstanceVariable) end - it "maps class variables" do + it 'maps class variables' do map = Solargraph::SourceMap.load_string(%( class Foo @@bar = 'bar' @@baz ||= 'baz' end )) - pin = map.pins.select{|p| p.name == '@@bar'}.first + pin = map.pins.select { |p| p.name == '@@bar' }.first expect(pin).to be_a(Solargraph::Pin::ClassVariable) - pin = map.pins.select{|p| p.name == '@@baz'}.first + pin = map.pins.select { |p| p.name == '@@baz' }.first expect(pin).to be_a(Solargraph::Pin::ClassVariable) end - it "maps local variables" do + it 'maps local variables' do map = Solargraph::SourceMap.load_string(%( x = y )) - pin = map.locals.select{|p| p.name == 'x'}.first + pin = map.locals.select { |p| p.name == 'x' }.first expect(pin).to be_a(Solargraph::Pin::LocalVariable) end - it "maps global variables" do + it 'maps global variables' do map = Solargraph::SourceMap.load_string(%( $x = y )) - pin = map.pins.select{|p| p.name == '$x'}.first + pin = map.pins.select { |p| p.name == '$x' }.first expect(pin).to be_a(Solargraph::Pin::GlobalVariable) end - it "maps constants" do + it 'maps constants' do map = Solargraph::SourceMap.load_string(%( module Foo BAR = 'bar' @@ -474,7 +474,7 @@ module Foo expect(pin).to be_a(Solargraph::Pin::Constant) end - it "maps singleton methods" do + it 'maps singleton methods' do map = Solargraph::SourceMap.load_string(%( class Foo def self.bar; end @@ -485,7 +485,7 @@ def self.bar; end expect(pin.context.scope).to be(:class) end - it "maps requalified singleton methods" do + it 'maps requalified singleton methods' do map = Solargraph::SourceMap.load_string(%( class Foo; end class Bar @@ -505,7 +505,7 @@ def boo; end expect(pin.context.scope).to be(:instance) end - it "maps private class methods" do + it 'maps private class methods' do map = Solargraph::SourceMap.load_string(%( class Foo def self.bar; end @@ -517,7 +517,7 @@ def self.bar; end expect(pin.visibility).to be(:private) end - it "maps singly defined private class methods" do + it 'maps singly defined private class methods' do map = Solargraph::SourceMap.load_string(%( class Foo private_class_method def bar; end @@ -528,7 +528,7 @@ class Foo expect(pin.visibility).to be(:private) end - it "maps private constants" do + it 'maps private constants' do map = Solargraph::SourceMap.load_string(%( class Foo BAR = 'bar' @@ -540,7 +540,7 @@ class Foo expect(pin.visibility).to be(:private) end - it "maps private namespaces" do + it 'maps private namespaces' do map = Solargraph::SourceMap.load_string(%( class Foo class Bar; end @@ -552,7 +552,7 @@ class Bar; end expect(pin.visibility).to be(:private) end - it "maps attribute writers" do + it 'maps attribute writers' do map = Solargraph::SourceMap.load_string(%( class Foo attr_writer :bar @@ -562,7 +562,7 @@ class Foo expect(map.pins.map(&:path)).not_to include('Foo#bar') end - it "maps attribute accessors" do + it 'maps attribute accessors' do map = Solargraph::SourceMap.load_string(%( class Foo attr_accessor :bar @@ -572,29 +572,29 @@ class Foo expect(map.pins.map(&:path)).to include('Foo#bar') end - it "maps extend self" do + it 'maps extend self' do map = Solargraph::SourceMap.load_string(%( class Foo extend self def bar; end end )) - pin = map.first_pin('Foo') + map.first_pin('Foo') # expect(pin.extend_references.map(&:name)).to include('Foo') - pin = map.pins.select{|p| p.is_a?(Solargraph::Pin::Reference::Extend)}.first + pin = map.pins.select { |p| p.is_a?(Solargraph::Pin::Reference::Extend) }.first expect(pin.namespace).to eq('Foo') expect(pin.name).to eq('Foo') end - it "maps require calls" do + it 'maps require calls' do map = Solargraph::SourceMap.load_string(%( require 'set' )) - pin = map.pins.select{|p| p.is_a?(Solargraph::Pin::Reference::Require)}.first + pin = map.pins.select { |p| p.is_a?(Solargraph::Pin::Reference::Require) }.first expect(pin.name).to eq('set') end - it "ignores dynamic require calls" do + it 'ignores dynamic require calls' do map = Solargraph::SourceMap.load_string(%( path = 'solargraph' require path @@ -602,16 +602,16 @@ def bar; end expect(map.requires.length).to eq(0) end - it "maps block parameters" do + it 'maps block parameters' do map = Solargraph::SourceMap.load_string(%( x.each do |y| end )) - pin = map.locals.select{|p| p.name == 'y'}.first + pin = map.locals.select { |p| p.name == 'y' }.first expect(pin).to be_a(Solargraph::Pin::Parameter) end - it "forces initialize methods to be private" do + it 'forces initialize methods to be private' do map = Solargraph::SourceMap.load_string(' class Foo def initialize name @@ -622,7 +622,7 @@ def initialize name expect(pin.visibility).to be(:private) end - it "maps top-level methods" do + it 'maps top-level methods' do map = Solargraph::SourceMap.load_string(%( def foo(bar, baz) end @@ -632,18 +632,18 @@ def foo(bar, baz) expect(pin).to be_a(Solargraph::Pin::Method) end - it "maps root blocks to class scope" do + it 'maps root blocks to class scope' do smap = Solargraph::SourceMap.load_string(%( @a = some_array @a.each do |b| b end ), 'test.rb') - pin = smap.pins.select{|p| p.is_a?(Solargraph::Pin::Block)}.first + pin = smap.pins.select { |p| p.is_a?(Solargraph::Pin::Block) }.first expect(pin.context.scope).to eq(:class) end - it "maps class method blocks to class scope" do + it 'maps class method blocks to class scope' do smap = Solargraph::SourceMap.load_string(%( class Foo def self.bar @@ -654,11 +654,11 @@ def self.bar end end )) - pin = smap.pins.select{|p| p.is_a?(Solargraph::Pin::Block)}.first + pin = smap.pins.select { |p| p.is_a?(Solargraph::Pin::Block) }.first expect(pin.context.scope).to eq(:class) end - it "maps instance method blocks to instance scope" do + it 'maps instance method blocks to instance scope' do smap = Solargraph::SourceMap.load_string(%( class Foo def bar @@ -669,11 +669,11 @@ def bar end end )) - pin = smap.pins.select{|p| p.is_a?(Solargraph::Pin::Block)}.first + pin = smap.pins.select { |p| p.is_a?(Solargraph::Pin::Block) }.first expect(pin.context.scope).to eq(:instance) end - it "maps rebased namespaces without leading colons" do + it 'maps rebased namespaces without leading colons' do smap = Solargraph::SourceMap.load_string(%( class Foo class ::Bar @@ -686,79 +686,79 @@ def baz; end expect(smap.first_pin('Bar#baz')).to be_a(Solargraph::Pin::Method) end - it "maps contexts of constants" do + it 'maps contexts of constants' do var = 'BAR' smap = Solargraph::SourceMap.load_string("#{var} = nil") - pin = smap.pins.select{|p| p.name == var}.first + pin = smap.pins.select { |p| p.name == var }.first expect(pin.context).to be_a(Solargraph::ComplexType) smap = Solargraph::SourceMap.load_string("#{var} ||= nil") - pin = smap.pins.select{|p| p.name == var}.first + pin = smap.pins.select { |p| p.name == var }.first expect(pin.context).to be_a(Solargraph::ComplexType) end - it "maps contexts of instance variables" do + it 'maps contexts of instance variables' do var = '@bar' smap = Solargraph::SourceMap.load_string("#{var} = nil") - pin = smap.pins.select{|p| p.name == var}.first + pin = smap.pins.select { |p| p.name == var }.first expect(pin.context).to be_a(Solargraph::ComplexType) smap = Solargraph::SourceMap.load_string("#{var} ||= nil") - pin = smap.pins.select{|p| p.name == var}.first + pin = smap.pins.select { |p| p.name == var }.first expect(pin.context).to be_a(Solargraph::ComplexType) end - it "maps contexts of class variables" do + it 'maps contexts of class variables' do var = '@@bar' smap = Solargraph::SourceMap.load_string("#{var} = nil") - pin = smap.pins.select{|p| p.name == var}.first + pin = smap.pins.select { |p| p.name == var }.first expect(pin.context).to be_a(Solargraph::ComplexType) smap = Solargraph::SourceMap.load_string("#{var} ||= nil") - pin = smap.pins.select{|p| p.name == var}.first + pin = smap.pins.select { |p| p.name == var }.first expect(pin.context).to be_a(Solargraph::ComplexType) end - it "maps contexts of global variables" do + it 'maps contexts of global variables' do var = '$bar' smap = Solargraph::SourceMap.load_string("#{var} = nil") - pin = smap.pins.select{|p| p.name == var}.first + pin = smap.pins.select { |p| p.name == var }.first expect(pin.context).to be_a(Solargraph::ComplexType) smap = Solargraph::SourceMap.load_string("#{var} ||= nil") - pin = smap.pins.select{|p| p.name == var}.first + pin = smap.pins.select { |p| p.name == var }.first expect(pin.context).to be_a(Solargraph::ComplexType) end - it "maps contexts of local variables" do + it 'maps contexts of local variables' do var = 'bar' smap = Solargraph::SourceMap.load_string("#{var} = nil") - pin = smap.locals.select{|p| p.name == var}.first + pin = smap.locals.select { |p| p.name == var }.first expect(pin.context).to be_a(Solargraph::ComplexType) smap = Solargraph::SourceMap.load_string("#{var} ||= nil") - pin = smap.locals.select{|p| p.name == var}.first + pin = smap.locals.select { |p| p.name == var }.first expect(pin.context).to be_a(Solargraph::ComplexType) end - it "maps method aliases" do + it 'maps method aliases' do smap = Solargraph::SourceMap.load_string(%( class Foo def bar; end alias baz bar end )) - pin = smap.pins.select{|p| p.path == 'Foo#baz'}.first + pin = smap.pins.select { |p| p.path == 'Foo#baz' }.first expect(pin).to be_a(Solargraph::Pin::MethodAlias) end - it "maps attribute aliases" do + it 'maps attribute aliases' do smap = Solargraph::SourceMap.load_string(%( class Foo attr_accessor :bar alias baz bar end )) - pin = smap.pins.select{|p| p.path == 'Foo#baz'}.first + pin = smap.pins.select { |p| p.path == 'Foo#baz' }.first expect(pin).to be_a(Solargraph::Pin::MethodAlias) end - it "maps class method aliases" do + it 'maps class method aliases' do smap = Solargraph::SourceMap.load_string(%( class Foo class << self @@ -767,12 +767,12 @@ def bar; end end end )) - pin = smap.pins.select{|p| p.path == 'Foo.baz'}.first + pin = smap.pins.select { |p| p.path == 'Foo.baz' }.first expect(pin).to be_a(Solargraph::Pin::MethodAlias) expect(pin.location.range.start.line).to eq(4) end - it "maps method macros" do + it 'maps method macros' do smap = Solargraph::SourceMap.load_string(%( class Foo # @!macro @@ -780,23 +780,23 @@ class Foo def make klass; end end ), 'test.rb') - pin = smap.pins.select{|p| p.path == 'Foo#make'}.first + pin = smap.pins.select { |p| p.path == 'Foo#make' }.first expect(pin.macros).not_to be_empty end - it "maps method directives" do + it 'maps method directives' do smap = Solargraph::SourceMap.load_string(%( class Foo # @!method bar(baz) # @return [String] end ), 'test.rb') - pin = smap.pins.select{|p| p.path == 'Foo#bar'}.first + pin = smap.pins.select { |p| p.path == 'Foo#bar' }.first expect(pin.return_type.tag).to eq('String') expect(pin.location.filename).to eq('test.rb') end - it "maps aliases from alias_method" do + it 'maps aliases from alias_method' do smap = Solargraph::SourceMap.load_string(%( class Foo class << self @@ -805,22 +805,22 @@ def bar; end end end )) - pin = smap.pins.select{|p| p.path == 'Foo.baz'}.first + pin = smap.pins.select { |p| p.path == 'Foo.baz' }.first expect(pin).to be_a(Solargraph::Pin::MethodAlias) expect(pin.location.range.start.line).to eq(4) end - it "maps aliases with unknown bases" do + it 'maps aliases with unknown bases' do smap = Solargraph::SourceMap.load_string(%( class Foo alias bar baz end )) - pin = smap.pins.select{|p| p.path == 'Foo#bar'}.first + pin = smap.pins.select { |p| p.path == 'Foo#bar' }.first expect(pin).to be_a(Solargraph::Pin::MethodAlias) end - it "maps aliases to superclass methods" do + it 'maps aliases to superclass methods' do smap = Solargraph::SourceMap.load_string(%( class Sup # My foo method @@ -830,33 +830,33 @@ class Sub < Sup alias bar foo end )) - pin = smap.pins.select{|p| p.path == 'Sub#bar'}.first + pin = smap.pins.select { |p| p.path == 'Sub#bar' }.first expect(pin).to be_a(Solargraph::Pin::MethodAlias) end - it "uses nodes for method parameter assignments" do + it 'uses nodes for method parameter assignments' do smap = Solargraph::SourceMap.load_string(%( class Foo def bar(baz = quz) end end )) - pin = smap.locals.select{|p| p.name == 'baz'}.first + pin = smap.locals.select { |p| p.name == 'baz' }.first # expect(pin.assignment).to be_a(Parser::AST::Node) expect(Solargraph::Parser.is_ast_node?(pin.assignment)).to be(true) end - it "defers resolution of distant alias_method aliases" do + it 'defers resolution of distant alias_method aliases' do smap = Solargraph::SourceMap.load_string(%( class MyClass alias_method :foo, :bar end )) - pin = smap.pins.select{|p| p.is_a?(Solargraph::Pin::MethodAlias)}.first + pin = smap.pins.select { |p| p.is_a?(Solargraph::Pin::MethodAlias) }.first expect(pin).not_to be_nil end - it "maps explicit begin nodes" do + it 'maps explicit begin nodes' do smap = Solargraph::SourceMap.load_string(%( def foo begin @@ -864,11 +864,11 @@ def foo end end )) - pin = smap.pins.select{|p| p.name == '@x'}.first + pin = smap.pins.select { |p| p.name == '@x' }.first expect(pin).not_to be_nil end - it "maps rescue nodes" do + it 'maps rescue nodes' do smap = Solargraph::SourceMap.load_string(%( def foo @x = make_x @@ -876,13 +876,13 @@ def foo @y = y end )) - err_pin = smap.locals{|p| p.name == 'err'}.first + err_pin = smap.locals { |p| p.name == 'err' }.first expect(err_pin).not_to be_nil - var_pin = smap.pins.select{|p| p.name == '@y'}.first + var_pin = smap.pins.select { |p| p.name == '@y' }.first expect(var_pin).not_to be_nil end - it "maps begin/rescue nodes" do + it 'maps begin/rescue nodes' do smap = Solargraph::SourceMap.load_string(%( def foo begin @@ -892,70 +892,70 @@ def foo end end )) - err_pin = smap.locals{|p| p.name == 'err'}.first + err_pin = smap.locals { |p| p.name == 'err' }.first expect(err_pin).not_to be_nil - var_pin = smap.pins.select{|p| p.name == '@y'}.first + var_pin = smap.pins.select { |p| p.name == '@y' }.first expect(var_pin).not_to be_nil end - it "maps classes with long namespaces" do + it 'maps classes with long namespaces' do smap = Solargraph::SourceMap.load_string(%( class Foo::Bar end ), 'test.rb') - pin = smap.pins.select{|p| p.path == 'Foo::Bar'}.first + pin = smap.pins.select { |p| p.path == 'Foo::Bar' }.first expect(pin).not_to be_nil expect(pin.namespace).to eq('Foo') expect(pin.name).to eq('Bar') expect(pin.path).to eq('Foo::Bar') end - it "ignores aliases that do not map to methods or attributes" do - expect { - smap = Solargraph::SourceMap.load_string(%( + it 'ignores aliases that do not map to methods or attributes' do + expect do + Solargraph::SourceMap.load_string(%( class Foo xyz = String alias foo xyz alias_method :foo, :xyz end ), 'test.rb') - }.not_to raise_error + end.not_to raise_error end - it "ignores private_class_methods that do not map to methods or attributes" do - expect { - smap = Solargraph::SourceMap.load_string(%( + it 'ignores private_class_methods that do not map to methods or attributes' do + expect do + Solargraph::SourceMap.load_string(%( class Foo var = some_method private_class_method :var end ), 'test.rb') - }.not_to raise_error + end.not_to raise_error end - it "ignores private_constants that do not map to namespaces or constants" do - expect { - smap = Solargraph::SourceMap.load_string(%( + it 'ignores private_constants that do not map to namespaces or constants' do + expect do + Solargraph::SourceMap.load_string(%( class Foo var = some_method private_constant :var end ), 'test.rb') - }.not_to raise_error + end.not_to raise_error end - it "ignores module_functions that do not map to methods or attributes" do - expect { - smap = Solargraph::SourceMap.load_string(%( + it 'ignores module_functions that do not map to methods or attributes' do + expect do + Solargraph::SourceMap.load_string(%( class Foo var = some_method module_function :var end ), 'test.rb') - }.not_to raise_error + end.not_to raise_error end - it "handles parse directives" do + it 'handles parse directives' do smap = Solargraph::SourceMap.load_string(%( class Foo # @!parse @@ -965,18 +965,18 @@ class Foo expect(smap.pins.map(&:path)).to include('Foo::Bar') end - it "ignores syntax errors in parse directives" do - expect { + it 'ignores syntax errors in parse directives' do + expect do Solargraph::SourceMap.load_string(%( class Foo # @!parse # def end )) - }.not_to raise_error + end.not_to raise_error end - it "sets visibility for symbol parameters" do + it 'sets visibility for symbol parameters' do smap = Solargraph::SourceMap.load_string(%( class Foo def pub; end @@ -987,33 +987,33 @@ def pro; end protected 'pro' end )) - pub = smap.pins.select{|pin| pin.path == 'Foo#pub'}.first + pub = smap.pins.select { |pin| pin.path == 'Foo#pub' }.first expect(pub.visibility).to eq(:public) - bar = smap.pins.select{|pin| pin.path == 'Foo#bar'}.first + bar = smap.pins.select { |pin| pin.path == 'Foo#bar' }.first expect(bar.visibility).to eq(:private) - baz = smap.pins.select{|pin| pin.path == 'Foo#baz'}.first + baz = smap.pins.select { |pin| pin.path == 'Foo#baz' }.first expect(baz.visibility).to eq(:public) - pro = smap.pins.select{|pin| pin.path == 'Foo#pro'}.first + pro = smap.pins.select { |pin| pin.path == 'Foo#pro' }.first expect(pro.visibility).to eq(:protected) end - it "ignores errors in method directives" do - expect { + it 'ignores errors in method directives' do + expect do Solargraph::SourceMap.load_string(%[ class Foo # @!method bar( end ]) - }.not_to raise_error + end.not_to raise_error end - it "handles invalid byte sequences" do - expect { + it 'handles invalid byte sequences' do + expect do Solargraph::SourceMap.load(File.join('spec', 'fixtures', 'invalid_utf8.rb')) - }.not_to raise_error + end.not_to raise_error end - it "applies private_class_method to attributes" do + it 'applies private_class_method to attributes' do smap = Solargraph::SourceMap.load_string(%( module Foo class << self @@ -1022,7 +1022,7 @@ class << self private_class_method :bar end )) - pin = smap.pins.select{|pin| pin.path == 'Foo.bar'}.first + pin = smap.pins.select { |pin| pin.path == 'Foo.bar' }.first expect(pin.visibility).to eq(:private) end @@ -1352,9 +1352,9 @@ class Foo private_class_method end ) - expect { + expect do Solargraph::SourceMap.load_string(code, 'test.rb') - }.not_to raise_error + end.not_to raise_error end it 'positions method directive pins' do @@ -1431,7 +1431,7 @@ def foo bar:, **splat end it 'gracefully handles misunderstood macros' do - expect { + expect do Solargraph::SourceMap.load_string(%( module Foo # @!macro macro1 @@ -1442,7 +1442,7 @@ module Foo class Bar; end end )) - }.not_to raise_error + end.not_to raise_error end it 'maps autoload paths' do @@ -1570,15 +1570,15 @@ def barbaz; end end it 'handles invalid byte sequences' do - expect { + expect do Solargraph::SourceMap.load('spec/fixtures/invalid_byte.rb') - }.not_to raise_error + end.not_to raise_error end it 'handles invalid byte sequences in stringified node comments' do - expect { + expect do Solargraph::SourceMap.load('spec/fixtures/invalid_node_comment.rb') - }.not_to raise_error + end.not_to raise_error end it 'parses method directives that start with multiple hashes' do diff --git a/spec/source_map_spec.rb b/spec/source_map_spec.rb index 60d4b523e..482f88655 100644 --- a/spec/source_map_spec.rb +++ b/spec/source_map_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::SourceMap do - it "locates named path pins" do + it 'locates named path pins' do map = Solargraph::SourceMap.load_string(%( class Foo def bar; end @@ -9,15 +9,17 @@ def bar; end expect(pin.path).to eq('Foo#bar') end - it "queries symbols using fuzzy matching" do + it 'queries symbols using fuzzy matching' do map = Solargraph::SourceMap.load_string(%( class FooBar def baz_qux; end end )) - expect(map.query_symbols("foo")).to eq(map.document_symbols) - expect(map.query_symbols("foobar")).to eq(map.document_symbols) - expect(map.query_symbols("bazqux")).to eq(map.document_symbols.select{ |pin_namespace| pin_namespace.name == "baz_qux" }) + expect(map.query_symbols('foo')).to eq(map.document_symbols) + expect(map.query_symbols('foobar')).to eq(map.document_symbols) + expect(map.query_symbols('bazqux')).to eq(map.document_symbols.select { |pin_namespace| + pin_namespace.name == 'baz_qux' + }) end it 'returns all pins, except for references as document symbols' do @@ -37,7 +39,7 @@ def baz_qux; end it 'includes convention pins in document symbols' do dummy_convention = Class.new(Solargraph::Convention::Base) do - def local(source_map) + def local source_map source_map.document_symbols # call memoized method Solargraph::Environ.new( @@ -65,7 +67,7 @@ def baz_qux; end Solargraph::Convention.unregister dummy_convention end - it "locates block pins" do + it 'locates block pins' do map = Solargraph::SourceMap.load_string(%( class Foo 100.times do @@ -149,7 +151,7 @@ class Foo; end end ), 'test.rb') locals = map.locals_at(Solargraph::Location.new('test.rb', Solargraph::Range.from_to(5, 0, 5, 0))).map(&:name) - expect(locals).to eq(['x', 'foo']) + expect(locals).to eq(%w[x foo]) end it 'updates cached inference when the ApiMap changes' do diff --git a/spec/source_spec.rb b/spec/source_spec.rb index 93624313c..53c7ba4d3 100644 --- a/spec/source_spec.rb +++ b/spec/source_spec.rb @@ -1,5 +1,5 @@ describe Solargraph::Source do - it "parses code" do + it 'parses code' do code = 'class Foo;def bar;end;end' source = described_class.new(code) expect(source.code).to eq(code) @@ -7,7 +7,7 @@ expect(source).to be_parsed end - it "fixes invalid code" do + it 'fixes invalid code' do code = 'class Foo; def bar; x.' source = described_class.new(code) expect(source.code).to eq(code) @@ -17,7 +17,7 @@ expect(source).not_to be_parsed end - it "finds ranges" do + it 'finds ranges' do code = %( class Foo def bar @@ -29,7 +29,7 @@ def bar expect(source.at(range)).to eq('def bar') end - it "finds nodes" do + it 'finds nodes' do code = 'class Foo;def bar;end;end' source = described_class.new(code) node = source.node_at(0, 0) @@ -38,7 +38,7 @@ def bar expect(node.type).to eq(:def) end - it "synchronizes from incremental updates" do + it 'synchronizes from incremental updates' do code = 'class Foo;def bar;end;end' source = described_class.new(code) updater = Solargraph::Source::Updater.new( @@ -55,19 +55,19 @@ def bar expect(changed.node.children[0].children[1]).to eq(:Food) end - it "synchronizes from full updates" do + it 'synchronizes from full updates' do code1 = 'class Foo;end' code2 = 'class Bar;end' source = described_class.new(code1) updater = Solargraph::Source::Updater.new(nil, 0, [ - Solargraph::Source::Change.new(nil, code2) - ]) + Solargraph::Source::Change.new(nil, code2) + ]) changed = source.synchronize(updater) expect(changed.code).to eq(code2) expect(changed.node.children[0].children[1]).to eq(:Bar) end - it "repairs broken incremental updates" do + it 'repairs broken incremental updates' do code = %( class Foo def bar @@ -89,18 +89,18 @@ def bar expect(changed).to be_repaired end - it "flags irreparable updates" do + it 'flags irreparable updates' do code = 'class Foo;def bar;end;end' source = described_class.new(code) updater = Solargraph::Source::Updater.new(nil, 0, [ - Solargraph::Source::Change.new(nil, 'end;end') - ]) + Solargraph::Source::Change.new(nil, 'end;end') + ]) changed = source.synchronize(updater) expect(changed).to be_parsed expect(changed).to be_repaired end - it "finds references" do + it 'finds references' do source = Solargraph::Source.load_string(%( class Foo def bar @@ -113,17 +113,17 @@ def bar= 𐐀.bar = 1 )) foos = source.references('Foo') - foobacks = foos.map{|f| source.at(f.range)} - expect(foobacks).to eq(['Foo', 'Foo']) + foobacks = foos.map { |f| source.at(f.range) } + expect(foobacks).to eq(%w[Foo Foo]) bars = source.references('bar') - barbacks = bars.map{|b| source.at(b.range)} - expect(barbacks).to eq(['bar', 'bar']) + barbacks = bars.map { |b| source.at(b.range) } + expect(barbacks).to eq(%w[bar bar]) assign_bars = source.references('bar=') - assign_barbacks = assign_bars.map{|b| source.at(b.range)} + assign_barbacks = assign_bars.map { |b| source.at(b.range) } expect(assign_barbacks).to eq(['bar=', 'bar =']) end - it "allows escape sequences incompatible with UTF-8" do + it 'allows escape sequences incompatible with UTF-8' do source = Solargraph::Source.new(' x = " Un bUen café \x92" puts x @@ -131,19 +131,19 @@ def bar= expect(source.parsed?).to be(true) end - it "fixes invalid byte sequences in UTF-8 encoding" do - expect { + it 'fixes invalid byte sequences in UTF-8 encoding' do + expect do Solargraph::Source.load('spec/fixtures/invalid_byte.rb') - }.not_to raise_error + end.not_to raise_error end - it "loads files with Unicode characters" do - expect { + it 'loads files with Unicode characters' do + expect do Solargraph::Source.load('spec/fixtures/unicode.rb') - }.not_to raise_error + end.not_to raise_error end - it "updates itself when code does not change" do + it 'updates itself when code does not change' do original = Solargraph::Source.load_string('x = y', 'test.rb') updater = Solargraph::Source::Updater.new('test.rb', 1, []) updated = original.synchronize(updater) @@ -151,7 +151,7 @@ def bar= expect(updated.version).to eq(1) end - it "handles unparseable code" do + it 'handles unparseable code' do source = Solargraph::Source.load_string(%( 100.times do |num| )) @@ -161,7 +161,7 @@ def bar= expect(source.parsed?).to be(false) end - it "finds foldable ranges" do + it 'finds foldable ranges' do # Of the 7 possible ranges, 2 are too short to be foldable source = Solargraph::Source.load_string(%( =begin @@ -236,7 +236,7 @@ def range_2 expect(source.folding_ranges.first.start.line).to eq(4) end - it "finishes synchronizations for unbalanced lines" do + it 'finishes synchronizations for unbalanced lines' do source1 = Solargraph::Source.load_string('x = 1', 'test.rb') source2 = source1.synchronize Solargraph::Source::Updater.new( 'test.rb', @@ -252,7 +252,7 @@ def range_2 expect(source2).to be_synchronized end - it "handles comment arrays that overlap lines" do + it 'handles comment arrays that overlap lines' do # Fixes negative argument error (castwide/solargraph#141) source = Solargraph::Source.load_string(%( =begin @@ -260,12 +260,12 @@ def range_2 y = 1 #foo )) node = source.node_at(3, 0) - expect { + expect do source.comments_for(node) - }.not_to raise_error + end.not_to raise_error end - it "formats comments with multiple hash prefixes" do + it 'formats comments with multiple hash prefixes' do source = Solargraph::Source.load_string(%( ## # one @@ -274,7 +274,7 @@ class Foo; end )) node = source.node_at(4, 7) comments = source.comments_for(node) - expect(comments.lines.map(&:chomp)).to eq(['one', 'two']) + expect(comments.lines.map(&:chomp)).to eq(%w[one two]) end it 'does not include inner comments' do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 00cc6c8c3..318970fc5 100755 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -33,13 +33,13 @@ # @param name [String] # @param value [String] -def with_env_var(name, value) - old_value = ENV[name] # Store the old value - ENV[name] = value # Set to new value +def with_env_var name, value + old_value = ENV.fetch(name, nil) # Store the old value + ENV[name] = value # Set to new value begin - yield # Execute the block + yield # Execute the block ensure - ENV[name] = old_value # Restore the old value + ENV[name] = old_value # Restore the old value end end diff --git a/spec/type_checker/levels/normal_spec.rb b/spec/type_checker/levels/normal_spec.rb index 9af91efe1..545dbbb61 100644 --- a/spec/type_checker/levels/normal_spec.rb +++ b/spec/type_checker/levels/normal_spec.rb @@ -1,6 +1,6 @@ describe Solargraph::TypeChecker do context 'normal level' do - def type_checker(code) + def type_checker code Solargraph::TypeChecker.load_string(code, 'test.rb', :normal) end diff --git a/spec/type_checker/levels/strict_spec.rb b/spec/type_checker/levels/strict_spec.rb index 47bf45a2c..248dd8176 100644 --- a/spec/type_checker/levels/strict_spec.rb +++ b/spec/type_checker/levels/strict_spec.rb @@ -1,7 +1,7 @@ describe Solargraph::TypeChecker do context 'strict level' do # @return [Solargraph::TypeChecker] - def type_checker(code) + def type_checker code Solargraph::TypeChecker.load_string(code, 'test.rb', :strict) end @@ -849,7 +849,7 @@ def foo *path, baz; end expect(checker.problems.map(&:message)).to eq([]) end - it "understands enough of define_method not to think the block is in class scope" do + it 'understands enough of define_method not to think the block is in class scope' do checker = type_checker(%( class Foo def initialize @@ -876,7 +876,7 @@ def bar expect(checker.problems.map(&:message)).to be_empty end - xit "Uses flow scope to specialize understanding of cvar types" do + xit 'Uses flow scope to specialize understanding of cvar types' do checker = type_checker(%( class Bar # @return [String] @@ -902,10 +902,10 @@ def foo end end )) - expect(checker.problems.map(&:message)).to eq(["Unresolved call to upcase!"]) + expect(checker.problems.map(&:message)).to eq(['Unresolved call to upcase!']) end - it "does not lose track of place and false alarm when using kwargs after a splat" do + it 'does not lose track of place and false alarm when using kwargs after a splat' do checker = type_checker(%( def foo(a, b, c); end def bar(*args, **kwargs, &blk) @@ -915,7 +915,7 @@ def bar(*args, **kwargs, &blk) expect(checker.problems.map(&:message)).to eq([]) end - it "understands Array#+ overloads" do + it 'understands Array#+ overloads' do checker = type_checker(%( c = ['a'] + ['a'] c @@ -923,7 +923,7 @@ def bar(*args, **kwargs, &blk) expect(checker.problems.map(&:message)).to eq([]) end - it "understands String#+ overloads" do + it 'understands String#+ overloads' do checker = type_checker(%( detail = '' detail += "foo" @@ -932,7 +932,7 @@ def bar(*args, **kwargs, &blk) expect(checker.problems.map(&:message)).to eq([]) end - it "understands Enumerable#each via _Each self type" do + it 'understands Enumerable#each via _Each self type' do checker = type_checker(%( class Blah # @param e [Enumerable] diff --git a/spec/type_checker/levels/strong_spec.rb b/spec/type_checker/levels/strong_spec.rb index 970435dc3..54c23c1f8 100644 --- a/spec/type_checker/levels/strong_spec.rb +++ b/spec/type_checker/levels/strong_spec.rb @@ -1,6 +1,6 @@ describe Solargraph::TypeChecker do context 'strong level' do - def type_checker(code) + def type_checker code Solargraph::TypeChecker.load_string(code, 'test.rb', :strong) end diff --git a/spec/type_checker/levels/typed_spec.rb b/spec/type_checker/levels/typed_spec.rb index b2071465e..e0efaa00b 100644 --- a/spec/type_checker/levels/typed_spec.rb +++ b/spec/type_checker/levels/typed_spec.rb @@ -1,6 +1,6 @@ describe Solargraph::TypeChecker do context 'typed level' do - def type_checker(code) + def type_checker code Solargraph::TypeChecker.load_string(code, 'test.rb', :typed) end diff --git a/spec/type_checker_spec.rb b/spec/type_checker_spec.rb index 33c2125e7..4597c6d75 100644 --- a/spec/type_checker_spec.rb +++ b/spec/type_checker_spec.rb @@ -2,12 +2,12 @@ describe Solargraph::TypeChecker do it 'does not raise errors checking unparsed sources' do - expect { + expect do checker = Solargraph::TypeChecker.load_string(%( foo{ )) checker.problems - }.not_to raise_error + end.not_to raise_error end it 'ignores tagged problems' do @@ -38,7 +38,7 @@ def documentation end ), nil, :strict) timed_out = true - Timeout::timeout(5) do # seconds + Timeout.timeout(5) do # seconds checker.problems timed_out = false end diff --git a/spec/workspace/config_spec.rb b/spec/workspace/config_spec.rb index 9b14d4337..4d8245d1b 100644 --- a/spec/workspace/config_spec.rb +++ b/spec/workspace/config_spec.rb @@ -2,17 +2,18 @@ require 'tmpdir' describe Solargraph::Workspace::Config do - let(:dir_path) { File.realpath(Dir.mktmpdir) } - after(:each) { FileUtils.remove_entry(dir_path) } + let(:dir_path) { File.realpath(Dir.mktmpdir) } - it "includes .rb files by default" do + after { FileUtils.remove_entry(dir_path) } + + it 'includes .rb files by default' do file = File.join(dir_path, 'file.rb') File.write(file, 'exit') config = Solargraph::Workspace::Config.new(dir_path) expect(config.calculated).to include(file) end - it "includes .rb files in subdirectories by default" do + it 'includes .rb files in subdirectories by default' do Dir.mkdir(File.join(dir_path, 'lib')) file = File.join(dir_path, 'lib', 'file.rb') File.write(file, 'exit') @@ -20,7 +21,7 @@ expect(config.calculated).to include(file) end - it "excludes test directories by default" do + it 'excludes test directories by default' do Dir.mkdir(File.join(dir_path, 'test')) file = File.join(dir_path, 'test', 'file.rb') File.write(file, 'exit') @@ -28,7 +29,7 @@ expect(config.calculated).not_to include(file) end - it "excludes spec directories by default" do + it 'excludes spec directories by default' do Dir.mkdir(File.join(dir_path, 'spec')) file = File.join(dir_path, 'spec', 'file.rb') File.write(file, 'exit') @@ -36,7 +37,7 @@ expect(config.calculated).not_to include(file) end - it "excludes vendor directories by default" do + it 'excludes vendor directories by default' do Dir.mkdir(File.join(dir_path, 'vendor')) file = File.join(dir_path, 'vendor', 'file.rb') File.write(file, 'exit') @@ -44,7 +45,7 @@ expect(config.calculated).not_to include(file) end - it "includes base reporters by default" do + it 'includes base reporters by default' do config = Solargraph::Workspace::Config.new(dir_path) expect(config.reporters).to include('rubocop') expect(config.reporters).to include('require_not_found') diff --git a/spec/workspace_spec.rb b/spec/workspace_spec.rb index db8141249..71bc0ebe5 100644 --- a/spec/workspace_spec.rb +++ b/spec/workspace_spec.rb @@ -6,15 +6,15 @@ let(:dir_path) { File.realpath(Dir.mktmpdir) } let(:file_path) { File.join(dir_path, 'file.rb') } - before(:each) { File.write(file_path, 'exit') } - after(:each) { FileUtils.remove_entry(dir_path) } + before { File.write(file_path, 'exit') } + after { FileUtils.remove_entry(dir_path) } - it "loads sources from a directory" do + it 'loads sources from a directory' do expect(workspace.filenames).to include(file_path) expect(workspace.has_file?(file_path)).to be(true) end - it "ignores non-Ruby files by default" do + it 'ignores non-Ruby files by default' do not_ruby = File.join(dir_path, 'not_ruby.txt') File.write not_ruby, 'text' @@ -22,14 +22,14 @@ expect(workspace.filenames).not_to include(not_ruby) end - it "does not merge non-workspace sources" do + it 'does not merge non-workspace sources' do source = Solargraph::Source.load_string('exit', 'not_ruby.txt') workspace.merge source expect(workspace.filenames).not_to include(source.filename) end - it "updates sources" do + it 'updates sources' do original = workspace.source(file_path) updated = Solargraph::Source.load_string('puts "updated"', file_path) workspace.merge updated @@ -39,7 +39,7 @@ expect(workspace.source(file_path)).to eq(updated) end - it "removes deleted sources" do + it 'removes deleted sources' do expect(workspace.filenames).to include(file_path) original = workspace.source(file_path) @@ -49,30 +49,30 @@ expect(workspace.filenames).not_to include(file_path) end - it "raises an exception for workspace size limits" do + it 'raises an exception for workspace size limits' do config = double(:config, calculated: Array.new(Solargraph::Workspace::Config::MAX_FILES + 1), max_files: Solargraph::Workspace::Config::MAX_FILES) - expect { + expect do Solargraph::Workspace.new('.', config) - }.to raise_error(Solargraph::WorkspaceTooLargeError) + end.to raise_error(Solargraph::WorkspaceTooLargeError) end - it "allows for unlimited files in config" do + it 'allows for unlimited files in config' do gemspec_file = File.join(dir_path, 'test.gemspec') File.write(gemspec_file, '') calculated = Array.new(Solargraph::Workspace::Config::MAX_FILES + 1) { gemspec_file } # @todo Mock reveals tight coupling config = double(:config, calculated: calculated, max_files: 0, allow?: true, require_paths: [], plugins: []) - expect { + expect do Solargraph::Workspace.new('.', config) - }.not_to raise_error + end.not_to raise_error end - it "generates default require path" do + it 'generates default require path' do expect(workspace.require_paths).to eq([File.join(dir_path, 'lib')]) end - it "generates require paths from gemspecs" do + it 'generates require paths from gemspecs' do gemspec_file = File.join(dir_path, 'test.gemspec') File.write(gemspec_file, %( Gem::Specification.new do |s| @@ -86,7 +86,7 @@ expect(workspace.require_paths).to eq([File.join(dir_path, 'other_lib')]) end - it "rescues errors in gemspecs" do + it 'rescues errors in gemspecs' do gemspec_file = File.join(dir_path, 'test.gemspec') File.write(gemspec_file, %( raise 'Error' @@ -94,7 +94,7 @@ expect(workspace.require_paths).to eq([File.join(dir_path, 'lib')]) end - it "rescues syntax errors in gemspecs" do + it 'rescues syntax errors in gemspecs' do gemspec_file = File.join(dir_path, 'test.gemspec') File.write(gemspec_file, %( 123. @@ -102,7 +102,7 @@ expect(workspace.require_paths).to eq([File.join(dir_path, 'lib')]) end - it "detects locally required paths" do + it 'detects locally required paths' do required_file = File.join(dir_path, 'lib', 'test.rb') Dir.mkdir(File.join(dir_path, 'lib')) File.write(required_file, 'exit') @@ -115,7 +115,7 @@ expect(workspace.would_require?('emptydir')).to be(false) end - it "uses configured require paths" do + it 'uses configured require paths' do workspace = Solargraph::Workspace.new('spec/fixtures/workspace') expect(workspace.require_paths).to eq(['spec/fixtures/workspace/lib', 'spec/fixtures/workspace/ext']) end @@ -127,9 +127,10 @@ end it 'rescues errors loading files into sources' do - config = double(:Config, directory: './path', calculated: ['./path/does_not_exist.rb'], max_files: 5000, require_paths: [], plugins: []) - expect { + config = double(:Config, directory: './path', calculated: ['./path/does_not_exist.rb'], max_files: 5000, + require_paths: [], plugins: []) + expect do Solargraph::Workspace.new('./path', config) - }.not_to raise_error + end.not_to raise_error end end diff --git a/spec/yard_map/mapper/to_method_spec.rb b/spec/yard_map/mapper/to_method_spec.rb index 9c5caa705..94fb983c3 100644 --- a/spec/yard_map/mapper/to_method_spec.rb +++ b/spec/yard_map/mapper/to_method_spec.rb @@ -1,38 +1,38 @@ describe Solargraph::YardMap::Mapper::ToMethod do - let(:code_object) { + let(:code_object) do namespace = YARD::CodeObjects::ModuleObject.new(nil, 'Example') YARD::CodeObjects::MethodObject.new(namespace, 'foo') - } + end it 'parses args' do - code_object.parameters = [["bar", nil]] + code_object.parameters = [['bar', nil]] pin = Solargraph::YardMap::Mapper::ToMethod.make(code_object) param = pin.parameters.first expect(param.decl).to be(:arg) - expect(param.name).to eq("bar") - expect(param.full).to eq("bar") + expect(param.name).to eq('bar') + expect(param.full).to eq('bar') end it 'parses optargs' do - code_object.parameters = [["bar", "'baz'"]] + code_object.parameters = [['bar', "'baz'"]] pin = Solargraph::YardMap::Mapper::ToMethod.make(code_object) param = pin.parameters.first expect(param.decl).to be(:optarg) - expect(param.name).to eq("bar") + expect(param.name).to eq('bar') expect(param.full).to eq("bar = 'baz'") end it 'parses kwargs' do - code_object.parameters = [["bar:", nil]] + code_object.parameters = [['bar:', nil]] pin = Solargraph::YardMap::Mapper::ToMethod.make(code_object) param = pin.parameters.first expect(param.name).to eq('bar') expect(param.decl).to be(:kwarg) - expect(param.full).to eq("bar:") + expect(param.full).to eq('bar:') end it 'parses kwoptargs' do - code_object.parameters = [["bar:", "'baz'"]] + code_object.parameters = [['bar:', "'baz'"]] pin = Solargraph::YardMap::Mapper::ToMethod.make(code_object) param = pin.parameters.first expect(param.decl).to be(:kwoptarg) @@ -41,41 +41,41 @@ end it 'parses restargs' do - code_object.parameters = [["*bar", nil]] + code_object.parameters = [['*bar', nil]] pin = Solargraph::YardMap::Mapper::ToMethod.make(code_object) param = pin.parameters.first expect(param.decl).to be(:restarg) expect(param.name).to eq('bar') - expect(param.full).to eq("*bar") + expect(param.full).to eq('*bar') end it 'parses kwrestargs' do - code_object.parameters = [["**bar", nil]] + code_object.parameters = [['**bar', nil]] pin = Solargraph::YardMap::Mapper::ToMethod.make(code_object) param = pin.parameters.first expect(param.decl).to be(:kwrestarg) expect(param.name).to eq('bar') - expect(param.full).to eq("**bar") + expect(param.full).to eq('**bar') end it 'parses blockargs' do - code_object.parameters = [["&bar", nil]] + code_object.parameters = [['&bar', nil]] pin = Solargraph::YardMap::Mapper::ToMethod.make(code_object) param = pin.parameters.first expect(param.decl).to be(:blockarg) expect(param.name).to eq('bar') - expect(param.full).to eq("&bar") + expect(param.full).to eq('&bar') end xit 'parses undefined but typed blockargs' do code_object.parameters = [] - code_object.docstring = <