diff --git a/.gitignore b/.gitignore index 6f644e008..e8a01607c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -/coverage/ +/tmp/ dog_bench.stackprof.dump dog_bench.pf2profile dog_bench.json \ No newline at end of file diff --git a/bin/typeprof b/bin/typeprof index c1d62d283..3bb7fd59d 100755 --- a/bin/typeprof +++ b/bin/typeprof @@ -2,26 +2,4 @@ require_relative "../lib/typeprof" -case ARGV[0] -when "--version" - puts "typeprof 0.30.0" -when "--lsp" - mode = ARGV[1]&.to_sym || :socket - - core = TypeProf::Core::Service.new - begin - case mode - when :socket - TypeProf::LSP::Server.start_socket(core) - when :stdio - TypeProf::LSP::Server.start_stdio(core) - else - puts "lsp mode '#{mode}' is not supported. expected mode: socket, stdio" - end - rescue Exception - puts $!.detailed_message(highlight: false) - raise - end -else - p ARGV -end +TypeProf::CLI::CLI.new(ARGV).run diff --git a/lib/typeprof.rb b/lib/typeprof.rb index 90cf120fd..e27ca1215 100644 --- a/lib/typeprof.rb +++ b/lib/typeprof.rb @@ -3,3 +3,4 @@ require_relative "typeprof/diagnostic" require_relative "typeprof/core" require_relative "typeprof/lsp" +require_relative "typeprof/cli" diff --git a/lib/typeprof/cli.rb b/lib/typeprof/cli.rb new file mode 100644 index 000000000..e4c270876 --- /dev/null +++ b/lib/typeprof/cli.rb @@ -0,0 +1,4 @@ +require "optparse" +require "pathname" + +require_relative "cli/cli" diff --git a/lib/typeprof/cli/cli.rb b/lib/typeprof/cli/cli.rb new file mode 100644 index 000000000..d7813149e --- /dev/null +++ b/lib/typeprof/cli/cli.rb @@ -0,0 +1,180 @@ +require "io/console" + +module TypeProf::CLI + class CLI + def initialize(argv) + opt = OptionParser.new + + opt.banner = "Usage: #{ opt.program_name } [options] files_or_dirs..." + + core_options = {} + lsp_options = {} + cli_options = {} + + output = nil + rbs_collection_path = nil + + opt.separator "" + opt.separator "Options:" + opt.on("-o OUTFILE", "Output to OUTFILE instead of stdout") {|v| output = v } + opt.on("-q", "--quiet", "Quiet mode") do + core_options[:display_indicator] = false + end + opt.on("-v", "--verbose", "Verbose mode") do + core_options[:show_errors] = true + end + opt.on("--version", "Display typeprof version") { cli_options[:display_version] = true } + opt.on("--collection PATH", "File path of collection configuration") { |v| rbs_collection_path = v } + opt.on("--no-collection", "Ignore collection configuration") { rbs_collection_path = :no } + opt.on("--lsp", "LSP server mode") do |v| + core_options[:display_indicator] = false + cli_options[:lsp] = true + end + + opt.separator "" + opt.separator "Analysis output options:" + opt.on("--[no-]show-typeprof-version", "Display TypeProf version in a header") {|v| core_options[:output_typeprof_version] = v } + opt.on("--[no-]show-errors", "Display possible errors found during the analysis") {|v| core_options[:output_diagnostics] = v } + opt.on("--[no-]show-parameter-names", "Display parameter names for methods") {|v| core_options[:output_parameter_names] = v } + opt.on("--[no-]show-source-locations", "Display definition source locations for methods") {|v| core_options[:output_source_locations] = v } + + opt.separator "" + opt.separator "Advanced options:" + opt.on("--[no-]stackprof MODE", /\Acpu|wall|object\z/, "Enable stackprof (for debugging purpose)") {|v| cli_options[:stackprof] = v.to_sym } + + opt.separator "" + opt.separator "LSP options:" + opt.on("--port PORT", Integer, "Specify a port number to listen for requests on") {|v| lsp_options[:port] = v } + opt.on("--stdio", "Use stdio for LSP transport") {|v| lsp_options[:stdio] = v } + + opt.parse!(argv) + + if cli_options[:lsp] && !lsp_options.empty? + raise OptionParser::InvalidOption.new("lsp options with non-lsp mode") + end + + @core_options = { + rbs_collection: setup_rbs_collection(rbs_collection_path), + display_indicator: $stderr.tty?, + output_typeprof_version: true, + output_errors: false, + output_parameter_names: false, + output_source_locations: false, + }.merge(core_options) + + @lsp_options = { + port: 0, + stdio: false, + }.merge(lsp_options) + + @cli_options = { + argv:, + output: output ? open(output, "w") : $stdout.dup, + display_version: false, + stackprof: nil, + lsp: false, + }.merge(cli_options) + + rescue OptionParser::InvalidOption, OptionParser::MissingArgument + puts $! + exit 1 + end + + def setup_rbs_collection(path) + return nil if path == :no + + unless path + path = RBS::Collection::Config::PATH.exist? ? RBS::Collection::Config::PATH.to_s : nil + return nil unless path + end + + if !File.readable?(path) + raise OptionParser::InvalidOption.new("file not found: #{ path }") + end + + lock_path = RBS::Collection::Config.to_lockfile_path(Pathname(path)) + if !File.readable?(lock_path) + raise OptionParser::InvalidOption.new("file not found: #{ lock_path.to_s }; please run 'rbs collection install") + end + + RBS::Collection::Config::Lockfile.from_lockfile(lockfile_path: lock_path, data: YAML.load_file(lock_path)) + end + + attr_reader :core_options, :lsp_options, :cli_options + + def run + core = TypeProf::Core::Service.new(@core_options) + + if @cli_options[:lsp] + run_lsp(core) + else + run_cli(core) + end + end + + def run_lsp(core) + if @lsp_options[:stdio] + TypeProf::LSP::Server.start_stdio(core) + else + TypeProf::LSP::Server.start_socket(core) + end + rescue Exception + puts $!.detailed_message(highlight: false).gsub(/^/, "---") + raise + end + + def run_cli(core) + puts "typeprof #{ TypeProf::VERSION }" if @cli_options[:display_version] + + files = find_files + + set_profiler do + output = @cli_options[:output] + + core.batch(files, @cli_options[:output]) + + output.close + end + + rescue OptionParser::InvalidOption, OptionParser::MissingArgument + puts $! + exit 1 + end + + def find_files + files = [] + @cli_options[:argv].each do |path| + if File.directory?(path) + files.concat(Dir.glob("#{ path }/**/*.{rb,rbs}")) + elsif File.file?(path) + files << path + else + raise OptionParser::InvalidOption.new("no such file or directory -- #{ path }") + end + end + + if files.empty? + exit if @cli_options[:display_version] + raise OptionParser::InvalidOption.new("no input files") + end + + files + end + + def set_profiler + if @cli_options[:stackprof] + require "stackprof" + out = "typeprof-stackprof-#{ @cli_options[:stackprof] }.dump" + StackProf.start(mode: @cli_options[:stackprof], out: out, raw: true) + end + + yield + + ensure + if @cli_options[:stackprof] && defined?(StackProf) + StackProf.stop + StackProf.results + end + end + end +end diff --git a/lib/typeprof/core/graph/box.rb b/lib/typeprof/core/graph/box.rb index 6d5097e87..9ac975bcb 100644 --- a/lib/typeprof/core/graph/box.rb +++ b/lib/typeprof/core/graph/box.rb @@ -554,7 +554,7 @@ def call(changes, genv, a_args, ret) end end - def show + def show(output_parameter_names) block_show = [] if @record_block.used blk_f_args = @record_block.f_args.map {|arg| arg.show }.join(", ") @@ -585,6 +585,21 @@ def show if @f_args.rest_keywords args << "**#{ Type.strip_parens(@f_args.rest_keywords.show) }" end + + if output_parameter_names && @node.is_a?(AST::DefNode) + names = [] + names.concat(@node.req_positionals) + names.concat(@node.opt_positionals) + names.concat(@node.rest_positionals) if @node.rest_positionals + names.concat(@node.post_positionals) + names.concat(@node.req_keywords) + names.concat(@node.opt_keywords) + names.concat(@node.rest_keywords) if @node.rest_keywords + args = args.zip(names).map do |arg, name| + name ? "#{ arg } #{ name }" : arg + end + end + args = args.join(", ") s = args.empty? ? [] : ["(#{ args })"] s << "#{ block_show.sort.join(" | ") }" unless block_show.empty? diff --git a/lib/typeprof/core/service.rb b/lib/typeprof/core/service.rb index be13606d2..6e6b559aa 100644 --- a/lib/typeprof/core/service.rb +++ b/lib/typeprof/core/service.rb @@ -1,19 +1,28 @@ module TypeProf::Core class Service - def initialize - unless defined?($rbs_env) - loader = RBS::EnvironmentLoader.new - $rbs_env = RBS::Environment.from_loader(loader) - end + def initialize(options) + @options = options @text_nodes = {} @genv = GlobalEnv.new - @genv.load_core_rbs($rbs_env.declarations) + @genv.load_core_rbs(load_rbs_declarations(@options[:rbs_collection]).declarations) Builtin.new(genv).deploy end + def load_rbs_declarations(rbs_collection) + if rbs_collection + loader = RBS::EnvironmentLoader.new + loader.add_collection(rbs_collection) + RBS::Environment.from_loader(loader) + else + return $raw_rbs_env if defined?($raw_rbs_env) + loader = RBS::EnvironmentLoader.new + $raw_rbs_env = RBS::Environment.from_loader(loader) + end + end + attr_reader :genv def reset! @@ -50,7 +59,7 @@ def update_rb_file(path, code) code = File.read(path) unless code node = AST.parse_rb(path, code) - return unless node + return false unless node node.diff(@text_nodes[path]) if prev_node @text_nodes[path] = node @@ -101,6 +110,8 @@ def update_rb_file(path, code) end end end + + return true end def update_rbs_file(path, code) @@ -109,8 +120,8 @@ def update_rbs_file(path, code) code = File.read(path) unless code begin decls = AST.parse_rbs(path, code) - rescue SyntaxError - return + rescue RBS::ParsingError + return false end # TODO: diff @@ -123,6 +134,8 @@ def update_rbs_file(path, code) decls.each {|decl| decl.install(@genv) } prev_decls.each {|decl| decl.uninstall(@genv) } if prev_decls @genv.run_all + + true end def diagnostics(path, &blk) @@ -305,7 +318,7 @@ def hover(path, pos) end if !me.defs.empty? me.defs.each do |mdef| - return "#{ orig_ty.show }##{ mid } : #{ mdef.show }" + return "#{ orig_ty.show }##{ mid } : #{ mdef.show(@options[:output_parameter_names]) }" end end end @@ -332,7 +345,7 @@ def code_lens(path) if event == :enter next if node.is_a?(AST::DefNode) && node.rbs_method_type node.boxes(:mdef) do |mdef| - hint = mdef.show + hint = mdef.show(@options[:output_parameter_names]) if hint yield mdef.node.code_range, hint end @@ -357,7 +370,7 @@ def completion(path, trigger, pos) end unless sig me.defs.each do |mdef| - sig = mdef.show + sig = mdef.show(@options[:output_parameter_names]) break end end @@ -379,6 +392,10 @@ def dump_declarations(path) if node.static_cpath if event == :enter out << " " * stack.size + "module #{ node.static_cpath.join("::") }" + if stack == [:toplevel] + out << "end" + stack.pop + end stack.push(node) else stack.pop @@ -398,6 +415,10 @@ def dump_declarations(path) elsif superclass.cpath != [] s << " < #{ superclass.show_cpath }" end + if stack == [:toplevel] + out << "end" + stack.pop + end out << " " * stack.size + s stack.push(node) mod.included_modules.each do |inc_def, inc_mod| @@ -419,19 +440,24 @@ def dump_declarations(path) else if event == :enter node.boxes(:mdef) do |mdef| - out << " " * stack.size + "def #{ mdef.singleton ? "self." : "" }#{ mdef.mid }: " + mdef.show + if stack.empty? + out << " " * stack.size + "class Object" + stack << :toplevel + end + if @options[:output_source_locations] + pos = mdef.node.code_range.first + out << " " * stack.size + "# #{ path }:#{ pos.lineno }:#{ pos.column + 1 }" + end + out << " " * stack.size + "def #{ mdef.singleton ? "self." : "" }#{ mdef.mid }: " + mdef.show(@options[:output_parameter_names]) end end end end - out = out.map {|s| s + "\n" }.chunk {|s| s.start_with?("def ") }.flat_map do |toplevel, lines| - if toplevel - ["class Object\n"] + lines.map {|line| " " + line } + ["end\n"] - else - lines - end + if stack == [:toplevel] + out << "end" + stack.pop end - out.join + out.join("\n") + "\n" end def get_method_sig(cpath, singleton, mid) @@ -441,11 +467,56 @@ def get_method_sig(cpath, singleton, mid) end s end + + def batch(files, output) + if @options[:output_typeprof_version] + output.puts "# TypeProf #{ TypeProf::VERSION }" + output.puts + end + + i = 0 + show_files = files.select do |file| + if @options[:display_indicator] + $stderr << "\r[%d/%d] %s\e[K" % [i, files.size, file] + i += 1 + end + + if File.extname(file) == ".rbs" + res = update_rbs_file(file, File.read(file)) + else + res = update_rb_file(file, File.read(file)) + end + + if res + true + else + output.puts "# failed to analyze: #{ file }" + false + end + end + if @options[:display_indicator] + $stderr << "\r\e[K" + end + + first = true + show_files.each do |file| + next if File.extname(file) == ".rbs" + output.puts unless first + first = false + output.puts "# #{ file }" + if @options[:output_diagnostics] + diagnostics(file) do |diag| + output.puts "# #{ diag.code_range.to_s }:#{ diag.msg }" + end + end + output.puts dump_declarations(file) + end + end end end if $0 == __FILE__ - core = TypeProf::Core::Service.new + core = TypeProf::Core::Service.new({}) core.add_workspaces(["foo"].to_a) core.update_rb_file("foo", "foo") end diff --git a/lib/typeprof/core/type.rb b/lib/typeprof/core/type.rb index f260d4887..9c5799043 100644 --- a/lib/typeprof/core/type.rb +++ b/lib/typeprof/core/type.rb @@ -124,7 +124,7 @@ def check_match_included_modules(genv, changes, ty, other_ty) if inc_ty.mod == other_ty.mod args_all_match = true inc_ty.args.zip(other_ty.args) do |arg, other_arg| - unless arg.check_match(genv, changes, other_arg) + if other_arg && !arg.check_match(genv, changes, other_arg) args_all_match = false break end diff --git a/scenario/known-issues/optional-type-param.rb b/scenario/known-issues/optional-type-param.rb new file mode 100644 index 000000000..a2c825e76 --- /dev/null +++ b/scenario/known-issues/optional-type-param.rb @@ -0,0 +1,14 @@ +## update: test.rbs +interface _Foo[X, Y = Integer] + def initialize: (X) -> void +end + +class Object + def get_foo_str: -> _Foo[String] + def accept_foo_str: (_Foo[String]) -> void +end + +## update: test.rb +accept_foo_str(get_foo_st) + +## assert diff --git a/test/cli_test.rb b/test/cli_test.rb new file mode 100644 index 000000000..c61b2df28 --- /dev/null +++ b/test/cli_test.rb @@ -0,0 +1,107 @@ +require_relative "helper" +require "stringio" + +module TypeProf + class CLITest < Test::Unit::TestCase + def test_run(fixture_path, argv) + output = StringIO.new(+"") + Dir.chdir(File.join(__dir__, "fixtures", fixture_path)) do + yield if block_given? + cli = TypeProf::CLI::CLI.new(argv) + cli.cli_options[:output] = output + cli.run + end + output.string + end + + def test_e2e_basic + assert_equal(<<~END, test_run("basic", ["."])) + # TypeProf #{ TypeProf::VERSION } + + # ./basic.rb + class Object + def foo: (String) -> String + end + END + end + + def test_e2e_type_error + assert_equal(<<~END, test_run("type_error", ["."])) + # TypeProf #{ TypeProf::VERSION } + + # ./type_error.rb + class Object + def check: -> untyped + end + END + + assert_equal(<<~END, test_run("type_error", ["--show-error", "."])) + # TypeProf #{ TypeProf::VERSION } + + # ./type_error.rb + # (2,10)-(2,20):failed to resolve overloads + class Object + def check: -> untyped + end + END + end + + def test_e2e_syntax_error + assert_equal(<<~END, test_run("syntax_error", ["."])) + # TypeProf #{ TypeProf::VERSION } + + # failed to analyze: ./syntax_error.rb + # failed to analyze: ./syntax_error.rbs + END + end + + def test_e2e_no_version + assert_equal(<<~END, test_run("basic", ["--no-show-typeprof-version", "."])) + # ./basic.rb + class Object + def foo: (String) -> String + end + END + end + + def test_e2e_output_param_names + assert_equal(<<~END, test_run("basic", ["--show-parameter-names", "."])) + # TypeProf #{ TypeProf::VERSION } + + # ./basic.rb + class Object + def foo: (String n) -> String + end + END + end + + def test_e2e_output_source_location + assert_equal(<<~END, test_run("basic", ["--show-source-location", "."])) + # TypeProf #{ TypeProf::VERSION } + + # ./basic.rb + class Object + # ./basic.rb:1:1 + def foo: (String) -> String + end + END + end + + def test_e2e_rbs_collection + exp = <<~END + # TypeProf #{ TypeProf::VERSION } + + # test.rb + class Object + def check: -> :ok + end + END + + assert_equal(exp, test_run("rbs_collection_test", ["test.rb"]) do + lock_path = RBS::Collection::Config.to_lockfile_path(Pathname("rbs_collection.yaml").expand_path) + + RBS::Collection::Installer.new(lockfile_path: lock_path).install_from_lockfile + end) + end + end +end diff --git a/test/lsp/fixtures/basic/basic.rb b/test/fixtures/basic/basic.rb similarity index 100% rename from test/lsp/fixtures/basic/basic.rb rename to test/fixtures/basic/basic.rb diff --git a/test/lsp/fixtures/basic/typeprof.conf.json b/test/fixtures/basic/typeprof.conf.json similarity index 100% rename from test/lsp/fixtures/basic/typeprof.conf.json rename to test/fixtures/basic/typeprof.conf.json diff --git a/test/fixtures/rbs_collection_test/.gitignore b/test/fixtures/rbs_collection_test/.gitignore new file mode 100644 index 000000000..eec38cc36 --- /dev/null +++ b/test/fixtures/rbs_collection_test/.gitignore @@ -0,0 +1 @@ +.gem_rbs_collection \ No newline at end of file diff --git a/test/fixtures/rbs_collection_test/Gemfile b/test/fixtures/rbs_collection_test/Gemfile new file mode 100644 index 000000000..988f73b21 --- /dev/null +++ b/test/fixtures/rbs_collection_test/Gemfile @@ -0,0 +1,3 @@ +source "https://rubygems.org" + +gem "my_dummy_gem", path: "dummy_gem_source/my_dummy_gem" diff --git a/test/fixtures/rbs_collection_test/Gemfile.lock b/test/fixtures/rbs_collection_test/Gemfile.lock new file mode 100644 index 000000000..14077546d --- /dev/null +++ b/test/fixtures/rbs_collection_test/Gemfile.lock @@ -0,0 +1,18 @@ +PATH + remote: dummy_gem_source/my_dummy_gem + specs: + my_dummy_gem (1.0.0) + +GEM + remote: https://rubygems.org/ + specs: + +PLATFORMS + ruby + x86_64-linux + +DEPENDENCIES + my_dummy_gem! + +BUNDLED WITH + 2.6.0.dev diff --git a/test/fixtures/rbs_collection_test/dummy_gem_source/my_dummy_gem/lib/my_dummy_gem.rb b/test/fixtures/rbs_collection_test/dummy_gem_source/my_dummy_gem/lib/my_dummy_gem.rb new file mode 100644 index 000000000..0b0c851d5 --- /dev/null +++ b/test/fixtures/rbs_collection_test/dummy_gem_source/my_dummy_gem/lib/my_dummy_gem.rb @@ -0,0 +1,4 @@ +def hello(name) + "Hello, #{ name }" + raise +end diff --git a/test/fixtures/rbs_collection_test/dummy_gem_source/my_dummy_gem/my_dummy_gem.gemspec b/test/fixtures/rbs_collection_test/dummy_gem_source/my_dummy_gem/my_dummy_gem.gemspec new file mode 100644 index 000000000..3d74b4946 --- /dev/null +++ b/test/fixtures/rbs_collection_test/dummy_gem_source/my_dummy_gem/my_dummy_gem.gemspec @@ -0,0 +1,21 @@ +Gem::Specification.new do |spec| + spec.name = "my_dummy_gem" + spec.version = "1.0.0" + spec.authors = ["Yusuke Endoh"] + spec.email = ["mame@ruby-lang.org"] + + spec.summary = %q{A dummy gem for testing TypePRof} + spec.description = %q{A dummy gem for testing TypePRof} + spec.homepage = "https://github.com/ruby/typeprof" + spec.license = "MIT" + spec.required_ruby_version = Gem::Requirement.new(">= 3.3") + + spec.metadata["homepage_uri"] = spec.homepage + spec.metadata["source_code_uri"] = "https://github.com/ruby/typeprof" + + # Specify which files should be added to the gem when it is released. + # The `git ls-files -z` loads the files in the RubyGem that have been added into git. + spec.files = ["lib/my_dummy_gem.rb"] + spec.executables = [] + spec.require_paths = ["lib"] +end diff --git a/test/fixtures/rbs_collection_test/dummy_rbs_collection/my_dummy_gem/1.0/my_dummy_gem.rbs b/test/fixtures/rbs_collection_test/dummy_rbs_collection/my_dummy_gem/1.0/my_dummy_gem.rbs new file mode 100644 index 000000000..a081deb01 --- /dev/null +++ b/test/fixtures/rbs_collection_test/dummy_rbs_collection/my_dummy_gem/1.0/my_dummy_gem.rbs @@ -0,0 +1,3 @@ +class MyDummyGem + def hello: (String) -> :ok +end \ No newline at end of file diff --git a/test/fixtures/rbs_collection_test/rbs_collection.lock.yaml b/test/fixtures/rbs_collection_test/rbs_collection.lock.yaml new file mode 100644 index 000000000..079410923 --- /dev/null +++ b/test/fixtures/rbs_collection_test/rbs_collection.lock.yaml @@ -0,0 +1,9 @@ +--- +path: ".gem_rbs_collection" +gems: +- name: my_dummy_gem + version: '1.0' + source: + type: local + path: "./dummy_rbs_collection" +gemfile_lock_path: Gemfile.lock diff --git a/test/fixtures/rbs_collection_test/rbs_collection.yaml b/test/fixtures/rbs_collection_test/rbs_collection.yaml new file mode 100644 index 000000000..9a515c206 --- /dev/null +++ b/test/fixtures/rbs_collection_test/rbs_collection.yaml @@ -0,0 +1,10 @@ +# Download sources +sources: + - type: local + path: ./dummy_rbs_collection + +# A directory to install the downloaded RBSs +path: .gem_rbs_collection + +gems: + - name: my_dummy_gem diff --git a/test/fixtures/rbs_collection_test/test.rb b/test/fixtures/rbs_collection_test/test.rb new file mode 100644 index 000000000..765463cfc --- /dev/null +++ b/test/fixtures/rbs_collection_test/test.rb @@ -0,0 +1,5 @@ +require "my_dummy_gem" + +def check + MyDummyGem.new.hello("mame") +end diff --git a/test/fixtures/syntax_error/syntax_error.rb b/test/fixtures/syntax_error/syntax_error.rb new file mode 100644 index 000000000..3e895bf0d --- /dev/null +++ b/test/fixtures/syntax_error/syntax_error.rb @@ -0,0 +1 @@ +def foo diff --git a/test/fixtures/syntax_error/syntax_error.rbs b/test/fixtures/syntax_error/syntax_error.rbs new file mode 100644 index 000000000..43c42f145 --- /dev/null +++ b/test/fixtures/syntax_error/syntax_error.rbs @@ -0,0 +1 @@ +class Foo \ No newline at end of file diff --git a/test/fixtures/type_error/type_error.rb b/test/fixtures/type_error/type_error.rb new file mode 100644 index 000000000..7dd370db8 --- /dev/null +++ b/test/fixtures/type_error/type_error.rb @@ -0,0 +1,3 @@ +def check + Foo.new.accept_int("str") +end diff --git a/test/fixtures/type_error/type_error.rbs b/test/fixtures/type_error/type_error.rbs new file mode 100644 index 000000000..24a0b60ca --- /dev/null +++ b/test/fixtures/type_error/type_error.rbs @@ -0,0 +1,3 @@ +class Foo + def accept_int: (Integer) -> :ok +end \ No newline at end of file diff --git a/test/lsp/lsp_test.rb b/test/lsp/lsp_test.rb index 61a550c1c..30b430372 100644 --- a/test/lsp/lsp_test.rb +++ b/test/lsp/lsp_test.rb @@ -31,7 +31,7 @@ def write(**json) def setup @dummy_io = DummyIO.new @th = Thread.new do - core = TypeProf::Core::Service.new + core = TypeProf::Core::Service.new({}) serv = TypeProf::LSP::Server.new(core, @dummy_io, @dummy_io) serv.run end @@ -39,7 +39,7 @@ def setup end def init(fixture) - @folder = "file://" + File.expand_path(File.join(__dir__, "fixtures", fixture)) + "/" + @folder = "file://" + File.expand_path(File.join(__dir__, "..", "fixtures", fixture)) + "/" id = request("initialize", workspaceFolders: [{ uri: @folder }]) expect_response(id) do |recv| assert_equal({ name: "typeprof", version: TypeProf::VERSION }, recv[:serverInfo]) diff --git a/test/scenario_compiler.rb b/test/scenario_compiler.rb index 67b100871..0d543aa98 100644 --- a/test/scenario_compiler.rb +++ b/test/scenario_compiler.rb @@ -19,7 +19,7 @@ def header require #{ File.join(__dir__, "../lib/typeprof").dump } require #{ File.join(__dir__, "helper").dump } class ScenarioTest < Test::Unit::TestCase - core = TypeProf::Core::Service.new + core = TypeProf::Core::Service.new({}) _ = core # stop "unused" warning END end @@ -36,7 +36,7 @@ def compile_scenario(scenario) out = %(eval(<<'TYPEPROF_SCENARIO_END', nil, #{ scenario.dump }, 1)\n) out << %(test(#{ scenario.dump }) do ) unless @fast - out << "core = TypeProf::Core::Service.new;" + out << "core = TypeProf::Core::Service.new({});" end close_str = "" need_comment_removal = false diff --git a/tool/dog_bench.rb b/tool/dog_bench.rb index 9ab735ec8..6e52d4e40 100644 --- a/tool/dog_bench.rb +++ b/tool/dog_bench.rb @@ -19,7 +19,7 @@ def main(core) pp h end -core = Service.new +core = Service.new({}) if ARGV[0] == "pf2" require "pf2" Pf2.start(interval_ms: 1, time_mode: :wall, threads: [Thread.current]) diff --git a/typeprof.gemspec b/typeprof.gemspec index 765f9d851..21fa1b254 100644 --- a/typeprof.gemspec +++ b/typeprof.gemspec @@ -28,5 +28,5 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.require_paths = ["lib"] - spec.add_runtime_dependency "rbs", ">= 3.5.1" + spec.add_runtime_dependency "rbs", ">= 3.6.0" end