Skip to content

Commit 0c3697b

Browse files
authored
ERB: Adds scanner based on Prism (#644)
- It is enabled by setting search: prism: "rails" # or "ruby"
1 parent 144c09d commit 0c3697b

File tree

4 files changed

+517
-5
lines changed

4 files changed

+517
-5
lines changed

CHANGES.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ search:
1717
prism: "ruby"
1818
```
1919
to use the Prism Scanner without Rails support.
20+
- Implements ERB-scanner using Prism, activated with same config as above.
21+
- The Prism-based scanner handles comments differently vs the `whitequark/parser`-based scanner does.
22+
- The usage will be for the magic comment line instead of the subsequent line.
23+
- This should not affect the results of the CLI tasks.
2024

2125
## v1.0.15
2226

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,12 +530,13 @@ WATSONX_PROJECT_ID=<watsonx project id>
530530
WATSONX_MODEL=<optional>
531531
```
532532

533-
### Prism-based scanner
533+
### Prism-based scanner for Ruby and ERB files
534534

535535
There is a scanner based on [Prism](https://github.com/ruby/prism) usable in two different modes.
536536

537537
- `rails` mode parses Rails code and handles context such as controllers, before_actions, model translations and more.
538538
- `ruby` mode parses Ruby code only, and works similar to the existing whitequark/parser-implementation.
539+
- The parser is used for both ruby and ERB files.
539540

540541
#### `rails` mode
541542

lib/i18n/tasks/scanners/erb_ast_scanner.rb

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,19 @@
22

33
require "i18n/tasks/scanners/ruby_scanner"
44
require "i18n/tasks/scanners/local_ruby_parser"
5+
require "i18n/tasks/scanners/occurrence_from_position"
6+
require "prism"
57

68
module I18n::Tasks::Scanners
7-
# Scan for I18n.translate calls in ERB-file better-html and ASTs
9+
# Scan for I18n.translate calls in ERB-file using regexp and Parser/Prism
810
class ErbAstScanner < RubyScanner
9-
DEFAULT_REGEXP = /<%(={1,2}|-|\#|%)?(.*?)([-=])?%>/m
11+
include OccurrenceFromPosition
12+
DEFAULT_REGEXP = /<%(={1,2}|-|\#-?|%)?(.*?)([-=])?%>/m
1013

11-
def initialize(**args)
14+
# Parser scanner, method called in RubyScanner
15+
def ast_parser_parse_file(path)
16+
@ruby_parser ||= LocalRubyParser.new(ignore_blocks: true)
1217
super
13-
@ruby_parser = LocalRubyParser.new(ignore_blocks: true)
1418
end
1519

1620
private
@@ -74,5 +78,59 @@ def root_node(children, buffer)
7478
)
7579
::Parser::AST::Node.new(:erb, children, location: location)
7680
end
81+
82+
# Prism scanner, method called in RubyScanner
83+
def prism_parse_file(path)
84+
occurrences = []
85+
content = File.read(path)
86+
87+
content.scan(DEFAULT_REGEXP) do |indicator, code, _tailch, _rspace|
88+
match = Regexp.last_match
89+
character = indicator ? indicator[0] : nil
90+
start = match.begin(0) + 2 + (character&.size || 0)
91+
92+
case character
93+
when "=", nil, "-"
94+
occurrences += process_code(path, code, content, start)
95+
when "#", "#-"
96+
occurrences += process_comments(path, code, content, start)
97+
end
98+
end
99+
100+
occurrences
101+
end
102+
103+
def process_code(path, code, content, start)
104+
return [] if code.strip.empty? # skip empty ERB tags
105+
106+
process_prism_results(path, Prism.parse(code)).map do |key, occurrence|
107+
[
108+
key,
109+
occurrence_from_position(
110+
path,
111+
content,
112+
start + occurrence.pos,
113+
raw_key: occurrence.raw_key
114+
)
115+
]
116+
end
117+
end
118+
119+
def process_comments(path, code, content, start)
120+
return [] if code.strip.empty?
121+
122+
parsed = Prism.parse(code.gsub("i18n-tasks-use ", "#i18n-tasks-use "))
123+
process_prism_results(path, parsed).map do |key, occurrence|
124+
[
125+
key,
126+
occurrence_from_position(
127+
path,
128+
content,
129+
start + (code.index(key) || occurrence.pos),
130+
raw_key: occurrence.raw_key
131+
)
132+
]
133+
end
134+
end
77135
end
78136
end

0 commit comments

Comments
 (0)