tapioca 0.8.3 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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