ruby-merge 7.1.1 → 7.1.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/README.md +2 -10
- data/lib/ruby/merge/provider.rb +77 -0
- data/lib/ruby/merge/version.rb +1 -1
- data/lib/ruby/merge.rb +3 -11
- data/sig/ruby/merge.rbs +13 -0
- data.tar.gz.sig +0 -0
- metadata +31 -27
- metadata.gz.sig +0 -0
- data/lib/ruby/merge/block_binding_support.rb +0 -22
- data/lib/ruby/merge/block_directive_detector.rb +0 -208
- data/lib/ruby/merge/doc_comment_support.rb +0 -97
- data/lib/ruby/merge/gemspec_support.rb +0 -32
- data/lib/ruby/merge/magic_comment_support.rb +0 -128
- data/lib/ruby/merge/method_similarity.rb +0 -75
- data/lib/ruby/merge/nocov_node_base.rb +0 -75
- data/lib/ruby/merge/nocov_wrapper_base.rb +0 -46
- data/lib/ruby/merge/rescue_semantics.rb +0 -209
- data/lib/ruby/merge/scaffold_chunk_support.rb +0 -74
- data/lib/ruby/merge/signature_support.rb +0 -97
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: aa7e44e52e059397107051f945efaceb307742e3e40c36f61bf900ac06dd84e6
|
|
4
|
+
data.tar.gz: 1bb04482ae836481586da92f9266f0e03781d351b5ac25eb7eaf7fd83ad4f649
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1828b958a01c2017de25ef21616c5a650cf3483b20804e93c54f9158a40c8eac146bdd6cde14118fae50b2fc6e85b439072a5bce5596cadb0ee2248213fab509
|
|
7
|
+
data.tar.gz: 12f7bb144511bc0d9ff4ba0f42241666ce394f416e1e2444fd329930aae8444ce158cbee7a950a5ddccb93398816b466083ab2f40d7faf032825fdb4a934e713
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/README.md
CHANGED
|
@@ -46,7 +46,7 @@ I've summarized my thoughts in [this blog post](https://dev.to/galtzo/hostile-ta
|
|
|
46
46
|
|
|
47
47
|
### Compatibility
|
|
48
48
|
|
|
49
|
-
Compatible with MRI Ruby 4.0.0+,
|
|
49
|
+
Compatible with MRI Ruby 4.0.0+, JRuby, and TruffleRuby.
|
|
50
50
|
CI workflows and Appraisals are generated for MRI Ruby 4.0.0+.
|
|
51
51
|
This test floor is configured by `ruby.test_minimum` in `.kettle-jem.yml` and
|
|
52
52
|
may be higher than the gem's runtime compatibility floor when legacy Rubies are
|
|
@@ -122,20 +122,12 @@ See [SECURITY.md][🔐security].
|
|
|
122
122
|
## 🤝 Contributing
|
|
123
123
|
|
|
124
124
|
If you need some ideas of where to help, you could work on adding more code coverage,
|
|
125
|
-
|
|
126
|
-
or use the gem and think about how it could be better.
|
|
125
|
+
check [issues][🤝gh-issues] or [PRs][🤝gh-pulls], or use the gem and think about how it could be better.
|
|
127
126
|
|
|
128
127
|
We [![Keep A Changelog][📗keep-changelog-img]][📗keep-changelog] so if you make changes, remember to update it.
|
|
129
128
|
|
|
130
129
|
See [CONTRIBUTING.md][🤝contributing] for more detailed instructions.
|
|
131
130
|
|
|
132
|
-
### Code Coverage
|
|
133
|
-
|
|
134
|
-
<details markdown="1">
|
|
135
|
-
<summary>Coverage service badges</summary>
|
|
136
|
-
|
|
137
|
-
</details>
|
|
138
|
-
|
|
139
131
|
## 📌 Versioning
|
|
140
132
|
|
|
141
133
|
This library follows [![Semantic Versioning 2.0.0][📌semver-img]][📌semver] for its public API where practical.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ruby
|
|
4
|
+
# Portable Ruby workflow integration.
|
|
5
|
+
module Merge
|
|
6
|
+
# Ruby workflow selector delegating source-preserving operations to Prism.
|
|
7
|
+
class Provider
|
|
8
|
+
BACKEND = :prism
|
|
9
|
+
DELEGATED_PROVIDER_ID = 'ruby.ruby.prism'
|
|
10
|
+
DEFAULT_PROFILE = :source_preserving
|
|
11
|
+
|
|
12
|
+
def provider_id = 'ruby.ruby'
|
|
13
|
+
def family = 'ruby'
|
|
14
|
+
|
|
15
|
+
def capabilities
|
|
16
|
+
{
|
|
17
|
+
operations: Ast::Merge::ProviderContract::OPERATIONS,
|
|
18
|
+
dialects: %i[ruby],
|
|
19
|
+
backends: [BACKEND],
|
|
20
|
+
profiles: [DEFAULT_PROFILE],
|
|
21
|
+
role: :workflow,
|
|
22
|
+
source_preservation: Prism::Merge.merge_provider.capabilities.fetch(:source_preservation)
|
|
23
|
+
}.freeze
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
Ast::Merge::ProviderContract::OPERATIONS.each do |operation|
|
|
27
|
+
define_method(operation) do |request|
|
|
28
|
+
delegated = Ast::Merge.dispatch_provider(operation, delegated_request(request))
|
|
29
|
+
delegated.merge(provider: workflow_identity(request, delegated))
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def delegated_request(request)
|
|
36
|
+
request.merge(
|
|
37
|
+
provider_id: DELEGATED_PROVIDER_ID,
|
|
38
|
+
family: :ruby,
|
|
39
|
+
dialect: :ruby,
|
|
40
|
+
backend: BACKEND,
|
|
41
|
+
profile_id: DEFAULT_PROFILE
|
|
42
|
+
)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def workflow_identity(request, delegated)
|
|
46
|
+
{
|
|
47
|
+
provider_id: provider_id,
|
|
48
|
+
family: family,
|
|
49
|
+
dialect: request[:dialect] || :ruby,
|
|
50
|
+
backend: request[:backend] || BACKEND,
|
|
51
|
+
package: PACKAGE_NAME,
|
|
52
|
+
package_version: Ruby::Merge::Version::VERSION,
|
|
53
|
+
delegated_provider: delegated_identity(delegated.fetch(:provider))
|
|
54
|
+
}
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def delegated_identity(identity)
|
|
58
|
+
{
|
|
59
|
+
provider_id: identity.fetch(:provider_id),
|
|
60
|
+
backend: identity.fetch(:backend),
|
|
61
|
+
package: identity[:package],
|
|
62
|
+
package_version: identity[:package_version]
|
|
63
|
+
}.compact
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
class << self
|
|
68
|
+
def merge_provider
|
|
69
|
+
@merge_provider ||= Provider.new
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def register_provider!(replace: false)
|
|
73
|
+
Ast::Merge.register_provider(merge_provider, replace: replace)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
data/lib/ruby/merge/version.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Ruby
|
|
|
5
5
|
# Version namespace for this gem.
|
|
6
6
|
module Version
|
|
7
7
|
# Current gem version.
|
|
8
|
-
VERSION = '7.1.
|
|
8
|
+
VERSION = '7.1.3'
|
|
9
9
|
end
|
|
10
10
|
# Current gem version exposed at the traditional constant location.
|
|
11
11
|
VERSION = Version::VERSION # Traditional Constant Location
|
data/lib/ruby/merge.rb
CHANGED
|
@@ -1,20 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'digest'
|
|
4
|
+
require 'prism/merge'
|
|
4
5
|
require 'tree_haver'
|
|
5
6
|
require 'ast/merge'
|
|
6
7
|
require_relative 'merge/version'
|
|
7
|
-
require_relative 'merge/block_directive_detector'
|
|
8
|
-
require_relative 'merge/block_binding_support'
|
|
9
|
-
require_relative 'merge/doc_comment_support'
|
|
10
|
-
require_relative 'merge/gemspec_support'
|
|
11
|
-
require_relative 'merge/magic_comment_support'
|
|
12
|
-
require_relative 'merge/method_similarity'
|
|
13
|
-
require_relative 'merge/nocov_node_base'
|
|
14
|
-
require_relative 'merge/nocov_wrapper_base'
|
|
15
|
-
require_relative 'merge/rescue_semantics'
|
|
16
|
-
require_relative 'merge/scaffold_chunk_support'
|
|
17
|
-
require_relative 'merge/signature_support'
|
|
18
8
|
|
|
19
9
|
module Ruby
|
|
20
10
|
module Merge
|
|
@@ -3143,6 +3133,8 @@ module Ruby
|
|
|
3143
3133
|
end
|
|
3144
3134
|
|
|
3145
3135
|
Ruby::Merge.register_backend!
|
|
3136
|
+
require_relative 'merge/provider'
|
|
3137
|
+
Ruby::Merge.register_provider!
|
|
3146
3138
|
|
|
3147
3139
|
TreeHaver::BackendRegistry.register_tag(
|
|
3148
3140
|
:tslp_ruby_import_records,
|
data/sig/ruby/merge.rbs
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
module Ruby
|
|
2
2
|
module Merge
|
|
3
|
+
class Provider
|
|
4
|
+
def provider_id: () -> String
|
|
5
|
+
def family: () -> String
|
|
6
|
+
def capabilities: () -> Hash[Symbol, untyped]
|
|
7
|
+
def analyze: (Hash[Symbol, untyped] request) -> Hash[Symbol, untyped]
|
|
8
|
+
def diff2: (Hash[Symbol, untyped] request) -> Hash[Symbol, untyped]
|
|
9
|
+
def merge2: (Hash[Symbol, untyped] request) -> Hash[Symbol, untyped]
|
|
10
|
+
def merge3: (Hash[Symbol, untyped] request) -> Hash[Symbol, untyped]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.merge_provider: () -> Provider
|
|
14
|
+
def self.register_provider!: (?replace: bool) -> untyped
|
|
15
|
+
|
|
3
16
|
module Version
|
|
4
17
|
VERSION: String
|
|
5
18
|
end
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby-merge
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 7.1.
|
|
4
|
+
version: 7.1.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter H. Boling
|
|
@@ -43,28 +43,42 @@ dependencies:
|
|
|
43
43
|
requirements:
|
|
44
44
|
- - '='
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: 7.1.
|
|
46
|
+
version: 7.1.3
|
|
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.
|
|
53
|
+
version: 7.1.3
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: prism-merge
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - '='
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: 7.1.3
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - '='
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: 7.1.3
|
|
54
68
|
- !ruby/object:Gem::Dependency
|
|
55
69
|
name: tree_haver
|
|
56
70
|
requirement: !ruby/object:Gem::Requirement
|
|
57
71
|
requirements:
|
|
58
72
|
- - '='
|
|
59
73
|
- !ruby/object:Gem::Version
|
|
60
|
-
version: 7.1.
|
|
74
|
+
version: 7.1.3
|
|
61
75
|
type: :runtime
|
|
62
76
|
prerelease: false
|
|
63
77
|
version_requirements: !ruby/object:Gem::Requirement
|
|
64
78
|
requirements:
|
|
65
79
|
- - '='
|
|
66
80
|
- !ruby/object:Gem::Version
|
|
67
|
-
version: 7.1.
|
|
81
|
+
version: 7.1.3
|
|
68
82
|
- !ruby/object:Gem::Dependency
|
|
69
83
|
name: version_gem
|
|
70
84
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -91,20 +105,20 @@ dependencies:
|
|
|
91
105
|
requirements:
|
|
92
106
|
- - "~>"
|
|
93
107
|
- !ruby/object:Gem::Version
|
|
94
|
-
version: '
|
|
108
|
+
version: '3.0'
|
|
95
109
|
- - ">="
|
|
96
110
|
- !ruby/object:Gem::Version
|
|
97
|
-
version:
|
|
111
|
+
version: 3.0.0
|
|
98
112
|
type: :development
|
|
99
113
|
prerelease: false
|
|
100
114
|
version_requirements: !ruby/object:Gem::Requirement
|
|
101
115
|
requirements:
|
|
102
116
|
- - "~>"
|
|
103
117
|
- !ruby/object:Gem::Version
|
|
104
|
-
version: '
|
|
118
|
+
version: '3.0'
|
|
105
119
|
- - ">="
|
|
106
120
|
- !ruby/object:Gem::Version
|
|
107
|
-
version:
|
|
121
|
+
version: 3.0.0
|
|
108
122
|
- !ruby/object:Gem::Dependency
|
|
109
123
|
name: bundler-audit
|
|
110
124
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -182,7 +196,7 @@ dependencies:
|
|
|
182
196
|
version: '3.2'
|
|
183
197
|
- - ">="
|
|
184
198
|
- !ruby/object:Gem::Version
|
|
185
|
-
version: 3.2.
|
|
199
|
+
version: 3.2.2
|
|
186
200
|
type: :development
|
|
187
201
|
prerelease: false
|
|
188
202
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -192,7 +206,7 @@ dependencies:
|
|
|
192
206
|
version: '3.2'
|
|
193
207
|
- - ">="
|
|
194
208
|
- !ruby/object:Gem::Version
|
|
195
|
-
version: 3.2.
|
|
209
|
+
version: 3.2.2
|
|
196
210
|
- !ruby/object:Gem::Dependency
|
|
197
211
|
name: kettle-test
|
|
198
212
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -222,7 +236,7 @@ dependencies:
|
|
|
222
236
|
version: '3.2'
|
|
223
237
|
- - ">="
|
|
224
238
|
- !ruby/object:Gem::Version
|
|
225
|
-
version: 3.2.
|
|
239
|
+
version: 3.2.5
|
|
226
240
|
type: :development
|
|
227
241
|
prerelease: false
|
|
228
242
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -232,7 +246,7 @@ dependencies:
|
|
|
232
246
|
version: '3.2'
|
|
233
247
|
- - ">="
|
|
234
248
|
- !ruby/object:Gem::Version
|
|
235
|
-
version: 3.2.
|
|
249
|
+
version: 3.2.5
|
|
236
250
|
- !ruby/object:Gem::Dependency
|
|
237
251
|
name: ruby-progressbar
|
|
238
252
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -298,17 +312,7 @@ files:
|
|
|
298
312
|
- README.md
|
|
299
313
|
- lib/ruby-merge.rb
|
|
300
314
|
- lib/ruby/merge.rb
|
|
301
|
-
- lib/ruby/merge/
|
|
302
|
-
- lib/ruby/merge/block_directive_detector.rb
|
|
303
|
-
- lib/ruby/merge/doc_comment_support.rb
|
|
304
|
-
- lib/ruby/merge/gemspec_support.rb
|
|
305
|
-
- lib/ruby/merge/magic_comment_support.rb
|
|
306
|
-
- lib/ruby/merge/method_similarity.rb
|
|
307
|
-
- lib/ruby/merge/nocov_node_base.rb
|
|
308
|
-
- lib/ruby/merge/nocov_wrapper_base.rb
|
|
309
|
-
- lib/ruby/merge/rescue_semantics.rb
|
|
310
|
-
- lib/ruby/merge/scaffold_chunk_support.rb
|
|
311
|
-
- lib/ruby/merge/signature_support.rb
|
|
315
|
+
- lib/ruby/merge/provider.rb
|
|
312
316
|
- lib/ruby/merge/version.rb
|
|
313
317
|
- sig/ruby/merge.rbs
|
|
314
318
|
homepage: https://github.com/structuredmerge/structuredmerge-ruby
|
|
@@ -317,10 +321,10 @@ licenses:
|
|
|
317
321
|
- PolyForm-Small-Business-1.0.0
|
|
318
322
|
metadata:
|
|
319
323
|
homepage_uri: https://structuredmerge.org
|
|
320
|
-
source_code_uri: https://github.com/structuredmerge/structuredmerge-ruby/tree/v7.1.
|
|
321
|
-
changelog_uri: https://github.com/structuredmerge/structuredmerge-ruby/blob/v7.1.
|
|
324
|
+
source_code_uri: https://github.com/structuredmerge/structuredmerge-ruby/tree/v7.1.3
|
|
325
|
+
changelog_uri: https://github.com/structuredmerge/structuredmerge-ruby/blob/v7.1.3/CHANGELOG.md
|
|
322
326
|
bug_tracker_uri: https://github.com/structuredmerge/structuredmerge-ruby/issues
|
|
323
|
-
documentation_uri: https://www.rubydoc.info/gems/ruby-merge/7.1.
|
|
327
|
+
documentation_uri: https://www.rubydoc.info/gems/ruby-merge/7.1.3
|
|
324
328
|
funding_uri: https://github.com/sponsors/pboling
|
|
325
329
|
wiki_uri: https://github.com/structuredmerge/structuredmerge-ruby/wiki
|
|
326
330
|
news_uri: https://www.railsbling.com/tags/ruby-merge
|
metadata.gz.sig
CHANGED
|
Binary file
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Ruby
|
|
4
|
-
module Merge
|
|
5
|
-
# Parser-neutral naming policy for a block-local receiver.
|
|
6
|
-
module BlockBindingSupport
|
|
7
|
-
module_function
|
|
8
|
-
|
|
9
|
-
def effective_receiver(receiver, block_var, placeholder: :__block_binding__)
|
|
10
|
-
block_var && receiver == block_var ? placeholder : receiver
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def preferred_block_var(template_var, destination_var)
|
|
14
|
-
template_var if template_var && destination_var && template_var != destination_var
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def merged_block_var(var, preferred_var)
|
|
18
|
-
preferred_var || var
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Ruby
|
|
4
|
-
module Merge
|
|
5
|
-
# Detects Ruby comment block directive pairs in source lines.
|
|
6
|
-
#
|
|
7
|
-
# This is Ruby-specific substrate behavior shared by Ruby parser providers.
|
|
8
|
-
# Parser-specific gems may consume the spans and project them into their own
|
|
9
|
-
# node types, but directive token semantics should live here.
|
|
10
|
-
class BlockDirectiveDetector
|
|
11
|
-
Span = Struct.new(:kind, :start_line, :end_line, :open_marker, :close_marker, keyword_init: true)
|
|
12
|
-
|
|
13
|
-
NOCOV_TOKEN = ':nocov:'
|
|
14
|
-
SIMPLECOV_DISABLE_RE = /\A\s*#\s*simplecov\s*:\s*disable\b/i
|
|
15
|
-
SIMPLECOV_ENABLE_RE = /\A\s*#\s*simplecov\s*:\s*enable\b/i
|
|
16
|
-
DIRECTIVE_CONTENT_RE = /\A(?::nocov:|[\w-]+:(?:freeze|unfreeze))\z/i
|
|
17
|
-
|
|
18
|
-
class << self
|
|
19
|
-
def coverage_directive_line?(line, nocov_token: NOCOV_TOKEN)
|
|
20
|
-
stripped = line.to_s.chomp
|
|
21
|
-
stripped.match?(simplecov_disable_re) ||
|
|
22
|
-
stripped.match?(simplecov_enable_re) ||
|
|
23
|
-
stripped.match?(nocov_re(nocov_token))
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def directive_content?(content)
|
|
27
|
-
DIRECTIVE_CONTENT_RE.match?(content.to_s.strip) ||
|
|
28
|
-
coverage_directive_line?("# #{content}")
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def simplecov_disable_re
|
|
32
|
-
SIMPLECOV_DISABLE_RE
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def simplecov_enable_re
|
|
36
|
-
SIMPLECOV_ENABLE_RE
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def nocov_re(nocov_token = NOCOV_TOKEN)
|
|
40
|
-
/\A\s*#\s?#{Regexp.escape(nocov_token)}\s*\z/i
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def initialize(lines, freeze_token: nil, nocov_token: NOCOV_TOKEN, source_label: nil)
|
|
45
|
-
@lines = lines
|
|
46
|
-
@freeze_token = freeze_token
|
|
47
|
-
@nocov_token = nocov_token
|
|
48
|
-
@source_label = source_label
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def detect_spans
|
|
52
|
-
raw_spans = []
|
|
53
|
-
raw_spans.concat(detect_freeze_spans) if @freeze_token
|
|
54
|
-
raw_spans.concat(detect_nocov_spans)
|
|
55
|
-
|
|
56
|
-
validate_no_crossing(raw_spans.sort_by(&:start_line))
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
private
|
|
60
|
-
|
|
61
|
-
def detector_name
|
|
62
|
-
'ruby-merge'
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def directive_error_class
|
|
66
|
-
Ast::Merge::Error
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def warn_prefix
|
|
70
|
-
if @source_label
|
|
71
|
-
"[#{detector_name}] BlockDirectiveDetector (#{@source_label}):"
|
|
72
|
-
else
|
|
73
|
-
"[#{detector_name}] BlockDirectiveDetector:"
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def report_unbalanced(message)
|
|
78
|
-
raise directive_error_class, "#{warn_prefix} #{message}" if @source_label
|
|
79
|
-
|
|
80
|
-
warn("#{warn_prefix} #{message} - ignoring")
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def detect_freeze_spans
|
|
84
|
-
freeze_pat = /\A\s*#\s?#{Regexp.escape(@freeze_token)}:freeze\b/i
|
|
85
|
-
unfreeze_pat = /\A\s*#\s?#{Regexp.escape(@freeze_token)}:unfreeze\b/i
|
|
86
|
-
|
|
87
|
-
spans = []
|
|
88
|
-
stack = []
|
|
89
|
-
|
|
90
|
-
@lines.each_with_index do |line, index|
|
|
91
|
-
line_num = index + 1
|
|
92
|
-
stripped = line.to_s.chomp
|
|
93
|
-
if stripped.match?(freeze_pat)
|
|
94
|
-
stack.push({ start_line: line_num, open_marker: stripped })
|
|
95
|
-
elsif stripped.match?(unfreeze_pat)
|
|
96
|
-
if (open = stack.pop)
|
|
97
|
-
spans << Span.new(
|
|
98
|
-
kind: :freeze,
|
|
99
|
-
start_line: open[:start_line],
|
|
100
|
-
end_line: line_num,
|
|
101
|
-
open_marker: open[:open_marker],
|
|
102
|
-
close_marker: stripped
|
|
103
|
-
)
|
|
104
|
-
else
|
|
105
|
-
report_unbalanced("unmatched #{@freeze_token}:unfreeze at line #{line_num}")
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
stack.each do |open|
|
|
111
|
-
report_unbalanced("unclosed #{@freeze_token}:freeze at line #{open[:start_line]}")
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
spans
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
def detect_nocov_spans
|
|
118
|
-
return [] unless @nocov_token
|
|
119
|
-
|
|
120
|
-
nocov_pat = self.class.nocov_re(@nocov_token)
|
|
121
|
-
|
|
122
|
-
spans = []
|
|
123
|
-
stack = []
|
|
124
|
-
|
|
125
|
-
@lines.each_with_index do |line, index|
|
|
126
|
-
line_num = index + 1
|
|
127
|
-
stripped = line.to_s.chomp
|
|
128
|
-
if stripped.match?(self.class.simplecov_disable_re)
|
|
129
|
-
stack.push({ start_line: line_num, open_marker: stripped })
|
|
130
|
-
elsif stripped.match?(self.class.simplecov_enable_re)
|
|
131
|
-
if (open = stack.pop)
|
|
132
|
-
spans << Span.new(
|
|
133
|
-
kind: :nocov,
|
|
134
|
-
start_line: open[:start_line],
|
|
135
|
-
end_line: line_num,
|
|
136
|
-
open_marker: open[:open_marker],
|
|
137
|
-
close_marker: stripped
|
|
138
|
-
)
|
|
139
|
-
else
|
|
140
|
-
report_unbalanced("unmatched simplecov:enable at line #{line_num}")
|
|
141
|
-
end
|
|
142
|
-
elsif stripped.match?(nocov_pat)
|
|
143
|
-
if stack.empty?
|
|
144
|
-
stack.push({ start_line: line_num, open_marker: stripped })
|
|
145
|
-
else
|
|
146
|
-
open = stack.pop
|
|
147
|
-
spans << Span.new(
|
|
148
|
-
kind: :nocov,
|
|
149
|
-
start_line: open[:start_line],
|
|
150
|
-
end_line: line_num,
|
|
151
|
-
open_marker: open[:open_marker],
|
|
152
|
-
close_marker: stripped
|
|
153
|
-
)
|
|
154
|
-
end
|
|
155
|
-
end
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
stack.each do |open|
|
|
159
|
-
report_unbalanced("unclosed coverage directive at line #{open[:start_line]}")
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
spans
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
def validate_no_crossing(spans)
|
|
166
|
-
valid = []
|
|
167
|
-
invalid_indices = Set.new
|
|
168
|
-
|
|
169
|
-
spans.each_with_index do |first, first_index|
|
|
170
|
-
next if invalid_indices.include?(first_index)
|
|
171
|
-
|
|
172
|
-
crossing = false
|
|
173
|
-
spans.each_with_index do |second, second_index|
|
|
174
|
-
next if first_index == second_index || invalid_indices.include?(second_index)
|
|
175
|
-
next unless crossing_spans?(first, second)
|
|
176
|
-
|
|
177
|
-
report_unbalanced("offset-overlapping #{first.kind} block " \
|
|
178
|
-
"(lines #{first.start_line}..#{first.end_line}) and #{second.kind} block " \
|
|
179
|
-
"(lines #{second.start_line}..#{second.end_line}) - both treated as plain comments")
|
|
180
|
-
invalid_indices.add(first_index)
|
|
181
|
-
invalid_indices.add(second_index)
|
|
182
|
-
crossing = true
|
|
183
|
-
break
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
valid << first unless crossing
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
valid
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
def crossing_spans?(first, second)
|
|
193
|
-
(first.start_line < second.start_line && first.end_line > second.start_line && first.end_line < second.end_line) ||
|
|
194
|
-
(second.start_line < first.start_line && second.end_line > first.start_line && second.end_line < first.end_line)
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
def top_level_spans_only(spans)
|
|
198
|
-
spans.reject do |span|
|
|
199
|
-
spans.any? do |other|
|
|
200
|
-
other != span &&
|
|
201
|
-
other.start_line <= span.start_line &&
|
|
202
|
-
other.end_line >= span.end_line
|
|
203
|
-
end
|
|
204
|
-
end
|
|
205
|
-
end
|
|
206
|
-
end
|
|
207
|
-
end
|
|
208
|
-
end
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Ruby
|
|
4
|
-
module Merge
|
|
5
|
-
# Ruby-specific doc-comment semantics shared by Ruby parser providers.
|
|
6
|
-
module DocCommentSupport
|
|
7
|
-
TAG_PREFIX = /\A@[a-z_]+\b/
|
|
8
|
-
EXAMPLE_TAG = /\A@example\b(?<rest>.*)\z/
|
|
9
|
-
MAGIC_COMMENT_PREFIXES = %w[
|
|
10
|
-
coding
|
|
11
|
-
encoding
|
|
12
|
-
frozen_string_literal
|
|
13
|
-
shareable_constant_value
|
|
14
|
-
typed
|
|
15
|
-
warn_indent
|
|
16
|
-
].freeze
|
|
17
|
-
|
|
18
|
-
module_function
|
|
19
|
-
|
|
20
|
-
def normalize_comment_content(raw)
|
|
21
|
-
raw.to_s.sub(/\A\s*#\s?/, '').strip
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def comment_prefix_for(raw)
|
|
25
|
-
raw.to_s[/\A\s*#\s*/] || '# '
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def doc_comment_content?(raw, magic_comment: false)
|
|
29
|
-
content = normalize_comment_content(raw)
|
|
30
|
-
return false if content.empty?
|
|
31
|
-
return false if BlockDirectiveDetector.directive_content?(content)
|
|
32
|
-
return false if magic_comment || magic_comment_content?(content)
|
|
33
|
-
|
|
34
|
-
true
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def magic_comment_content?(content)
|
|
38
|
-
MAGIC_COMMENT_PREFIXES.any? { |prefix| content.to_s.start_with?("#{prefix}:") }
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def declared_example_language(rest)
|
|
42
|
-
match = rest.to_s.strip.match(/\A\[(?<language>[^\]]+)\]/)
|
|
43
|
-
normalize_language(match && match[:language])
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def declared_example_language_for_tag(content)
|
|
47
|
-
match = EXAMPLE_TAG.match(content.to_s)
|
|
48
|
-
return unless match
|
|
49
|
-
|
|
50
|
-
declared_example_language(match[:rest])
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def normalize_language(language)
|
|
54
|
-
return if language.nil?
|
|
55
|
-
|
|
56
|
-
normalized = language.to_s.strip.downcase.tr('-', '_')
|
|
57
|
-
return if normalized.empty?
|
|
58
|
-
|
|
59
|
-
normalized
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def next_tag_index(normalized_lines, start_index)
|
|
63
|
-
normalized_lines.each_with_index do |content, index|
|
|
64
|
-
next if index < start_index
|
|
65
|
-
|
|
66
|
-
return index if TAG_PREFIX.match?(content)
|
|
67
|
-
end
|
|
68
|
-
nil
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def example_blocks(entries)
|
|
72
|
-
normalized = entries.map { |entry| normalize_comment_content(entry[:raw]) }
|
|
73
|
-
normalized.each_with_index.filter_map do |content, tag_index|
|
|
74
|
-
match = EXAMPLE_TAG.match(content)
|
|
75
|
-
next unless match
|
|
76
|
-
|
|
77
|
-
body_start_index = tag_index + 1
|
|
78
|
-
body_end_index = next_tag_index(normalized, body_start_index) || normalized.length
|
|
79
|
-
next if body_start_index >= body_end_index
|
|
80
|
-
|
|
81
|
-
body_entries = entries[body_start_index...body_end_index]
|
|
82
|
-
next if body_entries.nil? || body_entries.empty?
|
|
83
|
-
|
|
84
|
-
{
|
|
85
|
-
tag_index: tag_index,
|
|
86
|
-
tag_line: entries[tag_index][:line],
|
|
87
|
-
tag_text: normalized[tag_index],
|
|
88
|
-
body_start_index: body_start_index,
|
|
89
|
-
body_end_index: body_end_index,
|
|
90
|
-
body_entries: body_entries,
|
|
91
|
-
declared_language: declared_example_language(match[:rest])
|
|
92
|
-
}
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
end
|