p2 2.2 → 2.3

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: b35bc76b761dd22bacd7e2b8844f3be20cabdb38ee6174d4e4eaeb144f5562d8
4
- data.tar.gz: d677436567940ef41f922892b55844685d31fc52a8287c06f2ea0d89d2f1db55
3
+ metadata.gz: ad3bf1a720998e9b118a15d4a7b57677c5938bf74d6f65f474653ecaf58a9387
4
+ data.tar.gz: 6299a9c113a3bf8cc3c0a2c745ba281f7f42304ae7d127fca907b2cead73788c
5
5
  SHA512:
6
- metadata.gz: 37dd322edd50f7061e4375dbc8cb06a22d137106757250d99bc58b625e2dae8c7ea8fc00990e801caee03bae5fe59ba040b8456ef4e14b632874c30cf0784476
7
- data.tar.gz: fe24352b6bbc3843c0213e842f07cd094ae83bbb6475f86174e43dd8a55ba9497b832e9b195ef8364f7c5984dc60c4370fc971a7297a79c8d692e9453456d63a
6
+ metadata.gz: 8fffd7f51d9efd4a537f5e870987bf7cc849aaf3a22a912cb36f6f2ab046259a1191201966e9497941b863a7e0ac35a2dc49d4e6ecf93445d6d1ed0d4725fc09
7
+ data.tar.gz: 6b7165c8d382c91d97d7a4799e2da53e80cacb2100ce7703017af7adee1ec53c0a474a2ff6798231ec848e5463ffce26231026f0f135057803b4d9cf53ac9090
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ # 2.3 2025-08-10
2
+
3
+ - Fix whitespace issue in visit_yield_node
4
+ - Reimplement and optimize exception backtrace translation
5
+ - Minor improvement to code generation
6
+
1
7
  # 2.2 2025-08-09
2
8
 
3
9
  - Update docs
data/lib/p2/compiler.rb CHANGED
@@ -48,6 +48,15 @@ module P2
48
48
  eval(code, proc.binding, source_map[:compiled_fn])
49
49
  end
50
50
 
51
+ def self.source_map_store
52
+ @source__map_store ||= {}
53
+ end
54
+
55
+ def self.store_source_map(source_map)
56
+ fn = source_map[:compiled_fn]
57
+ source_map_store[fn] = source_map
58
+ end
59
+
51
60
  attr_reader :source_map
52
61
 
53
62
  # Initializes a compiler.
@@ -90,7 +99,7 @@ module P2
90
99
  source_code = @buffer
91
100
  @buffer = +''
92
101
  if wrap
93
- emit("# frozen_string_literal: true\n(#{@source_map.inspect}).then { |src_map| ->(__buffer__")
102
+ emit("# frozen_string_literal: true\n->(__buffer__")
94
103
 
95
104
  params = orig_ast.parameters
96
105
  params = params&.parameters
@@ -103,16 +112,19 @@ module P2
103
112
  emit(', &__block__')
104
113
  end
105
114
 
106
- emit(") do\n")
115
+ emit(") {\n")
107
116
  end
108
117
  @buffer << source_code
109
118
  emit_defer_postlude if @defer_mode
110
119
  if wrap
111
120
  emit('; __buffer__')
112
121
  adjust_whitespace(orig_ast.closing_loc)
113
- emit(";") if @buffer !~ /\n\s*$/m
114
- emit("rescue Exception => e; P2.translate_backtrace(e, src_map); raise e; end }")
122
+ emit('}')
123
+ # emit(";") if @buffer !~ /\n\s*$/m
124
+ # emit("rescue Exception => e; P2.translate_backtrace(e, src_map); raise e; end }")
115
125
  end
126
+ update_source_map
127
+ Compiler.store_source_map(@source_map)
116
128
  @buffer
117
129
  end
118
130
 
@@ -136,19 +148,16 @@ module P2
136
148
  when Prism::BlockArgumentNode
137
149
  flush_html_parts!
138
150
  adjust_whitespace(node.block)
139
- emit("; #{format_code(node.block.expression)}.render_to_buffer(__buffer__)")
151
+ emit("; #{format_code(node.block.expression)}.compiled_proc.(__buffer__)")
140
152
  end
141
153
 
142
154
  if node.inner_text
143
155
  if is_static_node?(node.inner_text)
144
156
  emit_html(node.location, ERB::Escape.html_escape(format_literal(node.inner_text)))
145
157
  else
