tapioca 0.4.17 → 0.4.22

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.
@@ -0,0 +1,106 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Tapioca
5
+ module RBI
6
+ module Rewriters
7
+ class GroupNodes < Visitor
8
+ extend T::Sig
9
+
10
+ sig { override.params(node: T.nilable(Node)).void }
11
+ def visit(node)
12
+ return unless node
13
+
14
+ case node
15
+ when Tree
16
+ kinds = node.nodes.map(&:group_kind)
17
+ kinds.compact!
18
+ kinds.uniq!
19
+
20
+ groups = {}
21
+ kinds.each { |kind| groups[kind] = Group.new(kind) }
22
+
23
+ node.nodes.dup.each do |child|
24
+ visit(child)
25
+ child.detach
26
+ groups[child.group_kind] << child
27
+ end
28
+
29
+ groups.each { |_, group| node << group }
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ class Tree
36
+ extend T::Sig
37
+
38
+ sig { void }
39
+ def group_nodes!
40
+ visitor = Rewriters::GroupNodes.new
41
+ visitor.visit(self)
42
+ end
43
+ end
44
+
45
+ class Node
46
+ extend T::Sig
47
+
48
+ sig { returns(Group::Kind) }
49
+ def group_kind
50
+ case self
51
+ when Include, Extend
52
+ Group::Kind::Mixins
53
+ when Helper
54
+ Group::Kind::Helpers
55
+ when TypeMember
56
+ Group::Kind::TypeMembers
57
+ when MixesInClassMethods
58
+ Group::Kind::MixesInClassMethods
59
+ when TStructField
60
+ Group::Kind::TStructFields
61
+ when TEnumBlock
62
+ Group::Kind::TEnums
63
+ when VisibilityGroup
64
+ Group::Kind::Methods
65
+ when Method
66
+ if name == "initialize"
67
+ Group::Kind::Inits
68
+ else
69
+ Group::Kind::Methods
70
+ end
71
+ when Scope, Const
72
+ Group::Kind::Consts
73
+ else
74
+ raise "Unknown group for #{self}"
75
+ end
76
+ end
77
+ end
78
+
79
+ class Group < Tree
80
+ extend T::Sig
81
+
82
+ sig { returns(Kind) }
83
+ attr_reader :kind
84
+
85
+ sig { params(kind: Kind).void }
86
+ def initialize(kind)
87
+ super()
88
+ @kind = kind
89
+ end
90
+
91
+ class Kind < T::Enum
92
+ enums do
93
+ Mixins = new
94
+ Helpers = new
95
+ TypeMembers = new
96
+ MixesInClassMethods = new
97
+ TStructFields = new
98
+ TEnums = new
99
+ Inits = new
100
+ Methods = new
101
+ Consts = new
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,65 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Tapioca
5
+ module RBI
6
+ module Rewriters
7
+ class NestNonPublicMethods < Visitor
8
+ extend T::Sig
9
+
10
+ sig { override.params(node: T.nilable(Node)).void }
11
+ def visit(node)
12
+ return unless node
13
+
14
+ case node
15
+ when Tree
16
+ public_group = VisibilityGroup.new(Visibility::Public)
17
+ protected_group = VisibilityGroup.new(Visibility::Protected)
18
+ private_group = VisibilityGroup.new(Visibility::Private)
19
+
20
+ node.nodes.dup.each do |child|
21
+ visit(child)
22
+ next unless child.is_a?(Method)
23
+ child.detach
24
+ case child.visibility
25
+ when Visibility::Protected
26
+ protected_group << child
27
+ when Visibility::Private
28
+ private_group << child
29
+ else
30
+ public_group << child
31
+ end
32
+ end
33
+
34
+ node << public_group unless public_group.empty?
35
+ node << protected_group unless protected_group.empty?
36
+ node << private_group unless private_group.empty?
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ class Tree
43
+ extend T::Sig
44
+
45
+ sig { void }
46
+ def nest_non_public_methods!
47
+ visitor = Rewriters::NestNonPublicMethods.new
48
+ visitor.visit(self)
49
+ end
50
+ end
51
+
52
+ class VisibilityGroup < Tree
53
+ extend T::Sig
54
+
55
+ sig { returns(Visibility) }
56
+ attr_reader :visibility
57
+
58
+ sig { params(visibility: Visibility).void }
59
+ def initialize(visibility)
60
+ super()
61
+ @visibility = visibility
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,42 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Tapioca
5
+ module RBI
6
+ module Rewriters
7
+ class NestSingletonMethods < Visitor
8
+ extend T::Sig
9
+
10
+ sig { override.params(node: T.nilable(Node)).void }
11
+ def visit(node)
12
+ return unless node
13
+
14
+ case node
15
+ when Tree
16
+ singleton_class = SingletonClass.new
17
+
18
+ node.nodes.dup.each do |child|
19
+ visit(child)
20
+ next unless child.is_a?(Method) && child.is_singleton
21
+ child.detach
22
+ child.is_singleton = false
23
+ singleton_class << child
24
+ end
25
+
26
+ node << singleton_class unless singleton_class.empty?
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ class Tree
33
+ extend T::Sig
34
+
35
+ sig { void }
36
+ def nest_singleton_methods!
37
+ visitor = Rewriters::NestSingletonMethods.new
38
+ visitor.visit(self)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,82 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Tapioca
5
+ module RBI
6
+ module Rewriters
7
+ class SortNodes < Visitor
8
+ extend T::Sig
9
+
10
+ sig { override.params(node: T.nilable(Node)).void }
11
+ def visit(node)
12
+ return unless node.is_a?(Tree)
13
+ visit_all(node.nodes)
14
+ node.nodes.sort! do |a, b|
15
+ res = node_rank(a) <=> node_rank(b)
16
+ res = node_name(a) <=> node_name(b) if res == 0
17
+ res || 0
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ sig { params(node: Node).returns(Integer) }
24
+ def node_rank(node)
25
+ case node
26
+ when Group then kind_rank(node.kind)
27
+ when Include, Extend then 0
28
+ when Helper then 1
29
+ when TypeMember then 2
30
+ when MixesInClassMethods then 3
31
+ when TStructField then 4
32
+ when TEnumBlock then 5
33
+ when Method
34
+ if node.name == "initialize"
35
+ 7
36
+ else
37
+ 8
38
+ end
39
+ when Scope, Const then 9
40
+ else
41
+ 10
42
+ end
43
+ end
44
+
45
+ sig { params(kind: Group::Kind).returns(Integer) }
46
+ def kind_rank(kind)
47
+ case kind
48
+ when Group::Kind::Mixins then 0
49
+ when Group::Kind::Helpers then 1
50
+ when Group::Kind::TypeMembers then 2
51
+ when Group::Kind::MixesInClassMethods then 3
52
+ when Group::Kind::TStructFields then 4
53
+ when Group::Kind::TEnums then 5
54
+ when Group::Kind::Inits then 6
55
+ when Group::Kind::Methods then 7
56
+ when Group::Kind::Consts then 8
57
+ else
58
+ T.absurd(kind)
59
+ end
60
+ end
61
+
62
+ sig { params(node: Node).returns(T.nilable(String)) }
63
+ def node_name(node)
64
+ case node
65
+ when Module, Class, Const, Method, Helper, TStructField
66
+ node.name
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ class Tree
73
+ extend T::Sig
74
+
75
+ sig { void }
76
+ def sort_nodes!
77
+ visitor = Rewriters::SortNodes.new
78
+ visitor.visit(self)
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,21 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Tapioca
5
+ module RBI
6
+ class Visitor
7
+ extend T::Helpers
8
+ extend T::Sig
9
+
10
+ abstract!
11
+
12
+ sig { abstract.params(node: T.nilable(Node)).void }
13
+ def visit(node); end
14
+
15
+ sig { params(nodes: T::Array[Node]).void }
16
+ def visit_all(nodes)
17
+ nodes.each { |node| visit(node) }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,66 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ require "tapioca/sorbet_ext/name_patch"
5
+
6
+ module T
7
+ module Generic
8
+ # This module intercepts calls to generic type instantiations and type variable definitions.
9
+ # Tapioca stores the data from those calls in a `GenericTypeRegistry` which can then be used
10
+ # to look up the original call details when we are trying to do code generation.
11
+ #
12
+ # We are interested in the data of the `[]`, `type_member` and `type_template` calls which
13
+ # are all needed to generate good generic information at runtime.
14
+ module TypeStoragePatch
15
+ def [](*types)
16
+ # `T::Generic#[]` just returns `self`, so let's call and store it.
17
+ constant = super
18
+ # `register_type` method builds and returns an instantiated clone of the generic type
19
+ # so, we just return that from this method as well.
20
+ Tapioca::GenericTypeRegistry.register_type(constant, types)
21
+ end
22
+
23
+ def type_member(variance = :invariant, fixed: nil, lower: T.untyped, upper: BasicObject)
24
+ # `T::Generic#type_member` just instantiates a `T::Type::TypeMember` instance and returns it.
25
+ # We use that when registering the type member and then later return it from this method.
26
+ type_member = super
27
+ Tapioca::GenericTypeRegistry.register_type_member(self, type_member, fixed, lower, upper)
28
+ type_member
29
+ end
30
+
31
+ def type_template(variance = :invariant, fixed: nil, lower: T.untyped, upper: BasicObject)
32
+ # `T::Generic#type_template` just instantiates a `T::Type::TypeTemplate` instance and returns it.
33
+ # We use that when registering the type template and then later return it from this method.
34
+ type_template = super
35
+ Tapioca::GenericTypeRegistry.register_type_template(self, type_template, fixed, lower, upper)
36
+ type_template
37
+ end
38
+ end
39
+
40
+ prepend TypeStoragePatch
41
+ end
42
+
43
+ module Types
44
+ class Simple
45
+ # This module intercepts calls to the `name` method for
46
+ # simple types, so that it can ask the name to the type if
47
+ # the type is generic, since, by this point, we've created
48
+ # a clone of that type with the `name` method returning the
49
+ # appropriate name for that specific concrete type.
50
+ module GenericNamePatch
51
+ def name
52
+ if T::Generic === @raw_type
53
+ # for types that are generic, use the name
54
+ # returned by the "name" method of this instance
55
+ @name ||= T.unsafe(@raw_type).name.freeze
56
+ else
57
+ # otherwise, fallback to the normal name lookup
58
+ super
59
+ end
60
+ end
61
+ end
62
+
63
+ prepend GenericNamePatch
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,16 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module T
5
+ module Types
6
+ class Simple
7
+ module NamePatch
8
+ def name
9
+ @name ||= Module.instance_method(:name).bind(@raw_type).call.freeze
10
+ end
11
+ end
12
+
13
+ prepend NamePatch
14
+ end
15
+ end
16
+ end
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Tapioca
5
- VERSION = "0.4.17"
5
+ VERSION = "0.4.22"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tapioca
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.17
4
+ version: 0.4.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ufuk Kayserilioglu
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: exe
13
13
  cert_chain: []
