Skip to content

Commit df8a3c3

Browse files
committed
Compactor
1 parent 2d0dc2f commit df8a3c3

File tree

2 files changed

+91
-56
lines changed

2 files changed

+91
-56
lines changed

lib/phlex/compiler/compactor.rb

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# frozen_string_literal: true
2+
3+
class Phlex::Compiler::Compactor < Refract::MutationVisitor
4+
visit Refract::StatementsNode do |node|
5+
queue = []
6+
results = []
7+
current_buffer = nil
8+
nil_context = false
9+
10+
node.body.reverse_each { |n| queue << n }
11+
12+
while (child_node = queue.pop)
13+
case child_node
14+
when Refract::StatementsNode
15+
child_node.body.reverse_each { |n| queue << n }
16+
when Phlex::Compiler::Concat
17+
if current_buffer
18+
current_buffer << child_node.node
19+
unless nil_context
20+
results << Refract::NilNode.new
21+
nil_context = true
22+
end
23+
else
24+
current_buffer = [child_node.node]
25+
results << Refract::ParenthesesNode.new(
26+
body: Refract::StatementsNode.new(
27+
body: [
28+
Refract::IfNode.new(
29+
inline: false,
30+
predicate: Refract::LocalVariableReadNode.new(
31+
name: :__phlex_should_render__
32+
),
33+
statements: Refract::StatementsNode.new(
34+
body: [
35+
Refract::CallNode.new(
36+
receiver: Refract::CallNode.new(
37+
name: :__phlex_buffer__,
38+
),
39+
name: :<<,
40+
arguments: Refract::ArgumentsNode.new(
41+
arguments: [
42+
Refract::InterpolatedStringNode.new(
43+
parts: current_buffer
44+
),
45+
]
46+
)
47+
),
48+
]
49+
)
50+
),
51+
Refract::NilNode.new,
52+
]
53+
)
54+
)
55+
nil_context = true
56+
end
57+
else
58+
resolved = visit(child_node)
59+
case resolved
60+
when Refract::StatementsNode
61+
resolved.body.reverse_each { |n| queue << n }
62+
else
63+
current_buffer = nil
64+
results << resolved
65+
nil_context = false
66+
end
67+
end
68+
end
69+
70+
node.copy(
71+
body: results
72+
)
73+
end
74+
end

lib/phlex/compiler/method_compiler.rb

Lines changed: 17 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,22 @@
33
require "prism"
44

55
module Phlex::Compiler
6+
Concat = Data.define(:node) do
7+
def start_line = nil
8+
def accept(visitor) = self
9+
end
10+
611
class MethodCompiler < Refract::MutationVisitor
712
def initialize(component)
813
super()
914
@component = component
10-
@current_buffer = nil
1115
@preamble = []
1216
end
1317

1418
def compile(node)
15-
visit(node)
16-
end
17-
18-
def around_visit(node)
19-
unless node in Refract::StatementsNode | Refract::CallNode | nil
20-
clear_buffer
21-
end
22-
23-
super
19+
Compactor.new.visit(
20+
visit(node)
21+
)
2422
end
2523

2624
visit Refract::ClassNode do |node|
@@ -105,7 +103,6 @@ def around_visit(node)
105103
end
106104
end
107105

108-
clear_buffer
109106
super(node)
110107
end
111108

@@ -175,8 +172,6 @@ def compile_phlex_attributes(node)
175172
)
176173
end
177174

178-
clear_buffer
179-
180175
Refract::CallNode.new(
181176
name: :__render_attributes__,
182177
arguments: Refract::ArgumentsNode.new(
@@ -208,7 +203,6 @@ def compile_phlex_block(node)
208203
end
209204
end
210205

211-
clear_buffer
212206
Refract::CallNode.new(
213207
name: :__yield_content__,
214208
block: node
@@ -291,7 +285,6 @@ def compile_plain_helper(node)
291285
if node.arguments.arguments in [Refract::StringNode]
292286
raw(node.arguments.arguments.first.unescaped)
293287
else
294-
clear_buffer
295288
node
296289
end
297290
end
@@ -351,8 +344,6 @@ def compile_comment_helper(node)
351344

352345
def compile_raw_helper(node)
353346
node => Refract::CallNode
354-
355-
clear_buffer
356347
node
357348
end
358349

@@ -404,46 +395,16 @@ def compile_raw_helper(node)
404395
private def buffer(node)
405396
node => Refract::StringNode | Refract::EmbeddedStatementsNode
406397

407-
if @current_buffer
408-
@current_buffer << node
409-
410-
nil
411-
else
412-
@current_buffer = [node]
413-
414-
Refract::StatementsNode.new(
415-
body: [
416-
Refract::IfNode.new(
417-
inline: false,
418-
predicate: Refract::LocalVariableReadNode.new(
419-
name: should_render_local
420-
),
421-
statements: Refract::StatementsNode.new(
422-
body: [
423-
Refract::CallNode.new(
424-
receiver: Refract::CallNode.new(
425-
name: buffer_local,
426-
),
427-
name: :<<,
428-
arguments: Refract::ArgumentsNode.new(
429-
arguments: [
430-
Refract::InterpolatedStringNode.new(
431-
parts: @current_buffer
432-
),
433-
]
434-
)
435-
),
436-
]
437-
)
438-
),
439-
Refract::NilNode.new,
440-
]
441-
)
442-
end
443-
end
398+
should_render_local
399+
buffer_local
444400

445-
private def clear_buffer
446-
@current_buffer = nil
401+
Refract::StatementsNode.new(
402+
body: [
403+
Concat.new(
404+
node
405+
),
406+
]
407+
)
447408
end
448409

449410
private def output_block?(node)

0 commit comments

Comments
 (0)