Skip to content

Commit

Permalink
Merge pull request #654 from Shopify/uk-rename-group-trackers
Browse files Browse the repository at this point in the history
  • Loading branch information
paracycle committed Dec 7, 2021
2 parents 2290b5b + 89e1f34 commit b1985b0
Show file tree
Hide file tree
Showing 12 changed files with 219 additions and 190 deletions.
4 changes: 1 addition & 3 deletions lib/tapioca.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ class Error < StandardError; end
end

require "tapioca/reflection"
require "tapioca/autoload_tracker"
require "tapioca/constant_locator"
require "tapioca/mixin_tracker"
require "tapioca/trackers"
require "tapioca/compilers/dsl/base"
require "tapioca/compilers/dynamic_mixin_compiler"
require "tapioca/helpers/active_record_column_type_helper"
Expand Down
68 changes: 0 additions & 68 deletions lib/tapioca/autoload_tracker.rb

This file was deleted.

23 changes: 11 additions & 12 deletions lib/tapioca/compilers/symbol_table/symbol_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
# frozen_string_literal: true

require "pathname"
require "tapioca/helpers/mixin_type"

module Tapioca
module Compilers
Expand Down Expand Up @@ -376,19 +375,19 @@ def compile_mixins(tree, constant)
Module != class_of(mod) || are_equal?(mod, singleton_class)
end

mixin_locations = MixinTracker.mixin_locations_for(constant)
mixin_locations = Trackers::Mixin.mixin_locations_for(constant)

add_mixins(tree, prepends.reverse, MixinType::Prepend, mixin_locations)
add_mixins(tree, includes.reverse, MixinType::Include, mixin_locations)
add_mixins(tree, extends.reverse, MixinType::Extend, mixin_locations)
add_mixins(tree, prepends.reverse, Trackers::Mixin::Type::Prepend, mixin_locations)
add_mixins(tree, includes.reverse, Trackers::Mixin::Type::Include, mixin_locations)
add_mixins(tree, extends.reverse, Trackers::Mixin::Type::Extend, mixin_locations)
end

sig do
params(
tree: RBI::Tree,
mods: T::Array[Module],
mixin_type: MixinType,
mixin_locations: T::Hash[MixinType, T::Hash[Module, T::Array[String]]]
mixin_type: Trackers::Mixin::Type,
mixin_locations: T::Hash[Trackers::Mixin::Type, T::Hash[Module, T::Array[String]]]
).void
end
def add_mixins(tree, mods, mixin_type, mixin_locations)
Expand All @@ -408,9 +407,9 @@ def add_mixins(tree, mods, mixin_type, mixin_locations)
# TODO: Sorbet currently does not handle prepend
# properly for method resolution, so we generate an
# include statement instead
when MixinType::Include, MixinType::Prepend
when Trackers::Mixin::Type::Include, Trackers::Mixin::Type::Prepend
tree << RBI::Include.new(T.must(qname))
when MixinType::Extend
when Trackers::Mixin::Type::Extend
tree << RBI::Extend.new(T.must(qname))
end
end
Expand Down Expand Up @@ -641,7 +640,7 @@ def method_in_gem?(method)
sig { params(constant: Module, strict: T::Boolean).returns(T::Boolean) }
def defined_in_gem?(constant, strict: true)
files = Set.new(get_file_candidates(constant))
.merge(Tapioca::ConstantLocator.files_for(constant))
.merge(Tapioca::Trackers::ConstantDefinition.files_for(constant))

return !strict if files.empty?

Expand All @@ -653,8 +652,8 @@ def defined_in_gem?(constant, strict: true)
sig do
params(
mod: Module,
mixin_type: MixinType,
mixin_locations: T::Hash[MixinType, T::Hash[Module, T::Array[String]]]
mixin_type: Trackers::Mixin::Type,
mixin_locations: T::Hash[Trackers::Mixin::Type, T::Hash[Module, T::Array[String]]]
).returns(T::Boolean)
end
def mixed_in_by_gem?(mod, mixin_type, mixin_locations)
Expand Down
40 changes: 0 additions & 40 deletions lib/tapioca/constant_locator.rb

This file was deleted.

2 changes: 1 addition & 1 deletion lib/tapioca/generators/gem.rb
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def require_gem_file
exit(1)
end