146
- convert_to_s = !is_string_type_node?(node.inner_text)
147
- if convert_to_s
148
- emit_html(node.location, interpolated("ERB::Escape.html_escape((#{format_code(node.inner_text)}).to_s)"))
149
- else
150
- emit_html(node.location, interpolated("ERB::Escape.html_escape(#{format_code(node.inner_text)})"))
151
- end
158
+ to_s = is_string_type_node?(node.inner_text) ? '' : '.to_s'
159
+
160
+ emit_html(node.location, interpolated("ERB::Escape.html_escape((#{format_code(node.inner_text)})#{to_s})"))
152
161
  end
153
162
  end
154
163
  emit_html(node.location, format_html_tag_close(tag))
@@ -165,7 +174,7 @@ module P2
165
174
  emit(node.receiver.location)
166
175
  emit('::')
167
176
  end
168
- emit("; #{node.name}.render_to_buffer(__buffer__")
177
+ emit("; #{node.name}.compiled_proc.(__buffer__")
169
178
  if node.arguments
170
179
  emit(', ')
171
180
  visit(node.arguments)
@@ -284,15 +293,15 @@ module P2
284
293
  # @param node [P2::YieldNode] node
285
294
  # @return [void]
286
295
  def visit_yield_node(node)
287
- adjust_whitespace(node.location)
288
296
  flush_html_parts!
297
+ adjust_whitespace(node.location)
289
298
  @yield_used = true
290
- emit("; (__block__ ? __block__.render_to_buffer(__buffer__")
299
+ emit("; (__block__ ? __block__.compiled_proc.(__buffer__")
291
300
  if node.arguments
292
301
  emit(', ')
293
302
  visit(node.arguments)
294
303
  end
295
- emit(") : raise(LocalJumpError, 'no block given (yield)'))")
304
+ emit(") : raise(LocalJumpError, 'no block given (yield/emit_yield)'))")
296
305
  end
297
306
 
298
307
  private
data/lib/p2/proc_ext.rb CHANGED
@@ -49,6 +49,9 @@ class ::Proc
49
49
  # @return [String] HTML string
50
50
  def render(*a, **b, &c)
51
51
  compiled_proc.(+'', *a, **b, &c)
52
+ rescue Exception => e
53
+ P2.translate_backtrace(e)
54
+ raise e
52
55
  end
53
56
 
54
57
  # Renders the proc into the given buffer
data/lib/p2/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module P2
4
- VERSION = '2.2'
4
+ VERSION = '2.3'
5
5
  end
data/lib/p2.rb CHANGED
@@ -44,29 +44,28 @@ module P2
44
44
  # @param source_map [Hash] source map
45
45
  #
46
46
  # @return [Exception] raised exception
47
- def translate_backtrace(exception, source_map)
48
- re = compute_source_map_re(source_map)
49
- source_fn = source_map[:source_fn]
50
- backtrace = exception.backtrace.map {
51
- if (m = it.match(re))
52
- line = m[2].to_i
53
- source_line = source_map[line] || "?(#{line})"
54
- it.sub(m[1], "#{source_fn}:#{source_line}")
55
- else
56
- it
57
- end
58
- }
47
+ def translate_backtrace(exception)
48
+ cache = {}
49
+ backtrace = exception.backtrace.map { |e| compute_backtrace_entry(e, cache) }
59
50
  exception.set_backtrace(backtrace)
60
51
  exception
61
52
  end
62
53
 
63
- # Computes a Regexp for matching hits in a backtrace.
64
- #
65
- # @param source_map [Hash] source map
66
- # @return [Regexp] computed regexp
67
- def compute_source_map_re(source_map)
68
- escaped = source_map[:compiled_fn].gsub(/[\(\)]/) { "\\#{it[0]}" }
69
- /^(#{escaped}\:(\d+))/
54
+ # Computes a backtrace entry with caching.
55
+ #
56
+ # @param entry [String] backtrace entry
57
+ # @param cache [Hash] cache store mapping compiled filename to source_map
58
+ def compute_backtrace_entry(entry, cache)
59
+ m = entry.match(/^((\:\:\(.+\:.+\))\:(\d+))/)
60
+ return entry if !m
61
+
62
+ fn = m[2]
63
+ line = m[3].to_i
64
+ source_map = cache[fn] ||= Compiler.source_map_store[fn]
65
+ return entry if !source_map
66
+
67
+ source_line = source_map[line] || "?(#{line})"
68
+ entry.sub(m[1], "#{source_map[:source_fn]}:#{source_line}")
70
69
  end
71
70
 
72
71
  # Renders Markdown into HTML. The `opts` argument will be merged with the
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: p2
3
3
  version: !ruby/object:Gem::Version
4
- version: '2.2'
4
+ version: '2.3'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner