ast-crispr 7.1.9 → 7.1.11

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: bd3dc44a9727fc783f41d0ff6cd2e2c916a4270e49d40b8d4b4302a84c71e79c
4
- data.tar.gz: 8c2722fca88a07c716059930f6f43f11ed4747a940989f6c2d3dfc9e4e589bd3
3
+ metadata.gz: 4168fea4e725521094e87a966bb547ab182d1325d7eaab859df07cdae015b052
4
+ data.tar.gz: f9b4b0a1b6b3e4e88b7aef5dff494cffcce25cd2d866b4b0e74ef958856d15b2
5
5
  SHA512:
6
- metadata.gz: 1528d81c8263d9af9adaa4ee02e63d8352c42561242b009d0cbffae4268e398b279cc7971aec5b1750bb7758a7cb3930c0735468271d09f1e3e76c904c98ebac
7
- data.tar.gz: cb18b1931e9fc8f949de3db02794d6be210d00f2acba16b492d1a5ea2a0990b9e2f3878401c7ec276c1f216ef2d55ab8f55d0a3e0602e72c8a1e878b414c7b0a
6
+ metadata.gz: d07d4bc65bb20b37e229e75a7d1873843553964d71d91410a6073980d286eadcbc49424ba0265ae93e790d63fc72c279de6024a7e486c0cbb1359b1b3d8ebe84
7
+ data.tar.gz: 73356af121cda989fd343410cabb807c3c8d64c4e7b2e7fd0bb7e62a6e1d01687b9676f8206958344452fc580e6fffc29d7f4031faf47b63fe22fdd65eb87108
checksums.yaml.gz.sig CHANGED
Binary file
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'typed_core_bridge'
4
+
5
+ module Ast
6
+ module Crispr
7
+ # Explicit profile and source-projection bridge to the Rust ast-crispr
8
+ # kernel. Structural node selection remains owned by Ruby.
9
+ class RustHostProvider
10
+ include TypedCoreBridge
11
+ PROVIDER_ID = 'rust.ast-crispr.profile'
12
+
13
+ class << self
14
+ def available?
15
+ require 'structuredmerge_core' unless defined?(::StructuredmergeCore)
16
+ %i[report_structural_boundary report_structural_limit report_structural_match
17
+ report_structural_selection report_structural_destination report_structural_operations
18
+ apply_explicit_source_edits].all? { |method| ::StructuredmergeCore.respond_to?(method) }
19
+ rescue LoadError
20
+ false
21
+ end
22
+ end
23
+
24
+ def provider_id = PROVIDER_ID
25
+
26
+ def capabilities
27
+ {
28
+ operations: %i[boundary limit match selection destination operation batch_operations explicit_source_edits],
29
+ backend: :rust_tslp,
30
+ execution: :profile_reports_and_explicit_source_edits,
31
+ source_projection: :explicit_byte_ranges,
32
+ structural_selection: :ruby_owned
33
+ }.freeze
34
+ end
35
+
36
+ def report(request)
37
+ unless self.class.available?
38
+ raise Error.new('Rust ast-crispr host is unavailable',
39
+ code: 'ast_crispr_rust_host_unavailable')
40
+ end
41
+
42
+ core_report(request)
43
+ rescue KeyError, ArgumentError, TypeError => e
44
+ raise e.message.to_s
45
+ end
46
+
47
+ def apply_source_edits(request)
48
+ unless self.class.available?
49
+ raise Error.new('Rust ast-crispr host is unavailable',
50
+ code: 'ast_crispr_rust_host_unavailable')
51
+ end
52
+
53
+ core_source_edits(request)
54
+ rescue KeyError, ArgumentError, TypeError => e
55
+ raise e.message.to_s
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,169 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'digest'
4
+ require 'securerandom'
5
+
6
+ module Ast
7
+ module Crispr
8
+ # Transport adaptation only. Classification and rendering are core-owned;
9
+ # this adapter never selects AST nodes or writes files.
10
+ module TypedCoreBridge
11
+ REQUEST_FIELDS = {
12
+ 'match' => %w[start_boundary end_boundary payload_kind],
13
+ 'selection' => %w[owner_scope owner_selector selector_kind selection_intent comment_region
14
+ include_trailing_gap],
15
+ 'destination' => %w[resolution_kind resolution_source anchor_boundary used_if_missing],
16
+ 'operation' => %w[operation_kind source_requirement destination_requirement replacement_source
17
+ captures_source_text supports_if_missing]
18
+ }.freeze
19
+ REPORT_FIELDS = {
20
+ 'match' => %w[start_boundary start_boundary_family known_start_boundary end_boundary end_boundary_family
21
+ known_end_boundary payload_kind payload_family known_payload_kind comment_anchored trailing_gap_extended],
22
+ 'selection' => %w[owner_scope owner_selector owner_selector_family known_owner_selector selector_kind
23
+ selector_kind_family known_selector_kind selection_intent selection_intent_family known_selection_intent comment_region comment_region_family known_comment_region comment_anchored include_trailing_gap],
24
+ 'destination' => %w[resolution_kind resolution_family known_resolution_kind resolution_source
25
+ resolution_source_family known_resolution_source anchor_boundary anchor_boundary_family known_anchor_boundary used_if_missing append_fallback anchored],
26
+ 'operation' => %w[operation_kind operation_family known_operation_kind source_requirement
27
+ known_source_requirement destination_requirement known_destination_requirement replacement_source known_replacement_source captures_source_text supports_if_missing selects_source requires_source supports_destination requires_destination explicit_replacement may_reuse_captured_text]
28
+ }.freeze
29
+ FLAGS = %w[include_trailing_gap used_if_missing captures_source_text supports_if_missing].freeze
30
+ OPERATORS = { '==' => 'equal', '!=' => 'not_equal', '<=' => 'at_most', '>=' => 'at_least', '<' => 'less_than',
31
+ '>' => 'greater_than' }.freeze
32
+
33
+ def core_report(request)
34
+ request = request.transform_keys(&:to_s)
35
+ kind = request.fetch('kind')
36
+ case kind
37
+ when 'boundary'
38
+ boundary_hash(StructuredmergeCore.report_structural_boundary)
39
+ when 'limit'
40
+ spec = request['spec']
41
+ constraints = spec.nil? ? nil : limit_constraints(spec)
42
+ result = StructuredmergeCore.report_structural_limit(StructuredmergeCore::CrisprLimitRequest.new(
43
+ constraints: constraints, counts: []
44
+ ))
45
+ { 'description' => result.description }
46
+ when 'batch_operations', 'operation'
47
+ operations = kind == 'operation' ? [request] : request.fetch('operations')
48
+ result = StructuredmergeCore.report_structural_operations(operations.map do |item|
49
+ profile_request('operation', item.transform_keys(&:to_s))
50
+ end)
51
+ profiles = result.operation_profiles.map { |profile| report_hash('operation', profile) }
52
+ if kind == 'operation'
53
+ profiles.first
54
+ else
55
+ { 'operation_count' => result.operation_count,
56
+ 'operation_kinds' => result.operation_kinds, 'operation_profiles' => profiles }
57
+ end
58
+ when 'match', 'selection', 'destination'
59
+ result = StructuredmergeCore.public_send("report_structural_#{kind}", profile_request(kind, request))
60
+ report_hash(kind, result)
61
+ else
62
+ raise ArgumentError, "unsupported ast-crispr report kind #{kind.inspect}"
63
+ end
64
+ end
65
+
66
+ def core_source_edits(request)
67
+ request = request.transform_keys(&:to_s)
68
+ source = request.fetch('source').dup.force_encoding(Encoding::UTF_8)
69
+ raise ArgumentError, 'source must be valid UTF-8' unless source.valid_encoding?
70
+
71
+ edits = request.fetch('edits').map do |entry|
72
+ entry = entry.transform_keys(&:to_s)
73
+ StructuredmergeCore::ExplicitSourceEdit.new(start_byte: entry.fetch('start_byte'),
74
+ end_byte: entry.fetch('end_byte'), replacement: entry.fetch('replacement'))
75
+ end
76
+ crlf = source.scan("\r\n").length
77
+ descriptor = StructuredmergeCore::SourceDescriptor.new(source_id: 'explicit-source', role: 'source',
78
+ byte_length: source.bytesize, sha256: Digest::SHA256.hexdigest(source), encoding: 'utf8',
79
+ bom: source.start_with?("\uFEFF"), final_newline: source.end_with?("\n", "\r"),
80
+ line_endings: StructuredmergeCore::LineEndings.new(lf: source.count("\n") - crlf, crlf: crlf, bare_cr: source.count("\r") - crlf))
81
+ input = StructuredmergeCore::SourceEditRequest.new(request_id: SecureRandom.uuid,
82
+ source: StructuredmergeCore::SourceInput.new(descriptor: descriptor, bytes: source.bytes), edits: edits)
83
+ limits = StructuredmergeCore::SourceEditLimits.new(max_input_bytes: source.bytesize,
84
+ max_output_bytes: source.bytesize + edits.sum do |edit|
85
+ edit.replacement.bytesize
86
+ end, max_edits: edits.length)
87
+ result = StructuredmergeCore.apply_explicit_source_edits(input, limits)
88
+ { 'ok' => true, 'output' => result.output, 'edit_count' => result.edit_count,
89
+ 'source_projection' => 'explicit_byte_ranges' }
90
+ rescue RuntimeError => e
91
+ raise unless e.message.start_with?('source_edit.rejected:')
92
+
93
+ { 'ok' => false, 'edit_count' => edits.length, 'source_projection' => 'explicit_byte_ranges',
94
+ 'diagnostics' => [{ 'severity' => 'error', 'category' => 'source_edit_rejected', 'message' => e.message.delete_prefix('source_edit.rejected: ') }] }
95
+ end
96
+
97
+ private
98
+
99
+ def profile_request(kind, request)
100
+ fields = REQUEST_FIELDS.fetch(kind).to_h do |field|
101
+ value = if FLAGS.include?(field)
102
+ request[field] == true
103
+ elsif field == 'comment_region'
104
+ request[field].is_a?(String) ? request[field] : nil
105
+ else
106
+ request.fetch(field).tap do |item|
107
+ raise ArgumentError, "#{field} must be a string" unless item.is_a?(String)
108
+ end
109
+ end
110
+ [field.to_sym, value]
111
+ end
112
+ StructuredmergeCore.const_get("Crispr#{kind.capitalize}Request").new(**fields)
113
+ end
114
+
115
+ def report_hash(kind, report)
116
+ REPORT_FIELDS.fetch(kind).to_h { |field| [field, report.public_send(field)] }
117
+ end
118
+
119
+ def boundary_hash(report)
120
+ result = %w[package layer status base_contract_package initial_exports future_exports].to_h do |field|
121
+ [field, report.public_send(field)]
122
+ end
123
+ result['relationship'] = %w[ast_merge ast_crispr provider_packages ast_template].to_h do |field|
124
+ [field, report.relationship.public_send(field)]
125
+ end
126
+ result['metadata'] = %w[source decision].to_h { |field| [field, report.metadata.public_send(field)] }
127
+ result['implementations'] = report.implementations.map do |item|
128
+ row = { 'language' => item.language, 'package_name' => item.package_name }
129
+ { 'import' => :import_path, 'require' => :require_path, 'crate' => :crate_name }.each do |key, field|
130
+ value = item.public_send(field)
131
+ row[key] = value unless value.nil?
132
+ end
133
+ row
134
+ end
135
+ result
136
+ end
137
+
138
+ def limit_constraints(spec)
139
+ case spec
140
+ when Array
141
+ spec.flat_map { |entry| limit_constraints(entry) }
142
+ when Hash
143
+ spec = spec.transform_keys(&:to_s)
144
+ constraints = { 'exactly' => 'equal', 'at_most' => 'at_most',
145
+ 'at_least' => 'at_least' }.filter_map do |key, operator|
146
+ value = spec[key]
147
+ limit_constraint(operator, value) if value.is_a?(Integer) && value >= 0
148
+ end
149
+ constraints << limit_constraint('at_most', 1) if spec['none_or_one'] == true
150
+ raise ArgumentError, 'ast-crispr limit must define at least one constraint' if constraints.empty?
151
+
152
+ constraints
153
+ when String
154
+ # This parses the limit expression DSL, not source-code structure.
155
+ match = /\A(==|!=|<=|>=|<|>)\s*(\+?\d+)\z/.match(spec.strip)
156
+ raise ArgumentError, 'Invalid ast-crispr limit expression' unless match
157
+
158
+ [limit_constraint(OPERATORS.fetch(match[1]), Integer(match[2], 10))]
159
+ else
160
+ raise ArgumentError, 'Unsupported ast-crispr limit specification'
161
+ end
162
+ end
163
+
164
+ def limit_constraint(operator, value)
165
+ StructuredmergeCore::CrisprLimitConstraint.new(operator: operator, value: value)
166
+ end
167
+ end
168
+ end
169
+ end
@@ -5,7 +5,7 @@ module Ast
5
5
  # Version namespace for this gem.
