rbs-inline-annotator 0.1.0 → 0.2.0
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
- data/README.md +2 -4
- data/lib/rbs/inline/annotator/cli.rb +2 -2
- data/lib/rbs/inline/annotator/processor.rb +6 -3
- data/lib/rbs/inline/annotator/version.rb +1 -1
- data/lib/rbs/inline/annotator/visitor.rb +74 -14
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d398c9f6b34b3f6ac6d807527341b09c180dde4f3bb75962c6fbc0f36cccd791
|
4
|
+
data.tar.gz: 34af7fd6c55711068669e67924403fd937a1301c4cede7e8e7fee4cf485ed320
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9096854e21fbc7e4ed5b982a6b7c0969438f475456b8b84256fba394c8114486a0f7a81d908014109e039ba945e02923805677d3d8513352d05404fae45128d
|
7
|
+
data.tar.gz: 61c6fcf5e3a26f81792ea91298e29433ef319482e92349864140bb1a2a22913430b6071ecbc017bd0731dcb633c39d0e992232f87dba5a5148d4da417c48302c
|
data/README.md
CHANGED
@@ -35,18 +35,16 @@ end
|
|
35
35
|
|
36
36
|
## Installation
|
37
37
|
|
38
|
-
TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
|
39
|
-
|
40
38
|
Install the gem and add to the application's Gemfile by executing:
|
41
39
|
|
42
40
|
```bash
|
43
|
-
bundle add
|
41
|
+
bundle add rbs-inline-annotator
|
44
42
|
```
|
45
43
|
|
46
44
|
If bundler is not being used to manage dependencies, install the gem by executing:
|
47
45
|
|
48
46
|
```bash
|
49
|
-
gem install
|
47
|
+
gem install rbs-inline-annotator
|
50
48
|
```
|
51
49
|
|
52
50
|
## Usage
|
@@ -52,10 +52,10 @@ module RBS::Inline::Annotator
|
|
52
52
|
Spinner.new.tap do |spinner|
|
53
53
|
print "\e[?25l" if @options.mode == 'write'
|
54
54
|
targets.each do |target|
|
55
|
-
annotated_code = Processor.new(target:, env:).process
|
55
|
+
annotated_code, changed = Processor.new(target:, env:).process
|
56
56
|
case @options.mode
|
57
57
|
when 'write'
|
58
|
-
File.write(target, annotated_code)
|
58
|
+
File.write(target, annotated_code) if changed
|
59
59
|
when 'print-only'
|
60
60
|
puts annotated_code
|
61
61
|
when 'quiet'
|
@@ -17,15 +17,18 @@ module RBS::Inline::Annotator
|
|
17
17
|
@env = env
|
18
18
|
end
|
19
19
|
|
20
|
+
# @rbs return: [String, bool] -- [code string, changed flag]
|
20
21
|
def process
|
21
22
|
absolute_path = Pathname.pwd + target
|
22
23
|
source = absolute_path.read
|
23
24
|
writer = Writer.new(source)
|
24
25
|
result = Result.new(writer:, prism_result: Prism.parse_file(absolute_path.to_s))
|
25
26
|
result.prism_result.value.accept(Visitor.new(env:, result:))
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
if result.writer.actions.empty?
|
28
|
+
[source, false]
|
29
|
+
else
|
30
|
+
[writer.process, true]
|
31
|
+
end
|
29
32
|
end
|
30
33
|
end
|
31
34
|
end
|
@@ -26,8 +26,8 @@ module RBS::Inline::Annotator
|
|
26
26
|
|
27
27
|
def node_range(node)
|
28
28
|
Range.new(
|
29
|
-
node.location.
|
30
|
-
node.location.
|
29
|
+
node.location.start_character_offset,
|
30
|
+
node.location.end_character_offset,
|
31
31
|
)
|
32
32
|
end
|
33
33
|
|
@@ -49,6 +49,7 @@ module RBS::Inline::Annotator
|
|
49
49
|
|
50
50
|
def visit_class_node(node)
|
51
51
|
push_type_name(node) do
|
52
|
+
with_generics(node)
|
52
53
|
with_superclass(node.superclass)
|
53
54
|
# TODO: Which file should we write to?
|
54
55
|
# with_embedding_rbs(header_node(node), node)
|
@@ -59,6 +60,7 @@ module RBS::Inline::Annotator
|
|
59
60
|
|
60
61
|
def visit_module_node(node)
|
61
62
|
push_type_name(node) do
|
63
|
+
with_generics(node)
|
62
64
|
with_module_self(node)
|
63
65
|
# TODO: Which file should we write to?
|
64
66
|
# with_embedding_rbs(header_node(node), node)
|
@@ -67,6 +69,14 @@ module RBS::Inline::Annotator
|
|
67
69
|
end
|
68
70
|
end
|
69
71
|
|
72
|
+
def with_generics(node)
|
73
|
+
entry = module_class_entry or return
|
74
|
+
indent = " " * node.location.start_column
|
75
|
+
entry.primary_decl.type_params.each do |type_param|
|
76
|
+
insert_before(node_range(node), "# @rbs generic #{type_param}\n#{indent}")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
70
80
|
def header_node(node)
|
71
81
|
case node
|
72
82
|
when Prism::ClassNode
|
@@ -252,13 +262,18 @@ module RBS::Inline::Annotator
|
|
252
262
|
new_annotation.call("return", return_type)
|
253
263
|
}
|
254
264
|
if node.parameters
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
265
|
+
case func
|
266
|
+
when RBS::Types::UntypedFunction
|
267
|
+
# do nothing
|
268
|
+
when RBS::Types::Function
|
269
|
+
for_positional_params.call(func.required_positionals, node.parameters.requireds)
|
270
|
+
for_positional_params.call(func.optional_positionals, node.parameters.optionals)
|
271
|
+
for_rest_param.call("*", func.rest_positionals, node.parameters.rest) if func.rest_positionals
|
272
|
+
for_positional_params.call(func.trailing_positionals, node.parameters.posts) if func.trailing_positionals
|
273
|
+
for_keyword_params.call(func.required_keywords, node.parameters.keywords.grep(Prism::RequiredKeywordParameterNode))
|
274
|
+
for_keyword_params.call(func.optional_keywords, node.parameters.keywords.grep(Prism::OptionalKeywordParameterNode))
|
275
|
+
for_rest_param.call("**", func.rest_keywords, node.parameters.keyword_rest) if func.rest_keywords
|
276
|
+
end
|
262
277
|
end
|
263
278
|
if method_type.block
|
264
279
|
name = node.parameters&.block&.name
|
@@ -297,6 +312,7 @@ module RBS::Inline::Annotator
|
|
297
312
|
(node.name == :attr_writer && member.is_a?(RBS::AST::Members::AttrWriter)) ||
|
298
313
|
(node.name == :attr_accessor && member.is_a?(RBS::AST::Members::AttrAccessor))
|
299
314
|
next unless member.name == value.to_sym
|
315
|
+
next unless member.kind == @kind
|
300
316
|
|
301
317
|
type = member.type.to_s
|
302
318
|
next if type == "untyped"
|
@@ -316,6 +332,7 @@ module RBS::Inline::Annotator
|
|
316
332
|
(node.name == :attr_writer && member.is_a?(RBS::AST::Members::AttrWriter)) ||
|
317
333
|
(node.name == :attr_accessor && member.is_a?(RBS::AST::Members::AttrAccessor))
|
318
334
|
next unless member.name == value.to_sym
|
335
|
+
next unless member.kind == @kind
|
319
336
|
|
320
337
|
indent = replaced_count == 0 ? "" : " " * node.location.start_column
|
321
338
|
insert_before(node_range(node), "#{indent}#{node.name} :#{value} #: #{member.type}\n")
|
@@ -387,18 +404,61 @@ module RBS::Inline::Annotator
|
|
387
404
|
end
|
388
405
|
end
|
389
406
|
|
407
|
+
def visit_constant_path_write_node(node)
|
408
|
+
constant_type_name = RBS::TypeName.parse(node.target.full_name).then do |c|
|
409
|
+
type_name ? type_name + c : c.absolute!
|
410
|
+
end
|
411
|
+
type = constant_type(node, constant_type_name) or return
|
412
|
+
add_rbs_inline_annotation_for_trailing(node:, type:)
|
413
|
+
end
|
414
|
+
|
390
415
|
def visit_constant_write_node(node)
|
416
|
+
namespace = type_name ? type_name.to_namespace : RBS::Namespace.root
|
391
417
|
constant_type_name = RBS::TypeName.new(
|
392
418
|
name: node.name,
|
393
|
-
namespace:
|
419
|
+
namespace:
|
394
420
|
)
|
395
|
-
|
396
|
-
type = entry.decl.type.to_s
|
397
|
-
return if type == "untyped"
|
398
|
-
|
421
|
+
type = constant_type(node, constant_type_name) or return
|
399
422
|
add_rbs_inline_annotation_for_trailing(node:, type:)
|
400
423
|
end
|
401
424
|
|
425
|
+
def constant_type(node, type_name)
|
426
|
+
entry = @env.constant_entry(type_name) or return
|
427
|
+
case entry
|
428
|
+
when RBS::Environment::ModuleAliasEntry
|
429
|
+
case node.value
|
430
|
+
when Prism::CallNode
|
431
|
+
"module-alias #{entry.decl.old_name}"
|
432
|
+
when Prism::ConstantReadNode, Prism::ConstantPathNode
|
433
|
+
"module-alias"
|
434
|
+
else
|
435
|
+
warn "Unsupported node: #{node.value.class}"
|
436
|
+
end
|
437
|
+
when RBS::Environment::ClassAliasEntry
|
438
|
+
case node.value
|
439
|
+
when Prism::CallNode
|
440
|
+
"class-alias #{entry.decl.old_name}"
|
441
|
+
when Prism::ConstantReadNode, Prism::ConstantPathNode
|
442
|
+
"class-alias"
|
443
|
+
else
|
444
|
+
warn "Unsupported node: #{node.value.class}"
|
445
|
+
end
|
446
|
+
when RBS::Environment::ConstantEntry
|
447
|
+
t = entry.decl.type.to_s
|
448
|
+
if (node.value.is_a?(Prism::IntegerNode) && t == "Integer" ||
|
449
|
+
node.value.is_a?(Prism::FloatNode) && t == "Float" ||
|
450
|
+
node.value.is_a?(Prism::TrueNode) && t == "bool" ||
|
451
|
+
node.value.is_a?(Prism::FalseNode) && t == "bool" ||
|
452
|
+
node.value.is_a?(Prism::StringNode) && t == "String" ||
|
453
|
+
node.value.is_a?(Prism::SymbolNode) && t == ":#{node.value.value}")
|
454
|
+
# The types of constants may be automatically inferred
|
455
|
+
nil
|
456
|
+
else
|
457
|
+
t
|
458
|
+
end
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
402
462
|
def add_rbs_inline_annotation_for_trailing(node:, type:)
|
403
463
|
return if type == "untyped"
|
404
464
|
|