Skip to content

Commit c1824a9

Browse files
committed
Handle more literal types in static attributes
1 parent d11b584 commit c1824a9

2 files changed

Lines changed: 60 additions & 3 deletions

File tree

lib/phlex/compiler/method_compiler.rb

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,11 @@ def compile_standard_element(node, tag)
7373

7474
def visit_phlex_attributes(node)
7575
if node.arguments in [Prism::KeywordHashNode[elements: attributes]]
76-
result = attributes.all? { |attribute| attribute in Prism::AssocNode[key: Prism::SymbolNode, value: Prism::StringNode] }
77-
if result
76+
literal_attributes = attributes.all? do |attribute|
77+
Prism::AssocNode === attribute && static_attribute_value_literal?(attribute)
78+
end
79+
80+
if literal_attributes
7881
return buffer(Phlex::SGML::Attributes.generate_attributes(eval("{#{node.slice}}")))
7982
end
8083
end
@@ -147,7 +150,7 @@ def compile_interpolated_string_node(node)
147150
buffer(").to_s)}"),
148151
]
149152
else
150-
raise Phlex::Compiler::Error, "Unexpected node type in InterpolatedStringNode: #{part.class}"
153+
raise Phlex::Compiler::Error, "Unexpected node type in InterpolatedStringNode: #{part.class}"
151154
end
152155
end
153156
end
@@ -309,6 +312,38 @@ def compile_raw_helper(node)
309312
end
310313
end
311314

315+
private def static_attribute_value_literal?(value)
316+
case value
317+
when Prism::SymbolNode, Prism::StringNode, Prism::IntegerNode, Prism::FloatNode, Prism::TrueNode, Prism::FalseNode, Prism::NilNode
318+
true
319+
when Prism::ArrayNode
320+
value.elements.all? { |n| static_token_value_literal?(n) }
321+
when Prism::HashNode
322+
value.elements.all? { |n| static_attribute_value_literal?(n) }
323+
when Prism::AssocNode
324+
(Prism::StringNode === value.key || Prism::SymbolNode === value.key) && static_attribute_value_literal?(value.value)
325+
when Prism::CallNode
326+
if value in { receiver: Prism::ConstantReadNode[name: :Set]| Prism::ConstantPathNode[name: :Set, parent: nil], name: :[] }
327+
value.arguments.arguments.all? { |n| static_token_value_literal?(n) }
328+
else
329+
false
330+
end
331+
else
332+
false
333+
end
334+
end
335+
336+
private def static_token_value_literal?(value)
337+
case value
338+
when Prism::SymbolNode, Prism::StringNode, Prism::IntegerNode, Prism::FloatNode, Prism::NilNode
339+
true
340+
when Prism::ArrayNode
341+
value.elements.all? { |n| static_token_value_literal?(n) }
342+
else
343+
false
344+
end
345+
end
346+
312347
private def whitespace_helper?(node)
313348
node.name == :whitespace && own_method_without_scope?(node)
314349
end
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# frozen_string_literal: true
2+
3+
class Attributes < Phlex::HTML
4+
def view_template
5+
div(
6+
a: nil,
7+
b: 1,
8+
c: :two,
9+
d: "three",
10+
e: 4.5,
11+
f: false,
12+
g: true,
13+
h: [nil, 1, :two, "three", 4.5, [1]],
14+
i: Set[nil, 1, :two, "three", 4.5, [1]],
15+
j: {
16+
k: 1,
17+
"l" => 2
18+
},
19+
"m" => 3
20+
)
21+
end
22+
end

0 commit comments

Comments
 (0)