6
6
  module Version
7
7
  # Current gem version.
8
- VERSION = '7.1.9'
8
+ VERSION = '7.1.11'
9
9
  end
10
10
  # Current gem version exposed at the traditional constant location.
11
11
  VERSION = Version::VERSION # Traditional Constant Location
data/lib/ast/crispr.rb CHANGED
@@ -6,6 +6,7 @@ require_relative 'crispr/version'
6
6
 
7
7
  module Ast
8
8
  module Crispr
9
+ autoload :RustHostProvider, 'ast/crispr/rust_host_provider'
9
10
  PACKAGE_NAME = 'ast-crispr'
10
11
 
11
12
  class Error < StandardError
@@ -1683,6 +1684,10 @@ module Ast
1683
1684
  end
1684
1685
 
1685
1686
  class << self
1687
+ def rust_host_provider
1688
+ @rust_host_provider ||= RustHostProvider.new
1689
+ end
1690
+
1686
1691
  def ast_merge_contract_anchor
1687
1692
  'Ast::Merge.structured_edit'
1688
1693
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ast-crispr
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.1.9
4
+ version: 7.1.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -43,14 +43,14 @@ dependencies:
43
43
  requirements:
44
44
  - - '='
45
45
  - !ruby/object:Gem::Version
46
- version: 7.1.9
46
+ version: 7.1.11
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - '='
52
52
  - !ruby/object:Gem::Version