14
- date: 2021-03-11 00:00:00.000000000 Z
14
+ date: 2021-05-19 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -125,8 +125,10 @@ files:
125
125
  - exe/tapioca
126
126
  - lib/tapioca.rb
127
127
  - lib/tapioca/cli.rb
128
+ - lib/tapioca/cli/main.rb
128
129
  - lib/tapioca/compilers/dsl/action_controller_helpers.rb
129
130
  - lib/tapioca/compilers/dsl/action_mailer.rb
131
+ - lib/tapioca/compilers/dsl/active_job.rb
130
132
  - lib/tapioca/compilers/dsl/active_record_associations.rb
131
133
  - lib/tapioca/compilers/dsl/active_record_columns.rb
132
134
  - lib/tapioca/compilers/dsl/active_record_enum.rb
@@ -153,9 +155,21 @@ files:
153
155
  - lib/tapioca/config_builder.rb
154
156
  - lib/tapioca/constant_locator.rb
155
157
  - lib/tapioca/core_ext/class.rb
158
+ - lib/tapioca/core_ext/string.rb
156
159
  - lib/tapioca/gemfile.rb
157
160
  - lib/tapioca/generator.rb
161
+ - lib/tapioca/generic_type_registry.rb
162
+ - lib/tapioca/internal.rb
158
163
  - lib/tapioca/loader.rb
164
+ - lib/tapioca/rbi/model.rb
165
+ - lib/tapioca/rbi/printer.rb
166
+ - lib/tapioca/rbi/rewriters/group_nodes.rb
167
+ - lib/tapioca/rbi/rewriters/nest_non_public_methods.rb
168
+ - lib/tapioca/rbi/rewriters/nest_singleton_methods.rb
169
+ - lib/tapioca/rbi/rewriters/sort_nodes.rb
170
+ - lib/tapioca/rbi/visitor.rb
171
+ - lib/tapioca/sorbet_ext/generic_name_patch.rb
172
+ - lib/tapioca/sorbet_ext/name_patch.rb
159
173
  - lib/tapioca/version.rb
160
174
  homepage: https://github.com/Shopify/tapioca
161
175
  licenses:
@@ -177,7 +191,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
177
191
  - !ruby/object:Gem::Version
178
192
  version: '0'
179
193
  requirements: []
180
- rubygems_version: 3.0.3
194
+ rubygems_version: 3.2.17
181
195
  signing_key:
182
196
  specification_version: 4
183
197
  summary: A Ruby Interface file generator for gems, core types and the Ruby standard