Git Product home page Git Product logo

typeprof's Introduction

TypeProf

An experimental type-level Ruby interpreter for testing and understanding Ruby code.

Development

  1. Install Ruby 3.3 or later.
  2. Git clone this repository: git clone https://github.com/ruby/typeprof.git
  3. Install VSCode extension: code --install-extension mame.ruby-typeprof
  4. Open the repository in VSCode: code typeprof

Testing

$ bundle install
$ bundle exec rake test

More details

https://speakerdeck.com/mame/good-first-issues-of-typeprof

LICENSE

See LICENSE file.

typeprof's People

Contributors

akouryy avatar alpaca-tc avatar euglena1215 avatar hoshinotsuyoshi avatar k-nasa avatar mame avatar notfounds avatar riseshia avatar shoheimitani avatar sinsoku avatar smasato avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

typeprof's Issues

`include Enumerable` causes error

sig/typeprof/app/services/usage_anomalies/detector.rbs:5:2: [error] Type `::Enumerable` is generic but used as a non generic type
│ Diagnostic ID: RBS::InvalidTypeApplication
│
└   class Detector
    ~~~~~~~~~~~~~~

typeprof --version fails on non-CRuby

For example on TruffleRuby:

$ typeprof --version
Currently, TypeProf can work on a Ruby implementation that supports RubyVM::InstructionSequence, such as CRuby.
zsh: exit 1     typeprof --version

If none of typeprof can work on non-CRuby I guess that makes sense, but still shouldn't --version and maybe also --help still work, and only fail when actually needing RubyVM::InstructionSequence?
I think that's what most libraries do and I think it's closer to expected behavior.

Context: I'm updating TruffleRuby to Ruby 3 compatibility.

Another option would be to not include typeprof on TruffleRuby/non-CRuby but I think that's bad because suddenly there would be some expected bundled gem missing, bundle install might fail if typeprof is in it, etc.

Updating a Rails app to Ruby 3.1.2 breaks typrof

$ rails -v
Rails 6.1.6
stevenaguilar ~/portal on add-linux-platform[$]
$ ruby -v
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-darwin21]

I'm currently trying to upgrade a Rails app to use Ruby 3.1.2. When I try to deploy to heroku I get the following error:

remote:        ERROR in vendor/ruby-3.1.2/lib/ruby/gems/3.1.0/gems/typeprof-0.21.2/vscode/src/extension.ts:3:25
remote:        TS2307: Cannot find module 'vscode' or its corresponding type declarations.

It seems that it comes from typeprof-0.21.2. Here is the full stack trace:

remote:           [0] ./node_modules/react/index.js 190 bytes {0} {1} [built]
remote:           [6] ./app/javascript/components/v2/App/Claims/ClaimDetails/ClaimStyles.tsx 16.8 KiB {0} {1} [built]
remote:           [9] ./app/javascript/components/v2/App/utils/index.ts + 2 modules 13.1 KiB {0} {1} [built]
remote:               | ./app/javascript/components/v2/App/utils/index.ts 9.34 KiB [built]
remote:               | ./node_modules/date-fns/esm/subMonths/index.js 1.17 KiB [built]
remote:               | ./node_modules/date-fns/esm/sub/index.js 2.53 KiB [built]
remote:          [12] ./app/javascript/components/v2/App/testUtils/Wrapper.tsx 795 bytes {0} {1} [built]
remote:          [13] ./app/javascript/components/v2/App/interfaces.ts 4.07 KiB {0} {1} [built]
remote:          [19] ./app/javascript/components/v2/App/utils/userRole.ts 1.57 KiB {0} {1} [built]
remote:          [20] ./app/javascript/components/v2/App/toast/use-toast.tsx 288 bytes {0} {1} [built]
remote:          [22] ./app/javascript/components/v2/App/Invitation/Styles.tsx 2.69 KiB {0} {1} [built]
remote:          [24] ./app/javascript/components/v2/App/utils/constants.ts 2.3 KiB {0} {1} [built]
remote:         [348] ./app/javascript/components/datatables/index.ts 837 bytes {0} {1} [built]
remote:         [647] ./app/javascript/components/modals/2fa_disable_modal.ts 1.52 KiB {0} {1} [built]
remote:         [828] ./app/javascript/components sync ^\.\/.*$ 38.2 KiB {0} {1} [built]
remote:        [1231] ./node_modules/react_ujs/react_ujs/index.js 5.89 KiB {0} {1} [built]
remote:        [1243] ./app/javascript/packs/application.ts 1.45 KiB {0} [built]
remote:        [1250] ./app/javascript/packs/server_rendering.ts 292 bytes {1} [built]
remote:            + 1528 hidden modules
remote:        
remote:        ERROR in vendor/ruby-3.1.2/lib/ruby/gems/3.1.0/gems/typeprof-0.21.2/vscode/src/extension.ts:3:25
remote:        TS2307: Cannot find module 'vscode' or its corresponding type declarations.
remote:            1 | "use strict";
remote:            2 |
remote:          > 3 | import * as vscode from "vscode";
remote:              |                         ^^^^^^^^
remote:            4 | import {
remote:            5 |   LanguageClient,
remote:            6 |   LanguageClientOptions,
remote:        
remote:        ERROR in vendor/ruby-3.1.2/lib/ruby/gems/3.1.0/gems/typeprof-0.21.2/vscode/src/extension.ts:8:8
remote:        TS2307: Cannot find module 'vscode-languageclient/node' or its corresponding type declarations.
remote:             6 |   LanguageClientOptions,
remote:             7 |   ServerOptions,
remote:          >  8 | } from "vscode-languageclient/node";
remote:               |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
remote:             9 | import * as net from "net";
remote:            10 | import * as child_process from "child_process";
remote:            11 | import { existsSync } from "fs";
remote:        
remote:        ERROR in vendor/ruby-3.1.2/lib/ruby/gems/3.1.0/gems/typeprof-0.21.2/vscode/src/extension.ts:278:9
remote:        TS2571: Object is of type 'unknown'.
remote:            276 |
remote:            277 |   activeFolders.forEach((folder) => {
remote:          > 278 |     if (folder.uri.scheme === "file" && !clientSessions.has(folder)) {
remote:                |         ^^^^^^
remote:            279 |       startTypeProf(folder);
remote:            280 |     }
remote:            281 |   });
remote:        Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--5-1!node_modules/postcss-loader/src/index.js??ref--5-2!node_modules/@reach/combobox/styles.css:
remote:            Entrypoint mini-css-extract-plugin = *
remote:            [0] ./node_modules/css-loader/dist/runtime/cssWithMappingToString.js 2.27 KiB {0} [built]
remote:            [1] ./node_modules/css-loader/dist/runtime/api.js 1.57 KiB {0} [built]
remote:            [2] ./node_modules/css-loader/dist/cjs.js??ref--5-1!./node_modules/postcss-loader/src??ref--5-2!./node_modules/@reach/combobox/styles.css 2.33 KiB {0} [built]
remote:        Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--5-1!node_modules/postcss-loader/src/index.js??ref--5-2!node_modules/@sayrhino/rhino-shared-js/build/datepicker.css:
remote:            Entrypoint mini-css-extract-plugin = *
remote:            [0] ./node_modules/css-loader/dist/runtime/cssWithMappingToString.js 2.27 KiB {0} [built]
remote:            [1] ./node_modules/css-loader/dist/runtime/api.js 1.57 KiB {0} [built]
remote:            [2] ./node_modules/css-loader/dist/cjs.js??ref--5-1!./node_modules/postcss-loader/src??ref--5-2!./node_modules/@sayrhino/rhino-shared-js/build/datepicker.css 53.1 KiB {0} [built]
remote:        Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/sass-loader/dist/cjs.js??ref--6-3!app/javascript/components/common/forms/RadioLabel.scss:
remote:            Entrypoint mini-css-extract-plugin = *
remote:            [0] ./node_modules/css-loader/dist/runtime/cssWithMappingToString.js 2.27 KiB {0} [built]
remote:            [1] ./node_modules/css-loader/dist/runtime/api.js 1.57 KiB {0} [built]
remote:            [2] ./node_modules/css-loader/dist/cjs.js??ref--6-1!./node_modules/postcss-loader/src??ref--6-2!./node_modules/sass-loader/dist/cjs.js??ref--6-3!./app/javascript/components/common/forms/RadioLabel.scss 765 bytes {0} [built]
remote:        Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/sass-loader/dist/cjs.js??ref--6-3!app/javascript/components/common/functions.scss:
remote:            Entrypoint mini-css-extract-plugin = *
remote:            [0] ./node_modules/css-loader/dist/runtime/cssWithMappingToString.js 2.27 KiB {0} [built]
remote:            [1] ./node_modules/css-loader/dist/runtime/api.js 1.57 KiB {0} [built]
remote:            [2] ./node_modules/css-loader/dist/cjs.js??ref--6-1!./node_modules/postcss-loader/src??ref--6-2!./node_modules/sass-loader/dist/cjs.js??ref--6-3!./app/javascript/components/common/functions.scss 516 bytes {0} [built]
remote:        
remote: 
remote:  !
remote:  !     Precompiling assets failed.
remote:  !
remote:  !     Push rejected, failed to compile Ruby app.
remote: 
remote:  !     Push failed
remote: Verifying deploy...
remote: 