53
- version: 7.1.9
53
+ version: 7.1.11
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: service_actor
56
56
  requirement: !ruby/object:Gem::Requirement
@@ -91,20 +91,20 @@ dependencies:
91
91
  requirements:
92
92
  - - "~>"
93
93
  - !ruby/object:Gem::Version
94
- version: '3.0'
94
+ version: '3.1'
95
95
  - - ">="
96
96
  - !ruby/object:Gem::Version
97
- version: 3.0.34
97
+ version: 3.1.8
98
98
  type: :development
99
99
  prerelease: false
100
100
  version_requirements: !ruby/object:Gem::Requirement
101
101
  requirements:
102
102
  - - "~>"
103
103
  - !ruby/object:Gem::Version
104
- version: '3.0'
104
+ version: '3.1'
105
105
  - - ">="
106
106
  - !ruby/object:Gem::Version
107
- version: 3.0.34
107
+ version: 3.1.8
108
108
  - !ruby/object:Gem::Dependency
109
109
  name: bundler-audit
110
110
  requirement: !ruby/object:Gem::Requirement
@@ -182,7 +182,7 @@ dependencies:
182
182
  version: '3.2'
183
183
  - - ">="
184
184
  - !ruby/object:Gem::Version
185
- version: 3.2.3
185
+ version: 3.2.5
186
186
  type: :development
