diff --git a/lib/i18n/tasks/scanners/erb_ast_processor.rb b/lib/i18n/tasks/scanners/erb_ast_processor.rb index 5a219753..1ccd2a5b 100644 --- a/lib/i18n/tasks/scanners/erb_ast_processor.rb +++ b/lib/i18n/tasks/scanners/erb_ast_processor.rb @@ -38,7 +38,9 @@ def on_code(node) # @param node [::Parser::AST::Node] # @return [::Parser::AST::Node] def handler_missing(node) - node = transform_misparsed_comment(node) + node = handle_comment(node) + return if node.nil? + node.updated( nil, node.children.map { |child| node?(child) ? process(child) : child } @@ -47,40 +49,22 @@ def handler_missing(node) private - # Works around incorrect handling of comments of the form: - # <%# ... #> - # (no space between % and #) - # - # With a space the AST is: - # - # s(:erb, nil, nil, - # s(:code, " # this should not fail: ' "), nil) + # Convert ERB-comments to ::Parser::Source::Comment and skip processing node # - # Without a space the AST is: - # - # s(:erb, - # s(:indicator, "#"), nil, - # s(:code, " this should not fail: ' "), nil) - # @param node [::Parser::AST::Node] - # @return [::Parser::AST::Node] - def transform_misparsed_comment(node) - return node unless node.type == :erb && node.children.size == 4 && - node.children[0]&.type == :indicator && node.children[0].children[0] == "#" && - node.children[1].nil? && - node.children[2]&.type == :code && - node.children[3].nil? - code_node = node.children[2] + # @param node Parser::AST::Node Potential comment node + # @return Parser::AST::Node or nil + def handle_comment(node) + if node.type == :erb && node.children.size == 4 && + node.children[0]&.type == :indicator && node.children[0].children[0] == '#' && + node.children[2]&.type == :code - # Prepend # to each line to make it a valid Ruby comment. - code = code_node.children[0].split("\n").map do |line| - next line if line =~ /^\s*#/ - "##{line}" - end.join("\n") + # Do not continue parsing this node + comment = node.children[2] + @comments << ::Parser::Source::Comment.new(comment.location.expression) + return + end - node.updated( - nil, - [nil, nil, code_node.updated(nil, [code]), nil] - ) + node end def node?(node) diff --git a/spec/fixtures/used_keys/app/views/application/comments.html.erb b/spec/fixtures/used_keys/app/views/application/comments.html.erb new file mode 100644 index 00000000..b4fd86ce --- /dev/null +++ b/spec/fixtures/used_keys/app/views/application/comments.html.erb @@ -0,0 +1,37 @@ + +<%= Translate.ignore_html_comment %> + +<% # i18n-tasks-use t('ruby.comment.works') %> +<%= Translate.ruby_comment_works %> + +<%# i18n-tasks-use t('erb.comment.works') %> +<%= Translate.erb_comment_works %> + + +============================================= +============================================= +============================================= +============================================= + + +<%# Do not fail while parsing these: %> + +<%# this should not fail: ' %> + +<%# this is a multiline comment +it's totally fine +nothing should fail %> + +<% # https://github.com/glebm/i18n-tasks/issues/434 %> + + +<%# + +%> diff --git a/spec/fixtures/used_keys/app/views/application/show.html.erb b/spec/fixtures/used_keys/app/views/application/show.html.erb index b8b95fcd..edcb2aba 100644 --- a/spec/fixtures/used_keys/app/views/application/show.html.erb +++ b/spec/fixtures/used_keys/app/views/application/show.html.erb @@ -4,12 +4,11 @@ I18n.t("this_should_not")