herb 0.9.3-arm-linux-gnu → 0.9.5-arm-linux-gnu
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.
- checksums.yaml +4 -4
- data/config.yml +57 -21
- data/ext/herb/nodes.c +93 -55
- data/lib/herb/3.0/herb.so +0 -0
- data/lib/herb/3.1/herb.so +0 -0
- data/lib/herb/3.2/herb.so +0 -0
- data/lib/herb/3.3/herb.so +0 -0
- data/lib/herb/3.4/herb.so +0 -0
- data/lib/herb/4.0/herb.so +0 -0
- data/lib/herb/ast/nodes.rb +212 -78
- data/lib/herb/engine/compiler.rb +52 -26
- data/lib/herb/engine.rb +3 -0
- data/lib/herb/project.rb +58 -17
- data/lib/herb/version.rb +1 -1
- data/lib/herb/visitor.rb +8 -2
- data/sig/herb/ast/nodes.rbs +85 -34
- data/sig/herb/engine/compiler.rbs +16 -0
- data/sig/herb/engine.rbs +3 -0
- data/sig/herb/visitor.rbs +5 -2
- data/sig/serialized_ast_nodes.rbs +20 -9
- data/src/analyze/action_view/javascript_tag.c +38 -0
- data/src/analyze/action_view/tag_helper_node_builders.c +23 -2
- data/src/analyze/action_view/tag_helpers.c +53 -14
- data/src/analyze/analyze.c +23 -3
- data/src/analyze/analyze_helpers.c +406 -0
- data/src/analyze/builders.c +1 -0
- data/src/analyze/missing_end.c +16 -0
- data/src/analyze/parse_errors.c +43 -1
- data/src/analyze/render_nodes.c +231 -35
- data/src/analyze/strict_locals.c +22 -324
- data/src/analyze/transform.c +23 -2
- data/src/ast/ast_nodes.c +114 -57
- data/src/ast/ast_pretty_print.c +109 -25
- data/src/include/analyze/action_view/tag_helper_handler.h +3 -0
- data/src/include/analyze/action_view/tag_helper_node_builders.h +7 -0
- data/src/include/analyze/analyze.h +6 -1
- data/src/include/analyze/helpers.h +18 -0
- data/src/include/ast/ast_nodes.h +27 -13
- data/src/include/version.h +1 -1
- data/src/parser/match_tags.c +37 -6
- data/src/parser.c +8 -0
- data/src/visitor.c +50 -7
- metadata +1 -1
data/lib/herb/project.rb
CHANGED
|
@@ -71,9 +71,9 @@ module Herb
|
|
|
71
71
|
attr_reader :successful, :failed, :timeout, :template_error, :unexpected_error,
|
|
72
72
|
:strict_parse_error, :analyze_parse_error,
|
|
73
73
|
:validation_error, :compilation_failed, :strict_compilation_failed,
|
|
74
|
-
:invalid_ruby,
|
|
74
|
+
:invalid_ruby, :skipped,
|
|
75
75
|
:error_outputs, :file_contents, :parse_errors, :compilation_errors,
|
|
76
|
-
:file_diagnostics
|
|
76
|
+
:file_diagnostics, :skip_reasons
|
|
77
77
|
|
|
78
78
|
def initialize
|
|
79
79
|
@successful = []
|
|
@@ -87,11 +87,13 @@ module Herb
|
|
|
87
87
|
@compilation_failed = []
|
|
88
88
|
@strict_compilation_failed = []
|
|
89
89
|
@invalid_ruby = []
|
|
90
|
+
@skipped = []
|
|
90
91
|
@error_outputs = {}
|
|
91
92
|
@file_contents = {}
|
|
92
93
|
@parse_errors = {}
|
|
93
94
|
@compilation_errors = {}
|
|
94
95
|
@file_diagnostics = {}
|
|
96
|
+
@skip_reasons = {}
|
|
95
97
|
end
|
|
96
98
|
|
|
97
99
|
def problem_files
|
|
@@ -432,8 +434,7 @@ module Herb
|
|
|
432
434
|
nil
|
|
433
435
|
end
|
|
434
436
|
|
|
435
|
-
{ file_path: file_path, status: :timeout, file_content: file_content,
|
|
436
|
-
log: "⏱️ Parsing #{file_path} timed out after 1 second" }
|
|
437
|
+
{ file_path: file_path, status: :timeout, file_content: file_content, log: "⏱️ Parsing #{file_path} timed out after 1 second" }
|
|
437
438
|
rescue StandardError => e
|
|
438
439
|
file_content ||= begin
|
|
439
440
|
File.read(file_path)
|
|
@@ -441,8 +442,7 @@ module Herb
|
|
|
441
442
|
nil
|
|
442
443
|
end
|
|
443
444
|
|
|
444
|
-
{ file_path: file_path, status: :failed, file_content: file_content,
|
|
445
|
-
log: "⚠️ Error processing #{file_path}: #{e.message}" }
|
|
445
|
+
{ file_path: file_path, status: :failed, file_content: file_content, log: "⚠️ Error processing #{file_path}: #{e.message}" }
|
|
446
446
|
ensure
|
|
447
447
|
[stdout_file, stderr_file].each do |tempfile|
|
|
448
448
|
next unless tempfile
|
|
@@ -488,6 +488,9 @@ module Herb
|
|
|
488
488
|
Herb::Engine.new(file_content, filename: file_path, escape: true, validate_ruby: validate_ruby)
|
|
489
489
|
|
|
490
490
|
{ status: :successful, log: "✅ Compiled #{file_path} successfully" }
|
|
491
|
+
rescue Herb::Engine::GeneratorTemplateError => e
|
|
492
|
+
{ status: :skipped, skip_reason: e.message,
|
|
493
|
+
log: "⊘ Skipping #{file_path}: #{e.message}" }
|
|
491
494
|
rescue Herb::Engine::InvalidRubyError => e
|
|
492
495
|
{ status: :invalid_ruby, file_content: file_content,
|
|
493
496
|
compilation_error: { error: e.message, backtrace: e.backtrace&.first(10) || [] },
|
|
@@ -545,6 +548,7 @@ module Herb
|
|
|
545
548
|
tracker.parse_errors[file_path] = result[:parse_error] if result[:parse_error]
|
|
546
549
|
tracker.compilation_errors[file_path] = result[:compilation_error] if result[:compilation_error]
|
|
547
550
|
tracker.file_diagnostics[file_path] = result[:diagnostics] if result[:diagnostics]&.any?
|
|
551
|
+
tracker.skip_reasons[file_path] = result[:skip_reason] if result[:skip_reason]
|
|
548
552
|
end
|
|
549
553
|
|
|
550
554
|
def print_summary(results, log, duration)
|
|
@@ -563,13 +567,18 @@ module Herb
|
|
|
563
567
|
puts " #{label("Checked")} #{cyan("#{total} #{pluralize(total, "file")}")}"
|
|
564
568
|
|
|
565
569
|
if total > 1
|
|
566
|
-
|
|
567
|
-
"#{bold(green("#{passed} clean"))} | #{bold(red("#{issues} with issues"))}"
|
|
568
|
-
else
|
|
569
|
-
bold(green("#{total} clean"))
|
|
570
|
-
end
|
|
570
|
+
files_parts = []
|
|
571
571
|
|
|
572
|
-
|
|
572
|
+
if issues.positive?
|
|
573
|
+
files_parts << bold(green("#{passed} clean"))
|
|
574
|
+
files_parts << bold(red("#{issues} with issues"))
|
|
575
|
+
else
|
|
576
|
+
files_parts << bold(green("#{total - results.skipped.count} clean"))
|
|
577
|
+
end
|
|
578
|
+
|
|
579
|
+
files_parts << dimmed("#{results.skipped.count} skipped") if results.skipped.any?
|
|
580
|
+
|
|
581
|
+
puts " #{label("Files")} #{files_parts.join(" | ")}"
|
|
573
582
|
end
|
|
574
583
|
|
|
575
584
|
parser_parts = []
|
|
@@ -581,8 +590,9 @@ module Herb
|
|
|
581
590
|
parser_parts << stat(results.analyze_parse_error.count, "analyze", :yellow) if results.analyze_parse_error.any?
|
|
582
591
|
puts " #{label("Parser")} #{parser_parts.join(" | ")}"
|
|
583
592
|
|
|
584
|
-
|
|
585
|
-
|
|
593
|
+
not_compiled = total - passed - results.skipped.count - results.validation_error.count -
|
|
594
|
+
results.compilation_failed.count - results.strict_compilation_failed.count -
|
|
595
|
+
results.invalid_ruby.count
|
|
586
596
|
|
|
587
597
|
engine_parts = []
|
|
588
598
|
engine_parts << stat(passed, "compiled", :green)
|
|
@@ -590,13 +600,17 @@ module Herb
|
|
|
590
600
|
engine_parts << stat(results.compilation_failed.count, "compilation", :red) if results.compilation_failed.any?
|
|
591
601
|
engine_parts << stat(results.strict_compilation_failed.count, "strict", :yellow) if results.strict_compilation_failed.any?
|
|
592
602
|
engine_parts << stat(results.invalid_ruby.count, "produced invalid Ruby", :red) if results.invalid_ruby.any?
|
|
593
|
-
engine_parts << dimmed("#{
|
|
603
|
+
engine_parts << dimmed("#{not_compiled} not compiled") if not_compiled.positive?
|
|
594
604
|
puts " #{label("Engine")} #{engine_parts.join(" | ")}"
|
|
595
605
|
|
|
596
606
|
if results.timeout.any?
|
|
597
607
|
puts " #{label("Timeout")} #{stat(results.timeout.count, "timed out", :yellow)}"
|
|
598
608
|
end
|
|
599
609
|
|
|
610
|
+
if results.skipped.any?
|
|
611
|
+
puts " #{label("Skipped")} #{dimmed("#{results.skipped.count} #{pluralize(results.skipped.count, "file")}")}"
|
|
612
|
+
end
|
|
613
|
+
|
|
600
614
|
if duration
|
|
601
615
|
puts " #{label("Duration")} #{cyan(format_duration(duration))}"
|
|
602
616
|
end
|
|
@@ -630,6 +644,7 @@ module Herb
|
|
|
630
644
|
log.puts ""
|
|
631
645
|
log.puts "--- Other ---"
|
|
632
646
|
log.puts "⏱️ Timed out: #{results.timeout.count} (#{percentage(results.timeout.count, total)}%)"
|
|
647
|
+
log.puts "⊘ Skipped: #{results.skipped.count} (#{percentage(results.skipped.count, total)}%)"
|
|
633
648
|
|
|
634
649
|
return unless duration
|
|
635
650
|
|
|
@@ -639,10 +654,27 @@ module Herb
|
|
|
639
654
|
def print_file_lists(results, log)
|
|
640
655
|
log_file_lists(results, log)
|
|
641
656
|
|
|
642
|
-
return unless results.problem_files.any?
|
|
643
|
-
|
|
644
657
|
printed_section = false
|
|
645
658
|
|
|
659
|
+
if results.skipped.any?
|
|
660
|
+
printed_section = true
|
|
661
|
+
|
|
662
|
+
puts "\n"
|
|
663
|
+
puts " #{bold("Skipped files:")}"
|
|
664
|
+
puts " #{dimmed("These files were parsed successfully but skipped for compilation by the engine.")}"
|
|
665
|
+
|
|
666
|
+
results.skipped.each do |file|
|
|
667
|
+
relative = relative_path(file)
|
|
668
|
+
reason = results.skip_reasons[file]
|
|
669
|
+
|
|
670
|
+
puts ""
|
|
671
|
+
puts " #{cyan(relative)}:"
|
|
672
|
+
puts " #{dimmed("⊘")} #{dimmed(reason)}"
|
|
673
|
+
end
|
|
674
|
+
end
|
|
675
|
+
|
|
676
|
+
return unless results.problem_files.any?
|
|
677
|
+
|
|
646
678
|
ISSUE_TYPES.each do |type|
|
|
647
679
|
file_list = results.send(type[:key])
|
|
648
680
|
next unless file_list.any?
|
|
@@ -682,6 +714,15 @@ module Herb
|
|
|
682
714
|
end
|
|
683
715
|
|
|
684
716
|
def log_file_lists(results, log)
|
|
717
|
+
if results.skipped.any?
|
|
718
|
+
log.puts "\n#{heading("Files: Skipped")}"
|
|
719
|
+
|
|
720
|
+
results.skipped.each do |file|
|
|
721
|
+
reason = results.skip_reasons[file]
|
|
722
|
+
log.puts "#{file} - #{reason}"
|
|
723
|
+
end
|
|
724
|
+
end
|
|
725
|
+
|
|
685
726
|
ISSUE_TYPES.each do |type|
|
|
686
727
|
file_list = results.send(type[:key])
|
|
687
728
|
next unless file_list.any?
|
data/lib/herb/version.rb
CHANGED
data/lib/herb/visitor.rb
CHANGED
|
@@ -271,6 +271,12 @@ module Herb
|
|
|
271
271
|
visit_child_nodes(node)
|
|
272
272
|
end
|
|
273
273
|
|
|
274
|
+
#: (Herb::AST::RubyRenderKeywordsNode) -> void
|
|
275
|
+
def visit_ruby_render_keywords_node(node)
|
|
276
|
+
visit_node(node)
|
|
277
|
+
visit_child_nodes(node)
|
|
278
|
+
end
|
|
279
|
+
|
|
274
280
|
#: (Herb::AST::ERBRenderNode) -> void
|
|
275
281
|
def visit_erb_render_node(node)
|
|
276
282
|
visit_node(node)
|
|
@@ -278,8 +284,8 @@ module Herb
|
|
|
278
284
|
visit_child_nodes(node)
|
|
279
285
|
end
|
|
280
286
|
|
|
281
|
-
#: (Herb::AST::
|
|
282
|
-
def
|
|
287
|
+
#: (Herb::AST::RubyParameterNode) -> void
|
|
288
|
+
def visit_ruby_parameter_node(node)
|
|
283
289
|
visit_node(node)
|
|
284
290
|
visit_child_nodes(node)
|
|
285
291
|
end
|
data/sig/herb/ast/nodes.rbs
CHANGED
|
@@ -944,6 +944,7 @@ module Herb
|
|
|
944
944
|
# | tag_closing: Herb::Token?,
|
|
945
945
|
# | prism_node: String?,
|
|
946
946
|
# | body: Array[Herb::AST::Node],
|
|
947
|
+
# | block_arguments: Array[Herb::AST::RubyParameterNode]?,
|
|
947
948
|
# | rescue_clause: Herb::AST::ERBRescueNode?,
|
|
948
949
|
# | else_clause: Herb::AST::ERBElseNode?,
|
|
949
950
|
# | ensure_clause: Herb::AST::ERBEnsureNode?,
|
|
@@ -962,6 +963,8 @@ module Herb
|
|
|
962
963
|
|
|
963
964
|
attr_reader body: Array[Herb::AST::Node]
|
|
964
965
|
|
|
966
|
+
attr_reader block_arguments: Array[Herb::AST::RubyParameterNode]?
|
|
967
|
+
|
|
965
968
|
attr_reader rescue_clause: Herb::AST::ERBRescueNode?
|
|
966
969
|
|
|
967
970
|
attr_reader else_clause: Herb::AST::ERBElseNode?
|
|
@@ -970,8 +973,8 @@ module Herb
|
|
|
970
973
|
|
|
971
974
|
attr_reader end_node: Herb::AST::ERBEndNode?
|
|
972
975
|
|
|
973
|
-
# : (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, String, Array[Herb::AST::Node], Herb::AST::ERBRescueNode, Herb::AST::ERBElseNode, Herb::AST::ERBEnsureNode, Herb::AST::ERBEndNode) -> void
|
|
974
|
-
def initialize: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, String, Array[Herb::AST::Node], Herb::AST::ERBRescueNode, Herb::AST::ERBElseNode, Herb::AST::ERBEnsureNode, Herb::AST::ERBEndNode) -> void
|
|
976
|
+
# : (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, String, Array[Herb::AST::Node], Array[Herb::AST::RubyParameterNode], Herb::AST::ERBRescueNode, Herb::AST::ERBElseNode, Herb::AST::ERBEnsureNode, Herb::AST::ERBEndNode) -> void
|
|
977
|
+
def initialize: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, String, Array[Herb::AST::Node], Array[Herb::AST::RubyParameterNode], Herb::AST::ERBRescueNode, Herb::AST::ERBElseNode, Herb::AST::ERBEnsureNode, Herb::AST::ERBEndNode) -> void
|
|
975
978
|
|
|
976
979
|
# : () -> Prism::node?
|
|
977
980
|
def deserialized_prism_node: () -> Prism::node?
|
|
@@ -1514,12 +1517,7 @@ module Herb
|
|
|
1514
1517
|
def tree_inspect: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
|
|
1515
1518
|
end
|
|
1516
1519
|
|
|
1517
|
-
# : type
|
|
1518
|
-
# | tag_opening: Herb::Token?,
|
|
1519
|
-
# | content: Herb::Token?,
|
|
1520
|
-
# | tag_closing: Herb::Token?,
|
|
1521
|
-
# | analyzed_ruby: nil,
|
|
1522
|
-
# | prism_node: String?,
|
|
1520
|
+
# : type serialized_ruby_render_keywords_node = {
|
|
1523
1521
|
# | partial: Herb::Token?,
|
|
1524
1522
|
# | template_path: Herb::Token?,
|
|
1525
1523
|
# | layout: Herb::Token?,
|
|
@@ -1539,19 +1537,9 @@ module Herb
|
|
|
1539
1537
|
# | content_type: Herb::Token?,
|
|
1540
1538
|
# | locals: Array[Herb::AST::RubyRenderLocalNode]?,
|
|
1541
1539
|
# | }
|
|
1542
|
-
class
|
|
1540
|
+
class RubyRenderKeywordsNode < Node
|
|
1543
1541
|
include Colors
|
|
1544
1542
|
|
|
1545
|
-
attr_reader tag_opening: Herb::Token?
|
|
1546
|
-
|
|
1547
|
-
attr_reader content: Herb::Token?
|
|
1548
|
-
|
|
1549
|
-
attr_reader tag_closing: Herb::Token?
|
|
1550
|
-
|
|
1551
|
-
attr_reader analyzed_ruby: nil
|
|
1552
|
-
|
|
1553
|
-
attr_reader prism_node: String?
|
|
1554
|
-
|
|
1555
1543
|
attr_reader partial: Herb::Token?
|
|
1556
1544
|
|
|
1557
1545
|
attr_reader template_path: Herb::Token?
|
|
@@ -1588,8 +1576,71 @@ module Herb
|
|
|
1588
1576
|
|
|
1589
1577
|
attr_reader locals: Array[Herb::AST::RubyRenderLocalNode]?
|
|
1590
1578
|
|
|
1591
|
-
# : (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token,
|
|
1592
|
-
def initialize: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token,
|
|
1579
|
+
# : (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Array[Herb::AST::RubyRenderLocalNode]) -> void
|
|
1580
|
+
def initialize: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Herb::Token, Array[Herb::AST::RubyRenderLocalNode]) -> void
|
|
1581
|
+
|
|
1582
|
+
# : () -> serialized_ruby_render_keywords_node
|
|
1583
|
+
def to_hash: () -> serialized_ruby_render_keywords_node
|
|
1584
|
+
|
|
1585
|
+
# : (Visitor) -> void
|
|
1586
|
+
def accept: (Visitor) -> void
|
|
1587
|
+
|
|
1588
|
+
# : () -> Array[Herb::AST::Node?]
|
|
1589
|
+
def child_nodes: () -> Array[Herb::AST::Node?]
|
|
1590
|
+
|
|
1591
|
+
# : () -> Array[Herb::AST::Node]
|
|
1592
|
+
def compact_child_nodes: () -> Array[Herb::AST::Node]
|
|
1593
|
+
|
|
1594
|
+
# : () -> String
|
|
1595
|
+
def inspect: () -> String
|
|
1596
|
+
|
|
1597
|
+
# : (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
|
|
1598
|
+
def tree_inspect: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
|
|
1599
|
+
end
|
|
1600
|
+
|
|
1601
|
+
# : type serialized_erb_render_node = {
|
|
1602
|
+
# | tag_opening: Herb::Token?,
|
|
1603
|
+
# | content: Herb::Token?,
|
|
1604
|
+
# | tag_closing: Herb::Token?,
|
|
1605
|
+
# | analyzed_ruby: nil,
|
|
1606
|
+
# | prism_node: String?,
|
|
1607
|
+
# | keywords: Herb::AST::RubyRenderKeywordsNode?,
|
|
1608
|
+
# | body: Array[Herb::AST::Node],
|
|
1609
|
+
# | block_arguments: Array[Herb::AST::RubyParameterNode]?,
|
|
1610
|
+
# | rescue_clause: Herb::AST::ERBRescueNode?,
|
|
1611
|
+
# | else_clause: Herb::AST::ERBElseNode?,
|
|
1612
|
+
# | ensure_clause: Herb::AST::ERBEnsureNode?,
|
|
1613
|
+
# | end_node: Herb::AST::ERBEndNode?,
|
|
1614
|
+
# | }
|
|
1615
|
+
class ERBRenderNode < Node
|
|
1616
|
+
include Colors
|
|
1617
|
+
|
|
1618
|
+
attr_reader tag_opening: Herb::Token?
|
|
1619
|
+
|
|
1620
|
+
attr_reader content: Herb::Token?
|
|
1621
|
+
|
|
1622
|
+
attr_reader tag_closing: Herb::Token?
|
|
1623
|
+
|
|
1624
|
+
attr_reader analyzed_ruby: nil
|
|
1625
|
+
|
|
1626
|
+
attr_reader prism_node: String?
|
|
1627
|
+
|
|
1628
|
+
attr_reader keywords: Herb::AST::RubyRenderKeywordsNode?
|
|
1629
|
+
|
|
1630
|
+
attr_reader body: Array[Herb::AST::Node]
|
|
1631
|
+
|
|
1632
|
+
attr_reader block_arguments: Array[Herb::AST::RubyParameterNode]?
|
|
1633
|
+
|
|
1634
|
+
attr_reader rescue_clause: Herb::AST::ERBRescueNode?
|
|
1635
|
+
|
|
1636
|
+
attr_reader else_clause: Herb::AST::ERBElseNode?
|
|
1637
|
+
|
|
1638
|
+
attr_reader ensure_clause: Herb::AST::ERBEnsureNode?
|
|
1639
|
+
|
|
1640
|
+
attr_reader end_node: Herb::AST::ERBEndNode?
|
|
1641
|
+
|
|
1642
|
+
# : (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, nil, String, Herb::AST::RubyRenderKeywordsNode, Array[Herb::AST::Node], Array[Herb::AST::RubyParameterNode], Herb::AST::ERBRescueNode, Herb::AST::ERBElseNode, Herb::AST::ERBEnsureNode, Herb::AST::ERBEndNode) -> void
|
|
1643
|
+
def initialize: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, nil, String, Herb::AST::RubyRenderKeywordsNode, Array[Herb::AST::Node], Array[Herb::AST::RubyParameterNode], Herb::AST::ERBRescueNode, Herb::AST::ERBElseNode, Herb::AST::ERBEnsureNode, Herb::AST::ERBEndNode) -> void
|
|
1593
1644
|
|
|
1594
1645
|
# : () -> Prism::node?
|
|
1595
1646
|
def deserialized_prism_node: () -> Prism::node?
|
|
@@ -1613,28 +1664,28 @@ module Herb
|
|
|
1613
1664
|
def tree_inspect: (?indent: Integer, ?depth: Integer, ?depth_limit: Integer) -> String
|
|
1614
1665
|
end
|
|
1615
1666
|
|
|
1616
|
-
# : type
|
|
1667
|
+
# : type serialized_ruby_parameter_node = {
|
|
1617
1668
|
# | name: Herb::Token?,
|
|
1618
1669
|
# | default_value: Herb::AST::RubyLiteralNode?,
|
|
1670
|
+
# | kind: String?,
|
|
1619
1671
|
# | required: bool,
|
|
1620
|
-
# | double_splat: bool,
|
|
1621
1672
|
# | }
|
|
1622
|
-
class
|
|
1673
|
+
class RubyParameterNode < Node
|
|
1623
1674
|
include Colors
|
|
1624
1675
|
|
|
1625
1676
|
attr_reader name: Herb::Token?
|
|
1626
1677
|
|
|
1627
1678
|
attr_reader default_value: Herb::AST::RubyLiteralNode?
|
|
1628
1679
|
|
|
1629
|
-
attr_reader
|
|
1680
|
+
attr_reader kind: String?
|
|
1630
1681
|
|
|
1631
|
-
attr_reader
|
|
1682
|
+
attr_reader required: bool
|
|
1632
1683
|
|
|
1633
|
-
# : (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::AST::RubyLiteralNode,
|
|
1634
|
-
def initialize: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::AST::RubyLiteralNode,
|
|
1684
|
+
# : (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::AST::RubyLiteralNode, String, bool) -> void
|
|
1685
|
+
def initialize: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::AST::RubyLiteralNode, String, bool) -> void
|
|
1635
1686
|
|
|
1636
|
-
# : () ->
|
|
1637
|
-
def to_hash: () ->
|
|
1687
|
+
# : () -> serialized_ruby_parameter_node
|
|
1688
|
+
def to_hash: () -> serialized_ruby_parameter_node
|
|
1638
1689
|
|
|
1639
1690
|
# : (Visitor) -> void
|
|
1640
1691
|
def accept: (Visitor) -> void
|
|
@@ -1658,7 +1709,7 @@ module Herb
|
|
|
1658
1709
|
# | tag_closing: Herb::Token?,
|
|
1659
1710
|
# | analyzed_ruby: nil,
|
|
1660
1711
|
# | prism_node: String?,
|
|
1661
|
-
# | locals: Array[Herb::AST::
|
|
1712
|
+
# | locals: Array[Herb::AST::RubyParameterNode]?,
|
|
1662
1713
|
# | }
|
|
1663
1714
|
class ERBStrictLocalsNode < Node
|
|
1664
1715
|
include Colors
|
|
@@ -1673,10 +1724,10 @@ module Herb
|
|
|
1673
1724
|
|
|
1674
1725
|
attr_reader prism_node: String?
|
|
1675
1726
|
|
|
1676
|
-
attr_reader locals: Array[Herb::AST::
|
|
1727
|
+
attr_reader locals: Array[Herb::AST::RubyParameterNode]?
|
|
1677
1728
|
|
|
1678
|
-
# : (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, nil, String, Array[Herb::AST::
|
|
1679
|
-
def initialize: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, nil, String, Array[Herb::AST::
|
|
1729
|
+
# : (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, nil, String, Array[Herb::AST::RubyParameterNode]) -> void
|
|
1730
|
+
def initialize: (String, Location, Array[Herb::Errors::Error], Herb::Token, Herb::Token, Herb::Token, nil, String, Array[Herb::AST::RubyParameterNode]) -> void
|
|
1680
1731
|
|
|
1681
1732
|
# : () -> Prism::node?
|
|
1682
1733
|
def deserialized_prism_node: () -> Prism::node?
|
|
@@ -5,6 +5,16 @@ module Herb
|
|
|
5
5
|
class Compiler < ::Herb::Visitor
|
|
6
6
|
EXPRESSION_TOKEN_TYPES: untyped
|
|
7
7
|
|
|
8
|
+
TRAILING_WHITESPACE: ::Regexp
|
|
9
|
+
|
|
10
|
+
TRAILING_INDENTATION: ::Regexp
|
|
11
|
+
|
|
12
|
+
TRAILING_INDENTATION_CAPTURE: ::Regexp
|
|
13
|
+
|
|
14
|
+
WHITESPACE_ONLY: ::Regexp
|
|
15
|
+
|
|
16
|
+
WHITESPACE_ONLY_CAPTURE: ::Regexp
|
|
17
|
+
|
|
8
18
|
attr_reader tokens: untyped
|
|
9
19
|
|
|
10
20
|
def initialize: (untyped engine, ?untyped options) -> untyped
|
|
@@ -85,6 +95,8 @@ module Herb
|
|
|
85
95
|
|
|
86
96
|
private
|
|
87
97
|
|
|
98
|
+
def check_for_escaped_erb_tag!: (untyped opening) -> untyped
|
|
99
|
+
|
|
88
100
|
def current_context: () -> untyped
|
|
89
101
|
|
|
90
102
|
def push_context: (untyped context) -> untyped
|
|
@@ -134,6 +146,10 @@ module Herb
|
|
|
134
146
|
|
|
135
147
|
def preceding_token_ends_with_newline?: () -> untyped
|
|
136
148
|
|
|
149
|
+
def left_trim?: (untyped node) -> untyped
|
|
150
|
+
|
|
151
|
+
def right_trim?: (untyped node) -> untyped
|
|
152
|
+
|
|
137
153
|
def last_text_token: () -> untyped
|
|
138
154
|
|
|
139
155
|
def extract_leading_space: () -> untyped
|
data/sig/herb/engine.rbs
CHANGED
data/sig/herb/visitor.rbs
CHANGED
|
@@ -130,11 +130,14 @@ module Herb
|
|
|
130
130
|
# : (Herb::AST::RubyRenderLocalNode) -> void
|
|
131
131
|
def visit_ruby_render_local_node: (Herb::AST::RubyRenderLocalNode) -> void
|
|
132
132
|
|
|
133
|
+
# : (Herb::AST::RubyRenderKeywordsNode) -> void
|
|
134
|
+
def visit_ruby_render_keywords_node: (Herb::AST::RubyRenderKeywordsNode) -> void
|
|
135
|
+
|
|
133
136
|
# : (Herb::AST::ERBRenderNode) -> void
|
|
134
137
|
def visit_erb_render_node: (Herb::AST::ERBRenderNode) -> void
|
|
135
138
|
|
|
136
|
-
# : (Herb::AST::
|
|
137
|
-
def
|
|
139
|
+
# : (Herb::AST::RubyParameterNode) -> void
|
|
140
|
+
def visit_ruby_parameter_node: (Herb::AST::RubyParameterNode) -> void
|
|
138
141
|
|
|
139
142
|
# : (Herb::AST::ERBStrictLocalsNode) -> void
|
|
140
143
|
def visit_erb_strict_locals_node: (Herb::AST::ERBStrictLocalsNode) -> void
|
|
@@ -170,6 +170,7 @@ module Herb
|
|
|
170
170
|
tag_closing: Herb::Token,
|
|
171
171
|
prism_node: String,
|
|
172
172
|
body: Array[Herb::AST::Node],
|
|
173
|
+
block_arguments: Array[Herb::AST::RubyParameterNode],
|
|
173
174
|
rescue_clause: Herb::AST::ERBRescueNode,
|
|
174
175
|
else_clause: Herb::AST::ERBElseNode,
|
|
175
176
|
ensure_clause: Herb::AST::ERBEnsureNode,
|
|
@@ -276,12 +277,7 @@ module Herb
|
|
|
276
277
|
value: Herb::AST::RubyLiteralNode,
|
|
277
278
|
}
|
|
278
279
|
|
|
279
|
-
type
|
|
280
|
-
tag_opening: Herb::Token,
|
|
281
|
-
content: Herb::Token,
|
|
282
|
-
tag_closing: Herb::Token,
|
|
283
|
-
analyzed_ruby: nil,
|
|
284
|
-
prism_node: String,
|
|
280
|
+
type serialized_ruby_render_keywords_node = serialized_node & {
|
|
285
281
|
partial: Herb::Token,
|
|
286
282
|
template_path: Herb::Token,
|
|
287
283
|
layout: Herb::Token,
|
|
@@ -302,11 +298,26 @@ module Herb
|
|
|
302
298
|
locals: Array[Herb::AST::RubyRenderLocalNode],
|
|
303
299
|
}
|
|
304
300
|
|
|
305
|
-
type
|
|
301
|
+
type serialized_erb_render_node = serialized_node & {
|
|
302
|
+
tag_opening: Herb::Token,
|
|
303
|
+
content: Herb::Token,
|
|
304
|
+
tag_closing: Herb::Token,
|
|
305
|
+
analyzed_ruby: nil,
|
|
306
|
+
prism_node: String,
|
|
307
|
+
keywords: Herb::AST::RubyRenderKeywordsNode,
|
|
308
|
+
body: Array[Herb::AST::Node],
|
|
309
|
+
block_arguments: Array[Herb::AST::RubyParameterNode],
|
|
310
|
+
rescue_clause: Herb::AST::ERBRescueNode,
|
|
311
|
+
else_clause: Herb::AST::ERBElseNode,
|
|
312
|
+
ensure_clause: Herb::AST::ERBEnsureNode,
|
|
313
|
+
end_node: Herb::AST::ERBEndNode,
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
type serialized_ruby_parameter_node = serialized_node & {
|
|
306
317
|
name: Herb::Token,
|
|
307
318
|
default_value: Herb::AST::RubyLiteralNode,
|
|
319
|
+
kind: String,
|
|
308
320
|
required: bool,
|
|
309
|
-
double_splat: bool,
|
|
310
321
|
}
|
|
311
322
|
|
|
312
323
|
type serialized_erb_strict_locals_node = serialized_node & {
|
|
@@ -315,7 +326,7 @@ module Herb
|
|
|
315
326
|
tag_closing: Herb::Token,
|
|
316
327
|
analyzed_ruby: nil,
|
|
317
328
|
prism_node: String,
|
|
318
|
-
locals: Array[Herb::AST::
|
|
329
|
+
locals: Array[Herb::AST::RubyParameterNode],
|
|
319
330
|
}
|
|
320
331
|
|
|
321
332
|
type serialized_erb_yield_node = serialized_node & {
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
#include "../../include/analyze/action_view/tag_helper_handler.h"
|
|
2
|
+
#include "../../include/analyze/action_view/tag_helper_node_builders.h"
|
|
3
|
+
#include "../../include/ast/ast_nodes.h"
|
|
4
|
+
#include "../../include/lib/hb_array.h"
|
|
5
|
+
#include "../../include/lib/hb_string.h"
|
|
6
|
+
#include "../../include/visitor.h"
|
|
2
7
|
|
|
3
8
|
#include <prism.h>
|
|
4
9
|
#include <stdbool.h>
|
|
@@ -45,6 +50,39 @@ bool javascript_tag_supports_block(void) {
|
|
|
45
50
|
return true;
|
|
46
51
|
}
|
|
47
52
|
|
|
53
|
+
bool wrap_javascript_tag_body_visitor(const AST_NODE_T* node, void* data) {
|
|
54
|
+
hb_allocator_T* allocator = (hb_allocator_T*) data;
|
|
55
|
+
|
|
56
|
+
if (node == NULL || node->type != AST_HTML_ELEMENT_NODE) { return true; }
|
|
57
|
+
|
|
58
|
+
AST_HTML_ELEMENT_NODE_T* element = (AST_HTML_ELEMENT_NODE_T*) node;
|
|
59
|
+
|
|
60
|
+
if (!hb_string_equals(element->element_source, hb_string("ActionView::Helpers::JavaScriptHelper#javascript_tag"))) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (element->body == NULL || hb_array_size(element->body) == 0) { return false; }
|
|
65
|
+
|
|
66
|
+
for (size_t i = 0; i < hb_array_size(element->body); i++) {
|
|
67
|
+
AST_NODE_T* child = (AST_NODE_T*) hb_array_get(element->body, i);
|
|
68
|
+
if (child && child->type == AST_CDATA_NODE) { return false; }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
hb_array_T* cdata_children = hb_array_init(hb_array_size(element->body), allocator);
|
|
72
|
+
|
|
73
|
+
for (size_t i = 0; i < hb_array_size(element->body); i++) {
|
|
74
|
+
hb_array_append(cdata_children, hb_array_get(element->body, i));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
AST_CDATA_NODE_T* cdata_node =
|
|
78
|
+
create_javascript_cdata_node(cdata_children, element->base.location.start, element->base.location.end, allocator);
|
|
79
|
+
|
|
80
|
+
element->body->size = 0;
|
|
81
|
+
hb_array_append(element->body, (AST_NODE_T*) cdata_node);
|
|
82
|
+
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
|
|
48
86
|
const tag_helper_handler_T javascript_tag_handler = {
|
|
49
87
|
.name = "javascript_tag",
|
|
50
88
|
.source = HB_STRING_LITERAL("ActionView::Helpers::JavaScriptHelper#javascript_tag"),
|
|
@@ -124,7 +124,7 @@ AST_HTML_ATTRIBUTE_NODE_T* create_html_attribute_node_precise(
|
|
|
124
124
|
open_quote,
|
|
125
125
|
value_children,
|
|
126
126
|
close_quote,
|
|
127
|
-
|
|
127
|
+
true,
|
|
128
128
|
positions->value_start,
|
|
129
129
|
positions->value_end,
|
|
130
130
|
hb_array_init(0, allocator),
|
|
@@ -179,7 +179,7 @@ AST_HTML_ATTRIBUTE_NODE_T* create_html_attribute_with_ruby_literal_precise(
|
|
|
179
179
|
NULL,
|
|
180
180
|
value_children,
|
|
181
181
|
NULL,
|
|
182
|
-
|
|
182
|
+
true,
|
|
183
183
|
positions->content_start,
|
|
184
184
|
positions->content_end,
|
|
185
185
|
hb_array_init(0, allocator),
|
|
@@ -385,3 +385,24 @@ void append_body_content_node(
|
|
|
385
385
|
if (text_node) { hb_array_append(body, (AST_NODE_T*) text_node); }
|
|
386
386
|
}
|
|
387
387
|
}
|
|
388
|
+
|
|
389
|
+
AST_CDATA_NODE_T* create_javascript_cdata_node(
|
|
390
|
+
hb_array_T* children,
|
|
391
|
+
position_T start,
|
|
392
|
+
position_T end,
|
|
393
|
+
hb_allocator_T* allocator
|
|
394
|
+
) {
|
|
395
|
+
token_T* cdata_opening = create_synthetic_token(allocator, "\n//<![CDATA[\n", TOKEN_CDATA_START, start, end);
|
|
396
|
+
|
|
397
|
+
token_T* cdata_closing = create_synthetic_token(allocator, "\n//]]>\n", TOKEN_CDATA_END, start, end);
|
|
398
|
+
|
|
399
|
+
return ast_cdata_node_init(
|
|
400
|
+
cdata_opening,
|
|
401
|
+
children,
|
|
402
|
+
cdata_closing,
|
|
403
|
+
start,
|
|
404
|
+
end,
|
|
405
|
+
hb_array_init(0, allocator),
|
|
406
|
+
allocator
|
|
407
|
+
);
|
|
408
|
+
}
|