187
187
  prerelease: false
188
188
  version_requirements: !ruby/object:Gem::Requirement
@@ -192,7 +192,7 @@ dependencies:
192
192
  version: '3.2'
193
193
  - - ">="
194
194
  - !ruby/object:Gem::Version
195
- version: 3.2.3
195
+ version: 3.2.5
196
196
  - !ruby/object:Gem::Dependency
197
197
  name: kettle-test
198
198
  requirement: !ruby/object:Gem::Requirement
@@ -202,7 +202,7 @@ dependencies:
202
202
  version: '2.0'
203
203
  - - ">="
204
204
  - !ruby/object:Gem::Version
205
- version: 2.0.21
205
+ version: 2.0.23
206
206
  type: :development
207
207
  prerelease: false
208
208
  version_requirements: !ruby/object:Gem::Requirement
@@ -212,7 +212,7 @@ dependencies:
212
212
  version: '2.0'
213
213
  - - ">="
214
214
  - !ruby/object:Gem::Version
215
- version: 2.0.21
215
+ version: 2.0.23
216
216
  - !ruby/object:Gem::Dependency
217
217
  name: turbo_tests2
218
218
  requirement: !ruby/object:Gem::Requirement
@@ -222,7 +222,7 @@ dependencies:
222
222
  version: '3.2'
223
223
  - - ">="
224
224
  - !ruby/object:Gem::Version
