sorbet_view 0.17.0 → 0.17.2
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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 858b6bd700e41b846fc44258e8a702bb8f32f25d952a3c64c1468500619c92f0
|
|
4
|
+
data.tar.gz: 4bbe6e97e5726844fd6135fcb148d486d01c196e33e4c1ef200f088fb79ed1a0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 48c1d98ade67fdb02c84c7650c985fe97ba35e38bdd7973fdb2586bfc4cd89e4fd654435cf5d3e9f8d6b07129cf2573ac76b10c4a857db3f919e92333a6b6b79
|
|
7
|
+
data.tar.gz: fb8bd91ca32e0473c1a533adbf3211d4c75ddbd8283bfc980ac9497c24acb3548efd7007d13d8ae771667753fbaec1951a4215a0cf94592a959c56770288710e
|
|
@@ -97,13 +97,14 @@ module SorbetView
|
|
|
97
97
|
return unless node.respond_to?(:content) && node.content
|
|
98
98
|
|
|
99
99
|
content_token = node.content
|
|
100
|
-
|
|
100
|
+
raw_value = content_token.value.to_s
|
|
101
|
+
code = raw_value.strip
|
|
101
102
|
return if code.empty?
|
|
102
103
|
|
|
103
|
-
# Herb lines are 1-based, we use 0-based
|
|
104
|
+
# Herb lines are 1-based, we use 0-based; raw content begins right after
|
|
105
|
+
# the opening tag, so advance past leading whitespace stripped from `code`.
|
|
104
106
|
loc = content_token.location
|
|
105
|
-
line = loc.start.line - 1
|
|
106
|
-
column = loc.start.column
|
|
107
|
+
line, column = advance_past_leading_whitespace(raw_value, loc.start.line - 1, loc.start.column)
|
|
107
108
|
|
|
108
109
|
tag = node.respond_to?(:tag_opening) ? node.tag_opening.value.to_s : '<%'
|
|
109
110
|
type = case tag
|
|
@@ -120,10 +121,12 @@ module SorbetView
|
|
|
120
121
|
return unless node.respond_to?(:content) && node.content
|
|
121
122
|
|
|
122
123
|
loc = node.content.location
|
|
124
|
+
raw_value = node.content.value.to_s
|
|
125
|
+
line, column = advance_past_leading_whitespace(raw_value, loc.start.line - 1, loc.start.column)
|
|
123
126
|
segments << RubySegment.new(
|
|
124
127
|
code: 'end',
|
|
125
|
-
line:
|
|
126
|
-
column:
|
|
128
|
+
line: line,
|
|
129
|
+
column: column,
|
|
127
130
|
type: :statement
|
|
128
131
|
)
|
|
129
132
|
end
|
|
@@ -137,14 +140,16 @@ module SorbetView
|
|
|
137
140
|
source.scan(INDICATOR_PATTERN) do
|
|
138
141
|
match = T.must(Regexp.last_match)
|
|
139
142
|
indicator = match[1] || ''
|
|
140
|
-
|
|
143
|
+
raw_code = match[2] || ''
|
|
144
|
+
code = raw_code.strip
|
|
141
145
|
offset = T.must(match.begin(0))
|
|
142
146
|
|
|
143
147
|
next if code.empty?
|
|
144
148
|
|
|
145
149
|
line, column = offset_to_line_column(line_offsets, offset)
|
|
146
150
|
tag_prefix_len = 2 + indicator.length
|
|
147
|
-
|
|
151
|
+
content_column = column + tag_prefix_len
|
|
152
|
+
code_line, code_column = advance_past_leading_whitespace(raw_code, line, content_column)
|
|
148
153
|
|
|
149
154
|
type = case indicator
|
|
150
155
|
when '#' then :comment
|
|
@@ -152,7 +157,7 @@ module SorbetView
|
|
|
152
157
|
else :statement
|
|
153
158
|
end
|
|
154
159
|
|
|
155
|
-
segments << RubySegment.new(code: code, line:
|
|
160
|
+
segments << RubySegment.new(code: code, line: code_line, column: code_column, type: type)
|
|
156
161
|
end
|
|
157
162
|
|
|
158
163
|
segments
|
|
@@ -173,6 +178,23 @@ module SorbetView
|
|
|
173
178
|
column = offset - (line_offsets[line] || 0)
|
|
174
179
|
[line, column]
|
|
175
180
|
end
|
|
181
|
+
|
|
182
|
+
# Returns the (line, column) of the first non-whitespace char in raw_value,
|
|
183
|
+
# given the position where raw_value begins. Used so that stripping leading
|
|
184
|
+
# whitespace from ERB content does not desync the segment's start position.
|
|
185
|
+
sig { params(raw_value: String, line: Integer, column: Integer).returns([Integer, Integer]) }
|
|
186
|
+
def advance_past_leading_whitespace(raw_value, line, column)
|
|
187
|
+
leading = raw_value[/\A\s*/] || ''
|
|
188
|
+
return [line, column] if leading.empty?
|
|
189
|
+
|
|
190
|
+
newlines = leading.count("\n")
|
|
191
|
+
if newlines == 0
|
|
192
|
+
[line, column + leading.length]
|
|
193
|
+
else
|
|
194
|
+
last_nl = T.must(leading.rindex("\n"))
|
|
195
|
+
[line + newlines, leading.length - last_nl - 1]
|
|
196
|
+
end
|
|
197
|
+
end
|
|
176
198
|
end
|
|
177
199
|
end
|
|
178
200
|
end
|
|
@@ -117,17 +117,19 @@ module SorbetView
|
|
|
117
117
|
|
|
118
118
|
lines << " #{stripped}"
|
|
119
119
|
|
|
120
|
-
# Build mapping entry
|
|
120
|
+
# Build mapping entry — for the first line we already advanced past
|
|
121
|
+
# leading whitespace in the adapter; for subsequent lines, use the
|
|
122
|
+
# actual indent of the source line so the template column matches.
|
|
121
123
|
template_start_col = if i == 0
|
|
122
124
|
seg.column
|
|
123
125
|
else
|
|
124
|
-
|
|
126
|
+
code_line.length - code_line.lstrip.length
|
|
125
127
|
end
|
|
126
128
|
|
|
127
129
|
mapping_entries << SourceMap::MappingEntry.new(
|
|
128
130
|
template_range: SourceMap::Range.new(
|
|
129
131
|
start: SourceMap::Position.new(line: seg.line + i, column: template_start_col),
|
|
130
|
-
end_: SourceMap::Position.new(line: seg.line + i, column: template_start_col +
|
|
132
|
+
end_: SourceMap::Position.new(line: seg.line + i, column: template_start_col + stripped.length)
|
|
131
133
|
),
|
|
132
134
|
ruby_range: SourceMap::Range.new(
|
|
133
135
|
start: SourceMap::Position.new(line: ruby_line, column: 4),
|
data/lib/sorbet_view/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sorbet_view
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.17.
|
|
4
|
+
version: 0.17.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- kazuma
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-04-
|
|
10
|
+
date: 2026-04-22 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: herb
|
|
@@ -118,7 +118,6 @@ files:
|
|
|
118
118
|
- lib/sorbet_view/source_map/source_map.rb
|
|
119
119
|
- lib/sorbet_view/version.rb
|
|
120
120
|
- lib/tapioca/dsl/compilers/sorbet_view.rb
|
|
121
|
-
- sorbet_view.gemspec
|
|
122
121
|
- vscode/.gitignore
|
|
123
122
|
- vscode/.vscode/launch.json
|
|
124
123
|
- vscode/.vscodeignore
|
data/sorbet_view.gemspec
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'lib/sorbet_view/version'
|
|
4
|
-
|
|
5
|
-
Gem::Specification.new do |spec|
|
|
6
|
-
spec.name = 'sorbet_view'
|
|
7
|
-
spec.version = SorbetView::VERSION
|
|
8
|
-
spec.authors = ['kazuma']
|
|
9
|
-
spec.summary = 'Sorbet type-checking for Rails view templates'
|
|
10
|
-
spec.description = 'Extracts Ruby code from view templates (ERB, etc.) for Sorbet type-checking, with LSP support'
|
|
11
|
-
spec.homepage = 'https://github.com/kazzix14/sorbet_view'
|
|
12
|
-
spec.license = 'MIT'
|
|
13
|
-
spec.required_ruby_version = '>= 3.2'
|
|
14
|
-
|
|
15
|
-
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
16
|
-
spec.metadata['homepage_uri'] = spec.homepage
|
|
17
|
-
spec.metadata['source_code_uri'] = spec.homepage
|
|
18
|
-
|
|
19
|
-
spec.files = Dir.chdir(__dir__) do
|
|
20
|
-
`git ls-files -z`.split("\x0").reject do |f|
|
|
21
|
-
(File.expand_path(f) == __FILE__) ||
|
|
22
|
-
f.start_with?(*%w[bin/ test/ spec/ features/ .git .github Gemfile])
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
spec.bindir = 'exe'
|
|
26
|
-
spec.executables = ['sv']
|
|
27
|
-
spec.require_paths = ['lib']
|
|
28
|
-
|
|
29
|
-
spec.add_dependency 'herb'
|
|
30
|
-
spec.add_dependency 'listen', '~> 3.0'
|
|
31
|
-
spec.add_dependency 'psych'
|
|
32
|
-
spec.add_dependency 'sorbet-runtime'
|
|
33
|
-
spec.add_dependency 'srb_lens', '~> 0.5.1'
|
|
34
|
-
end
|