[Feature Request] --exclude-untyped option for better typing experience

Background

When trying to add types to complex ruby projects (e.g, Ruby on Rails), it will be hard to analyze correctly entire projects and we will need to add types manually.
But even if we specify types based on typeprof outpus, running typeprof again will override our manually typed files.

What do you want

I think we need --exclude-untyped options.
For example, I want to analyze Ruby on Rails projects like following steps.
FYI Pocke san's blog

  • download gem_rbs (e.g, git submodule add https://github.com/ruby/gem_rbs.git gem_rbs)
  • Run rbs_rails rake task (bin/rake rbs_rails:all )
  • Run typeprof with --exlude-untyped to analyze types (typeprof --exclude-untyped gem_rbs/gems/**/*.rbs sig/rbs_rails**/*.rbs app/models/*.rb -o sig/typeprof/models.rbs)
  • Run typeprof to output prototype or run rbs prototype (typeprof gem_rbs/gems/**/*.rbs sig/rbs_rails**/*.rbs sig/typeprof/models.rbs -o sig/manual/models.rbs)
  • Edit sig/manual/models.rbs manually
  • Run steep with gem_rbs/gems/**/*.rbs , sig/rbs_rails**/*.rbs, sig/typeprof/*.rbs, sig/manual/*.rbs

Summarizing the Prism AST Coverage

Hello. I'm delighted to see such a fantastic tool being developed.

It would be beneficial to indicate the current extent of typeprof's syntax support. This would demonstrate the tool's usefulness and assist those interested in contributing (I am particularly focused on the latter).

This should ideally indicate the stages of support rather than just a checklist, but as a first step, I have marked the syntax that is at least partially supported.

Coverage

  • alias_global_variable_node
  • alias_method_node
  • alternation_pattern_node
  • and_node
  • arguments_node
  • array_node
  • array_pattern_node
  • assoc_node
  • assoc_splat_node
  • back_reference_read_node
  • begin_node
  • block_argument_node
  • block_local_variable_node
  • block_node
  • block_parameter_node
  • block_parameters_node
  • break_node
  • call_and_write_node
  • call_node
  • call_operator_write_node
  • call_or_write_node
  • call_target_node
  • capture_pattern_node
  • case_match_node
  • case_node
  • class_node
  • class_variable_and_write_node
  • class_variable_operator_write_node
  • class_variable_or_write_node
  • class_variable_read_node
  • class_variable_target_node
  • class_variable_write_node
  • constant_and_write_node
  • constant_operator_write_node
  • constant_or_write_node
  • constant_path_and_write_node
  • constant_path_node
  • constant_path_operator_write_node
  • constant_path_or_write_node
  • constant_path_target_node
  • constant_path_write_node
  • constant_read_node
  • constant_target_node
  • constant_write_node
  • def_node
  • defined_node
  • else_node
  • embedded_statements_node
  • embedded_variable_node
  • ensure_node
  • false_node
  • find_pattern_node
  • flip_flop_node
  • float_node
  • for_node
  • forwarding_arguments_node
  • forwarding_parameter_node
  • forwarding_super_node
  • global_variable_and_write_node
  • global_variable_operator_write_node
  • global_variable_or_write_node
  • global_variable_read_node
  • global_variable_target_node
  • global_variable_write_node
  • hash_node
  • hash_pattern_node
  • if_node
  • imaginary_node
  • implicit_node
  • implicit_rest_node
  • in_node
  • index_and_write_node
  • index_operator_write_node
  • index_or_write_node
  • index_target_node
  • instance_variable_and_write_node
  • instance_variable_operator_write_node
  • instance_variable_or_write_node
  • instance_variable_read_node
  • instance_variable_target_node
  • instance_variable_write_node
  • integer_node
  • interpolated_match_last_line_node
  • interpolated_regular_expression_node
  • interpolated_string_node
  • interpolated_symbol_node
  • interpolated_xstring_node
  • it_parameters_node
  • keyword_hash_node
  • keyword_rest_parameter_node
  • lambda_node
  • local_variable_and_write_node
  • local_variable_operator_write_node
  • local_variable_or_write_node
  • local_variable_read_node
  • local_variable_target_node
  • local_variable_write_node
  • match_last_line_node
  • match_predicate_node
  • match_required_node
  • match_write_node
  • missing_node
  • module_node
  • multi_target_node
  • multi_write_node
  • next_node
  • nil_node
  • no_keywords_parameter_node
  • numbered_parameters_node
  • numbered_reference_read_node
  • optional_keyword_parameter_node
  • optional_parameter_node
  • or_node
  • parameters_node
  • parentheses_node
  • pinned_expression_node
  • pinned_variable_node
  • post_execution_node
  • pre_execution_node
  • program_node
  • range_node
  • rational_node
  • redo_node
  • regular_expression_node
  • required_keyword_parameter_node
  • required_parameter_node
  • rescue_modifier_node
  • rescue_node
  • rest_parameter_node
  • retry_node
  • return_node
  • self_node
  • shareable_constant_node
  • singleton_class_node
  • source_encoding_node
  • source_file_node
  • source_line_node
  • splat_node
  • statements_node
  • string_node
  • super_node
  • symbol_node
  • true_node
  • undef_node
  • unless_node
  • until_node
  • when_node
  • while_node
  • xstring_node
  • yield_node

Enumerator expects 2 arguments

sig/typeprof/app/models/requests_fetcher.rbs:19:41: [error] Type `::Enumerator` expects 2 arguments, but 1 arguments are given
│ Diagnostic ID: RBS::InvalidTypeApplication
│
└   def responses_for_guid: (untyped guid, Enumerator[untyped] times, untyped client) -> untyped

Crash with generics

Trying with matrix, with a hint rbs using generics, I get a crash.

I bypassed the crash calling warn, but it crashes further down. I didn't investigate more.

Are generics supported?

RBS hint file I'm trying (it's the last commit of my PR):

class Matrix[unchecked out Elem]
  @rows : Array[Array[Elem]]
end

class Vector[unchecked out Elem]
  @elements : Array[Elem]
end

Error I'm getting:

$ bundle exec typeprof ../matrix/sig/matrix.rbs ../matrix/lib/matrix.rb -o ../matrix/sig/matrix_gen.rbs
bundler: failed to load command: typeprof (/Users/mal/.rvm/gems/ruby-head/bin/typeprof)
ArgumentError: wrong number of arguments (given 1, expected 2)
  /Users/mal/ruby/typeprof/lib/typeprof/analyzer.rb:708:in `warn'
  /Users/mal/ruby/typeprof/lib/typeprof/analyzer.rb:658:in `get_ivar'
  /Users/mal/ruby/typeprof/lib/typeprof/analyzer.rb:673:in `block in add_ivar_write!'
  /Users/mal/ruby/typeprof/lib/typeprof/type.rb:90:in `each_child'
  /Users/mal/ruby/typeprof/lib/typeprof/analyzer.rb:672:in `add_ivar_write!'
  /Users/mal/ruby/typeprof/lib/typeprof/analyzer.rb:945:in `set_instance_variable'
  /Users/mal/ruby/typeprof/lib/typeprof/analyzer.rb:1372:in `step'
  /Users/mal/ruby/typeprof/lib/typeprof/analyzer.rb:807:in `type_profile'
  /Users/mal/ruby/typeprof/lib/typeprof/config.rb:87:in `analyze'
  /Users/mal/ruby/typeprof/exe/typeprof:6:in `<top (required)>'
  /Users/mal/.rvm/gems/ruby-head/bin/typeprof:23:in `load'
  /Users/mal/.rvm/gems/ruby-head/bin/typeprof:23:in `<top (required)>'

After bypassing that bug:

[23:50][~/ruby/typeprof(master)]$ bundle exec typeprof ../matrix/sig/matrix.rbs ../matrix/lib/matrix.rb -o ../matrix/sig/matrix_gen.rbs
bundler: failed to load command: typeprof (/Users/mal/.rvm/gems/ruby-head/bin/typeprof)
NoMethodError: undefined method `get_method' for #<TypeProf::Type::Var:0x00007ff5b4f1f9a8 @name=:Elem>
  /Users/mal/ruby/typeprof/lib/typeprof/analyzer.rb:1929:in `do_send'
  /Users/mal/ruby/typeprof/lib/typeprof/analyzer.rb:1204:in `block in step'
  /Users/mal/ruby/typeprof/lib/typeprof/type.rb:90:in `each_child'
  /Users/mal/ruby/typeprof/lib/typeprof/analyzer.rb:1203:in `step'
  /Users/mal/ruby/typeprof/lib/typeprof/analyzer.rb:807:in `type_profile'
  /Users/mal/ruby/typeprof/lib/typeprof/config.rb:87:in `analyze'
  /Users/mal/ruby/typeprof/exe/typeprof:6:in `<top (required)>'
  /Users/mal/.rvm/gems/ruby-head/bin/typeprof:23:in `load'
  /Users/mal/.rvm/gems/ruby-head/bin/typeprof:23:in `<top (required)>'

tests not working for 0.21.7 on ruby 3.1

Hi,

I'm trying to build typeprof 0.21.7 against ruby 3.1 but I'm getting errors from the tests:

(none):1: warning: possibly useless use of a literal in void context
Loaded suite /usr/lib/ruby/gems/3.1.0/gems/rake-13.0.6/lib/rake/rake_test_loader
Started
....F
===============================================================================
Failure: test: testbed/diff-lcs(TypeProf::DiffLCSTest): <nil> is not true.
/build/ruby-typeprof/src/typeprof-0.21.7/test/typeprof/diff-lcs_test.rb:20:in `block in <class:DiffLCSTest>'
     17:
     18:         # No special reason to choose these two classes (Goodcheck::Analyzer and Trigger)
     19:
  => 20:         assert(actual =~ /^module Diff\n  module LCS\n(?:(?:    .*?\n|\n)*)^  end\n^end\n/)
     21:         assert_include($&, "def self.diff: (Array[T] | LCS seq1, Array[T] seq2, ?nil callbacks) ?{ (Array[Change] | Change | ContextChange) -> nil } -> (Array[(Array[Change?] | Change | ContextChange)?])")
     22:
     23:         assert(actual =~ /^    class Change\n(?:(?:      .*?\n|\n)*)^    end\n/)
===============================================================================
E
===============================================================================
Error: test: testbed/goodcheck(TypeProf::GoodcheckTest): Bundler::GemfileNotFound: /build/ruby-typeprof/src/typeprof-0.21.7/testbed/goodcheck/Gemfile not found
/usr/lib/ruby/3.1.0/bundler/definition.rb:36:in `build'
/usr/lib/ruby/3.1.0/bundler.rb:207:in `definition'
/usr/lib/ruby/3.1.0/bundler.rb:155:in `setup'
/build/ruby-typeprof/src/typeprof-0.21.7/test/typeprof/goodcheck_test.rb:34:in `block in <class:GoodcheckTest>'
===============================================================================(none):25: warning: possibly useless use of a constant in void context
path/to/file:25: warning: possibly useless use of a constant in void context

....TypeProf for IDE is started successfully
...........................................................................
...............................................................................
...............................................................................
............................................................................
Finished in 48.261118663 seconds.
-------------------------------------------------------------------------------
319 tests, 355 assertions, 1 failures, 1 errors, 0 pendings, 0 omissions, 0 notifications
99.373% passed
-------------------------------------------------------------------------------
6.61 tests/s, 7.36 assertions/s
rake aborted!

Any idea what is wrong?

[warning] already initialized constant Foo::A

The warning [warning] already initialized constant Foo::A is displayed.
When a class with constants exists in an RBS file that has already been created.

Ruby TypeProf Playground
https://mame.github.io/typeprof-playground/#rb=class+Foo%0A++A+%3D+1%0Aend%0A&rbs=class+Foo%0A++A%3A+Integer%0Aend

Ruby

class Foo
  A = 1
end

RBS

class Foo
  A: Integer
end

Output

# TypeProf 0.15.0

# Errors
test.rb:2: [warning] already initialized constant Foo::A

# Classes
class Foo
  A: Integer
end


## Version info:
##   * Ruby: 3.0.0
##   * RBS: 1.3.1
##   * TypeProf: 0.15.0

undefined method `decls' for nil:NilClass (NoMethodError)

What is the problem?

When analyzing ActiveRecord children class with rbs_rails outputs, this error has occured.

$ typeprof gem_rbs/gems/**/*.rbs sig/rbs_rails**/*.rbs app/models/post.rb -o sig/post.rbs
/Users/foo/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/typeprof-0.11.0/lib/typeprof/import.rb:262:in `each_class_decl': undefined method `decls' for nil:NilClass (NoMethodError)
	from /Users/foo/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/typeprof-0.11.0/lib/typeprof/import.rb:113:in `conv_classes'
	from /Users/foo/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/typeprof-0.11.0/lib/typeprof/import.rb:80:in `dump_json'
	from /Users/foo/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/typeprof-0.11.0/lib/typeprof/import.rb:69:in `load_rbs'
	from /Users/foo/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/typeprof-0.11.0/lib/typeprof/import.rb:48:in `load_path'
	from /Users/foo/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/typeprof-0.11.0/lib/typeprof/import.rb:481:in `import_rbs_file'
	from /Users/foo/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/typeprof-0.11.0/lib/typeprof/config.rb:100:in `block in analyze'
	from /Users/foo/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/typeprof-0.11.0/lib/typeprof/config.rb:96:in `each'
	from /Users/foo/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/typeprof-0.11.0/lib/typeprof/config.rb:96:in `analyze'
	from /Users/foo/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/typeprof-0.11.0/exe/typeprof:6:in `<top (required)>'
	from /Users/foo/.rbenv/versions/3.0.0/bin/typeprof:23:in `load'
	from /Users/foo/.rbenv/versions/3.0.0/bin/typeprof:23:in `<main>'

Steps to Reproduce

Please setup this minimum rbs_rails sample, and run typeprof gem_rbs/gems/**/*.rbs sig/rbs_rails**/*.rbs app/models/post.rb -o sig/post.rbs.
https://github.com/nullnull/rails_with_rbs_rails_sample

Versions

$ typeprof --version
typeprof 0.11.0

Other

Thanks for developing cool library!

Symbol-Array loop and `define_method` finds only one method.

Hello! The last time i tried define_method typeprof couldn't handle it at all. I am happy that it changed and it is nice to see the progress.

Issue

As you can see i provide an array of method names, iterate over them and create an empty method.
My expectation would be that the class Human would have two methods in the typeprof output: :a and :b. But only :a is shown.

I am quite sure this is a hard bug, because it relies on loop unwrapping.

ruby

class Human
  define_method(:fo) { }
  
  [:a, :b].each { |m|
    define_method(m) { }
  }
end

rbs

output

# TypeProf 0.12.0

# Classes
class Human
  def a: -> nil
end


## Version info:
##   * Ruby: 3.0.0
##   * RBS: 1.0.3
##   * TypeProf: 0.12.0

Try it on playground:

https://mame.github.io/typeprof-playground/#rb=class+Human%0A++%5B%3Aa%2C+%3Ab%5D.each+%7B+%7Cm%7C%0A++++define_method%28m%29+%7B+%7D%0A++%7D%0Aend&rbs=

Typing of dynamic methods and variables

  1. define_singleton_method

  2. define_method

  3. {local,thread,instance,class}_variable_{set,get}

Receiving check errors because defined methods parameters are untyped.

Rail's JSON support causes issues

This can also be produced with the following file:

require "json"

class Exception
  def as_json(options = nil)
    to_s
  end
end

This causes the following backtrace

/Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/utils.rb:4:in `array_update': undefined method `%' for nil:NilClass (NoMethodError)
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/analyzer.rb:234:in `local_update'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/method.rb:117:in `do_check_send'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/method.rb:307:in `block in do_match_iseq_mdef'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/method.rb:306:in `each'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/method.rb:306:in `do_match_iseq_mdef'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/analyzer.rb:2421:in `block in do_define_iseq_method'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/analyzer.rb:2420:in `each'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/analyzer.rb:2420:in `do_define_iseq_method'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/analyzer.rb:1413:in `step'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/analyzer.rb:1050:in `type_profile'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/config.rb:123:in `analyze'
        from exe/typeprof:9:in `<main>'

Now `tool/dog_bench.rb` cannot handle `core/ast/base.rb`

Recently, I found that the typeprof VSCode extension does not work correctly on lib/typeprof/ when using the latest master branch (50d2d7c). However, it works fine with the previous commit (b21905b).

The execution results of tool/dog_bench.rb also reflect this behavior.

Given that the former results in an error and the latter succeeds, I am reporting this as a problem.

Problem

At 50d2d7c , $ bundle exec ruby tool/dog_bench.rb failed

$ bundle exec ruby tool/dog_bench.rb ; echo $?
lib/typeprof/code_range.rb
lib/typeprof/core/ast/base.rb
/Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/env.rb:297:in `get_var': unhandled exception
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/control.rb:189:in `install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/base.rb:93:in `install'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/misc.rb:23:in `block in install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/misc.rb:22:in `each'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/misc.rb:22:in `install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/base.rb:93:in `install'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/control.rb:66:in `install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/base.rb:93:in `install'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/misc.rb:23:in `block in install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/misc.rb:22:in `each'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/misc.rb:22:in `install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/base.rb:93:in `install'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/control.rb:139:in `install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/base.rb:93:in `install'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/misc.rb:23:in `block in install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/misc.rb:22:in `each'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/misc.rb:22:in `install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/base.rb:93:in `install'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/method.rb:224:in `install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/base.rb:93:in `install'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/method.rb:189:in `install'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/misc.rb:23:in `block in install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/misc.rb:22:in `each'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/misc.rb:22:in `install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/base.rb:93:in `install'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/module.rb:67:in `install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/module.rb:113:in `install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/base.rb:93:in `install'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/misc.rb:23:in `block in install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/misc.rb:22:in `each'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/misc.rb:22:in `install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/base.rb:93:in `install'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/module.rb:67:in `install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/module.rb:113:in `install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/base.rb:93:in `install'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/misc.rb:23:in `block in install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/misc.rb:22:in `each'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/misc.rb:22:in `install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/base.rb:93:in `install'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/module.rb:67:in `install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/base.rb:93:in `install'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/misc.rb:23:in `block in install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/misc.rb:22:in `each'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/misc.rb:22:in `install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/base.rb:93:in `install'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/base.rb:211:in `install0'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/ast/base.rb:93:in `install'
        from /Users/hoshino/ghq/github.com/ruby/typeprof/lib/typeprof/core/service.rb:81:in `update_rb_file'
        from tool/dog_bench.rb:10:in `block in main'
        from <internal:dir>:411:in `glob'
        from tool/dog_bench.rb:7:in `main'
        from tool/dog_bench.rb:31:in `block in <main>'
        from tool/dog_bench.rb:30:in `run'
        from tool/dog_bench.rb:30:in `<main>'
1

At previous commit b21905b , $ bundle exec ruby tool/dog_bench.rb succeeds

$ bundle exec ruby tool/dog_bench.rb ; echo $?
lib/typeprof/code_range.rb
lib/typeprof/core/ast/base.rb
lib/typeprof/core/ast/call.rb
lib/typeprof/core/ast/const.rb
lib/typeprof/core/ast/control.rb
lib/typeprof/core/ast/meta.rb
lib/typeprof/core/ast/method.rb
lib/typeprof/core/ast/misc.rb
lib/typeprof/core/ast/module.rb
lib/typeprof/core/ast/sig_decl.rb
lib/typeprof/core/ast/sig_type.rb
lib/typeprof/core/ast/value.rb
lib/typeprof/core/ast/variable.rb
lib/typeprof/core/ast.rb
lib/typeprof/core/builtin.rb
lib/typeprof/core/env/method.rb
lib/typeprof/core/env/method_entity.rb
lib/typeprof/core/env/module_entity.rb
lib/typeprof/core/env/static_read.rb
lib/typeprof/core/env/type_alias_entity.rb
lib/typeprof/core/env/value_entity.rb
lib/typeprof/core/env.rb
lib/typeprof/core/graph/box.rb
lib/typeprof/core/graph/change_set.rb
lib/typeprof/core/graph/filter.rb
lib/typeprof/core/graph/vertex.rb
lib/typeprof/core/graph.rb
lib/typeprof/core/service.rb
lib/typeprof/core/type.rb
lib/typeprof/core/util.rb
lib/typeprof/core.rb
lib/typeprof/diagnostic.rb
lib/typeprof/version.rb
Elapsed: 0.708826
{TypeProf::Core::Type::Instance=>1822,
 TypeProf::Core::Type::Singleton=>539,
 TypeProf::Core::Type::Array=>615,
 TypeProf::Core::Type::Proc=>1132,
 TypeProf::Core::Type::Symbol=>464,
 TypeProf::Core::Type::Hash=>135,
 TypeProf::Core::Type::Bot=>1,
 TypeProf::Core::Type::Var=>236}
0

Added Known-Issue PR

I believe the following part of core/ast/base.rb is causing typeprof to fail:

until queue.empty?
subnode = queue.shift
next unless subnode

In other words, I think the program fails when it looks like this.

until (cond)
  next
end

Ideally, I would have solved the root cause of the issue, but I was unable to do so 🙏. Therefore, I created a PR marking it as a known issue. I would appreciate it if you could review it. #210 .

Additional Information

This change makes the tests pass, but currently, I am not fully sure what I am doing 😇 😇

--- a/lib/typeprof/core/ast/control.rb
+++ b/lib/typeprof/core/ast/control.rb
@@ -186,7 +186,9 @@ module TypeProf::Core

       def install0(genv)
         @arg.install(genv)
-        @lenv.add_next_box(@changes.add_escape_box(genv, @arg.ret, @lenv.get_var(:"*expected_block_ret")))
+        if @lenv.locals[:"*expected_block_ret"]
+          @lenv.add_next_box(@changes.add_escape_box(genv, @arg.ret, @lenv.get_var(:"*expected_block_ret")))
+        end
         Source.new(Type::Bot.new(genv))
       end
     end

URI require issue

A file with the following causes a crash

require 'uri/generic'
require 'uri'
/Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/analyzer.rb:1252:in `block (2 levels) in get_instance_variable': undefined method `detailed_source_location' for nil:NilClass (NoMethodError)
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/analyzer.rb:1245:in `each'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/analyzer.rb:1245:in `block in get_instance_variable'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/analyzer.rb:851:in `block in add_write!'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/analyzer.rb:850:in `each'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/analyzer.rb:850:in `add_write!'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/analyzer.rb:896:in `block in add_ivar_write!'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/type.rb:90:in `each_child'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/analyzer.rb:892:in `add_ivar_write!'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/import.rb:611:in `block (2 levels) in import'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/import.rb:606:in `each'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/import.rb:606:in `block in import'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/import.rb:577:in `each'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/import.rb:577:in `import'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/import.rb:529:in `import_library'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/builtin.rb:643:in `file_require'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/builtin.rb:684:in `kernel_require'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/method.rb:323:in `[]'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/method.rb:323:in `do_send'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/analyzer.rb:2392:in `block (2 levels) in do_send'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/utils.rb:101:in `each_key'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/utils.rb:101:in `each'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/analyzer.rb:2391:in `block in do_send'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/type.rb:90:in `each_child'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/analyzer.rb:2367:in `do_send'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/analyzer.rb:1512:in `step'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/analyzer.rb:1050:in `type_profile'
        from /Users/peterwagenet/Development/Ruby/typeprof/lib/typeprof/config.rb:123:in `analyze'
        from exe/typeprof:9:in `<main>'

Readme needs update

I found that the ruby-type-profiler is being renamed to typeprof.
It seems that Readme and some files still contain the old names, and I guess you're going to update them including some file names and the repository name soon.

Should we wait for the finish of the updates?

Incorrect signature type with conditional implicit return

While testing TypeProf, I tried different scenarios, and when using a one-line condition, I noticed that if there are 2 opposite one-line conditions, only the last one is taken in TypeProf's analysis.

Implicit return:

def demo(arg)
  {} if arg
  [] unless arg
end

TypeProf analyze def demo: (untyped arg) -> Array[untyped]?

Explicit return:

def demo2(arg)
  return {} if arg
  return [] unless arg
end

TypeProf analyze def demo2: (untyped arg) -> ((Array[untyped] | Hash[untyped, untyped])?)

Here are the scenarios in the playground:
https://mame.github.io/typeprof-playground/#rb=def+demo%28arg%29%0A++%7B%7D+if+arg%0A++%5B%5D+unless+arg%0Aend%0A%0Adef+demo2%28arg%29%0A++return+%7B%7D+if+arg%0A++return+%5B%5D+unless+arg%0Aend%0A%0A%0Adef+demo3%28arg%29%0A++arg+%3F+%7B%7D+%3A+%5B%5D%0Aend%0A%0Adef+demo4%28arg%29%0A++if+arg%0A++++%7B%7D%0A++else%0A++++%5B%5D%0A++end%0Aend&rbs=

Consider excluding the doc directory from the gem

The doc directory is 66% of the total size of this gem and is probably not needed at runtime. can we exclude it as well as smoke and testbed?

$ pwd
/home/ursm/.gem/ruby/3.0.2/gems/typeprof-0.20.3

$ du -h .
4.0K	./.github/workflows
4.0K	./.github
964K	./doc
4.0K	./exe
348K	./lib/typeprof
352K	./lib
8.0K	./tools
4.0K	./vscode/.vscode
4.0K	./vscode/sandbox
12K	./vscode/src
180K	./vscode
1.6M	.

Fail to start TypeProf for IDE on zsh

Here is the log:

[vscode] Try to start TypeProf for IDE
[vscode] stderr: /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems.rb:283:in `find_spec_for_exe': Could not find 'bundler' (2.3.15) required by your /Users/s15236/workspace/typeprof/vscode/src/test/simpleProgram/Gemfile.lock. (Gem::GemNotFoundException)
[vscode] stderr: To update to the latest version installed on your system, run `bundle update --bundler`.
[vscode] stderr: To install the missing version, run `gem install bundler:2.3.15`
[vscode] stderr: 	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems.rb:302:in `activate_bin_path'
[vscode] stderr: 	from /usr/bin/bundle:23:in `<main>'
[vscode] failed to invoke typeprof: error code 1

Tests for version 0.21.8 are failing in ruby 3.2.2 with rbs 2.8.2

When running the tests for this gem I get the following error:

(none):1: warning: possibly useless use of a literal in void context
Loaded suite /usr/lib/ruby/gems/3.2.0/gems/rake-13.0.6/lib/rake/rake_test_loader
Started
....Initialized empty Git repository in /build/ruby-typeprof/src/typeprof-0.21.8/testbed/diff-lcs/.git/
From https://github.com/mame/diff-lcs
 * branch            de838d2df80514adbf22c26daed728ddd06af60b -> FETCH_HEAD
.(none):25: warning: possibly useless use of a constant in void context
path/to/file:25: warning: possibly useless use of a constant in void context
....TypeProf for IDE is started successfully
......................................................................
...............................................................................
............F
===============================================================================
Failure: test: smoke/integer.rb(TypeProf::SmokeTest)
/build/ruby-typeprof/src/typeprof-0.21.8/test/typeprof/smoke_test.rb:36:in `block (2 levels) in <class:SmokeTest>'
     33:           expected = actual
     34:         end
     35:
  => 36:         assert_equal(expected, actual)
     37:       end
     38:     end
     39:   end
<"# Classes\n" +
"class Object\n" +
"  private\n" +
"  def foo: (Integer? x) -> nil\n" +
"end\n"> expected but was
<"# Classes\n" +
"class Object\n" +
"  private\n" +
"  def foo: (Integer x) -> nil\n" +
"end\n">

diff:
  # Classes
  class Object
    private
?   def foo: (Integer? x) -> nil
  end
===============================================================================
...............................................................................
....................................................................
Finished in 43.381750919 seconds.
-------------------------------------------------------------------------------
318 tests, 361 assertions, 1 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
99.6855% passed
-------------------------------------------------------------------------------
7.33 tests/s, 8.32 assertions/s
rake aborted!
Command failed with status (1)

Tasks: TOP => test
(See full trace by running task with --trace)

This seems to be a regression from 30a334e which is designed to make the tests compatible to rbs 3.2.0. This seems to make the tests only support rbs >= 3.2.0, but the gemspec file stills says rbs >= 1.8.1 is required and supported: https://github.com/ruby/typeprof/blob/v0.21.8/typeprof.gemspec#L33

So I guess either the test needs to be updated to somehow support all the rbs versions, or the gem needs to update its requirements for the minimal required version of rbs.

crash on `each_with_index` usage

Is it too early for bug reports?

I tried typeprof on lib/matrix.rb and all the methods that call Array#each_with_index crash it with:

DEBUG: ../dev/lib/matrix.rb:620 (each_with_index) PC=68 insn=send sp=1
["../dev/lib/matrix.rb:620", "[error] undefined method: String#each_with_index"]
["../dev/lib/matrix.rb:620", "[error] undefined method: nil#each_with_index"]
bundler: failed to load command: typeprof (/Users/mal/.rvm/gems/ruby-head/bin/typeprof)
RuntimeError: nil
  /Users/mal/ruby/typeprof/lib/typeprof/type.rb:205:in `block in initialize'

If I comment out these methods, typeprof seems to take many minutes analysing a few (unusual) lines like these.

After ~12 minutes (I have a 2013 MacbookAir 😅 ), it crashes with:

NoMethodError: undefined method `each' for nil:NilClass
  /Users/mal/ruby/typeprof/lib/typeprof/analyzer.rb:1976:in `block (2 levels) in show_block_signature'
  /Users/mal/ruby/typeprof/lib/typeprof/type.rb:94:in `each_child_global'
  /Users/mal/ruby/typeprof/lib/typeprof/analyzer.rb:1966:in `block in show_block_signature'
  /Users/mal/ruby/typeprof/lib/typeprof/analyzer.rb:1965:in `each'
  /Users/mal/ruby/typeprof/lib/typeprof/analyzer.rb:1965:in `show_block_signature'
  /Users/mal/ruby/typeprof/lib/typeprof/type.rb:803:in `screen_name'
  /Users/mal/ruby/typeprof/lib/typeprof/analyzer.rb:2023:in `show_method_signature'
  /Users/mal/ruby/typeprof/lib/typeprof/export.rb:139:in `block (3 levels) in conv_class'
  /Users/mal/ruby/typeprof/lib/typeprof/utils.rb:101:in `each_key'
  /Users/mal/ruby/typeprof/lib/typeprof/utils.rb:101:in `each'
  /Users/mal/ruby/typeprof/lib/typeprof/export.rb:131:in `block (2 levels) in conv_class'
  /Users/mal/ruby/typeprof/lib/typeprof/utils.rb:101:in `each_key'
  /Users/mal/ruby/typeprof/lib/typeprof/utils.rb:101:in `each'
  /Users/mal/ruby/typeprof/lib/typeprof/export.rb:125:in `block in conv_class'
  /Users/mal/ruby/typeprof/lib/typeprof/export.rb:124:in `each'
  /Users/mal/ruby/typeprof/lib/typeprof/export.rb:124:in `conv_class'
  /Users/mal/ruby/typeprof/lib/typeprof/export.rb:241:in `block in build_class_hierarchy'
  /Users/mal/ruby/typeprof/lib/typeprof/export.rb:239:in `each'
  /Users/mal/ruby/typeprof/lib/typeprof/export.rb:239:in `map'
  /Users/mal/ruby/typeprof/lib/typeprof/export.rb:239:in `build_class_hierarchy'
  /Users/mal/ruby/typeprof/lib/typeprof/export.rb:214:in `show'
  /Users/mal/ruby/typeprof/lib/typeprof/analyzer.rb:857:in `report'
  /Users/mal/ruby/typeprof/lib/typeprof/config.rb:90:in `analyze'
  /Users/mal/ruby/typeprof/exe/typeprof:6:in `<top (required)>'
  /Users/mal/.rvm/gems/ruby-head/bin/typeprof:23:in `load'
  /Users/mal/.rvm/gems/ruby-head/bin/typeprof:23:in `<top (required)>'

Facing issues with bundle install

Am facing follwing issue with the bundle install command

image

Can someone help me regarding this ?

I opened this issue here coz I saw a "bundle update " commit 10 hours before opening my issue , hoping for a nice response with a solution from the community

undefined method: singleton

My environment:

  • Ruby 3.1.0
  • Rails 7.0.1
  • Ubuntu 20.04

I created a simple blog application for the demo and I use VSCode.

When I open any file then the typeprof gem show warning and an error message but the app does not error any.

[warning] superclass is any; Object is used insteadTypeProf
[error] undefined method: singleton(PostsController)#before_actionTypeProf

typeprof

Typeprof failed to start when rbs_collection.lock.yaml doesn't exist.

To reproduce this error, you can do such as:

$ tree
.
├── Gemfile
├── Gemfile.lock
├── rbs_collection.yaml
└── target.rb

Here is the log:

[vscode] Try to start TypeProf for IDE
[vscode] typeprof version: typeprof 0.21.4
[vscode] Starting Ruby TypeProf (typeprof 0.21.4)...
[Info  - 11:06:55 PM] TypeProf for IDE is started successfully
[vscode] Ruby TypeProf is running
[Info  - 11:06:55 PM] bundler: failed to load command: typeprof (/Users/s15236/.rbenv/versions/3.1.0/bin/typeprof)
[Info  - 11:06:55 PM] Connection to server got closed. Server will restart.
[Info  - 11:06:55 PM] <internal:ast>:67:in `of': Interrupt
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/3.1.0/error_highlight/core_ext.rb:19:in `to_s'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/3.1.0/did_you_mean/core_ext/name_error.rb:15:in `to_s'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/lib/bundler/vendor/thor/lib/thor/command.rb:114:in `message'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/lib/bundler/vendor/thor/lib/thor/command.rb:114:in `handle_no_method_error?'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/lib/bundler/vendor/thor/lib/thor/command.rb:36:in `rescue in run'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/lib/bundler/vendor/thor/lib/thor/command.rb:20:in `run'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/lib/bundler/cli.rb:31:in `dispatch'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/lib/bundler/cli.rb:25:in `start'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/exe/bundle:48:in `block in <top (required)>'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/lib/bundler/friendly_errors.rb:117:in `with_friendly_errors'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/exe/bundle:36:in `<top (required)>'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/bin/bundle:25:in `load'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/bin/bundle:25:in `<main>'
[Info  - 11:06:55 PM] /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/typeprof-0.21.4/lib/typeprof/import.rb:10:in `initialize': undefined method `repo_path' for nil:NilClass (NoMethodError)
[Info  - 11:06:55 PM] 
[Info  - 11:06:55 PM]         @repo.add(collection_lock.repo_path)
[Info  - 11:06:55 PM]                                  ^^^^^^^^^^
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/typeprof-0.21.4/lib/typeprof/analyzer.rb:306:in `new'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/typeprof-0.21.4/lib/typeprof/analyzer.rb:306:in `initialize'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/typeprof-0.21.4/lib/typeprof/config.rb:89:in `new'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/typeprof-0.21.4/lib/typeprof/config.rb:89:in `analyze'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/typeprof-0.21.4/lib/typeprof/lsp.rb:289:in `analyze'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/typeprof-0.21.4/lib/typeprof/lsp.rb:89:in `initialize'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/typeprof-0.21.4/lib/typeprof/lsp.rb:567:in `new'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/typeprof-0.21.4/lib/typeprof/lsp.rb:567:in `run'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/typeprof-0.21.4/lib/typeprof/lsp.rb:857:in `block in run'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/typeprof-0.21.4/lib/typeprof/lsp.rb:792:in `read'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/typeprof-0.21.4/lib/typeprof/lsp.rb:852:in `run'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/typeprof-0.21.4/lib/typeprof/lsp.rb:32:in `block (2 levels) in start_lsp_server'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/3.1.0/socket.rb:810:in `block (2 levels) in accept_loop'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/3.1.0/socket.rb:807:in `each'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/3.1.0/socket.rb:807:in `block in accept_loop'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/3.1.0/socket.rb:805:in `loop'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/3.1.0/socket.rb:805:in `accept_loop'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/typeprof-0.21.4/lib/typeprof/lsp.rb:27:in `block in start_lsp_server'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/3.1.0/socket.rb:782:in `tcp_server_sockets'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/typeprof-0.21.4/lib/typeprof/lsp.rb:16:in `start_lsp_server'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/typeprof-0.21.4/exe/typeprof:7:in `<top (required)>'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/bin/typeprof:25:in `load'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/bin/typeprof:25:in `<top (required)>'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/lib/bundler/cli/exec.rb:58:in `load'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/lib/bundler/cli/exec.rb:58:in `kernel_load'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/lib/bundler/cli/exec.rb:23:in `run'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/lib/bundler/cli.rb:483:in `exec'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/lib/bundler/cli.rb:31:in `dispatch'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/lib/bundler/cli.rb:25:in `start'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/exe/bundle:48:in `block in <top (required)>'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/lib/bundler/friendly_errors.rb:117:in `with_friendly_errors'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/bundler-2.3.15/exe/bundle:36:in `<top (required)>'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/bin/bundle:25:in `load'
[Info  - 11:06:55 PM] 	from /Users/s15236/.rbenv/versions/3.1.0/bin/bundle:25:in `<main>'

Handle type arguments appropriately

Currently, TypeProf completely ignores Array[X] of class Bar[X] < Foo[Array[X]].

class Foo[X]
  def test_superclass: -> X
end

module M[X]
  def test_module: -> X
end

class Bar[X] < Foo[Array[X]]
  def initialize: (X) -> void
  include M[Integer]
end
obj = Bar.new("str")
p obj                 #=> Foo[String]
p obj.test_superclass #=> expected: Array[String], actual: String
p obj.test_module     #=> expected: Integer, actual: String

More practical example:

p({ a: 1 }.find { true }) #=> nil | untyped

because:

  • A class Hash includes Enumerable[[K, V], Hash[K, V]].
  • Enumerable#find returns Elem?. In this case, Elem == [K, V]
  • However, TypeProf don't know that Elem == [K, V], so it replaces Elem with untyped

Generated class order should reflect source

For some reason, typeprof on lib/matrix generates rbs for Matrix, then Vector, but if I provide a hint file below, then the order is reversed, Vector first then Matrix:

type numeric = Integer | Float | Rational | Complex

class Matrix
  @rows : Array[Array[numeric]]
end

class Vector
  @elements : Array[numeric]
end

Auto-commenting of methods doesn't handle multiple lines

Example:

class AppResource
# def assign: (untyped apps, untyped collaborators) -> untyped
            | (untyped apps, untyped collaborators) -> untyped
            | (untyped apps, untyped invitations) -> untyped
end

The comment needs to be extended onto the wrapped lines

Instance variables in subclasses sometimes are defined incorrectly

In my specific case, it is overwriting the parent type with something overly specific:

class Base
  @warnings_suppressed: bool
end

class Subclass < Base
  @warnings_suppressed: bot
end

Rough code:

class Base
  def initialize
    @warnings_suppressed = false
  end

  def suppress_warnings!
    tap { @warnings_suppressed = true }
  end

  def warn(message, event = nil)
    return if @warnings_suppressed
    puts message
  end
end

class Subclass < Base
  def do_stuff
    warn("Something went wrong")
  end
end

Special handling for Array#min, max, etc.

as = [1, 2, 3]
as.min.to_s(2) #=> [error] failed to resolve overload: nil#to_s

Array[Elem]#min returns Elem | nil in RBS definition. It is correct but it would be useful to return Elem when the receiver is a non-empty tuple.

Special handling for Array#zip

It is useful to keep the elements of Array#zip as tuples. RBS of Array#zip has less information for the behavior, so it would be good to implement it as a built-in method.

as = [1, 2, 3]
bs = %w(a b c)

p as.zip(bs)
#=> expected: Array[[Integer, String]] (or [Integer, String?])
#   actual:   Array[Array[(Integer | String)?]]

as.zip(bs) do |a, b|
  p a #=> expected: Integer
      #   actual: (Integer | String)?
  p b #=> expected: String (or String?)
      #   actual: (Integer | String)?
end

cs = [1.0, 2.0, 3.0]

as.zip(bs, cs) do |a, b, c|
  p a #=> expected: Integer
      #   actual: untyped
  p b #=> expected: String (or String?)
      #   actual: untyped
  p c #=> expected: Float (or Float?)
      #   actual: untyped
end

More useful regexp variables

"foo 123 bar".gsub(/\w+/) do
    $&.upcase #=> [error] undefined method: nil#upcase
end

It would be great if $&, $1, etc. respects the context.

BTW, Steep seems to handle such variables as always Strings. It is not correct but maybe more useful.

Many smoke files/tests are included in the 0.12.0 gem

I don't think these files are necessary or useful to ship in Ruby implementations, so it seems best to not include them in the .gem.

$ tree /home/eregon/.rubies/ruby-3.0.2/lib/ruby/gems/3.0.0/gems/typeprof-0.12.0 
/home/eregon/.rubies/ruby-3.0.2/lib/ruby/gems/3.0.0/gems/typeprof-0.12.0
├── doc
│   ├── demo.md
│   ├── doc.ja.md
│   ├── doc.md
│   ├── ppl2019.pdf
│   └── todo.md
├── exe
│   └── typeprof
├── Gemfile
├── Gemfile.lock
├── lib
│   ├── typeprof
│   │   ├── analyzer.rb
│   │   ├── arguments.rb
│   │   ├── block.rb
│   │   ├── builtin.rb
│   │   ├── cli.rb
│   │   ├── config.rb
│   │   ├── container-type.rb
│   │   ├── export.rb
│   │   ├── import.rb
│   │   ├── insns-def.rb
│   │   ├── iseq.rb
│   │   ├── method.rb
│   │   ├── type.rb
│   │   ├── utils.rb
│   │   └── version.rb
│   └── typeprof.rb
├── LICENSE
├── Rakefile
├── README.md
├── smoke
│   ├── alias2.rb
│   ├── alias.rb
│   ├── any1.rb
│   ├── any2.rb
│   ├── any-cbase.rb
│   ├── arguments2.rb
│   ├── arguments.rb
│   ├── array10.rb
│   ├── array11.rb
│   ├── array12.rb
│   ├── array13.rb
│   ├── array14.rb
│   ├── array15.rb
│   ├── array1.rb
│   ├── array2.rb
│   ├── array3.rb
│   ├── array4.rb
│   ├── array5.rb
│   ├── array6.rb
│   ├── array7.rb
│   ├── array8.rb
│   ├── array9.rb
│   ├── array-each2.rb
│   ├── array-each3.rb
│   ├── array-each.rb
│   ├── array-ltlt2.rb
│   ├── array-ltlt.rb
│   ├── array-map2.rb
│   ├── array-map3.rb
│   ├── array-map.rb
│   ├── array-mul.rb
│   ├── array-plus1.rb
│   ├── array-plus2.rb
│   ├── array-pop.rb
│   ├── array-range-aref.rb
│   ├── array-replace.rb
│   ├── array-s-aref.rb
│   ├── attr-module.rb
│   ├── attr.rb
│   ├── attr-vis.rb
│   ├── attr-vis.rbs
│   ├── autoload.rb
│   ├── backtrace.rb
│   ├── block10.rb
│   ├── block11.rb
│   ├── block12.rb
│   ├── block13.rb
│   ├── block13.rbs
│   ├── block14.rb
│   ├── block1.rb
│   ├── block2.rb
│   ├── block3.rb
│   ├── block4.rb
│   ├── block5.rb
│   ├── block6.rb
│   ├── block7.rb
│   ├── block8.rb
│   ├── block9.rb
│   ├── block-ambiguous.rb
│   ├── block-args1.rb
│   ├── block-args1-rest.rb
│   ├── block-args2.rb
│   ├── block-args2-rest.rb
│   ├── block-args3.rb
│   ├── block-args3-rest.rb
│   ├── block-blockarg.rb
│   ├── block_given.rb
│   ├── block-kwarg.rb
│   ├── blown.rb
│   ├── break1.rb
│   ├── break2.rb
│   ├── break3.rb
│   ├── case2.rb
│   ├── case3.rb
│   ├── case.rb
│   ├── class-hierarchy2.rb
│   ├── class-hierarchy.rb
│   ├── class_instance_var.rb
│   ├── class_method2.rb
│   ├── class_method3.rb
│   ├── class_method.rb
│   ├── class-new.rb
│   ├── class.rb
│   ├── constant1.rb
│   ├── constant2.rb
│   ├── constant3.rb
│   ├── constant4.rb
│   ├── context-sensitive1.rb
│   ├── cvar2.rb
│   ├── cvar.rb
│   ├── define_method2.rb
│   ├── define_method3.rb
│   ├── define_method3.rbs
│   ├── define_method4.rb
│   ├── define_method4.rbs
│   ├── define_method5.rb
│   ├── define_method6.rb
│   ├── define_method.rb
│   ├── demo10.rb
│   ├── demo11.rb
│   ├── demo1.rb
│   ├── demo2.rb
│   ├── demo3.rb
│   ├── demo4.rb
│   ├── demo5.rb
│   ├── demo6.rb
│   ├── demo7.rb
│   ├── demo8.rb
│   ├── demo9.rb
│   ├── demo.rb
│   ├── dummy_element.rb
│   ├── dummy-execution1.rb
│   ├── dummy-execution2.rb
│   ├── ensure1.rb
│   ├── enumerator.rb
│   ├── enum_for2.rb
│   ├── enum_for.rb
│   ├── expandarray1.rb
│   ├── expandarray2.rb
│   ├── fib.rb
│   ├── flip-flop.rb
│   ├── flow10.rb
│   ├── flow1.rb
│   ├── flow2.rb
│   ├── flow3.rb
│   ├── flow4.rb
│   ├── flow5.rb
│   ├── flow6.rb
│   ├── flow7.rb
│   ├── flow8.rb
│   ├── flow9.rb
│   ├── for.rb
│   ├── freeze.rb
│   ├── function.rb
│   ├── gvar2.rb
│   ├── gvar2.rbs
│   ├── gvar.rb
│   ├── hash1.rb
│   ├── hash2.rb
│   ├── hash3.rb
│   ├── hash4.rb
│   ├── hash5.rb
│   ├── hash-bot.rb
│   ├── hash-fetch.rb
│   ├── hash-merge-bang.rb
│   ├── inheritance2.rb
│   ├── inheritance.rb
│   ├── initialize.rb
│   ├── instance_eval2.rb
│   ├── instance_eval3.rb
│   ├── instance_eval.rb
│   ├── integer.rb
│   ├── int_times.rb
│   ├── ivar2.rb
│   ├── ivar3.rb
│   ├── ivar3.rbs
│   ├── ivar4.rb
│   ├── ivar.rb
│   ├── kernel-class.rb
│   ├── keyword1.rb
│   ├── keyword2.rb
│   ├── keyword3.rb
│   ├── keyword4.rb
│   ├── keyword5.rb
│   ├── kwrest.rb
│   ├── kwrest.rbs
│   ├── kwsplat1.rb
│   ├── kwsplat2.rb
│   ├── lit-complex.rb
│   ├── lit-encoding.rb
│   ├── manual-rbs2.rb
│   ├── manual-rbs2.rbs
│   ├── manual-rbs3.rb
│   ├── manual-rbs3.rbs
│   ├── manual-rbs.rb
│   ├── manual-rbs.rbs
│   ├── masgn1.rb
│   ├── masgn2.rb
│   ├── masgn3.rb
│   ├── method_in_branch.rb
│   ├── method_missing.rb
│   ├── module1.rb
│   ├── module2.rb
│   ├── module3.rb
│   ├── module4.rb
│   ├── module5.rb
│   ├── module6.rb
│   ├── module_function1.rb
│   ├── module_function2.rb
│   ├── multiple-include.rb
│   ├── multiple-superclass.rb
│   ├── next1.rb
│   ├── next2.rb
│   ├── object-send1.rb
│   ├── object-send2.rb
│   ├── object-send3.rb
│   ├── once.rb
│   ├── optional1.rb
│   ├── optional2.rb
│   ├── optional3.rb
│   ├── parameterizedd-self2.rb
│   ├── parameterizedd-self.rb
│   ├── pathname1.rb
│   ├── pathname2.rb
│   ├── pattern-match1.rb
│   ├── pattern-match2.rb
│   ├── prepend1.rb
│   ├── prepend2.rb
│   ├── prepend2.rbs
│   ├── primitive_method.rb
│   ├── printf.rb
│   ├── proc2.rb
│   ├── proc3.rb
│   ├── proc4.rb
│   ├── proc5.rb
│   ├── proc.rb
│   ├── public.rb
│   ├── range.rb
│   ├── rbs-alias.rb
│   ├── rbs-alias.rbs
│   ├── rbs-attr2.rb
│   ├── rbs-attr2.rbs
│   ├── rbs-attr.rb
│   ├── rbs-attr.rbs
│   ├── rbs-extend.rb
│   ├── rbs-extend.rbs
│   ├── rbs-interface.rb
│   ├── rbs-interface.rbs
│   ├── rbs-module.rb
│   ├── rbs-module.rbs
│   ├── rbs-opt-and-rest.rb
│   ├── rbs-opt-and-rest.rbs
│   ├── rbs-proc1.rb
│   ├── rbs-proc1.rbs
│   ├── rbs-proc2.rb
│   ├── rbs-proc2.rbs
│   ├── rbs-proc3.rb
│   ├── rbs-proc3.rbs
│   ├── rbs-record.rb
│   ├── rbs-record.rbs
│   ├── rbs-tyvar2.rb
│   ├── rbs-tyvar2.rbs
│   ├── rbs-tyvar3.rb
│   ├── rbs-tyvar3.rbs
│   ├── rbs-tyvar4.rb
│   ├── rbs-tyvar5.rb
│   ├── rbs-tyvar5.rbs
│   ├── rbs-tyvar6.rb
│   ├── rbs-tyvar6.rbs
│   ├── rbs-tyvar7.rb
│   ├── rbs-tyvar7.rbs
│   ├── rbs-tyvar.rb
│   ├── rbs-tyvar.rbs
│   ├── rbs-vars.rb
│   ├── rbs-vars.rbs
│   ├── redo1.rb
│   ├── redo2.rb
│   ├── req-keyword.rb
│   ├── rescue1.rb
│   ├── rescue2.rb
│   ├── rescue3.rb
│   ├── rescue4.rb
│   ├── respond_to.rb
│   ├── rest1.rb
│   ├── rest2.rb
│   ├── rest3.rb
│   ├── rest4.rb
│   ├── rest5.rb
│   ├── rest6.rb
│   ├── rest-farg.rb
│   ├── retry1.rb
│   ├── return.rb
│   ├── reveal.rb
│   ├── simple.rb
│   ├── singleton_class.rb
│   ├── singleton_method.rb
│   ├── step.rb
│   ├── string-split.rb
│   ├── struct2.rb
│   ├── struct3.rb
│   ├── struct4.rb
│   ├── struct5.rb
│   ├── struct6.rb
│   ├── struct7.rb
│   ├── struct-keyword_init.rb
│   ├── struct.rb
│   ├── stub-keyword.rb
│   ├── super1.rb
│   ├── super2.rb
│   ├── super3.rb
│   ├── super4.rb
│   ├── super5.rb
│   ├── svar1.rb
│   ├── symbol-proc-attr2.rb
│   ├── symbol-proc-attr.rb
│   ├── symbol-proc-bot.rb
│   ├── symbol-proc.rb
│   ├── tap1.rb
│   ├── toplevel.rb
│   ├── two-map.rb
│   ├── typed_method.rb
│   ├── type_var.rb
│   ├── uninitialize-var.rb
│   ├── union-recv.rb
│   ├── user-demo.rb
│   ├── wrong-extend.rb
│   ├── wrong-include2.rb
│   ├── wrong-include.rb
│   ├── wrong-rbs.rb
│   └── wrong-rbs.rbs
├── testbed
│   ├── ao.rb
│   ├── diff-lcs-entrypoint.rb
│   └── goodcheck-Gemfile.lock
└── tools
    ├── coverage.rb
    └── setup-insns-def.rb

7 directories, 342 files

vscode error: typeprof running on wrong ruby

Hi, I have a local setup using chruby (shouldn't be much different from other setups). I usually switch to the right ruby then open the project on VSCode via code ., in order to make sure that the extensions use the right ruby and deps versions. This works well for the steep plugin. However, the typeprof plugin picks up the wrong ruby, i.e. the system ruby. So, I switch to ruby 3, but I get the following error output from within vscode:

[vscode] Try to start TypeProf for IDE
[vscode] stderr: /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems.rb:283:in `find_spec_for_exe': Could not find 'bundler' (2.2.15) required by your /Users/tiago.cardoso/dev/jwt-token-kms/Gemfile.lock. (Gem::GemNotFoundException)
[vscode] stderr: To update to the latest version installed on your system, run `bundle update --bundler`.
[vscode] stderr: To install the missing version, run `gem install bundler:2.2.15`
[vscode] stderr: 	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems.rb:302:in `activate_bin_path'
[vscode] stderr: 	from /usr/bin/bundle:23:in `<main>'
[vscode] failed to invoke typeprof: error code 1
# that's the location from system ruby, not ruby 3

I suspect I'm entering this path, where the extensions recognizes the existence of a Gemfile, and runs typeprof via bundler, but picks up the wrong bundler. And this might be so because typeprof's not picking up the ruby defined by the VSCode ruby plugin, which I set to ruby (should have been ruby 3). steep does this a bit differently, but can't figure out what's the correct way to patch typeprof's command.

Error

Please feel free to rename this issue to something more appropriate.

The following code causes an error when run through typeprof.

[].each_with_object({}) do |(key, value), acc|
  acc[key] =
    case value
    when Array
      :array
    else
      :other
    end
end
/Users/peterwagenet/.rvm/gems/ruby-3.0.1/gems/typeprof-0.20.4/lib/typeprof/iseq.rb:824:in `check_send_branch': Unknown insn: #<struct TypeProf::ISeq::Insn insn=:getlocal_checkmatch_branch, operands=[[3, 0], [:if, 19]], lineno=nil, code_range=nil, definitions=nil> (RuntimeError)
        from /Users/peterwagenet/.rvm/gems/ruby-3.0.1/gems/typeprof-0.20.4/lib/typeprof/iseq.rb:573:in `block in unify_instructions'
        from /Users/peterwagenet/.rvm/gems/ruby-3.0.1/gems/typeprof-0.20.4/lib/typeprof/iseq.rb:567:in `times'
        from /Users/peterwagenet/.rvm/gems/ruby-3.0.1/gems/typeprof-0.20.4/lib/typeprof/iseq.rb:567:in `unify_instructions'
        from /Users/peterwagenet/.rvm/gems/ruby-3.0.1/gems/typeprof-0.20.4/lib/typeprof/iseq.rb:57:in `block in compile_core'
        from /Users/peterwagenet/.rvm/gems/ruby-3.0.1/gems/typeprof-0.20.4/lib/typeprof/iseq.rb:56:in `each'
        from /Users/peterwagenet/.rvm/gems/ruby-3.0.1/gems/typeprof-0.20.4/lib/typeprof/iseq.rb:56:in `compile_core'
        from /Users/peterwagenet/.rvm/gems/ruby-3.0.1/gems/typeprof-0.20.4/lib/typeprof/iseq.rb:19:in `compile'
        from /Users/peterwagenet/.rvm/gems/ruby-3.0.1/gems/typeprof-0.20.4/lib/typeprof/analyzer.rb:1020:in `type_profile'
        from /Users/peterwagenet/.rvm/gems/ruby-3.0.1/gems/typeprof-0.20.4/lib/typeprof/config.rb:123:in `analyze'
        from /Users/peterwagenet/.rvm/gems/ruby-3.0.1/gems/typeprof-0.20.4/exe/typeprof:9:in `<top (required)>'
        from /Users/peterwagenet/.rvm/gems/ruby-3.0.1/bin/typeprof:23:in `load'
        from /Users/peterwagenet/.rvm/gems/ruby-3.0.1/bin/typeprof:23:in `<main>'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.