tapioca 0.8.3 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -2
  3. data/README.md +182 -36
  4. data/lib/tapioca/cli.rb +122 -65
  5. data/lib/tapioca/commands/annotations.rb +165 -33
  6. data/lib/tapioca/commands/check_shims.rb +91 -0
  7. data/lib/tapioca/commands/{init.rb → configure.rb} +1 -1
  8. data/lib/tapioca/commands/dsl.rb +1 -1
  9. data/lib/tapioca/commands/gem.rb +5 -5
  10. data/lib/tapioca/commands.rb +2 -1
  11. data/lib/tapioca/dsl/compiler.rb +1 -13
  12. data/lib/tapioca/dsl/compilers/active_model_attributes.rb +1 -1
  13. data/lib/tapioca/dsl/compilers/active_record_relations.rb +17 -0
  14. data/lib/tapioca/dsl/compilers/active_record_typed_store.rb +5 -4
  15. data/lib/tapioca/dsl/compilers/protobuf.rb +6 -0
  16. data/lib/tapioca/dsl/compilers.rb +0 -4
  17. data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +2 -2
  18. data/lib/tapioca/dsl/pipeline.rb +0 -2
  19. data/lib/tapioca/dsl.rb +8 -0
  20. data/lib/tapioca/executor.rb +0 -3
  21. data/lib/tapioca/gem/events.rb +16 -2
  22. data/lib/tapioca/gem/listeners/base.rb +11 -0
  23. data/lib/tapioca/gem/listeners/dynamic_mixins.rb +5 -0
  24. data/lib/tapioca/gem/listeners/foreign_constants.rb +65 -0
  25. data/lib/tapioca/gem/listeners/methods.rb +6 -17
  26. data/lib/tapioca/gem/listeners/mixins.rb +31 -10
  27. data/lib/tapioca/gem/listeners/remove_empty_payload_scopes.rb +5 -0
  28. data/lib/tapioca/gem/listeners/sorbet_enums.rb +5 -0
  29. data/lib/tapioca/gem/listeners/sorbet_helpers.rb +5 -0
  30. data/lib/tapioca/gem/listeners/sorbet_props.rb +5 -0
  31. data/lib/tapioca/gem/listeners/sorbet_required_ancestors.rb +5 -0
  32. data/lib/tapioca/gem/listeners/sorbet_signatures.rb +6 -1
  33. data/lib/tapioca/gem/listeners/sorbet_type_variables.rb +5 -0
  34. data/lib/tapioca/gem/listeners/subconstants.rb +5 -0
  35. data/lib/tapioca/gem/listeners/yard_doc.rb +5 -0
  36. data/lib/tapioca/gem/listeners.rb +1 -0
  37. data/lib/tapioca/gem/pipeline.rb +58 -15
  38. data/lib/tapioca/gem.rb +6 -0
  39. data/lib/tapioca/gemfile.rb +7 -6
  40. data/lib/tapioca/helpers/cli_helper.rb +8 -2
  41. data/lib/tapioca/helpers/config_helper.rb +0 -2
  42. data/lib/tapioca/helpers/env_helper.rb +16 -0
  43. data/lib/tapioca/helpers/rbi_files_helper.rb +252 -0
  44. data/lib/tapioca/helpers/rbi_helper.rb +74 -94
  45. data/lib/tapioca/helpers/sorbet_helper.rb +2 -3
  46. data/lib/tapioca/helpers/test/content.rb +0 -2
  47. data/lib/tapioca/helpers/test/template.rb +0 -2
  48. data/lib/tapioca/internal.rb +34 -12
  49. data/lib/tapioca/rbi_ext/model.rb +2 -15
  50. data/lib/tapioca/runtime/dynamic_mixin_compiler.rb +18 -16
  51. data/lib/tapioca/runtime/reflection.rb +27 -0
  52. data/lib/tapioca/runtime/trackers/constant_definition.rb +17 -7
  53. data/lib/tapioca/runtime/trackers/mixin.rb +49 -14
  54. data/lib/tapioca/sorbet_ext/generic_name_patch.rb +1 -4
  55. data/lib/tapioca/static/requires_compiler.rb +0 -2
  56. data/lib/tapioca/static/symbol_loader.rb +26 -30
  57. data/lib/tapioca/static/symbol_table_parser.rb +0 -3
  58. data/lib/tapioca/version.rb +1 -1
  59. data/lib/tapioca.rb +3 -0
  60. metadata +22 -7
  61. data/lib/tapioca/dsl/helpers/param_helper.rb +0 -55
  62. data/lib/tapioca/helpers/shims_helper.rb +0 -115
  63. data/lib/tapioca/helpers/signatures_helper.rb +0 -17
  64. data/lib/tapioca/helpers/type_variable_helper.rb +0 -43