225
- version: 3.2.7
225
+ version: 3.2.14
226
226
  type: :development
227
227
  prerelease: false
228
228
  version_requirements: !ruby/object:Gem::Requirement
@@ -232,7 +232,7 @@ dependencies:
232
232
  version: '3.2'
233
233
  - - ">="
234
234
  - !ruby/object:Gem::Version
235
- version: 3.2.7
235
+ version: 3.2.14
236
236
  - !ruby/object:Gem::Dependency
237
237
  name: ruby-progressbar
238
238
  requirement: !ruby/object:Gem::Requirement
@@ -256,7 +256,7 @@ dependencies:
256
256
  version: '1.0'
257
257
  - - ">="
258
258
  - !ruby/object:Gem::Version
259
- version: 1.0.8
259
+ version: 1.0.9
260
260
  type: :development
261
261
  prerelease: false
262
262
  version_requirements: !ruby/object:Gem::Requirement
@@ -266,7 +266,7 @@ dependencies:
266
266
  version: '1.0'
267
267
  - - ">="
268
268
  - !ruby/object:Gem::Version
269
- version: 1.0.8
269
+ version: 1.0.9
270
270
  - !ruby/object:Gem::Dependency
271
271
  name: gitmoji-regex
272
272
  requirement: !ruby/object:Gem::Requirement
@@ -276,7 +276,7 @@ dependencies:
276
276
  version: '2.0'
277
277
  - - ">="
278
278
  - !ruby/object:Gem::Version
279
- version: 2.0.12
279
+ version: 2.0.15
280
280
  type: :development
281
281
  prerelease: false
282
282
  version_requirements: !ruby/object:Gem::Requirement
@@ -286,7 +286,7 @@ dependencies:
286
286
  version: '2.0'
287
287
  - - ">="
288
288
  - !ruby/object:Gem::Version
289
- version: 2.0.12
289
+ version: 2.0.15
290
290
  description: "\U0001F9EC A thin structural edit tool layer over ast-merge structured-edit
291
291
  contracts."
292
292
  email:
@@ -305,6 +305,8 @@ files:
305
305
  - lib/ast/crispr/rspec/shared_examples/operation_profile.rb
306
306
  - lib/ast/crispr/rspec/shared_examples/selection_profile.rb
307
307
  - lib/ast/crispr/rspec/shared_examples/structure_profile.rb
308
+ - lib/ast/crispr/rust_host_provider.rb
309
+ - lib/ast/crispr/typed_core_bridge.rb
308
310
  - lib/ast/crispr/version.rb
309
311
  - sig/ast/crispr.rbs
310
312
  homepage: https://github.com/structuredmerge/structuredmerge-ruby
@@ -313,10 +315,10 @@ licenses:
313
315
  - PolyForm-Small-Business-1.0.0
314
316
  metadata:
315
317
  homepage_uri: https://structuredmerge.org
316
- source_code_uri: https://github.com/structuredmerge/structuredmerge-ruby/tree/v7.1.9
317
- changelog_uri: https://github.com/structuredmerge/structuredmerge-ruby/blob/v7.1.9/CHANGELOG.md
318
+ source_code_uri: https://github.com/structuredmerge/structuredmerge-ruby/tree/v7.1.11
319
+ changelog_uri: https://github.com/structuredmerge/structuredmerge-ruby/blob/v7.1.11/CHANGELOG.md
318
320
  bug_tracker_uri: https://github.com/structuredmerge/structuredmerge-ruby/issues
319
- documentation_uri: https://www.rubydoc.info/gems/ast-crispr/7.1.9
321
+ documentation_uri: https://www.rubydoc.info/gems/ast-crispr/7.1.11
320
322
  funding_uri: https://github.com/sponsors/pboling
321
323
  wiki_uri: https://github.com/structuredmerge/structuredmerge-ruby/wiki
322
324
  news_uri: https://www.railsbling.com/tags/ast-crispr
@@ -346,7 +348,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
346
348
  - !ruby/object:Gem::Version
347
349
  version: '0'
348
350
  requirements: []
349
- rubygems_version: 4.0.17
351
+ rubygems_version: 4.0.20
350
352
  specification_version: 4
351
353
  summary: "\U0001F9EC Structured edit tooling over Structured Merge AST contracts"
352
354
  test_files: []
metadata.gz.sig CHANGED
Binary file