Skip to content

Commit

Permalink
Clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
camertron committed Jul 21, 2023
1 parent ecffaab commit 314f75d
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 68 deletions.
6 changes: 2 additions & 4 deletions lib/view_component/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,16 +130,14 @@ def render_parent
@__vc_parent_render_level ||= 0 # ensure a good starting value

begin
target_render = self.class.instance_variable_get(:@__vc_ancestor_calls).reverse[@__vc_parent_render_level]
target_render = self.class.instance_variable_get(:@__vc_ancestor_calls)[@__vc_parent_render_level]
@__vc_parent_render_level += 1

target_render.bind_call(self, @__vc_variant)
nil
ensure
@__vc_parent_render_level -= 1
end

# @__vc_parent_call_block&.call
end

# Optional content to be returned after the rendered template.
Expand Down Expand Up @@ -474,7 +472,7 @@ def render_template_for(variant = nil)
if instance_methods(false).include?(:render_template_for)
__vc_ancestor_calls = defined?(@__vc_ancestor_calls) ? @__vc_ancestor_calls.dup : []

__vc_ancestor_calls.push(instance_method(:render_template_for))
__vc_ancestor_calls.unshift(instance_method(:render_template_for))
child.instance_variable_set(:@__vc_ancestor_calls, __vc_ancestor_calls)
end

Expand Down
83 changes: 20 additions & 63 deletions lib/view_component/compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,22 @@ def compile(raise_errors: false, force: false)
if has_inline_template?
template = component_class.inline_template

template_info = {
path: template.path,
lineno: template.lineno - 4,
body: compiled_inline_template(template)
}
redefinition_lock.synchronize do
component_class.silence_redefinition_of_method("call")
# rubocop:disable Style/EvalWithLocation
component_class.class_eval <<-RUBY, template.path, template.lineno
def call
#{compiled_inline_template(template)}
end
RUBY
# rubocop:enable Style/EvalWithLocation

define_compiled_template_methods("call", template_info)
component_class.define_method("_call_#{safe_class_name}", component_class.instance_method(:call))

redefinition_lock.synchronize do
component_class.silence_redefinition_of_method("render_template_for")
component_class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def render_template_for(variant = nil)
call
_call_#{safe_class_name}
end
RUBY
end
Expand All @@ -76,8 +79,6 @@ def #{method_name}
RUBY
# rubocop:enable Style/EvalWithLocation
end

# define_compiled_template_methods(method_name, template_info)
end

define_render_template_for
Expand All @@ -92,70 +93,22 @@ def #{method_name}

attr_reader :component_class, :redefinition_lock

def define_compiled_template_methods(method_name, template_info)
unique_method_name = "#{method_name}__#{methodize(component_class.name)}"
unique_superclass_name = methodize(component_class.superclass.name)

redefinition_lock.synchronize do
# Remove existing compiled template methods,
# as Ruby warns when redefining a method.
component_class.silence_redefinition_of_method(method_name)
component_class.silence_redefinition_of_method(unique_method_name)

# rubocop:disable Style/EvalWithLocation
component_class.class_eval <<-RUBY, template_info[:path], template_info[:lineno]
private def #{unique_method_name}(&block)
if block
@__vc_parent_call_block = block
begin
#{template_info[:body]}
end.tap do
@__vc_parent_call_block = nil
end
else
#{unique_method_name} do
super_method_name = if @__vc_variant
super_variant_method_name = :"call_\#{@__vc_variant}__#{unique_superclass_name}"
respond_to?(super_variant_method_name, true) ? super_variant_method_name : nil
end
super_method_name ||= :call__#{unique_superclass_name}
send(super_method_name)
nil
end
end
end
def #{method_name}
#{unique_method_name}
end
RUBY
# rubocop:enable Style/EvalWithLocation
end
end

def methodize(str)
str.gsub("::", "_").underscore
end

def define_render_template_for
variant_elsifs = variants.compact.uniq.map do |variant|
safe_name = "_call_variant_#{normalized_variant_name(variant)}_#{component_class.name.underscore}"
component_class.define_method("_call_variant_#{normalized_variant_name(variant)}_#{component_class.name.underscore}", component_class.instance_method(call_method_name(variant)))
safe_name = "_call_variant_#{normalized_variant_name(variant)}_#{safe_class_name}"
component_class.define_method(safe_name, component_class.instance_method(call_method_name(variant)))

"elsif variant.to_sym == :'#{variant}'\n #{safe_name}"
end.join("\n")

component_class.define_method("_call_#{component_class.name.underscore.gsub("/", "__")}", component_class.instance_method(:call))
component_class.define_method("_call_#{safe_class_name}", component_class.instance_method(:call))

body = <<-RUBY
if variant.nil?
_call_#{component_class.name.underscore.gsub("/", "__")}
_call_#{safe_class_name}
#{variant_elsifs}
else
_call_#{component_class.name.underscore.gsub("/", "__")}
_call_#{safe_class_name}
end
RUBY

Expand Down Expand Up @@ -328,6 +281,10 @@ def normalized_variant_name(variant)
variant.to_s.gsub("-", "__").gsub(".", "___")
end

def safe_class_name
@safe_class_name ||= component_class.name.gsub("::", "_").underscore
end

def should_compile_superclass?
development? && templates.empty? && !has_inline_template? && !call_defined?
end
Expand Down
2 changes: 1 addition & 1 deletion test/sandbox/test/inline_template_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class InlineErbSubclassComponent < InlineErbComponent
erb_template <<~ERB
<h1>Hey, <%= name %>!</h1>
<div class="parent">
<%= yield :parent %>
<%= render_parent %>
</div>
ERB
end
Expand Down

0 comments on commit 314f75d

Please sign in to comment.