steep 1.6.0 → 1.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/CHANGELOG.md +49 -0
- data/README.md +18 -0
- data/Rakefile +5 -0
- data/bin/output_test.rb +1 -0
- data/doc/narrowing.md +195 -0
- data/doc/shape.md +194 -0
- data/guides/src/gem-rbs-collection/gem-rbs-collection.md +7 -24
- data/guides/src/getting-started/getting-started.md +10 -11
- data/lib/steep/ast/ignore.rb +148 -0
- data/lib/steep/ast/types/factory.rb +27 -18
- data/lib/steep/ast/types/helper.rb +4 -0
- data/lib/steep/ast/types/intersection.rb +7 -0
- data/lib/steep/ast/types/proc.rb +14 -9
- data/lib/steep/ast/types/record.rb +7 -0
- data/lib/steep/ast/types/tuple.rb +7 -0
- data/lib/steep/ast/types/union.rb +7 -0
- data/lib/steep/cli.rb +6 -1
- data/lib/steep/diagnostic/ruby.rb +16 -0
- data/lib/steep/drivers/stats.rb +2 -2
- data/lib/steep/drivers/utils/driver_helper.rb +22 -11
- data/lib/steep/drivers/validate.rb +4 -2
- data/lib/steep/expectations.rb +2 -2
- data/lib/steep/interface/block.rb +1 -1
- data/lib/steep/interface/builder.rb +342 -358
- data/lib/steep/interface/function.rb +82 -11
- data/lib/steep/interface/method_type.rb +18 -10
- data/lib/steep/interface/shape.rb +69 -18
- data/lib/steep/interface/substitution.rb +4 -0
- data/lib/steep/node_helper.rb +30 -1
- data/lib/steep/project/dsl.rb +18 -21
- data/lib/steep/project/options.rb +39 -2
- data/lib/steep/project/pattern.rb +1 -2
- data/lib/steep/project.rb +11 -7
- data/lib/steep/rake_task.rb +132 -0
- data/lib/steep/server/change_buffer.rb +2 -2
- data/lib/steep/server/interaction_worker.rb +67 -11
- data/lib/steep/server/lsp_formatter.rb +2 -0
- data/lib/steep/server/worker_process.rb +3 -1
- data/lib/steep/services/completion_provider.rb +59 -26
- data/lib/steep/services/file_loader.rb +15 -19
- data/lib/steep/services/signature_help_provider.rb +37 -35
- data/lib/steep/services/type_check_service.rb +36 -8
- data/lib/steep/signature/validator.rb +185 -133
- data/lib/steep/source/ignore_ranges.rb +69 -0
- data/lib/steep/source.rb +10 -4
- data/lib/steep/subtyping/check.rb +50 -43
- data/lib/steep/subtyping/result.rb +6 -0
- data/lib/steep/subtyping/variable_variance.rb +3 -3
- data/lib/steep/test.rb +9 -0
- data/lib/steep/type_construction.rb +205 -309
- data/lib/steep/type_inference/block_params.rb +12 -4
- data/lib/steep/type_inference/case_when.rb +301 -0
- data/lib/steep/type_inference/context.rb +1 -1
- data/lib/steep/type_inference/logic_type_interpreter.rb +3 -2
- data/lib/steep/type_inference/method_params.rb +16 -0
- data/lib/steep/type_inference/send_args.rb +5 -2
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +25 -8
- data/steep.gemspec +5 -2
- metadata +12 -396
- data/.github/dependabot.yml +0 -22
- data/.github/workflows/ruby-windows.yml +0 -34
- data/.github/workflows/ruby.yml +0 -33
- data/.vscode/steep-shared.code-snippets +0 -41
- data/Gemfile +0 -14
- data/Gemfile.lock +0 -104
- data/Gemfile.steep +0 -0
- data/gemfile_steep/Gemfile +0 -3
- data/gemfile_steep/Gemfile.lock +0 -64
- data/rbs_collection.steep.lock.yaml +0 -106
- data/rbs_collection.steep.yaml +0 -23
- data/sig/shims/bundler.rbs +0 -3
- data/sig/shims/concurrent-ruby.rbs +0 -39
- data/sig/shims/exception.rbs +0 -4
- data/sig/shims/language-server_protocol.rbs +0 -450
- data/sig/shims/parser/comment.rbs +0 -33
- data/sig/shims/parser/nodes.rbs +0 -252
- data/sig/shims/parser/source/map.rbs +0 -146
- data/sig/shims/parser/source/range.rbs +0 -237
- data/sig/shims/parser.rbs +0 -59
- data/sig/shims/string.rbs +0 -4
- data/sig/shims/tagged_logging.rbs +0 -6
- data/sig/steep/annotation_parser.rbs +0 -60
- data/sig/steep/ast/annotation/collection.rbs +0 -78
- data/sig/steep/ast/annotation.rbs +0 -121
- data/sig/steep/ast/builtin.rbs +0 -69
- data/sig/steep/ast/node/type_application.rbs +0 -31
- data/sig/steep/ast/node/type_assertion.rbs +0 -32
- data/sig/steep/ast/types/any.rbs +0 -29
- data/sig/steep/ast/types/boolean.rbs +0 -31
- data/sig/steep/ast/types/bot.rbs +0 -29
- data/sig/steep/ast/types/class.rbs +0 -33
- data/sig/steep/ast/types/factory.rbs +0 -110
- data/sig/steep/ast/types/helper.rbs +0 -22
- data/sig/steep/ast/types/instance.rbs +0 -33
- data/sig/steep/ast/types/intersection.rbs +0 -38
- data/sig/steep/ast/types/literal.rbs +0 -35
- data/sig/steep/ast/types/logic.rbs +0 -83
- data/sig/steep/ast/types/name.rbs +0 -80
- data/sig/steep/ast/types/nil.rbs +0 -31
- data/sig/steep/ast/types/proc.rbs +0 -53
- data/sig/steep/ast/types/record.rbs +0 -37
- data/sig/steep/ast/types/self.rbs +0 -33
- data/sig/steep/ast/types/top.rbs +0 -29
- data/sig/steep/ast/types/tuple.rbs +0 -35
- data/sig/steep/ast/types/union.rbs +0 -38
- data/sig/steep/ast/types/var.rbs +0 -42
- data/sig/steep/ast/types/void.rbs +0 -29
- data/sig/steep/ast/types.rbs +0 -16
- data/sig/steep/cli.rbs +0 -55
- data/sig/steep/diagnostic/deprecated/else_on_exhaustive_case.rbs +0 -13
- data/sig/steep/diagnostic/deprecated/unknown_constant_assigned.rbs +0 -15
- data/sig/steep/diagnostic/helper.rbs +0 -15
- data/sig/steep/diagnostic/lsp_formatter.rbs +0 -36
- data/sig/steep/diagnostic/ruby.rbs +0 -695
- data/sig/steep/diagnostic/signature.rbs +0 -252
- data/sig/steep/drivers/annotations.rbs +0 -17
- data/sig/steep/drivers/check.rbs +0 -33
- data/sig/steep/drivers/checkfile.rbs +0 -27
- data/sig/steep/drivers/diagnostic_printer.rbs +0 -25
- data/sig/steep/drivers/init.rbs +0 -19
- data/sig/steep/drivers/langserver.rbs +0 -36
- data/sig/steep/drivers/print_project.rbs +0 -15
- data/sig/steep/drivers/stats.rbs +0 -47
- data/sig/steep/drivers/utils/driver_helper.rbs +0 -25
- data/sig/steep/drivers/utils/jobs_option.rbs +0 -19
- data/sig/steep/drivers/validate.rbs +0 -15
- data/sig/steep/drivers/vendor.rbs +0 -19
- data/sig/steep/drivers/watch.rbs +0 -27
- data/sig/steep/drivers/worker.rbs +0 -29
- data/sig/steep/equatable.rbs +0 -11
- data/sig/steep/expectations.rbs +0 -72
- data/sig/steep/index/rbs_index.rbs +0 -141
- data/sig/steep/index/signature_symbol_provider.rbs +0 -41
- data/sig/steep/index/source_index.rbs +0 -63
- data/sig/steep/interface/block.rbs +0 -41
- data/sig/steep/interface/builder.rbs +0 -166
- data/sig/steep/interface/function.rbs +0 -265
- data/sig/steep/interface/method_type.rbs +0 -105
- data/sig/steep/interface/shape.rbs +0 -61
- data/sig/steep/interface/substitution.rbs +0 -49
- data/sig/steep/interface/type_param.rbs +0 -43
- data/sig/steep/method_name.rbs +0 -30
- data/sig/steep/module_helper.rbs +0 -16
- data/sig/steep/node_helper.rbs +0 -78
- data/sig/steep/path_helper.rbs +0 -15
- data/sig/steep/project/dsl.rbs +0 -104
- data/sig/steep/project/options.rbs +0 -27
- data/sig/steep/project/pattern.rbs +0 -47
- data/sig/steep/project/target.rbs +0 -25
- data/sig/steep/project.rbs +0 -26
- data/sig/steep/range_extension.rbs +0 -7
- data/sig/steep/server/base_worker.rbs +0 -49
- data/sig/steep/server/change_buffer.rbs +0 -36
- data/sig/steep/server/delay_queue.rbs +0 -37
- data/sig/steep/server/interaction_worker.rbs +0 -80
- data/sig/steep/server/lsp_formatter.rbs +0 -63
- data/sig/steep/server/master.rbs +0 -299
- data/sig/steep/server/type_check_worker.rbs +0 -141
- data/sig/steep/server/worker_process.rbs +0 -97
- data/sig/steep/services/completion_provider.rbs +0 -251
- data/sig/steep/services/content_change.rbs +0 -37
- data/sig/steep/services/file_loader.rbs +0 -21
- data/sig/steep/services/goto_service.rbs +0 -106
- data/sig/steep/services/hover_provider/rbs.rbs +0 -47
- data/sig/steep/services/hover_provider/ruby.rbs +0 -127
- data/sig/steep/services/hover_provider/singleton_methods.rbs +0 -11
- data/sig/steep/services/path_assignment.rbs +0 -21
- data/sig/steep/services/signature_help_provider.rbs +0 -49
- data/sig/steep/services/signature_service.rbs +0 -156
- data/sig/steep/services/stats_calculator.rbs +0 -41
- data/sig/steep/services/type_check_service.rbs +0 -107
- data/sig/steep/services/type_name_completion.rbs +0 -135
- data/sig/steep/signature/validator.rbs +0 -85
- data/sig/steep/source.rbs +0 -102
- data/sig/steep/subtyping/cache.rbs +0 -17
- data/sig/steep/subtyping/check.rbs +0 -129
- data/sig/steep/subtyping/constraints.rbs +0 -111
- data/sig/steep/subtyping/relation.rbs +0 -63
- data/sig/steep/subtyping/result.rbs +0 -175
- data/sig/steep/subtyping/variable_variance.rbs +0 -25
- data/sig/steep/thread_waiter.rbs +0 -13
- data/sig/steep/type_construction.rbs +0 -567
- data/sig/steep/type_inference/block_params.rbs +0 -170
- data/sig/steep/type_inference/constant_env.rbs +0 -29
- data/sig/steep/type_inference/context.rbs +0 -214
- data/sig/steep/type_inference/context_array.rbs +0 -38
- data/sig/steep/type_inference/logic_type_interpreter.rbs +0 -108
- data/sig/steep/type_inference/method_call.rbs +0 -124
- data/sig/steep/type_inference/method_params.rbs +0 -127
- data/sig/steep/type_inference/multiple_assignment.rbs +0 -76
- data/sig/steep/type_inference/send_args.rbs +0 -243
- data/sig/steep/type_inference/type_env.rbs +0 -160
- data/sig/steep/type_inference/type_env_builder.rbs +0 -81
- data/sig/steep/typing.rbs +0 -75
- data/sig/steep.rbs +0 -36
- data/smoke/alias/Steepfile +0 -6
- data/smoke/alias/a.rb +0 -16
- data/smoke/alias/a.rbs +0 -10
- data/smoke/alias/b.rb +0 -6
- data/smoke/alias/c.rb +0 -8
- data/smoke/alias/test_expectations.yml +0 -96
- data/smoke/and/Steepfile +0 -6
- data/smoke/and/a.rb +0 -8
- data/smoke/and/test_expectations.yml +0 -29
- data/smoke/array/Steepfile +0 -6
- data/smoke/array/a.rb +0 -18
- data/smoke/array/b.rb +0 -12
- data/smoke/array/c.rb +0 -6
- data/smoke/array/test_expectations.yml +0 -103
- data/smoke/block/Steepfile +0 -6
- data/smoke/block/a.rb +0 -10
- data/smoke/block/a.rbs +0 -6
- data/smoke/block/b.rb +0 -13
- data/smoke/block/c.rb +0 -9
- data/smoke/block/c.rbs +0 -3
- data/smoke/block/d.rb +0 -11
- data/smoke/block/e.rb +0 -12
- data/smoke/block/e.rbs +0 -4
- data/smoke/block/test_expectations.yml +0 -133
- data/smoke/case/Steepfile +0 -6
- data/smoke/case/a.rb +0 -18
- data/smoke/case/test_expectations.yml +0 -47
- data/smoke/class/Steepfile +0 -6
- data/smoke/class/a.rb +0 -25
- data/smoke/class/a.rbs +0 -23
- data/smoke/class/b.rb +0 -5
- data/smoke/class/c.rb +0 -9
- data/smoke/class/f.rb +0 -10
- data/smoke/class/g.rb +0 -6
- data/smoke/class/h.rb +0 -19
- data/smoke/class/h.rbs +0 -6
- data/smoke/class/i.rb +0 -14
- data/smoke/class/i.rbs +0 -9
- data/smoke/class/test_expectations.yml +0 -117
- data/smoke/compact/Steepfile +0 -6
- data/smoke/compact/a.rb +0 -2
- data/smoke/compact/a.rbs +0 -5
- data/smoke/compact/b.rb +0 -2
- data/smoke/compact/test_expectations.yml +0 -18
- data/smoke/const/Steepfile +0 -6
- data/smoke/const/a.rb +0 -27
- data/smoke/const/b.rb +0 -7
- data/smoke/const/b.rbs +0 -5
- data/smoke/const/test_expectations.yml +0 -134
- data/smoke/diagnostics/Steepfile +0 -6
- data/smoke/diagnostics/a.rbs +0 -22
- data/smoke/diagnostics/argument_type_mismatch.rb +0 -1
- data/smoke/diagnostics/block_body_type_mismatch.rb +0 -1
- data/smoke/diagnostics/block_type_mismatch.rb +0 -3
- data/smoke/diagnostics/break_type_mismatch.rb +0 -1
- data/smoke/diagnostics/different_method_parameter_kind.rb +0 -9
- data/smoke/diagnostics/else_on_exhaustive_case.rb +0 -12
- data/smoke/diagnostics/incompatible_annotation.rb +0 -6
- data/smoke/diagnostics/incompatible_argument.rb +0 -1
- data/smoke/diagnostics/incompatible_assignment.rb +0 -8
- data/smoke/diagnostics/method_arity_mismatch.rb +0 -11
- data/smoke/diagnostics/method_body_type_mismatch.rb +0 -6
- data/smoke/diagnostics/method_definition_missing.rb +0 -2
- data/smoke/diagnostics/method_parameter_mismatch.rb +0 -10
- data/smoke/diagnostics/method_return_type_annotation_mismatch.rb +0 -7
- data/smoke/diagnostics/missing_keyword.rb +0 -1
- data/smoke/diagnostics/no_method.rb +0 -1
- data/smoke/diagnostics/proc_type_expected.rb +0 -3
- data/smoke/diagnostics/required_block_missing.rb +0 -1
- data/smoke/diagnostics/return_type_mismatch.rb +0 -6
- data/smoke/diagnostics/test_expectations.yml +0 -591
- data/smoke/diagnostics/unexpected_block_given.rb +0 -1
- data/smoke/diagnostics/unexpected_dynamic_method.rb +0 -3
- data/smoke/diagnostics/unexpected_jump.rb +0 -4
- data/smoke/diagnostics/unexpected_jump_value.rb +0 -3
- data/smoke/diagnostics/unexpected_keyword.rb +0 -1
- data/smoke/diagnostics/unexpected_splat.rb +0 -1
- data/smoke/diagnostics/unexpected_yield.rb +0 -6
- data/smoke/diagnostics/unknown_constant_assigned.rb +0 -7
- data/smoke/diagnostics/unresolved_overloading.rb +0 -1
- data/smoke/diagnostics/unsupported_syntax.rb +0 -2
- data/smoke/diagnostics-rbs/Steepfile +0 -8
- data/smoke/diagnostics-rbs/duplicated-method-definition.rbs +0 -20
- data/smoke/diagnostics-rbs/generic-parameter-mismatch.rbs +0 -7
- data/smoke/diagnostics-rbs/inherit-module.rbs +0 -2
- data/smoke/diagnostics-rbs/invalid-method-overload.rbs +0 -3
- data/smoke/diagnostics-rbs/invalid-type-application.rbs +0 -7
- data/smoke/diagnostics-rbs/invalid_variance_annotation.rbs +0 -3
- data/smoke/diagnostics-rbs/mixin-class-error.rbs +0 -6
- data/smoke/diagnostics-rbs/nonregular-type-alias.rbs +0 -3
- data/smoke/diagnostics-rbs/recursive-alias.rbs +0 -5
- data/smoke/diagnostics-rbs/recursive-class.rbs +0 -8
- data/smoke/diagnostics-rbs/recursive-type-alias.rbs +0 -3
- data/smoke/diagnostics-rbs/superclass-mismatch.rbs +0 -7
- data/smoke/diagnostics-rbs/test_expectations.yml +0 -300
- data/smoke/diagnostics-rbs/unknown-method-alias.rbs +0 -3
- data/smoke/diagnostics-rbs/unknown-type-name-2.rbs +0 -5
- data/smoke/diagnostics-rbs/unknown-type-name.rbs +0 -13
- data/smoke/diagnostics-rbs-duplicated/Steepfile +0 -6
- data/smoke/diagnostics-rbs-duplicated/a.rbs +0 -5
- data/smoke/diagnostics-rbs-duplicated/test_expectations.yml +0 -13
- data/smoke/diagnostics-ruby-unsat/Steepfile +0 -6
- data/smoke/diagnostics-ruby-unsat/a.rbs +0 -3
- data/smoke/diagnostics-ruby-unsat/test_expectations.yml +0 -27
- data/smoke/diagnostics-ruby-unsat/unsatisfiable_constraint.rb +0 -6
- data/smoke/dstr/Steepfile +0 -6
- data/smoke/dstr/a.rb +0 -5
- data/smoke/dstr/test_expectations.yml +0 -13
- data/smoke/ensure/Steepfile +0 -6
- data/smoke/ensure/a.rb +0 -18
- data/smoke/ensure/test_expectations.yml +0 -62
- data/smoke/enumerator/Steepfile +0 -6
- data/smoke/enumerator/a.rb +0 -6
- data/smoke/enumerator/b.rb +0 -17
- data/smoke/enumerator/test_expectations.yml +0 -47
- data/smoke/extension/Steepfile +0 -6
- data/smoke/extension/a.rb +0 -10
- data/smoke/extension/a.rbs +0 -13
- data/smoke/extension/b.rb +0 -10
- data/smoke/extension/c.rb +0 -9
- data/smoke/extension/d.rb +0 -2
- data/smoke/extension/e.rb +0 -2
- data/smoke/extension/e.rbs +0 -7
- data/smoke/extension/f.rb +0 -2
- data/smoke/extension/f.rbs +0 -3
- data/smoke/extension/test_expectations.yml +0 -73
- data/smoke/hash/Steepfile +0 -6
- data/smoke/hash/a.rb +0 -17
- data/smoke/hash/a.rbs +0 -8
- data/smoke/hash/b.rb +0 -6
- data/smoke/hash/c.rb +0 -15
- data/smoke/hash/d.rb +0 -5
- data/smoke/hash/e.rb +0 -1
- data/smoke/hash/e.rbs +0 -3
- data/smoke/hash/f.rb +0 -11
- data/smoke/hash/test_expectations.yml +0 -81
- data/smoke/hello/Steepfile +0 -6
- data/smoke/hello/hello.rb +0 -11
- data/smoke/hello/hello.rbs +0 -7
- data/smoke/hello/test_expectations.yml +0 -25
- data/smoke/if/Steepfile +0 -6
- data/smoke/if/a.rb +0 -20
- data/smoke/if/test_expectations.yml +0 -34
- data/smoke/implements/Steepfile +0 -6
- data/smoke/implements/a.rb +0 -12
- data/smoke/implements/a.rbs +0 -6
- data/smoke/implements/b.rb +0 -13
- data/smoke/implements/b.rbs +0 -12
- data/smoke/implements/test_expectations.yml +0 -23
- data/smoke/initialize/Steepfile +0 -6
- data/smoke/initialize/a.rb +0 -12
- data/smoke/initialize/a.rbs +0 -3
- data/smoke/initialize/test_expectations.yml +0 -1
- data/smoke/integer/Steepfile +0 -6
- data/smoke/integer/a.rb +0 -26
- data/smoke/integer/test_expectations.yml +0 -110
- data/smoke/interface/Steepfile +0 -6
- data/smoke/interface/a.rb +0 -12
- data/smoke/interface/a.rbs +0 -12
- data/smoke/interface/test_expectations.yml +0 -23
- data/smoke/kwbegin/Steepfile +0 -6
- data/smoke/kwbegin/a.rb +0 -7
- data/smoke/kwbegin/test_expectations.yml +0 -17
- data/smoke/lambda/Steepfile +0 -6
- data/smoke/lambda/a.rb +0 -10
- data/smoke/lambda/test_expectations.yml +0 -17
- data/smoke/literal/Steepfile +0 -6
- data/smoke/literal/a.rb +0 -11
- data/smoke/literal/b.rb +0 -7
- data/smoke/literal/literal_methods.rbs +0 -4
- data/smoke/literal/test_expectations.yml +0 -106
- data/smoke/map/Steepfile +0 -6
- data/smoke/map/a.rb +0 -5
- data/smoke/map/test_expectations.yml +0 -1
- data/smoke/method/Steepfile +0 -6
- data/smoke/method/a.rb +0 -21
- data/smoke/method/a.rbs +0 -4
- data/smoke/method/b.rb +0 -25
- data/smoke/method/c.rb +0 -5
- data/smoke/method/d.rb +0 -1
- data/smoke/method/d.rbs +0 -3
- data/smoke/method/test_expectations.yml +0 -121
- data/smoke/module/Steepfile +0 -6
- data/smoke/module/a.rb +0 -19
- data/smoke/module/a.rbs +0 -16
- data/smoke/module/b.rb +0 -6
- data/smoke/module/c.rb +0 -22
- data/smoke/module/d.rb +0 -4
- data/smoke/module/e.rb +0 -13
- data/smoke/module/f.rb +0 -11
- data/smoke/module/test_expectations.yml +0 -75
- data/smoke/regexp/Steepfile +0 -6
- data/smoke/regexp/a.rb +0 -109
- data/smoke/regexp/b.rb +0 -79
- data/smoke/regexp/test_expectations.yml +0 -615
- data/smoke/regression/Steepfile +0 -6
- data/smoke/regression/array.rb +0 -7
- data/smoke/regression/block_param_split.rb +0 -7
- data/smoke/regression/block_param_split.rbs +0 -3
- data/smoke/regression/empty_yield.rb +0 -5
- data/smoke/regression/empty_yield.rbs +0 -3
- data/smoke/regression/enumerator_product.rb +0 -1
- data/smoke/regression/fun.rb +0 -8
- data/smoke/regression/fun.rbs +0 -4
- data/smoke/regression/hash.rb +0 -7
- data/smoke/regression/hello world.rb +0 -1
- data/smoke/regression/issue_328.rb +0 -1
- data/smoke/regression/issue_328.rbs +0 -0
- data/smoke/regression/issue_332.rb +0 -11
- data/smoke/regression/issue_332.rbs +0 -19
- data/smoke/regression/issue_372.rb +0 -8
- data/smoke/regression/issue_372.rbs +0 -4
- data/smoke/regression/lambda.rb +0 -3
- data/smoke/regression/masgn.rb +0 -4
- data/smoke/regression/poly_new.rb +0 -2
- data/smoke/regression/poly_new.rbs +0 -4
- data/smoke/regression/range.rb +0 -5
- data/smoke/regression/set_divide.rb +0 -12
- data/smoke/regression/test_expectations.yml +0 -120
- data/smoke/regression/thread.rb +0 -7
- data/smoke/rescue/Steepfile +0 -6
- data/smoke/rescue/a.rb +0 -48
- data/smoke/rescue/test_expectations.yml +0 -79
- data/smoke/self/Steepfile +0 -6
- data/smoke/self/a.rb +0 -21
- data/smoke/self/a.rbs +0 -4
- data/smoke/self/test_expectations.yml +0 -23
- data/smoke/skip/Steepfile +0 -6
- data/smoke/skip/skip.rb +0 -13
- data/smoke/skip/test_expectations.yml +0 -23
- data/smoke/stdout/Steepfile +0 -6
- data/smoke/stdout/a.rb +0 -8
- data/smoke/stdout/a.rbs +0 -7
- data/smoke/stdout/test_expectations.yml +0 -1
- data/smoke/super/Steepfile +0 -6
- data/smoke/super/a.rb +0 -30
- data/smoke/super/a.rbs +0 -10
- data/smoke/super/test_expectations.yml +0 -69
- data/smoke/toplevel/Steepfile +0 -6
- data/smoke/toplevel/a.rb +0 -3
- data/smoke/toplevel/a.rbs +0 -3
- data/smoke/toplevel/test_expectations.yml +0 -15
- data/smoke/tsort/Steepfile +0 -7
- data/smoke/tsort/a.rb +0 -12
- data/smoke/tsort/test_expectations.yml +0 -1
- data/smoke/type_case/Steepfile +0 -6
- data/smoke/type_case/a.rb +0 -24
- data/smoke/type_case/test_expectations.yml +0 -58
- data/smoke/unexpected/Steepfile +0 -6
- data/smoke/unexpected/test_expectations.yml +0 -13
- data/smoke/unexpected/unexpected.rbs +0 -3
- data/smoke/yield/Steepfile +0 -6
- data/smoke/yield/a.rb +0 -15
- data/smoke/yield/b.rb +0 -6
- data/smoke/yield/test_expectations.yml +0 -88
@@ -3,346 +3,313 @@ module Steep
|
|
3
3
|
class Builder
|
4
4
|
class Config
|
5
5
|
attr_reader :self_type, :class_type, :instance_type, :variable_bounds
|
6
|
-
attr_reader :resolve_self, :resolve_instance, :resolve_class
|
7
6
|
|
8
|
-
def initialize(self_type:, class_type
|
7
|
+
def initialize(self_type:, class_type: nil, instance_type: nil, variable_bounds:)
|
9
8
|
@self_type = self_type
|
10
9
|
@class_type = class_type
|
11
10
|
@instance_type = instance_type
|
12
|
-
@resolve_self = resolve_self
|
13
|
-
@resolve_class = resolve_class
|
14
|
-
@resolve_instance = resolve_instance
|
15
11
|
@variable_bounds = variable_bounds
|
16
12
|
end
|
17
13
|
|
18
|
-
def
|
19
|
-
|
20
|
-
self_type: self_type,
|
21
|
-
class_type: class_type,
|
22
|
-
instance_type: instance_type,
|
23
|
-
resolve_self: resolve_self,
|
24
|
-
resolve_class: resolve_class,
|
25
|
-
resolve_instance: resolve_instance,
|
26
|
-
variable_bounds: variable_bounds
|
27
|
-
)
|
14
|
+
def self.empty
|
15
|
+
new(self_type: nil, variable_bounds: {})
|
28
16
|
end
|
29
17
|
|
30
|
-
def
|
31
|
-
if
|
32
|
-
|
33
|
-
else
|
34
|
-
self
|
18
|
+
def subst
|
19
|
+
if self_type || class_type || instance_type
|
20
|
+
Substitution.build([], [], self_type: self_type, module_type: class_type, instance_type: instance_type)
|
35
21
|
end
|
36
22
|
end
|
37
23
|
|
38
|
-
def
|
39
|
-
|
40
|
-
end
|
41
|
-
|
42
|
-
def ==(other)
|
43
|
-
other.is_a?(Config) &&
|
44
|
-
other.self_type == self_type &&
|
45
|
-
other.class_type == class_type &&
|
46
|
-
other.instance_type == instance_type &&
|
47
|
-
other.resolve_self == resolve_self &&
|
48
|
-
other.resolve_class == resolve_class &&
|
49
|
-
other.resolve_instance == resolve_instance &&
|
50
|
-
other.variable_bounds == variable_bounds
|
51
|
-
end
|
52
|
-
|
53
|
-
alias eql? ==
|
54
|
-
|
55
|
-
def hash
|
56
|
-
self_type.hash ^ class_type.hash ^ instance_type.hash ^ resolve_self.hash ^ resolve_class.hash ^ resolve_instance.hash ^ variable_bounds.hash
|
24
|
+
def validate_self_type
|
25
|
+
validate_fvs(:self_type, self_type)
|
57
26
|
end
|
58
27
|
|
59
|
-
def
|
60
|
-
|
61
|
-
Substitution.build(
|
62
|
-
[],
|
63
|
-
[],
|
64
|
-
self_type: self_type,
|
65
|
-
module_type: class_type || AST::Types::Class.instance,
|
66
|
-
instance_type: instance_type || AST::Types::Instance.instance
|
67
|
-
)
|
68
|
-
end
|
28
|
+
def validate_instance_type
|
29
|
+
validate_fvs(:instance_type, instance_type)
|
69
30
|
end
|
70
31
|
|
71
|
-
def
|
72
|
-
|
73
|
-
self_type
|
74
|
-
end
|
32
|
+
def validate_class_type
|
33
|
+
validate_fvs(:class_type, class_type)
|
75
34
|
end
|
76
35
|
|
77
|
-
def
|
78
|
-
|
79
|
-
|
36
|
+
def validate_fvs(name, type)
|
37
|
+
if type
|
38
|
+
fvs = type.free_variables
|
39
|
+
if fvs.include?(AST::Types::Self.instance)
|
40
|
+
raise "#{name} cannot include 'self' type: #{type}"
|
41
|
+
end
|
42
|
+
if fvs.include?(AST::Types::Instance.instance)
|
43
|
+
Steep.logger.fatal { "#{name} cannot include 'instance' type: #{type}" }
|
44
|
+
raise "#{name} cannot include 'instance' type: #{type}"
|
45
|
+
end
|
46
|
+
if fvs.include?(AST::Types::Class.instance)
|
47
|
+
raise "#{name} cannot include 'class' type: #{type}"
|
48
|
+
end
|
80
49
|
end
|
81
50
|
end
|
82
51
|
|
83
|
-
def
|
84
|
-
|
85
|
-
class_type
|
86
|
-
end
|
52
|
+
def upper_bound(a)
|
53
|
+
variable_bounds.fetch(a, nil)
|
87
54
|
end
|
88
55
|
end
|
89
56
|
|
90
|
-
attr_reader :factory, :
|
91
|
-
attr_reader :raw_instance_object_shape_cache, :raw_singleton_object_shape_cache, :raw_interface_object_shape_cache
|
57
|
+
attr_reader :factory, :object_shape_cache, :union_shape_cache, :singleton_shape_cache
|
92
58
|
|
93
59
|
def initialize(factory)
|
94
60
|
@factory = factory
|
95
|
-
@
|
96
|
-
@
|
97
|
-
@
|
98
|
-
@raw_interface_object_shape_cache = {}
|
61
|
+
@object_shape_cache = {}
|
62
|
+
@union_shape_cache = {}
|
63
|
+
@singleton_shape_cache = {}
|
99
64
|
end
|
100
65
|
|
101
|
-
def
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
66
|
+
def shape(type, config)
|
67
|
+
Steep.logger.tagged "shape(#{type})" do
|
68
|
+
if shape = raw_shape(type, config)
|
69
|
+
# Optimization that skips unnecesary substittuion
|
70
|
+
if type.free_variables.include?(AST::Types::Self.instance)
|
71
|
+
shape
|
72
|
+
else
|
73
|
+
if s = config.subst
|
74
|
+
shape.subst(s)
|
75
|
+
else
|
76
|
+
shape
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
107
80
|
end
|
108
81
|
end
|
109
82
|
|
110
|
-
def fetch_cache(
|
111
|
-
has_self = include_self?(type)
|
112
|
-
fvs = type.free_variables
|
113
|
-
|
114
|
-
# @type var key: cache_key
|
115
|
-
key = [
|
116
|
-
type,
|
117
|
-
public_only,
|
118
|
-
has_self ? config.self_type : nil,
|
119
|
-
has_self ? config.class_type : nil,
|
120
|
-
has_self ? config.instance_type : nil,
|
121
|
-
config.resolve_self,
|
122
|
-
config.resolve_class,
|
123
|
-
config.resolve_instance,
|
124
|
-
if config.variable_bounds.each_key.any? {|var| fvs.include?(var)}
|
125
|
-
config.variable_bounds.select {|var, _| fvs.include?(var) }
|
126
|
-
else
|
127
|
-
nil
|
128
|
-
end
|
129
|
-
]
|
130
|
-
|
83
|
+
def fetch_cache(cache, key)
|
131
84
|
if cache.key?(key)
|
132
|
-
cache
|
133
|
-
else
|
134
|
-
cache[key] = yield
|
85
|
+
return cache.fetch(key)
|
135
86
|
end
|
136
|
-
end
|
137
|
-
|
138
|
-
def shape(type, public_only:, config:)
|
139
|
-
fetch_cache(type, public_only, config) do
|
140
|
-
case type
|
141
|
-
when AST::Types::Self
|
142
|
-
if self_type = config.self_type?
|
143
|
-
self_type = self_type.subst(config.subst)
|
144
|
-
shape(self_type, public_only: public_only, config: config.update(resolve_self: false))
|
145
|
-
end
|
146
|
-
when AST::Types::Instance
|
147
|
-
if instance_type = config.instance_type?
|
148
|
-
instance_type = instance_type.subst(config.subst)
|
149
|
-
shape(instance_type, public_only: public_only, config: config.update(resolve_instance: false))
|
150
|
-
end
|
151
|
-
when AST::Types::Class
|
152
|
-
if class_type = config.class_type?
|
153
|
-
class_type = class_type.subst(config.subst)
|
154
|
-
shape(class_type, public_only: public_only, config: config.update(resolve_class: false))
|
155
|
-
end
|
156
|
-
when AST::Types::Name::Instance, AST::Types::Name::Interface, AST::Types::Name::Singleton
|
157
|
-
object_shape(
|
158
|
-
type.subst(config.subst),
|
159
|
-
public_only,
|
160
|
-
!config.resolve_self,
|
161
|
-
!config.resolve_instance,
|
162
|
-
!config.resolve_class
|
163
|
-
)
|
164
|
-
when AST::Types::Name::Alias
|
165
|
-
if expanded = factory.deep_expand_alias(type)
|
166
|
-
shape(expanded, public_only: public_only, config: config)&.update(type: type)
|
167
|
-
end
|
168
|
-
when AST::Types::Any, AST::Types::Bot, AST::Types::Void, AST::Types::Top
|
169
|
-
nil
|
170
|
-
when AST::Types::Var
|
171
|
-
if bound = config.variable_bounds[type.name]
|
172
|
-
shape(bound, public_only: public_only, config: config)&.update(type: type)
|
173
|
-
end
|
174
|
-
when AST::Types::Union
|
175
|
-
if include_self?(type)
|
176
|
-
self_var = AST::Types::Var.fresh(:SELF)
|
177
|
-
class_var = AST::Types::Var.fresh(:CLASS)
|
178
|
-
instance_var = AST::Types::Var.fresh(:INSTANCE)
|
179
|
-
|
180
|
-
bounds = config.variable_bounds.merge({ self_var.name => config.self_type, instance_var.name => config.instance_type, class_var.name => config.class_type })
|
181
|
-
type_ = type.subst(Substitution.build([], [], self_type: self_var, instance_type: instance_var, module_type: class_var)) #: AST::Types::Union
|
182
87
|
|
183
|
-
|
184
|
-
|
185
|
-
shapes = type_.types.map do |type|
|
186
|
-
shape(type, public_only: public_only, config: config_) or return
|
187
|
-
end
|
88
|
+
cache[key] = yield
|
89
|
+
end
|
188
90
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
91
|
+
def raw_shape(type, config)
|
92
|
+
case type
|
93
|
+
when AST::Types::Self
|
94
|
+
config.validate_self_type
|
95
|
+
self_type = config.self_type or raise
|
96
|
+
self_shape(self_type, config)
|
97
|
+
when AST::Types::Instance
|
98
|
+
config.validate_instance_type
|
99
|
+
instance_type = config.instance_type or raise
|
100
|
+
raw_shape(instance_type, config)
|
101
|
+
when AST::Types::Class
|
102
|
+
config.validate_class_type
|
103
|
+
klass_type = config.class_type or raise
|
104
|
+
raw_shape(klass_type, config)
|
105
|
+
when AST::Types::Name::Singleton
|
106
|
+
singleton_shape(type.name).subst(class_subst(type))
|
107
|
+
when AST::Types::Name::Instance
|
108
|
+
object_shape(type.name).subst(class_subst(type).merge(app_subst(type)), type: type)
|
109
|
+
when AST::Types::Name::Interface
|
110
|
+
object_shape(type.name).subst(interface_subst(type).merge(app_subst(type)), type: type)
|
111
|
+
when AST::Types::Union
|
112
|
+
groups = type.types.group_by do |type|
|
113
|
+
if type.is_a?(AST::Types::Literal)
|
114
|
+
type.back_type
|
201
115
|
else
|
202
|
-
|
203
|
-
|
204
|
-
shapes = type.types.map do |type|
|
205
|
-
shape(type, public_only: public_only, config: config_) or return
|
206
|
-
end
|
207
|
-
|
208
|
-
if shape = union_shape(type, shapes, public_only)
|
209
|
-
shape.subst(
|
210
|
-
Substitution.build(
|
211
|
-
[], [],
|
212
|
-
self_type: type,
|
213
|
-
instance_type: AST::Builtin.any_type,
|
214
|
-
module_type: AST::Builtin.any_type
|
215
|
-
)
|
216
|
-
)
|
217
|
-
end
|
218
|
-
end
|
219
|
-
when AST::Types::Intersection
|
220
|
-
self_var = AST::Types::Var.fresh(:SELF)
|
221
|
-
class_var = AST::Types::Var.fresh(:CLASS)
|
222
|
-
instance_var = AST::Types::Var.fresh(:INSTANCE)
|
223
|
-
|
224
|
-
bounds = config.variable_bounds.merge({ self_var.name => config.self_type, instance_var.name => config.instance_type, class_var.name => config.class_type })
|
225
|
-
type_ = type.subst(Substitution.build([], [], self_type: self_var, instance_type: instance_var, module_type: class_var)) #: AST::Types::Intersection
|
226
|
-
|
227
|
-
config_ = config.update(resolve_self: false, resolve_class: true, resolve_instance: true, variable_bounds: bounds)
|
228
|
-
|
229
|
-
shapes = type_.types.map do |type|
|
230
|
-
shape(type, public_only: public_only, config: config_) or return
|
116
|
+
nil
|
231
117
|
end
|
118
|
+
end
|
232
119
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
),
|
242
|
-
type: type.subst(config.subst)
|
243
|
-
)
|
120
|
+
shapes = [] #: Array[Shape]
|
121
|
+
groups.each do |name, types|
|
122
|
+
if name
|
123
|
+
union = AST::Types::Union.build(types: types)
|
124
|
+
subst = class_subst(name).update(self_type: union)
|
125
|
+
shapes << object_shape(name.name).subst(subst, type: union)
|
126
|
+
else
|
127
|
+
shapes.concat(types.map {|ty| raw_shape(ty, config) or return })
|
244
128
|
end
|
129
|
+
end
|
245
130
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
131
|
+
fetch_cache(union_shape_cache, type) do
|
132
|
+
union_shape(type, shapes)
|
133
|
+
end
|
134
|
+
when AST::Types::Intersection
|
135
|
+
shapes = type.types.map do |type|
|
136
|
+
raw_shape(type, config) or return
|
137
|
+
end
|
138
|
+
intersection_shape(type, shapes)
|
139
|
+
when AST::Types::Name::Alias
|
140
|
+
expanded = factory.expand_alias(type)
|
141
|
+
if shape = raw_shape(expanded, config)
|
142
|
+
shape.update(type: type)
|
143
|
+
end
|
144
|
+
when AST::Types::Literal
|
145
|
+
instance_type = type.back_type
|
146
|
+
subst = class_subst(instance_type).update(self_type: type)
|
147
|
+
object_shape(instance_type.name).subst(subst, type: type)
|
148
|
+
when AST::Types::Boolean
|
149
|
+
true_shape =
|
150
|
+
(object_shape(RBS::BuiltinNames::TrueClass.name)).
|
151
|
+
subst(class_subst(AST::Builtin::TrueClass.instance_type).update(self_type: type))
|
152
|
+
false_shape =
|
153
|
+
(object_shape(RBS::BuiltinNames::FalseClass.name)).
|
154
|
+
subst(class_subst(AST::Builtin::FalseClass.instance_type).update(self_type: type))
|
155
|
+
union_shape(type, [true_shape, false_shape])
|
156
|
+
when AST::Types::Proc
|
157
|
+
shape = object_shape(AST::Builtin::Proc.module_name).subst(class_subst(AST::Builtin::Proc.instance_type).update(self_type: type))
|
158
|
+
proc_shape(type, shape)
|
159
|
+
when AST::Types::Tuple
|
160
|
+
tuple_shape(type) do |array|
|
161
|
+
object_shape(array.name).subst(
|
162
|
+
class_subst(array).update(self_type: type).merge(app_subst(array))
|
163
|
+
)
|
164
|
+
end
|
165
|
+
when AST::Types::Record
|
166
|
+
record_shape(type) do |hash|
|
167
|
+
object_shape(hash.name).subst(
|
168
|
+
class_subst(hash).update(self_type: type).merge(app_subst(hash))
|
262
169
|
)
|
263
|
-
|
264
|
-
if shape
|
265
|
-
shape.subst(Substitution.build([], [], self_type: type))
|
266
|
-
end
|
267
|
-
when AST::Types::Nil
|
268
|
-
if shape = object_shape(AST::Builtin::NilClass.instance_type, public_only, true, !config.resolve_instance, !config.resolve_class)
|
269
|
-
if config.resolve_self
|
270
|
-
shape.subst(Substitution.build([], [], self_type: type), type: type)
|
271
|
-
else
|
272
|
-
shape.update(type: type)
|
273
|
-
end
|
274
|
-
end
|
275
|
-
when AST::Types::Proc
|
276
|
-
proc_shape(type, public_only, config)
|
277
|
-
else
|
278
|
-
raise "Unknown type is given: #{type}"
|
279
170
|
end
|
171
|
+
when AST::Types::Var
|
172
|
+
if bound = config.upper_bound(type.name)
|
173
|
+
new_config = Config.new(self_type: bound, variable_bounds: config.variable_bounds)
|
174
|
+
sub = Substitution.build([], self_type: type)
|
175
|
+
# We have to use `self_shape` insead of `raw_shape` here.
|
176
|
+
# Keep the `self` types included in the `bound`'s shape, and replace it to the type variable.
|
177
|
+
self_shape(bound, new_config)&.subst(sub, type: type)
|
178
|
+
end
|
179
|
+
when AST::Types::Nil
|
180
|
+
subst = class_subst(AST::Builtin::NilClass.instance_type).update(self_type: type)
|
181
|
+
object_shape(AST::Builtin::NilClass.module_name).subst(subst, type: type)
|
182
|
+
when AST::Types::Logic::Base
|
183
|
+
true_shape =
|
184
|
+
(object_shape(RBS::BuiltinNames::TrueClass.name)).
|
185
|
+
subst(class_subst(AST::Builtin::TrueClass.instance_type).update(self_type: type))
|
186
|
+
false_shape =
|
187
|
+
(object_shape(RBS::BuiltinNames::FalseClass.name)).
|
188
|
+
subst(class_subst(AST::Builtin::FalseClass.instance_type).update(self_type: type))
|
189
|
+
union_shape(type, [true_shape, false_shape])
|
190
|
+
else
|
191
|
+
nil
|
280
192
|
end
|
281
193
|
end
|
282
194
|
|
283
|
-
def
|
284
|
-
factory.definition_builder
|
285
|
-
end
|
286
|
-
|
287
|
-
def object_shape(type, public_only, keep_self, keep_instance, keep_singleton)
|
195
|
+
def self_shape(type, config)
|
288
196
|
case type
|
197
|
+
when AST::Types::Self, AST::Types::Instance, AST::Types::Class
|
198
|
+
raise
|
199
|
+
when AST::Types::Name::Singleton
|
200
|
+
singleton_shape(type.name).subst(class_subst(type).update(self_type: nil))
|
289
201
|
when AST::Types::Name::Instance
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
module_type: keep_singleton ? AST::Types::Class.instance : AST::Types::Name::Singleton.new(name: type.name),
|
296
|
-
instance_type: keep_instance ? AST::Types::Instance.instance : factory.instance_type(type.name)
|
297
|
-
)
|
202
|
+
object_shape(type.name)
|
203
|
+
.subst(
|
204
|
+
class_subst(type).update(self_type: nil).merge(app_subst(type)),
|
205
|
+
type: type
|
206
|
+
)
|
298
207
|
when AST::Types::Name::Interface
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
208
|
+
object_shape(type.name).subst(app_subst(type), type: type)
|
209
|
+
when AST::Types::Literal
|
210
|
+
instance_type = type.back_type
|
211
|
+
subst = class_subst(instance_type).update(self_type: nil)
|
212
|
+
object_shape(instance_type.name).subst(subst, type: type)
|
213
|
+
when AST::Types::Boolean
|
214
|
+
true_shape =
|
215
|
+
(object_shape(RBS::BuiltinNames::TrueClass.name)).
|
216
|
+
subst(class_subst(AST::Builtin::TrueClass.instance_type).update(self_type: nil))
|
217
|
+
false_shape =
|
218
|
+
(object_shape(RBS::BuiltinNames::FalseClass.name)).
|
219
|
+
subst(class_subst(AST::Builtin::FalseClass.instance_type).update(self_type: nil))
|
220
|
+
union_shape(type, [true_shape, false_shape])
|
221
|
+
when AST::Types::Proc
|
222
|
+
shape = object_shape(AST::Builtin::Proc.module_name).subst(class_subst(AST::Builtin::Proc.instance_type).update(self_type: nil))
|
223
|
+
proc_shape(type, shape)
|
224
|
+
when AST::Types::Var
|
225
|
+
if bound = config.upper_bound(type.name)
|
226
|
+
self_shape(bound, config)&.update(type: type)
|
227
|
+
end
|
228
|
+
else
|
229
|
+
raw_shape(type, config)
|
313
230
|
end
|
314
|
-
|
315
|
-
raw_object_shape(type, public_only, subst)
|
316
231
|
end
|
317
232
|
|
318
|
-
def
|
319
|
-
|
233
|
+
def app_subst(type)
|
234
|
+
if type.args.empty?
|
235
|
+
return Substitution.empty
|
236
|
+
end
|
237
|
+
|
238
|
+
vars =
|
320
239
|
case type
|
321
240
|
when AST::Types::Name::Instance
|
322
|
-
|
241
|
+
entry = factory.env.normalized_module_class_entry(type.name) or raise
|
242
|
+
entry.primary.decl.type_params.map { _1.name }
|
323
243
|
when AST::Types::Name::Interface
|
324
|
-
|
325
|
-
|
326
|
-
|
244
|
+
entry = factory.env.interface_decls.fetch(type.name)
|
245
|
+
entry.decl.type_params.map { _1.name }
|
246
|
+
when AST::Types::Name::Alias
|
247
|
+
entry = factory.env.type_alias_decls.fetch(type.name)
|
248
|
+
entry.decl.type_params.map { _1.name }
|
327
249
|
end
|
328
250
|
|
329
|
-
|
330
|
-
|
251
|
+
Substitution.build(vars, type.args)
|
252
|
+
end
|
331
253
|
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
254
|
+
def class_subst(type)
|
255
|
+
case type
|
256
|
+
when AST::Types::Name::Singleton
|
257
|
+
self_type = type
|
258
|
+
singleton_type = type
|
259
|
+
instance_type = factory.instance_type(type.name)
|
260
|
+
when AST::Types::Name::Instance
|
261
|
+
self_type = type
|
262
|
+
singleton_type = type.to_module
|
263
|
+
instance_type = factory.instance_type(type.name)
|
264
|
+
end
|
265
|
+
|
266
|
+
Substitution.build([], self_type: self_type, module_type: singleton_type, instance_type: instance_type)
|
267
|
+
end
|
268
|
+
|
269
|
+
def interface_subst(type)
|
270
|
+
Substitution.build([], self_type: type)
|
271
|
+
end
|
272
|
+
|
273
|
+
def singleton_shape(type_name)
|
274
|
+
singleton_shape_cache[type_name] ||= begin
|
275
|
+
shape = Interface::Shape.new(type: AST::Types::Name::Singleton.new(name: type_name), private: true)
|
276
|
+
definition = factory.definition_builder.build_singleton(type_name)
|
340
277
|
|
341
278
|
definition.methods.each do |name, method|
|
342
|
-
|
279
|
+
Steep.logger.tagged "method = #{type_name}.#{name}" do
|
280
|
+
shape.methods[name] = Interface::Shape::Entry.new(
|
281
|
+
private_method: method.private?,
|
282
|
+
method_types: method.defs.map do |type_def|
|
283
|
+
method_name = method_name_for(type_def, name)
|
284
|
+
decl = TypeInference::MethodCall::MethodDecl.new(method_name: method_name, method_def: type_def)
|
285
|
+
method_type = factory.method_type(type_def.type, method_decls: Set[decl])
|
286
|
+
replace_primitive_method(method_name, type_def, method_type)
|
287
|
+
end
|
288
|
+
)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
shape
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
def object_shape(type_name)
|
297
|
+
object_shape_cache[type_name] ||= begin
|
298
|
+
shape = Interface::Shape.new(type: AST::Builtin.bottom_type, private: true)
|
299
|
+
|
300
|
+
case
|
301
|
+
when type_name.class?
|
302
|
+
definition = factory.definition_builder.build_instance(type_name)
|
303
|
+
when type_name.interface?
|
304
|
+
definition = factory.definition_builder.build_interface(type_name)
|
305
|
+
end
|
306
|
+
|
307
|
+
definition or raise
|
343
308
|
|
344
|
-
|
309
|
+
definition.methods.each do |name, method|
|
310
|
+
Steep.logger.tagged "method = #{type_name}##{name}" do
|
345
311
|
shape.methods[name] = Interface::Shape::Entry.new(
|
312
|
+
private_method: method.private?,
|
346
313
|
method_types: method.defs.map do |type_def|
|
347
314
|
method_name = method_name_for(type_def, name)
|
348
315
|
decl = TypeInference::MethodCall::MethodDecl.new(method_name: method_name, method_def: type_def)
|
@@ -355,8 +322,84 @@ module Steep
|
|
355
322
|
|
356
323
|
shape
|
357
324
|
end
|
325
|
+
end
|
326
|
+
|
327
|
+
def union_shape(shape_type, shapes)
|
328
|
+
s0, *sx = shapes
|
329
|
+
s0 or raise
|
330
|
+
all_common_methods = Set.new(s0.methods.each_name)
|
331
|
+
sx.each do |shape|
|
332
|
+
all_common_methods &= shape.methods.each_name
|
333
|
+
end
|
334
|
+
|
335
|
+
shape = Interface::Shape.new(type: shape_type, private: true)
|
336
|
+
all_common_methods.each do |method_name|
|
337
|
+
method_typess = [] #: Array[Array[MethodType]]
|
338
|
+
private_method = false
|
339
|
+
shapes.each do |shape|
|
340
|
+
entry = shape.methods[method_name] || raise
|
341
|
+
method_typess << entry.method_types
|
342
|
+
private_method ||= entry.private_method?
|
343
|
+
end
|
344
|
+
|
345
|
+
shape.methods[method_name] = Interface::Shape::Entry.new(private_method: private_method) do
|
346
|
+
method_typess.inject do |types1, types2|
|
347
|
+
# @type break: nil
|
348
|
+
|
349
|
+
if types1 == types2
|
350
|
+
decl_array1 = types1.map(&:method_decls)
|
351
|
+
decl_array2 = types2.map(&:method_decls)
|
352
|
+
|
353
|
+
if decl_array1 == decl_array2
|
354
|
+
next types1
|
355
|
+
end
|
356
|
+
|
357
|
+
decls1 = decl_array1.each.with_object(Set[]) {|array, decls| decls.merge(array) } #$ Set[TypeInference::MethodCall::MethodDecl]
|
358
|
+
decls2 = decl_array2.each.with_object(Set[]) {|array, decls| decls.merge(array) } #$ Set[TypeInference::MethodCall::MethodDecl]
|
358
359
|
|
359
|
-
|
360
|
+
if decls1 == decls2
|
361
|
+
next types1
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
method_types = {} #: Hash[MethodType, bool]
|
366
|
+
|
367
|
+
types1.each do |type1|
|
368
|
+
types2.each do |type2|
|
369
|
+
if type1 == type2
|
370
|
+
method_types[type1.with(method_decls: type1.method_decls + type2.method_decls)] = true
|
371
|
+
else
|
372
|
+
if type = MethodType.union(type1, type2, subtyping)
|
373
|
+
method_types[type] = true
|
374
|
+
end
|
375
|
+
end
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
break nil if method_types.empty?
|
380
|
+
|
381
|
+
method_types.keys
|
382
|
+
end
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
shape
|
387
|
+
end
|
388
|
+
|
389
|
+
def intersection_shape(type, shapes)
|
390
|
+
shape = Interface::Shape.new(type: type, private: true)
|
391
|
+
|
392
|
+
shapes.each do |s|
|
393
|
+
shape.methods.merge!(s.methods) do |name, old_entry, new_entry|
|
394
|
+
if old_entry.public_method? && new_entry.private_method?
|
395
|
+
old_entry
|
396
|
+
else
|
397
|
+
new_entry
|
398
|
+
end
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
shape
|
360
403
|
end
|
361
404
|
|
362
405
|
def method_name_for(type_def, name)
|
@@ -383,63 +426,19 @@ module Steep
|
|
383
426
|
@subtyping ||= Subtyping::Check.new(builder: self)
|
384
427
|
end
|
385
428
|
|
386
|
-
def
|
387
|
-
shapes.inject do |shape1, shape2|
|
388
|
-
Interface::Shape.new(type: shape_type, private: !public_only).tap do |shape|
|
389
|
-
common_methods = Set.new(shape1.methods.each_name) & Set.new(shape2.methods.each_name)
|
390
|
-
common_methods.each do |name|
|
391
|
-
Steep.logger.tagged(name.to_s) do
|
392
|
-
types1 = shape1.methods[name]&.method_types or raise
|
393
|
-
types2 = shape2.methods[name]&.method_types or raise
|
394
|
-
|
395
|
-
if types1 == types2 && types1.map {|type| type.method_decls.to_a }.to_set == types2.map {|type| type.method_decls.to_a }.to_set
|
396
|
-
shape.methods[name] = (shape1.methods[name] or raise)
|
397
|
-
else
|
398
|
-
method_types = {} #: Hash[MethodType, true]
|
399
|
-
|
400
|
-
types1.each do |type1|
|
401
|
-
types2.each do |type2|
|
402
|
-
if type1 == type2
|
403
|
-
method_types[type1.with(method_decls: type1.method_decls + type2.method_decls)] = true
|
404
|
-
else
|
405
|
-
if type = MethodType.union(type1, type2, subtyping)
|
406
|
-
method_types[type] = true
|
407
|
-
end
|
408
|
-
end
|
409
|
-
end
|
410
|
-
end
|
411
|
-
|
412
|
-
unless method_types.empty?
|
413
|
-
shape.methods[name] = Interface::Shape::Entry.new(method_types: method_types.keys)
|
414
|
-
end
|
415
|
-
end
|
416
|
-
end
|
417
|
-
end
|
418
|
-
end
|
419
|
-
end
|
420
|
-
end
|
421
|
-
|
422
|
-
def intersection_shape(type, shapes, public_only)
|
423
|
-
shapes.inject do |shape1, shape2|
|
424
|
-
Interface::Shape.new(type: type, private: !public_only).tap do |shape|
|
425
|
-
shape.methods.merge!(shape1.methods)
|
426
|
-
shape.methods.merge!(shape2.methods)
|
427
|
-
end
|
428
|
-
end
|
429
|
-
end
|
430
|
-
|
431
|
-
def tuple_shape(tuple, public_only, config)
|
429
|
+
def tuple_shape(tuple)
|
432
430
|
element_type = AST::Types::Union.build(types: tuple.types, location: nil)
|
433
431
|
array_type = AST::Builtin::Array.instance_type(element_type)
|
434
432
|
|
435
|
-
array_shape =
|
436
|
-
shape = Shape.new(type: tuple, private:
|
433
|
+
array_shape = yield(array_type) or raise
|
434
|
+
shape = Shape.new(type: tuple, private: true)
|
437
435
|
shape.methods.merge!(array_shape.methods)
|
438
436
|
|
439
437
|
aref_entry = array_shape.methods[:[]].yield_self do |aref|
|
440
438
|
raise unless aref
|
441
439
|
|
442
440
|
Shape::Entry.new(
|
441
|
+
private_method: false,
|
443
442
|
method_types: tuple.types.map.with_index {|elem_type, index|
|
444
443
|
MethodType.new(
|
445
444
|
type_params: [],
|
@@ -459,6 +458,7 @@ module Steep
|
|
459
458
|
raise unless update
|
460
459
|
|
461
460
|
Shape::Entry.new(
|
461
|
+
private_method: false,
|
462
462
|
method_types: tuple.types.map.with_index {|elem_type, index|
|
463
463
|
MethodType.new(
|
464
464
|
type_params: [],
|
@@ -478,6 +478,7 @@ module Steep
|
|
478
478
|
raise unless fetch
|
479
479
|
|
480
480
|
Shape::Entry.new(
|
481
|
+
private_method: false,
|
481
482
|
method_types: tuple.types.flat_map.with_index {|elem_type, index|
|
482
483
|
[
|
483
484
|
MethodType.new(
|
@@ -530,6 +531,7 @@ module Steep
|
|
530
531
|
|
531
532
|
first_entry = array_shape.methods[:first].yield_self do |first|
|
532
533
|
Shape::Entry.new(
|
534
|
+
private_method: false,
|
533
535
|
method_types: [
|
534
536
|
MethodType.new(
|
535
537
|
type_params: [],
|
@@ -547,6 +549,7 @@ module Steep
|
|
547
549
|
|
548
550
|
last_entry = array_shape.methods[:last].yield_self do |last|
|
549
551
|
Shape::Entry.new(
|
552
|
+
private_method: false,
|
550
553
|
method_types: [
|
551
554
|
MethodType.new(
|
552
555
|
type_params: [],
|
@@ -568,17 +571,10 @@ module Steep
|
|
568
571
|
shape.methods[:first] = first_entry
|
569
572
|
shape.methods[:last] = last_entry
|
570
573
|
|
571
|
-
shape
|
572
|
-
Substitution.build(
|
573
|
-
[], [],
|
574
|
-
self_type: config.resolve_self ? tuple : AST::Types::Self.instance,
|
575
|
-
instance_type: AST::Builtin::Array.instance_type(fill_untyped: true),
|
576
|
-
module_type: AST::Builtin::Array.module_type
|
577
|
-
)
|
578
|
-
)
|
574
|
+
shape
|
579
575
|
end
|
580
576
|
|
581
|
-
def record_shape(record
|
577
|
+
def record_shape(record)
|
582
578
|
all_key_type = AST::Types::Union.build(
|
583
579
|
types: record.elements.each_key.map {|value| AST::Types::Literal.new(value: value, location: nil) },
|
584
580
|
location: nil
|
@@ -586,13 +582,14 @@ module Steep
|
|
586
582
|
all_value_type = AST::Types::Union.build(types: record.elements.values, location: nil)
|
587
583
|
hash_type = AST::Builtin::Hash.instance_type(all_key_type, all_value_type)
|
588
584
|
|
589
|
-
hash_shape =
|
590
|
-
shape = Shape.new(type: record, private:
|
585
|
+
hash_shape = yield(hash_type) or raise
|
586
|
+
shape = Shape.new(type: record, private: true)
|
591
587
|
shape.methods.merge!(hash_shape.methods)
|
592
588
|
|
593
589
|
shape.methods[:[]] = hash_shape.methods[:[]].yield_self do |aref|
|
594
590
|
aref or raise
|
595
591
|
Shape::Entry.new(
|
592
|
+
private_method: false,
|
596
593
|
method_types: record.elements.map do |key_value, value_type|
|
597
594
|
key_type = AST::Types::Literal.new(value: key_value, location: nil)
|
598
595
|
|
@@ -614,6 +611,7 @@ module Steep
|
|
614
611
|
update or raise
|
615
612
|
|
616
613
|
Shape::Entry.new(
|
614
|
+
private_method: false,
|
617
615
|
method_types: record.elements.map do |key_value, value_type|
|
618
616
|
key_type = AST::Types::Literal.new(value: key_value, location: nil)
|
619
617
|
MethodType.new(
|
@@ -633,6 +631,7 @@ module Steep
|
|
633
631
|
update or raise
|
634
632
|
|
635
633
|
Shape::Entry.new(
|
634
|
+
private_method: false,
|
636
635
|
method_types: record.elements.flat_map {|key_value, value_type|
|
637
636
|
key_type = AST::Types::Literal.new(value: key_value, location: nil)
|
638
637
|
|
@@ -680,34 +679,19 @@ module Steep
|
|
680
679
|
)
|
681
680
|
end
|
682
681
|
|
683
|
-
shape
|
684
|
-
Substitution.build(
|
685
|
-
[], [],
|
686
|
-
self_type: config.resolve_self ? record : AST::Types::Self.instance,
|
687
|
-
instance_type: AST::Builtin::Hash.instance_type(fill_untyped: true),
|
688
|
-
module_type: AST::Builtin::Hash.module_type
|
689
|
-
)
|
690
|
-
)
|
682
|
+
shape
|
691
683
|
end
|
692
684
|
|
693
|
-
def proc_shape(proc,
|
694
|
-
|
695
|
-
|
696
|
-
shape = Shape.new(type: proc, private: !public_only)
|
685
|
+
def proc_shape(proc, proc_shape)
|
686
|
+
shape = Shape.new(type: proc, private: true)
|
697
687
|
shape.methods.merge!(proc_shape.methods)
|
698
688
|
|
699
689
|
shape.methods[:[]] = shape.methods[:call] = Shape::Entry.new(
|
690
|
+
private_method: false,
|
700
691
|
method_types: [MethodType.new(type_params: [], type: proc.type, block: proc.block, method_decls: Set[])]
|
701
692
|
)
|
702
693
|
|
703
|
-
shape
|
704
|
-
Substitution.build(
|
705
|
-
[], [],
|
706
|
-
self_type: config.resolve_self ? proc : AST::Types::Self.instance,
|
707
|
-
instance_type: AST::Builtin::Proc.instance_type(fill_untyped: true),
|
708
|
-
module_type: AST::Builtin::Proc.module_type
|
709
|
-
)
|
710
|
-
)
|
694
|
+
shape
|
711
695
|
end
|
712
696
|
|
713
697
|
def replace_primitive_method(method_name, method_def, method_type)
|