Tapioca::AutoloadTracker.eager_load_all!
Tapioca::Trackers::Autoload.eager_load_all!

say(" Done", :green)
unless bundle.missing_specs.empty?
Expand Down
12 changes: 0 additions & 12 deletions lib/tapioca/helpers/mixin_type.rb

This file was deleted.

50 changes: 0 additions & 50 deletions lib/tapioca/mixin_tracker.rb

This file was deleted.

14 changes: 14 additions & 0 deletions lib/tapioca/trackers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# typed: strict
# frozen_string_literal: true

# The load order below is important:
# ----------------------------------
# We want the mixin tracker to be the first thing that is
# loaded because other trackers might apply their own mixins
# into core types (like `Module` and `Kernel`). In order to
# catch and filter those mixins as coming from Tapioca, we need
# the mixin tracker to be in place, before any mixin operations
# are performed.
require "tapioca/trackers/mixin"
require "tapioca/trackers/constant_definition"
require "tapioca/trackers/autoload"
70 changes: 70 additions & 0 deletions lib/tapioca/trackers/autoload.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# typed: true
# frozen_string_literal: true

module Tapioca
module Trackers
module Autoload
extend T::Sig

NOOP_METHOD = -> (*_args, **_kwargs, &_block) {}

@constant_names_registered_for_autoload = T.let([], T::Array[String])

class << self
extend T::Sig

sig { void }
def eager_load_all!
with_disabled_exits do
until @constant_names_registered_for_autoload.empty?
# Grab the next constant name
constant_name = T.must(@constant_names_registered_for_autoload.shift)
# Trigger autoload by constantizing the registered name
Reflection.constantize(constant_name, inherit: true)
end
end
end

sig { params(constant_name: String).void }
def register(constant_name)
@constant_names_registered_for_autoload << constant_name
end

sig do
type_parameters(:Result)
.params(block: T.proc.returns(T.type_parameter(:Result)))
.returns(T.type_parameter(:Result))
end
def with_disabled_exits(&block)
original_abort = Kernel.instance_method(:abort)
original_exit = Kernel.instance_method(:exit)

begin
Kernel.define_method(:abort, NOOP_METHOD)
Kernel.define_method(:exit, NOOP_METHOD)

block.call
ensure
Kernel.define_method(:exit, original_exit)
Kernel.define_method(:abort, original_abort)
end
end
end
end
end
end

# We need to do the alias-method-chain dance since Bootsnap does the same,
# and prepended modules and alias-method-chain don't play well together.
#
# So, why does Bootsnap do alias-method-chain and not prepend? Glad you asked!
# That's because RubyGems does alias-method-chain for Kernel#require and such,
# so, if Bootsnap were to do prepend, it might end up breaking RubyGems.
class Module
alias_method(:autoload_without_tapioca, :autoload)

def autoload(const_name, path)
Tapioca::Trackers::Autoload.register("#{self}::#{const_name}")
autoload_without_tapioca(const_name, path)
end
end
42 changes: 42 additions & 0 deletions lib/tapioca/trackers/constant_definition.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# typed: true
# frozen_string_literal: true

require "set"

module Tapioca
module Trackers
# Registers a TracePoint immediately upon load to track points at which
# classes and modules are opened for definition. This is used to track
# correspondence between classes/modules and files, as this information isn't
# available in the ruby runtime without extra accounting.
module ConstantDefinition
extend Reflection

@class_files = {}

# Immediately activated upon load. Observes class/module definition.
TracePoint.trace(:class) do |tp|
unless tp.self.singleton_class?
key = name_of(tp.self)
file = tp.path
if file == "(eval)"
file = T.must(caller_locations)
.drop_while { |loc| loc.path == "(eval)" }
.first&.path
end
@class_files[key] ||= Set.new
@class_files[key] << file
end
end

# Returns the files in which this class or module was opened. Doesn't know
# about situations where the class was opened prior to +require+ing,
# or where metaprogramming was used via +eval+, etc.
def self.files_for(klass)
name = String === klass ? klass : name_of(klass)
files = @class_files[name]
files || Set.new
end
end
end
end

0 comments on commit b1985b0

Please sign in to comment.