typeprof 0.15.2 → 0.20.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +1 -1
- data/Gemfile.lock +4 -4
- data/doc/ide.md +81 -0
- data/doc/typeprof-for-ide-log.png +0 -0
- data/doc/typeprof-for-ide.png +0 -0
- data/exe/typeprof +5 -1
- data/lib/typeprof/analyzer.rb +235 -56
- data/lib/typeprof/arguments.rb +1 -0
- data/lib/typeprof/builtin.rb +23 -23
- data/lib/typeprof/cli.rb +23 -5
- data/lib/typeprof/code-range.rb +177 -0
- data/lib/typeprof/config.rb +41 -20
- data/lib/typeprof/container-type.rb +10 -1
- data/lib/typeprof/export.rb +191 -15
- data/lib/typeprof/import.rb +38 -9
- data/lib/typeprof/insns-def.rb +1 -0
- data/lib/typeprof/iseq.rb +224 -17
- data/lib/typeprof/lsp.rb +884 -0
- data/lib/typeprof/method.rb +15 -11
- data/lib/typeprof/type.rb +46 -38
- data/lib/typeprof/utils.rb +18 -1
- data/lib/typeprof/version.rb +1 -1
- data/lib/typeprof.rb +3 -5
- data/typeprof-lsp +3 -0
- data/typeprof.gemspec +2 -2
- data/vscode/.gitignore +5 -0
- data/vscode/.vscode/launch.json +16 -0
- data/vscode/.vscodeignore +7 -0
- data/vscode/README.md +22 -0
- data/vscode/development.md +31 -0
- data/vscode/package-lock.json +2211 -0
- data/vscode/package.json +71 -0
- data/vscode/sandbox/test.rb +24 -0
- data/vscode/src/extension.ts +285 -0
- data/vscode/tsconfig.json +15 -0
- metadata +20 -333
- data/smoke/alias.rb +0 -31
- data/smoke/alias2.rb +0 -21
- data/smoke/any-cbase.rb +0 -5
- data/smoke/any1.rb +0 -16
- data/smoke/any2.rb +0 -18
- data/smoke/arguments.rb +0 -17
- data/smoke/arguments2.rb +0 -56
- data/smoke/array-each.rb +0 -15
- data/smoke/array-each2.rb +0 -16
- data/smoke/array-each3.rb +0 -13
- data/smoke/array-ltlt.rb +0 -14
- data/smoke/array-ltlt2.rb +0 -17
- data/smoke/array-map.rb +0 -12
- data/smoke/array-map2.rb +0 -11
- data/smoke/array-map3.rb +0 -23
- data/smoke/array-mul.rb +0 -18
- data/smoke/array-plus1.rb +0 -11
- data/smoke/array-plus2.rb +0 -16
- data/smoke/array-pop.rb +0 -12
- data/smoke/array-range-aref.rb +0 -71
- data/smoke/array-replace.rb +0 -13
- data/smoke/array-s-aref.rb +0 -12
- data/smoke/array1.rb +0 -27
- data/smoke/array10.rb +0 -15
- data/smoke/array11.rb +0 -14
- data/smoke/array12.rb +0 -25
- data/smoke/array13.rb +0 -31
- data/smoke/array14.rb +0 -14
- data/smoke/array15.rb +0 -16
- data/smoke/array2.rb +0 -28
- data/smoke/array3.rb +0 -26
- data/smoke/array4.rb +0 -15
- data/smoke/array5.rb +0 -14
- data/smoke/array6.rb +0 -17
- data/smoke/array7.rb +0 -14
- data/smoke/array8.rb +0 -13
- data/smoke/array9.rb +0 -13
- data/smoke/attr-module.rb +0 -24
- data/smoke/attr-vis.rb +0 -43
- data/smoke/attr-vis.rbs +0 -4
- data/smoke/attr.rb +0 -28
- data/smoke/autoload.rb +0 -14
- data/smoke/backtrace.rb +0 -33
- data/smoke/block-ambiguous.rb +0 -37
- data/smoke/block-args1-rest.rb +0 -64
- data/smoke/block-args1.rb +0 -60
- data/smoke/block-args2-rest.rb +0 -64
- data/smoke/block-args2.rb +0 -60
- data/smoke/block-args3-rest.rb +0 -75
- data/smoke/block-args3.rb +0 -71
- data/smoke/block-blockarg.rb +0 -28
- data/smoke/block-kwarg.rb +0 -53
- data/smoke/block1.rb +0 -23
- data/smoke/block10.rb +0 -15
- data/smoke/block11.rb +0 -40
- data/smoke/block12.rb +0 -23
- data/smoke/block13.rb +0 -9
- data/smoke/block13.rbs +0 -3
- data/smoke/block14.rb +0 -18
- data/smoke/block2.rb +0 -15
- data/smoke/block3.rb +0 -38
- data/smoke/block4.rb +0 -19
- data/smoke/block5.rb +0 -21
- data/smoke/block6.rb +0 -21
- data/smoke/block7.rb +0 -19
- data/smoke/block8.rb +0 -28
- data/smoke/block9.rb +0 -13
- data/smoke/block_given.rb +0 -37
- data/smoke/blown.rb +0 -13
- data/smoke/break1.rb +0 -19
- data/smoke/break2.rb +0 -16
- data/smoke/break3.rb +0 -13
- data/smoke/break4.rb +0 -17
- data/smoke/case.rb +0 -17
- data/smoke/case2.rb +0 -18
- data/smoke/case3.rb +0 -17
- data/smoke/class-hierarchy.rb +0 -54
- data/smoke/class-hierarchy2.rb +0 -27
- data/smoke/class-new.rb +0 -15
- data/smoke/class.rb +0 -7
- data/smoke/class_eval.rb +0 -22
- data/smoke/class_instance_var.rb +0 -9
- data/smoke/class_method.rb +0 -25
- data/smoke/class_method2.rb +0 -21
- data/smoke/class_method3.rb +0 -29
- data/smoke/constant1.rb +0 -46
- data/smoke/constant2.rb +0 -36
- data/smoke/constant3.rb +0 -10
- data/smoke/constant4.rb +0 -12
- data/smoke/context-sensitive1.rb +0 -13
- data/smoke/cvar.rb +0 -31
- data/smoke/cvar2.rb +0 -17
- data/smoke/define_method.rb +0 -16
- data/smoke/define_method2.rb +0 -18
- data/smoke/define_method3.rb +0 -14
- data/smoke/define_method3.rbs +0 -3
- data/smoke/define_method4.rb +0 -15
- data/smoke/define_method4.rbs +0 -3
- data/smoke/define_method5.rb +0 -12
- data/smoke/define_method6.rb +0 -19
- data/smoke/define_method7.rb +0 -18
- data/smoke/demo.rb +0 -81
- data/smoke/demo1.rb +0 -17
- data/smoke/demo10.rb +0 -21
- data/smoke/demo11.rb +0 -12
- data/smoke/demo2.rb +0 -15
- data/smoke/demo3.rb +0 -17
- data/smoke/demo4.rb +0 -27
- data/smoke/demo5.rb +0 -16
- data/smoke/demo6.rb +0 -22
- data/smoke/demo7.rb +0 -15
- data/smoke/demo8.rb +0 -19
- data/smoke/demo9.rb +0 -18
- data/smoke/dummy-execution1.rb +0 -15
- data/smoke/dummy-execution2.rb +0 -16
- data/smoke/dummy_element.rb +0 -14
- data/smoke/ensure1.rb +0 -21
- data/smoke/enum_for.rb +0 -15
- data/smoke/enum_for2.rb +0 -17
- data/smoke/enumerator.rb +0 -16
- data/smoke/expandarray1.rb +0 -23
- data/smoke/expandarray2.rb +0 -24
- data/smoke/extended.rb +0 -38
- data/smoke/fib.rb +0 -28
- data/smoke/flip-flop.rb +0 -28
- data/smoke/flow1.rb +0 -17
- data/smoke/flow10.rb +0 -17
- data/smoke/flow11.rb +0 -17
- data/smoke/flow2.rb +0 -15
- data/smoke/flow3.rb +0 -15
- data/smoke/flow4.rb +0 -5
- data/smoke/flow5.rb +0 -20
- data/smoke/flow6.rb +0 -20
- data/smoke/flow7.rb +0 -21
- data/smoke/flow8.rb +0 -14
- data/smoke/flow9.rb +0 -12
- data/smoke/for.rb +0 -9
- data/smoke/freeze.rb +0 -12
- data/smoke/function.rb +0 -17
- data/smoke/gvar.rb +0 -14
- data/smoke/gvar2.rb +0 -15
- data/smoke/gvar2.rbs +0 -1
- data/smoke/hash-bot.rb +0 -12
- data/smoke/hash-fetch.rb +0 -28
- data/smoke/hash-merge-bang.rb +0 -12
- data/smoke/hash1.rb +0 -20
- data/smoke/hash2.rb +0 -13
- data/smoke/hash3.rb +0 -14
- data/smoke/hash4.rb +0 -11
- data/smoke/hash5.rb +0 -14
- data/smoke/huge_union.rb +0 -86
- data/smoke/identifier_keywords.rb +0 -17
- data/smoke/included.rb +0 -38
- data/smoke/inheritance.rb +0 -34
- data/smoke/inheritance2.rb +0 -35
- data/smoke/inherited.rb +0 -26
- data/smoke/initialize.rb +0 -28
- data/smoke/instance_eval.rb +0 -18
- data/smoke/instance_eval2.rb +0 -10
- data/smoke/instance_eval3.rb +0 -25
- data/smoke/instance_eval4.rb +0 -12
- data/smoke/int_times.rb +0 -15
- data/smoke/integer.rb +0 -11
- data/smoke/ivar.rb +0 -31
- data/smoke/ivar2.rb +0 -30
- data/smoke/ivar3.rb +0 -17
- data/smoke/ivar3.rbs +0 -3
- data/smoke/ivar4.rb +0 -21
- data/smoke/kernel-class.rb +0 -13
- data/smoke/keyword1.rb +0 -12
- data/smoke/keyword2.rb +0 -12
- data/smoke/keyword3.rb +0 -12
- data/smoke/keyword4.rb +0 -12
- data/smoke/keyword5.rb +0 -16
- data/smoke/kwrest.rb +0 -13
- data/smoke/kwrest.rbs +0 -3
- data/smoke/kwsplat1.rb +0 -43
- data/smoke/kwsplat2.rb +0 -13
- data/smoke/lit-complex.rb +0 -10
- data/smoke/lit-encoding.rb +0 -10
- data/smoke/manual-rbs.rb +0 -29
- data/smoke/manual-rbs.rbs +0 -3
- data/smoke/manual-rbs2.rb +0 -21
- data/smoke/manual-rbs2.rbs +0 -8
- data/smoke/manual-rbs3.rb +0 -13
- data/smoke/manual-rbs3.rbs +0 -3
- data/smoke/masgn1.rb +0 -14
- data/smoke/masgn2.rb +0 -18
- data/smoke/masgn3.rb +0 -13
- data/smoke/method_in_branch.rb +0 -23
- data/smoke/method_missing.rb +0 -29
- data/smoke/module1.rb +0 -29
- data/smoke/module2.rb +0 -28
- data/smoke/module3.rb +0 -33
- data/smoke/module4.rb +0 -35
- data/smoke/module5.rb +0 -17
- data/smoke/module6.rb +0 -40
- data/smoke/module_function1.rb +0 -29
- data/smoke/module_function2.rb +0 -29
- data/smoke/multiple-include.rb +0 -15
- data/smoke/multiple-superclass.rb +0 -28
- data/smoke/next1.rb +0 -21
- data/smoke/next2.rb +0 -17
- data/smoke/noname.rb +0 -9
- data/smoke/object-send1.rb +0 -23
- data/smoke/object-send2.rb +0 -10
- data/smoke/object-send3.rb +0 -18
- data/smoke/once.rb +0 -13
- data/smoke/optional1.rb +0 -14
- data/smoke/optional2.rb +0 -16
- data/smoke/optional3.rb +0 -11
- data/smoke/or_raise.rb +0 -18
- data/smoke/parameterizedd-self.rb +0 -20
- data/smoke/parameterizedd-self2.rb +0 -15
- data/smoke/pathname1.rb +0 -14
- data/smoke/pathname2.rb +0 -14
- data/smoke/pattern-match1.rb +0 -19
- data/smoke/pattern-match2.rb +0 -16
- data/smoke/prepend1.rb +0 -33
- data/smoke/prepend2.rb +0 -10
- data/smoke/prepend2.rbs +0 -9
- data/smoke/primitive_method.rb +0 -19
- data/smoke/printf.rb +0 -20
- data/smoke/proc.rb +0 -20
- data/smoke/proc2.rb +0 -17
- data/smoke/proc3.rb +0 -15
- data/smoke/proc4.rb +0 -12
- data/smoke/proc5.rb +0 -19
- data/smoke/proc6.rb +0 -13
- data/smoke/proc7.rb +0 -32
- data/smoke/public.rb +0 -38
- data/smoke/range.rb +0 -14
- data/smoke/rbs-alias.rb +0 -10
- data/smoke/rbs-alias.rbs +0 -4
- data/smoke/rbs-attr.rb +0 -27
- data/smoke/rbs-attr.rbs +0 -5
- data/smoke/rbs-attr2.rb +0 -11
- data/smoke/rbs-attr2.rbs +0 -3
- data/smoke/rbs-extend.rb +0 -10
- data/smoke/rbs-extend.rbs +0 -7
- data/smoke/rbs-interface.rb +0 -25
- data/smoke/rbs-interface.rbs +0 -12
- data/smoke/rbs-module.rb +0 -26
- data/smoke/rbs-module.rbs +0 -4
- data/smoke/rbs-opt-and-rest.rb +0 -10
- data/smoke/rbs-opt-and-rest.rbs +0 -3
- data/smoke/rbs-proc1.rb +0 -10
- data/smoke/rbs-proc1.rbs +0 -3
- data/smoke/rbs-proc2.rb +0 -21
- data/smoke/rbs-proc2.rbs +0 -3
- data/smoke/rbs-proc3.rb +0 -14
- data/smoke/rbs-proc3.rbs +0 -4
- data/smoke/rbs-record.rb +0 -18
- data/smoke/rbs-record.rbs +0 -4
- data/smoke/rbs-tyvar.rb +0 -19
- data/smoke/rbs-tyvar.rbs +0 -5
- data/smoke/rbs-tyvar2.rb +0 -21
- data/smoke/rbs-tyvar2.rbs +0 -9
- data/smoke/rbs-tyvar3.rb +0 -18
- data/smoke/rbs-tyvar3.rbs +0 -5
- data/smoke/rbs-tyvar4.rb +0 -37
- data/smoke/rbs-tyvar5.rb +0 -13
- data/smoke/rbs-tyvar5.rbs +0 -8
- data/smoke/rbs-tyvar6.rb +0 -18
- data/smoke/rbs-tyvar6.rbs +0 -12
- data/smoke/rbs-tyvar7.rb +0 -12
- data/smoke/rbs-tyvar7.rbs +0 -7
- data/smoke/rbs-vars.rb +0 -35
- data/smoke/rbs-vars.rbs +0 -7
- data/smoke/redo1.rb +0 -22
- data/smoke/redo2.rb +0 -23
- data/smoke/req-keyword.rb +0 -13
- data/smoke/require1.rb +0 -13
- data/smoke/require2.rb +0 -13
- data/smoke/rescue1.rb +0 -21
- data/smoke/rescue2.rb +0 -23
- data/smoke/rescue3.rb +0 -20
- data/smoke/rescue4.rb +0 -17
- data/smoke/respond_to.rb +0 -23
- data/smoke/rest-farg.rb +0 -11
- data/smoke/rest1.rb +0 -26
- data/smoke/rest2.rb +0 -31
- data/smoke/rest3.rb +0 -37
- data/smoke/rest4.rb +0 -19
- data/smoke/rest5.rb +0 -11
- data/smoke/rest6.rb +0 -12
- data/smoke/retry1.rb +0 -21
- data/smoke/return.rb +0 -14
- data/smoke/reveal.rb +0 -13
- data/smoke/simple.rb +0 -12
- data/smoke/singleton_class.rb +0 -8
- data/smoke/singleton_method.rb +0 -12
- data/smoke/step.rb +0 -18
- data/smoke/string-split.rb +0 -12
- data/smoke/struct-keyword_init.rb +0 -10
- data/smoke/struct.rb +0 -13
- data/smoke/struct2.rb +0 -25
- data/smoke/struct3.rb +0 -14
- data/smoke/struct4.rb +0 -7
- data/smoke/struct5.rb +0 -16
- data/smoke/struct6.rb +0 -15
- data/smoke/struct7.rb +0 -17
- data/smoke/stub-keyword.rb +0 -10
- data/smoke/super1.rb +0 -69
- data/smoke/super2.rb +0 -16
- data/smoke/super3.rb +0 -20
- data/smoke/super4.rb +0 -45
- data/smoke/super5.rb +0 -38
- data/smoke/svar1.rb +0 -13
- data/smoke/symbol-proc-attr.rb +0 -22
- data/smoke/symbol-proc-attr2.rb +0 -15
- data/smoke/symbol-proc-bot.rb +0 -13
- data/smoke/symbol-proc.rb +0 -25
- data/smoke/tap1.rb +0 -18
- data/smoke/toplevel.rb +0 -13
- data/smoke/two-map.rb +0 -18
- data/smoke/type_var.rb +0 -11
- data/smoke/typed_method.rb +0 -16
- data/smoke/uninitialize-var.rb +0 -13
- data/smoke/union-recv.rb +0 -35
- data/smoke/user-demo.rb +0 -15
- data/smoke/wrong-extend.rb +0 -27
- data/smoke/wrong-include.rb +0 -27
- data/smoke/wrong-include2.rb +0 -17
- data/smoke/wrong-rbs.rb +0 -15
- data/smoke/wrong-rbs.rbs +0 -7
- data/testbed/ao.rb +0 -297
- data/testbed/diff-lcs-entrypoint.rb +0 -4
- data/testbed/goodcheck-Gemfile.lock +0 -51
data/lib/typeprof/builtin.rb
CHANGED
@@ -624,7 +624,7 @@ module TypeProf
|
|
624
624
|
end
|
625
625
|
|
626
626
|
def self.file_load(path, ep, env, scratch, &ctn)
|
627
|
-
iseq = ISeq.compile(path)
|
627
|
+
iseq, = ISeq.compile(path)
|
628
628
|
callee_ep, callee_env = TypeProf.starting_state(iseq)
|
629
629
|
scratch.merge_env(callee_ep, callee_env)
|
630
630
|
|
@@ -793,27 +793,27 @@ module TypeProf
|
|
793
793
|
|
794
794
|
Import.import_builtin(scratch)
|
795
795
|
|
796
|
-
Type::Builtin[:vmcore] = scratch.new_class(klass_obj, :VMCore, [], klass_obj, nil)
|
797
|
-
Type::Builtin[:int] = scratch.get_constant(klass_obj, :Integer)
|
798
|
-
Type::Builtin[:float] = scratch.get_constant(klass_obj, :Float)
|
799
|
-
Type::Builtin[:rational] = scratch.get_constant(klass_obj, :Rational)
|
800
|
-
Type::Builtin[:complex] = scratch.get_constant(klass_obj, :Complex)
|
801
|
-
Type::Builtin[:sym] = scratch.get_constant(klass_obj, :Symbol)
|
802
|
-
Type::Builtin[:str] = scratch.get_constant(klass_obj, :String)
|
803
|
-
Type::Builtin[:struct] = scratch.get_constant(klass_obj, :Struct)
|
804
|
-
Type::Builtin[:ary] = scratch.get_constant(klass_obj, :Array)
|
805
|
-
Type::Builtin[:hash] = scratch.get_constant(klass_obj, :Hash)
|
806
|
-
Type::Builtin[:io] = scratch.get_constant(klass_obj, :IO)
|
807
|
-
Type::Builtin[:proc] = scratch.get_constant(klass_obj, :Proc)
|
808
|
-
Type::Builtin[:range] = scratch.get_constant(klass_obj, :Range)
|
809
|
-
Type::Builtin[:regexp] = scratch.get_constant(klass_obj, :Regexp)
|
810
|
-
Type::Builtin[:matchdata] = scratch.get_constant(klass_obj, :MatchData)
|
811
|
-
Type::Builtin[:class] = scratch.get_constant(klass_obj, :Class)
|
812
|
-
Type::Builtin[:module] = scratch.get_constant(klass_obj, :Module)
|
813
|
-
Type::Builtin[:exc] = scratch.get_constant(klass_obj, :Exception)
|
814
|
-
Type::Builtin[:encoding] = scratch.get_constant(klass_obj, :Encoding)
|
815
|
-
Type::Builtin[:enumerator] = scratch.get_constant(klass_obj, :Enumerator)
|
816
|
-
Type::Builtin[:kernel] = scratch.get_constant(klass_obj, :Kernel)
|
796
|
+
Type::Builtin[:vmcore] , = scratch.new_class(klass_obj, :VMCore, [], klass_obj, nil)
|
797
|
+
Type::Builtin[:int] , = scratch.get_constant(klass_obj, :Integer)
|
798
|
+
Type::Builtin[:float] , = scratch.get_constant(klass_obj, :Float)
|
799
|
+
Type::Builtin[:rational] , = scratch.get_constant(klass_obj, :Rational)
|
800
|
+
Type::Builtin[:complex] , = scratch.get_constant(klass_obj, :Complex)
|
801
|
+
Type::Builtin[:sym] , = scratch.get_constant(klass_obj, :Symbol)
|
802
|
+
Type::Builtin[:str] , = scratch.get_constant(klass_obj, :String)
|
803
|
+
Type::Builtin[:struct] , = scratch.get_constant(klass_obj, :Struct)
|
804
|
+
Type::Builtin[:ary] , = scratch.get_constant(klass_obj, :Array)
|
805
|
+
Type::Builtin[:hash] , = scratch.get_constant(klass_obj, :Hash)
|
806
|
+
Type::Builtin[:io] , = scratch.get_constant(klass_obj, :IO)
|
807
|
+
Type::Builtin[:proc] , = scratch.get_constant(klass_obj, :Proc)
|
808
|
+
Type::Builtin[:range] , = scratch.get_constant(klass_obj, :Range)
|
809
|
+
Type::Builtin[:regexp] , = scratch.get_constant(klass_obj, :Regexp)
|
810
|
+
Type::Builtin[:matchdata] , = scratch.get_constant(klass_obj, :MatchData)
|
811
|
+
Type::Builtin[:class] , = scratch.get_constant(klass_obj, :Class)
|
812
|
+
Type::Builtin[:module] , = scratch.get_constant(klass_obj, :Module)
|
813
|
+
Type::Builtin[:exc] , = scratch.get_constant(klass_obj, :Exception)
|
814
|
+
Type::Builtin[:encoding] , = scratch.get_constant(klass_obj, :Encoding)
|
815
|
+
Type::Builtin[:enumerator] , = scratch.get_constant(klass_obj, :Enumerator)
|
816
|
+
Type::Builtin[:kernel] , = scratch.get_constant(klass_obj, :Kernel)
|
817
817
|
|
818
818
|
klass_vmcore = Type::Builtin[:vmcore]
|
819
819
|
klass_ary = Type::Builtin[:ary]
|
@@ -881,7 +881,7 @@ module TypeProf
|
|
881
881
|
# ENV: Hash[String, String]
|
882
882
|
str_ty = Type::Instance.new(Type::Builtin[:str])
|
883
883
|
env_ty = Type.gen_hash {|h| h[str_ty] = Type.optional(str_ty) }
|
884
|
-
scratch.add_constant(klass_obj, :ENV, env_ty,
|
884
|
+
scratch.add_constant(klass_obj, :ENV, env_ty, nil)
|
885
885
|
|
886
886
|
scratch.search_method(Type::Builtin[:kernel], false, :sprintf) do |mdefs,|
|
887
887
|
mdefs.each do |mdef|
|
data/lib/typeprof/cli.rb
CHANGED
@@ -18,11 +18,14 @@ module TypeProf
|
|
18
18
|
verbose = 1
|
19
19
|
|
20
20
|
options = {}
|
21
|
+
lsp_options = {}
|
21
22
|
dir_filter = nil
|
22
23
|
gem_rbs_features = []
|
23
|
-
gem_repo_dirs = []
|
24
24
|
show_version = false
|
25
25
|
max_sec = max_iter = nil
|
26
|
+
collection_path = RBS::Collection::Config::PATH
|
27
|
+
|
28
|
+
load_path_ext = []
|
26
29
|
|
27
30
|
opt.separator ""
|
28
31
|
opt.separator "Options:"
|
@@ -30,9 +33,11 @@ module TypeProf
|
|
30
33
|
opt.on("-q", "--quiet", "Do not display progress indicator") { options[:show_indicator] = false }
|
31
34
|
opt.on("-v", "--verbose", "Alias to --show-errors") { options[:show_errors] = true }
|
32
35
|
opt.on("--version", "Display typeprof version") { show_version = true }
|
33
|
-
opt.on("-I DIR", "Add DIR to the load/require path") {|v|
|
36
|
+
opt.on("-I DIR", "Add DIR to the load/require path") {|v| load_path_ext << v }
|
34
37
|
opt.on("-r FEATURE", "Require RBS of the FEATURE gem") {|v| gem_rbs_features << v }
|
35
|
-
opt.on("--
|
38
|
+
opt.on("--collection PATH", "File path of collection configuration") { |v| collection_path = v }
|
39
|
+
opt.on("--no-collection", "Ignore collection configuration") { collection_path = nil }
|
40
|
+
opt.on("--lsp", "LSP mode") {|v| options[:lsp] = true }
|
36
41
|
|
37
42
|
opt.separator ""
|
38
43
|
opt.separator "Analysis output options:"
|
@@ -68,8 +73,15 @@ module TypeProf
|
|
68
73
|
opt.on("--debug", "Display analysis log (for debugging purpose)") { verbose = 2 }
|
69
74
|
opt.on("--[no-]stackprof MODE", /\Acpu|wall|object\z/, "Enable stackprof (for debugging purpose)") {|v| options[:stackprof] = v.to_sym }
|
70
75
|
|
76
|
+
opt.separator ""
|
77
|
+
opt.separator "LSP options:"
|
78
|
+
opt.on("--port PORT", Integer, "Specify a port number to listen for requests on") {|v| lsp_options[:port] = v }
|
79
|
+
opt.on("--stdio", "Use stdio for LSP transport") {|v| lsp_options[:stdio] = v }
|
80
|
+
|
71
81
|
opt.parse!(argv)
|
72
82
|
|
83
|
+
$LOAD_PATH.unshift(*load_path_ext)
|
84
|
+
|
73
85
|
dir_filter ||= ConfigData::DEFAULT_DIR_FILTER
|
74
86
|
rb_files = []
|
75
87
|
rbs_files = []
|
@@ -82,22 +94,28 @@ module TypeProf
|
|
82
94
|
end
|
83
95
|
|
84
96
|
puts "typeprof #{ VERSION }" if show_version
|
85
|
-
if rb_files.empty?
|
97
|
+
if rb_files.empty? && !options[:lsp]
|
86
98
|
exit if show_version
|
87
99
|
raise OptionParser::InvalidOption.new("no input files")
|
88
100
|
end
|
89
101
|
|
102
|
+
if !options[:lsp] && !lsp_options.empty?
|
103
|
+
exit if show_version
|
104
|
+
raise OptionParser::InvalidOption.new("lsp options with non-lsp mode")
|
105
|
+
end
|
106
|
+
|
90
107
|
ConfigData.new(
|
91
108
|
rb_files: rb_files,
|
92
109
|
rbs_files: rbs_files,
|
93
110
|
output: output,
|
94
111
|
gem_rbs_features: gem_rbs_features,
|
95
|
-
|
112
|
+
collection_path: collection_path,
|
96
113
|
verbose: verbose,
|
97
114
|
dir_filter: dir_filter,
|
98
115
|
max_sec: max_sec,
|
99
116
|
max_iter: max_iter,
|
100
117
|
options: options,
|
118
|
+
lsp_options: lsp_options,
|
101
119
|
)
|
102
120
|
|
103
121
|
rescue OptionParser::InvalidOption
|
@@ -0,0 +1,177 @@
|
|
1
|
+
module TypeProf
|
2
|
+
class CodeLocation
|
3
|
+
# In Ruby, lineno is 1-origin, and column is 0-origin
|
4
|
+
def initialize(lineno, column)
|
5
|
+
@lineno = lineno
|
6
|
+
@column = column
|
7
|
+
end
|
8
|
+
|
9
|
+
def inspect
|
10
|
+
"(%d,%d)" % [@lineno, @column]
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :lineno, :column
|
14
|
+
|
15
|
+
def self.from_lsp(lsp_loc)
|
16
|
+
# In the Language Server Protocol, lineno and column are both 0-origin
|
17
|
+
CodeLocation.new(lsp_loc[:line] + 1, lsp_loc[:character])
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_lsp
|
21
|
+
{ line: @lineno - 1, character: @column }
|
22
|
+
end
|
23
|
+
|
24
|
+
def advance_cursor(offset, source_text)
|
25
|
+
new_lineno = @lineno
|
26
|
+
new_column = @column
|
27
|
+
while offset > 0
|
28
|
+
line_text = source_text.lines[new_lineno - 1]
|
29
|
+
if new_column + offset >= line_text.length
|
30
|
+
advanced = line_text.length - new_column
|
31
|
+
offset -= advanced
|
32
|
+
new_lineno += 1
|
33
|
+
new_column = 0
|
34
|
+
else
|
35
|
+
new_column += offset
|
36
|
+
break
|
37
|
+
end
|
38
|
+
end
|
39
|
+
CodeLocation.new(new_lineno, new_column)
|
40
|
+
end
|
41
|
+
|
42
|
+
def <=>(other)
|
43
|
+
ret = @lineno <=> other.lineno
|
44
|
+
return ret if ret != 0
|
45
|
+
@column <=> other.column
|
46
|
+
end
|
47
|
+
|
48
|
+
include Comparable
|
49
|
+
end
|
50
|
+
|
51
|
+
class CodeRange
|
52
|
+
def initialize(first, last)
|
53
|
+
@first, @last = first, last
|
54
|
+
end
|
55
|
+
|
56
|
+
def inspect
|
57
|
+
"%p-%p" % [@first, @last]
|
58
|
+
end
|
59
|
+
|
60
|
+
attr_reader :first
|
61
|
+
attr_reader :last
|
62
|
+
|
63
|
+
def self.from_lsp(lsp_range)
|
64
|
+
CodeRange.new(CodeLocation.from_lsp(lsp[:start]), CodeLocation.from_lsp(lsp[:end]))
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.from_rbs(rbs_loc)
|
68
|
+
CodeRange.new(
|
69
|
+
CodeLocation.new(rbs_loc.start_line, rbs_loc.start_column),
|
70
|
+
CodeLocation.new(rbs_loc.end_line, rbs_loc.end_column),
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
def to_lsp
|
75
|
+
{ start: @first.to_lsp, end: @last.to_lsp }
|
76
|
+
end
|
77
|
+
|
78
|
+
def contain_loc?(loc)
|
79
|
+
@first <= loc && loc < @last
|
80
|
+
end
|
81
|
+
|
82
|
+
def contain?(other)
|
83
|
+
@first <= other.first && other.last <= @last
|
84
|
+
end
|
85
|
+
|
86
|
+
def overlap?(other)
|
87
|
+
if @first <= other.first
|
88
|
+
return @last > other.first
|
89
|
+
else
|
90
|
+
return @first < other.last
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class CodeRangeTable
|
96
|
+
Entry = Struct.new(:range, :value, :children)
|
97
|
+
|
98
|
+
class Entry
|
99
|
+
def inspect
|
100
|
+
"[%p, %p, %p]" % [range, value, children]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def initialize(list = [])
|
105
|
+
@list = list # Array[Entry]
|
106
|
+
end
|
107
|
+
|
108
|
+
def []=(range, value)
|
109
|
+
i_b = @list.bsearch_index {|e| e.range.last > range.first } || @list.size
|
110
|
+
i_e = @list.bsearch_index {|e| e.range.first >= range.last } || @list.size
|
111
|
+
if i_b < i_e
|
112
|
+
# for all i in i_b...i_e, @list[i] overlaps with the range
|
113
|
+
if i_e - i_b == 1
|
114
|
+
if range.contain?(@list[i_b].range)
|
115
|
+
@list[i_b] = Entry[range, value, CodeRangeTable.new(@list[i_b, 1])]
|
116
|
+
elsif @list[i_b].range.contain?(range)
|
117
|
+
@list[i_b].children[range] = value
|
118
|
+
else
|
119
|
+
raise
|
120
|
+
end
|
121
|
+
else
|
122
|
+
if range.contain?(@list[i_b].range) && range.contain?(@list[i_e - 1].range)
|
123
|
+
@list[i_b...i_e] = [Entry[range, value, CodeRangeTable.new(@list[i_b...i_e])]]
|
124
|
+
else
|
125
|
+
raise
|
126
|
+
end
|
127
|
+
end
|
128
|
+
else
|
129
|
+
@list[i_b, 0] = [Entry[range, value, CodeRangeTable.new]]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def [](loc)
|
134
|
+
e = @list.bsearch {|e| e.range.last > loc }
|
135
|
+
if e && e.range.contain_loc?(loc)
|
136
|
+
return e.children[loc] || e.value
|
137
|
+
end
|
138
|
+
return nil
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
if $0 == __FILE__
|
144
|
+
include TypeProf
|
145
|
+
cr1 = CodeRange.new(CodeLocation.new(1, 0), CodeLocation.new(1, 2))
|
146
|
+
cr2 = CodeRange.new(CodeLocation.new(1, 2), CodeLocation.new(1, 4))
|
147
|
+
cr3 = CodeRange.new(CodeLocation.new(2, 0), CodeLocation.new(2, 2))
|
148
|
+
cr4 = CodeRange.new(CodeLocation.new(2, 3), CodeLocation.new(2, 5))
|
149
|
+
cr1and2 = CodeRange.new(CodeLocation.new(1, 0), CodeLocation.new(1, 5))
|
150
|
+
cr3and4 = CodeRange.new(CodeLocation.new(2, 0), CodeLocation.new(2, 5))
|
151
|
+
[[cr1, "A"], [cr2, "B"], [cr3, "C"], [cr4, "D"], [cr1and2, "AB"], [cr3and4, "CD"]].permutation do |ary|
|
152
|
+
tbl = CodeRangeTable.new
|
153
|
+
ary.each do |cr, v|
|
154
|
+
tbl[cr] = v
|
155
|
+
end
|
156
|
+
values = []
|
157
|
+
[1, 2].each do |lineno|
|
158
|
+
(0..5).each do |column|
|
159
|
+
values << tbl[CodeLocation.new(lineno, column)]
|
160
|
+
end
|
161
|
+
end
|
162
|
+
raise if values != ["A", "A", "B", "B", "AB", nil, "C", "C", "CD", "D", "D", nil]
|
163
|
+
end
|
164
|
+
|
165
|
+
source = <<~EOS
|
166
|
+
AB
|
167
|
+
CDE
|
168
|
+
F
|
169
|
+
EOS
|
170
|
+
a_loc = CodeLocation.new(1, 0)
|
171
|
+
b_loc = a_loc.advance_cursor(1, source)
|
172
|
+
raise unless b_loc.inspect == "(1,1)"
|
173
|
+
c_loc = a_loc.advance_cursor(3, source)
|
174
|
+
raise unless c_loc.inspect == "(2,0)"
|
175
|
+
f_loc = c_loc.advance_cursor(4, source)
|
176
|
+
raise unless f_loc.inspect == "(3,0)"
|
177
|
+
end
|
data/lib/typeprof/config.rb
CHANGED
@@ -6,12 +6,14 @@ module TypeProf
|
|
6
6
|
:rbs_files,
|
7
7
|
:output,
|
8
8
|
:gem_rbs_features,
|
9
|
-
:
|
9
|
+
:collection_path,
|
10
10
|
:verbose,
|
11
11
|
:dir_filter,
|
12
12
|
:max_iter,
|
13
13
|
:max_sec,
|
14
14
|
:options,
|
15
|
+
:lsp_options,
|
16
|
+
:lsp,
|
15
17
|
keyword_init: true
|
16
18
|
)
|
17
19
|
|
@@ -26,7 +28,6 @@ module TypeProf
|
|
26
28
|
def initialize(**opt)
|
27
29
|
opt[:output] ||= $stdout
|
28
30
|
opt[:gem_rbs_features] ||= []
|
29
|
-
opt[:gem_repo_dirs] ||= []
|
30
31
|
opt[:dir_filter] ||= DEFAULT_DIR_FILTER
|
31
32
|
opt[:verbose] ||= 0
|
32
33
|
opt[:options] ||= {}
|
@@ -43,6 +44,10 @@ module TypeProf
|
|
43
44
|
union_width_limit: 10,
|
44
45
|
stackprof: nil,
|
45
46
|
}.merge(opt[:options])
|
47
|
+
opt[:lsp_options] = {
|
48
|
+
port: 0,
|
49
|
+
stdio: false,
|
50
|
+
}.merge(opt[:lsp_options] || {})
|
46
51
|
super(**opt)
|
47
52
|
end
|
48
53
|
|
@@ -61,29 +66,36 @@ module TypeProf
|
|
61
66
|
]
|
62
67
|
end
|
63
68
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
TypeProf.send(:remove_const, :Config)
|
69
|
+
module Config
|
70
|
+
def self.current
|
71
|
+
Thread.current[:typeprof_config]
|
68
72
|
end
|
69
|
-
TypeProf.const_set(:Config, config)
|
70
73
|
|
71
|
-
|
74
|
+
def self.set_current(config)
|
75
|
+
Thread.current[:typeprof_config] = config
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.analyze(config, cancel_token = nil)
|
80
|
+
# Deploy the config to the TypeProf::Config (Note: This is thread local)
|
81
|
+
Config.set_current(config)
|
82
|
+
|
83
|
+
if Config.current.options[:stackprof]
|
72
84
|
require "stackprof"
|
73
|
-
out = "typeprof-stackprof-#{ Config.options[:stackprof] }.dump"
|
74
|
-
StackProf.start(mode: Config.options[:stackprof], out: out, raw: true)
|
85
|
+
out = "typeprof-stackprof-#{ Config.current.options[:stackprof] }.dump"
|
86
|
+
StackProf.start(mode: Config.current.options[:stackprof], out: out, raw: true)
|
75
87
|
end
|
76
88
|
|
77
89
|
scratch = Scratch.new
|
78
90
|
Builtin.setup_initial_global_env(scratch)
|
79
91
|
|
80
|
-
Config.gem_rbs_features.each do |feature|
|
92
|
+
Config.current.gem_rbs_features.each do |feature|
|
81
93
|
Import.import_library(scratch, feature)
|
82
94
|
end
|
83
95
|
|
84
96
|
rbs_files = []
|
85
97
|
rbs_codes = []
|
86
|
-
Config.rbs_files.each do |rbs|
|
98
|
+
Config.current.rbs_files.each do |rbs|
|
87
99
|
if rbs.is_a?(Array) # [String name, String content]
|
88
100
|
rbs_codes << rbs
|
89
101
|
else
|
@@ -95,30 +107,39 @@ module TypeProf
|
|
95
107
|
Import.import_rbs_code(scratch, name, content)
|
96
108
|
end
|
97
109
|
|
98
|
-
|
110
|
+
def_code_range_table = nil
|
111
|
+
caller_code_range_table = nil
|
112
|
+
Config.current.rb_files.each do |rb|
|
99
113
|
if rb.is_a?(Array) # [String name, String content]
|
100
|
-
iseq = ISeq.compile_str(*rb.reverse)
|
114
|
+
iseq, def_tbl, caller_tbl = ISeq.compile_str(*rb.reverse)
|
115
|
+
def_code_range_table ||= def_tbl
|
116
|
+
caller_code_range_table ||= caller_tbl
|
101
117
|
else
|
102
118
|
iseq = rb
|
103
119
|
end
|
104
120
|
scratch.add_entrypoint(iseq)
|
105
121
|
end
|
106
122
|
|
107
|
-
result = scratch.type_profile
|
123
|
+
result = scratch.type_profile(cancel_token)
|
124
|
+
|
125
|
+
if Config.current.options[:lsp]
|
126
|
+
return scratch.report_lsp, def_code_range_table, caller_code_range_table
|
127
|
+
end
|
108
128
|
|
109
|
-
if Config.output.respond_to?(:write)
|
110
|
-
scratch.report(result, Config.output)
|
129
|
+
if Config.current.output.respond_to?(:write)
|
130
|
+
scratch.report(result, Config.current.output)
|
111
131
|
else
|
112
|
-
open(Config.output, "w") do |output|
|
132
|
+
open(Config.current.output, "w") do |output|
|
113
133
|
scratch.report(result, output)
|
114
134
|
end
|
115
135
|
end
|
116
136
|
|
117
137
|
rescue TypeProfError => exc
|
118
|
-
exc.report(Config.output)
|
138
|
+
exc.report(Config.current.output)
|
119
139
|
|
140
|
+
return nil
|
120
141
|
ensure
|
121
|
-
if Config.options[:stackprof] && defined?(StackProf)
|
142
|
+
if Config.current.options[:stackprof] && defined?(StackProf)
|
122
143
|
StackProf.stop
|
123
144
|
StackProf.results
|
124
145
|
end
|
@@ -307,7 +307,11 @@ module TypeProf
|
|
307
307
|
def screen_name(scratch)
|
308
308
|
if @rest_ty == Type.bot
|
309
309
|
if @lead_tys.empty?
|
310
|
-
|
310
|
+
# This is heuristic: in general, an empty array is a wrong guess.
|
311
|
+
# Note that an empty array is representable as "[ ]" in RBS, but
|
312
|
+
# users often have to modify it to "Array[something]".
|
313
|
+
# In this term, "Array[untyped]" is considered more useful than "[ ]".
|
314
|
+
return "Array[untyped]"
|
311
315
|
end
|
312
316
|
s = @lead_tys.map do |ty|
|
313
317
|
ty.screen_name(scratch)
|
@@ -317,6 +321,9 @@ module TypeProf
|
|
317
321
|
end
|
318
322
|
|
319
323
|
"*[#{ squash.screen_name(scratch) }]"
|
324
|
+
rescue SystemStackError
|
325
|
+
p squash
|
326
|
+
exit!
|
320
327
|
end
|
321
328
|
|
322
329
|
def pretty_print(q)
|
@@ -673,6 +680,8 @@ module TypeProf
|
|
673
680
|
k_ty = k_ty.union(k)
|
674
681
|
v_ty = v_ty.union(v)
|
675
682
|
end
|
683
|
+
k_ty = Type.any if k_ty == Type.bot
|
684
|
+
v_ty = Type.any if v_ty == Type.bot
|
676
685
|
k_ty = k_ty.screen_name(scratch)
|
677
686
|
v_ty = v_ty.screen_name(scratch)
|
678
687
|
"Hash[#{ k_ty }, #{ v_ty }]"
|