@@ -1,115 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- module Tapioca
5
- module ShimsHelper
6
- extend T::Sig
7
- extend T::Helpers
8
-
9
- requires_ancestor { Thor::Shell }
10
-
11
- SORBET_PAYLOAD_URL = "https://github.com/sorbet/sorbet/tree/master/rbi"
12
-
13
- sig { params(index: RBI::Index, dir: String).void }
14
- def index_payload(index, dir)
15
- return unless Dir.exist?(dir)
16
-
17
- say("Loading Sorbet payload... ")
18
- files = Dir.glob("#{dir}/**/*.rbi").sort
19
- parse_and_index_files(index, files)
20
- say(" Done", :green)
21
- end
22
-
23
- sig { params(index: RBI::Index, kind: String, dir: String).void }
24
- def index_rbis(index, kind, dir)
25
- return unless Dir.exist?(dir) && !Dir.empty?(dir)
26
-
27
- say("Loading #{kind} RBIs from #{dir}... ")
28
- files = Dir.glob("#{dir}/**/*.rbi").sort
29
- parse_and_index_files(index, files)
30
- say(" Done", :green)
31
- end
32
-
33
- sig { params(index: RBI::Index, shim_rbi_dir: String).returns(T::Hash[String, T::Array[RBI::Node]]) }
34
- def duplicated_nodes_from_index(index, shim_rbi_dir)
35
- duplicates = {}
36
- say("Looking for duplicates... ")
37
- index.keys.each do |key|
38
- nodes = index[key]
39
- next unless shims_have_duplicates?(nodes, shim_rbi_dir)
40
-
41
- duplicates[key] = nodes
42
- end
43
- say(" Done", :green)
44
- duplicates
45
- end
46
-
47
- sig { params(loc: RBI::Loc, path_prefix: T.nilable(String)).returns(String) }
48
- def location_to_payload_url(loc, path_prefix:)
49
- return loc.to_s unless path_prefix
50
-
51
- url = loc.file || ""
52
- return loc.to_s unless url.start_with?(path_prefix)
53
-
54
- url = url.sub(path_prefix, SORBET_PAYLOAD_URL)
55
- url = "#{url}#L#{loc.begin_line}"
56
- url
57
- end
58
-
59
- private
60
-
61
- sig { params(index: RBI::Index, files: T::Array[String]).void }
62
- def parse_and_index_files(index, files)
63
- trees = files.map do |file|
64
- RBI::Parser.parse_file(file)
65
- rescue RBI::ParseError => e
66
- say_error("\nWarning: #{e} (#{e.location})", :yellow)
67
- end.compact
68
- index.visit_all(trees)
69
- end
70
-
71
- sig { params(nodes: T::Array[RBI::Node], shim_rbi_dir: String).returns(T::Boolean) }
72
- def shims_have_duplicates?(nodes, shim_rbi_dir)
73
- return false if nodes.size == 1
74
-
75
- shims = extract_shims(nodes, shim_rbi_dir)
76
- return false if shims.empty?
77
-
78
- props = extract_methods_and_attrs(shims)
79
- return false if props.empty?
80
-
81
- shims_with_sigs = extract_nodes_with_sigs(props)
82
- shims_with_sigs.each do |shim|
83
- shim_sigs = shim.sigs
84
-
85
- extract_methods_and_attrs(nodes).each do |node|
86
- next if node == shim
87
- return true if shim_sigs.all? { |sig| node.sigs.include?(sig) }
88
- end
89
-
90
- return false
91
- end
92
-
93
- true
94
- end
95
-
96
- sig { params(nodes: T::Array[RBI::Node], shim_rbi_dir: String).returns(T::Array[RBI::Node]) }
97
- def extract_shims(nodes, shim_rbi_dir)
98
- nodes.select do |node|
99
- node.loc&.file&.start_with?(shim_rbi_dir)
100
- end
101
- end
102
-
103
- sig { params(nodes: T::Array[RBI::Node]).returns(T::Array[T.any(RBI::Method, RBI::Attr)]) }
104
- def extract_methods_and_attrs(nodes)
105
- T.cast(nodes.select do |node|
106
- node.is_a?(RBI::Method) || node.is_a?(RBI::Attr)
107
- end, T::Array[T.any(RBI::Method, RBI::Attr)])
108
- end
109
-
110
- sig { params(nodes: T::Array[T.any(RBI::Method, RBI::Attr)]).returns(T::Array[T.any(RBI::Method, RBI::Attr)]) }
111
- def extract_nodes_with_sigs(nodes)
112
- nodes.reject { |node| node.sigs.empty? }
113
- end
114
- end
115
- end
@@ -1,17 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- module Tapioca
5
- module SignaturesHelper
6
- extend T::Sig
7
-
8
- sig { params(sig_string: String).returns(String) }
9
- def sanitize_signature_types(sig_string)
10
- sig_string
11
- .gsub(".returns(<VOID>)", ".void")
12
- .gsub("<VOID>", "void")
13
- .gsub("<NOT-TYPED>", "T.untyped")
14
- .gsub(".params()", "")
15
- end
16
- end
17
- end
@@ -1,43 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- module Tapioca
5
- module TypeVariableHelper
6
- extend T::Sig
7
- extend SorbetHelper
8
-
9
- sig do
10
- params(
11
- type: String,
12
- variance: Symbol,
13
- fixed: T.nilable(String),
14
- upper: T.nilable(String),
15
- lower: T.nilable(String)
16
- ).returns(String)
17
- end
18
- def self.serialize_type_variable(type, variance, fixed, upper, lower)
19
- variance = nil if variance == :invariant
20
-
21
- bounds = []
22
- bounds << "fixed: #{fixed}" if fixed
23
- bounds << "lower: #{lower}" if lower
24
- bounds << "upper: #{upper}" if upper
25
-
26
- parameters = []
27
- block = []
28
-
29
- parameters << ":#{variance}" if variance
30
-
31
- if sorbet_supports?(:type_variable_block_syntax)
32
- block = bounds
33
- else
34
- parameters.concat(bounds)
35
- end
36
-
37
- serialized = type.dup
38
- serialized << "(#{parameters.join(", ")})" unless parameters.empty?
39
- serialized << " { { #{block.join(", ")} } }" unless block.empty?
40
- serialized
41
- end
42
- end
43
- end