irbs 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6c8b175c641b45064dcf880ee4c21133ba9a6240f55c7237e8ef859bc3e51156
4
+ data.tar.gz: ad4a5fbf12afc99fee4ad48bd11c348acdb4c2cdf94e120656eeb8d50a2a3cf2
5
+ SHA512:
6
+ metadata.gz: 1af6c2167935bad83840c1fba0497f3bda725c65d4521cdbf245e0d02aaa8cf93539bc9da5d010e12b8d3f5b0c284aa35459831c85fc3c9f172b8fbed3f5a392
7
+ data.tar.gz: d1682623eb9e908ad5b1e79ee9fb23824a57ed7ce216560de37678f4a934c9eb2cd378fcf1b1e71d17dd2effcceba8f93fd821a501466ad132366c72493a2b0e
data/.rubocop.yml ADDED
@@ -0,0 +1,61 @@
1
+ ---
2
+ AllCops:
3
+ NewCops: enable
4
+
5
+ ################
6
+ ## Style
7
+ ################
8
+
9
+ Style/DisableCopsWithinSourceCodeDirective:
10
+ AllowedCops: []
11
+
12
+ # ケツカンマ。行を追加したときに変更が少ないほうがいい
13
+ Style/TrailingCommaInHashLiteral:
14
+ EnforcedStyleForMultiline: consistent_comma
15
+ Style/TrailingCommaInArrayLiteral:
16
+ EnforcedStyleForMultiline: consistent_comma
17
+ Style/TrailingCommaInArguments:
18
+ EnforcedStyleForMultiline: consistent_comma
19
+
20
+ # ;より改行のほうが視認しやすい
21
+ Style/EmptyMethod:
22
+ EnforcedStyle: expanded
23
+
24
+ # Blockかどうかは返り値を使うかどうかで決めたい
25
+ Style/BlockDelimiters:
26
+ EnforcedStyle: semantic
27
+
28
+ # 内容は名前で示したい
29
+ Style/Documentation:
30
+ Enabled: false
31
+
32
+ ################
33
+ ## Layout
34
+ ################
35
+
36
+ # インデント
37
+ Layout/ArgumentAlignment:
38
+ EnforcedStyle: with_fixed_indentation
39
+ Layout/ArrayAlignment:
40
+ EnforcedStyle: with_fixed_indentation
41
+ Layout/ParameterAlignment:
42
+ EnforcedStyle: with_fixed_indentation
43
+
44
+ Layout/LineEndStringConcatenationIndentation:
45
+ EnforcedStyle: indented
46
+
47
+ Layout/FirstHashElementIndentation:
48
+ EnforcedStyle: consistent
49
+
50
+ Layout/MultilineMethodCallIndentation:
51
+ EnforcedStyle: indented
52
+
53
+ # スペース
54
+ Layout/SpaceInsideBlockBraces:
55
+ SpaceBeforeBlockParameters: false
56
+
57
+ Layout/SpaceBeforeBlockBraces:
58
+ EnforcedStyle: no_space
59
+
60
+ Layout/SpaceInsideHashLiteralBraces:
61
+ EnforcedStyle: no_space
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in irbs.gemspec
6
+ # gemspec
7
+
8
+ gem 'yard'
9
+
10
+ group :develepment do
11
+ gem 'minitest', '~> 5.0'
12
+ gem 'rake', '~> 13.0'
13
+ gem 'rubocop', '~> 1.21'
14
+ gem 'steep'
15
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,84 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ activesupport (7.0.4)
5
+ concurrent-ruby (~> 1.0, >= 1.0.2)
6
+ i18n (>= 1.6, < 2)
7
+ minitest (>= 5.1)
8
+ tzinfo (~> 2.0)
9
+ ast (2.4.2)
10
+ concurrent-ruby (1.1.10)
11
+ csv (3.2.5)
12
+ ffi (1.15.5)
13
+ fileutils (1.6.0)
14
+ i18n (1.12.0)
15
+ concurrent-ruby (~> 1.0)
16
+ json (2.6.2)
17
+ language_server-protocol (3.17.0.1)
18
+ listen (3.7.1)
19
+ rb-fsevent (~> 0.10, >= 0.10.3)
20
+ rb-inotify (~> 0.9, >= 0.9.10)
21
+ logger (1.5.1)
22
+ minitest (5.16.3)
23
+ parallel (1.22.1)
24
+ parser (3.1.2.1)
25
+ ast (~> 2.4.1)
26
+ rainbow (3.1.1)
27
+ rake (13.0.6)
28
+ rb-fsevent (0.11.2)
29
+ rb-inotify (0.10.1)
30
+ ffi (~> 1.0)
31
+ rbs (2.7.0)
32
+ regexp_parser (2.6.1)
33
+ rexml (3.2.5)
34
+ rubocop (1.39.0)
35
+ json (~> 2.3)
36
+ parallel (~> 1.10)
37
+ parser (>= 3.1.2.1)
38
+ rainbow (>= 2.2.2, < 4.0)
39
+ regexp_parser (>= 1.8, < 3.0)
40
+ rexml (>= 3.2.5, < 4.0)
41
+ rubocop-ast (>= 1.23.0, < 2.0)
42
+ ruby-progressbar (~> 1.7)
43
+ unicode-display_width (>= 1.4.0, < 3.0)
44
+ rubocop-ast (1.23.0)
45
+ parser (>= 3.1.1.0)
46
+ ruby-progressbar (1.11.0)
47
+ securerandom (0.2.0)
48
+ steep (1.2.1)
49
+ activesupport (>= 5.1)
50
+ csv (>= 3.0.9)
51
+ fileutils (>= 1.1.0)
52
+ json (>= 2.1.0)
53
+ language_server-protocol (>= 3.15, < 4.0)
54
+ listen (~> 3.0)
55
+ logger (>= 1.3.0)
56
+ parallel (>= 1.0.0)
57
+ parser (>= 3.1)
58
+ rainbow (>= 2.2.2, < 4.0)
59
+ rbs (>= 2.7.0)
60
+ securerandom (>= 0.1)
61
+ strscan (>= 1.0.0)
62
+ terminal-table (>= 2, < 4)
63
+ strscan (3.0.4)
64
+ terminal-table (3.0.2)
65
+ unicode-display_width (>= 1.1.1, < 3)
66
+ tzinfo (2.0.5)
67
+ concurrent-ruby (~> 1.0)
68
+ unicode-display_width (2.3.0)
69
+ webrick (1.7.0)
70
+ yard (0.9.28)
71
+ webrick (~> 1.7.0)
72
+
73
+ PLATFORMS
74
+ arm64-darwin-21
75
+
76
+ DEPENDENCIES
77
+ minitest (~> 5.0)
78
+ rake (~> 13.0)
79
+ rubocop (~> 1.21)
80
+ steep
81
+ yard
82
+
83
+ BUNDLED WITH
84
+ 2.3.18
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022 diaphragm
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # Irbs
2
+
3
+ ***Inline RBS***
4
+
5
+ This gem generate rbs code from ruby source code with signature annotation comment.
6
+ ## Installation
7
+
8
+ Install the gem and add to the application's Gemfile by executing:
9
+
10
+ $ bundle add irbs
11
+
12
+ If bundler is not being used to manage dependencies, install the gem by executing:
13
+
14
+ $ gem install irbs
15
+
16
+ ## Usage
17
+
18
+ Prepare ruby code with signature annotation comment
19
+
20
+ ```rb
21
+ # example.rb
22
+
23
+ module App
24
+ # @sig (Integer) -> String
25
+ def some_method(arg)
26
+ arg.to_s
27
+ end
28
+
29
+ # @sig (String) -> Integer
30
+ def some_private_method(arg)
31
+ arg.to_i
32
+ end
33
+ end
34
+ ```
35
+
36
+ and run `irbs example.rb -o example.rbs`,
37
+ then rbs code will be generated
38
+
39
+ ```rbs
40
+ # example.rbs
41
+
42
+ module ::App
43
+ public def some_method: (Integer) -> String
44
+ private def some_private_method: (String) -> Integer
45
+ end
46
+ ```
47
+
48
+ See example task in [`Rakefile`](https://github.com/diaphragm/irbs/tree/master/Rakefile) and [`exmaple/`](https://github.com/diaphragm/irbs/tree/master/example) for more examples.
49
+
50
+ This library uses itself for type checking.
51
+ See typecheck task in [`Rakefile`](https://github.com/diaphragm/irbs/tree/master/Rakefile) and [`isig/irbs.rbs`](https://github.com/diaphragm/irbs/tree/master/isig/irbs.rbs)
52
+
53
+ ## Development
54
+
55
+ ```
56
+ bundle install
57
+ rake setup
58
+ ```
59
+
60
+ ## Contributing
61
+
62
+ Bug reports and pull requests are welcome on GitHub at https://github.com/diaphragm/irbs.
63
+
64
+ ## License
65
+
66
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << 'test'
8
+ t.libs << 'lib'
9
+ t.test_files = FileList['test/**/test_*.rb']
10
+ end
11
+
12
+ require 'rubocop/rake_task'
13
+
14
+ RuboCop::RakeTask.new
15
+
16
+ task default: %i[rubocop typecheck test]
17
+
18
+ desc 'Setup develop environment'
19
+ task :setup do
20
+ sh 'rbs collection install'
21
+ end
22
+
23
+ desc 'typecheck'
24
+ task :typecheck do
25
+ sh 'mkdir -p isig'
26
+
27
+ sh 'exe/irbs "lib/**/*.rb" -o isig/irbs.rbs'
28
+ sh 'steep check lib'
29
+ end
30
+
31
+ desc 'Example of usage with TypeProf and Steep'
32
+ task :example do
33
+ sh 'exe/irbs example/app.rb -o example/irbs.rbs --ignore-constant'
34
+ sh 'typeprof example/app.rb example/irbs.rbs -o example/typeprof.rbs'
35
+ sh 'steep check example'
36
+ end
data/Steepfile ADDED
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ # D = Steep::Diagnostic
4
+ #
5
+ # target :lib do
6
+ # signature "sig"
7
+ #
8
+ # check "lib" # Directory name
9
+ # check "Gemfile" # File name
10
+ # check "app/models/**/*.rb" # Glob
11
+ # # ignore "lib/templates/*.rb"
12
+ #
13
+ # # library "pathname", "set" # Standard libraries
14
+ # # library "strong_json" # Gems
15
+ #
16
+ # # configure_code_diagnostics(D::Ruby.strict) # `strict` diagnostics setting
17
+ # # configure_code_diagnostics(D::Ruby.lenient) # `lenient` diagnostics setting
18
+ # # configure_code_diagnostics do |hash| # You can setup everything yourself
19
+ # # hash[D::Ruby::NoMethod] = :information
20
+ # # end
21
+ # end
22
+
23
+ # target :test do
24
+ # signature "sig", "sig-private"
25
+ #
26
+ # check "test"
27
+ #
28
+ # # library "pathname", "set" # Standard libraries
29
+ # end
30
+
31
+ target :lib do
32
+ signature 'isig'
33
+
34
+ check 'lib'
35
+ end
36
+
37
+ target :example do
38
+ signature 'example'
39
+
40
+ check 'example'
41
+ end
data/example/app.rb ADDED
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Submodule
4
+ def submethod
5
+ end
6
+ end
7
+
8
+ module Example
9
+ # @rbs type key = String | Symbol
10
+ class App
11
+ include Submodule
12
+ extend Submodule
13
+
14
+ module Hoge
15
+ # @sig (Integer) -> String
16
+ def self.hoge(arg)
17
+ arg.to_s
18
+ end
19
+
20
+ class << self
21
+ # @sig () -> bool
22
+ def fuga
23
+ false
24
+ end
25
+ end
26
+ end
27
+
28
+ # @sig String
29
+ HOGE = 'hoge'
30
+ # @sig Integer
31
+ FUGA = 1
32
+ private_constant :FUGA
33
+
34
+ # @sig Integer
35
+ attr_reader :xxx
36
+ # @sig String
37
+ attr_accessor :yyy
38
+
39
+ class << self
40
+ attr_reader :class_attr
41
+ end
42
+
43
+ # @sig (Integer, String) -> void
44
+ def initialize(xxx, yyy)
45
+ @xxx = xxx
46
+ @yyy = yyy
47
+ end
48
+
49
+ # @sig () -> bool
50
+ def foo
51
+ false
52
+ end
53
+
54
+ # @sig () -> void
55
+ def self.classmethod
56
+ end
57
+
58
+ private
59
+
60
+ # @sig Array[untyped]
61
+ attr_writer :zzz
62
+
63
+ # @sig [T] (T) -> T
64
+ def bar(zzz)
65
+ zzz
66
+ end
67
+ end
68
+ end
data/example/irbs.rbs ADDED
@@ -0,0 +1,27 @@
1
+ # Irbs 0.1.0
2
+
3
+ module ::Submodule
4
+ end
5
+
6
+ module ::Example
7
+ end
8
+
9
+ class ::Example::App
10
+ type key = String | Symbol
11
+ extend ::Submodule
12
+ include ::Submodule
13
+
14
+ public attr_reader xxx: Integer
15
+ public attr_accessor yyy: String
16
+ private attr_writer zzz: Array[untyped]
17
+ public def initialize: (Integer, String) -> void
18
+ public def foo: () -> bool
19
+ public def self.classmethod: () -> void
20
+ private def bar: [T] (T) -> T
21
+ end
22
+
23
+ module ::Example::App::Hoge
24
+ public def self.hoge: (Integer) -> String
25
+ public def self.fuga: () -> bool
26
+ end
27
+
@@ -0,0 +1,23 @@
1
+ # TypeProf 0.21.3
2
+
3
+ # Classes
4
+ module Submodule
5
+ def submethod: -> nil
6
+ end
7
+
8
+ module Example
9
+ class App
10
+ HOGE: String
11
+ FUGA: Integer
12
+ extend Submodule
13
+ include Submodule
14
+
15
+ # def initialize: (Integer, String) -> void
16
+ # def foo: () -> bool
17
+ # def self.classmethod: () -> void
18
+ # def bar: [T] (T) -> T
19
+ # attr_reader xxx: Integer
20
+ # attr_accessor yyy: String
21
+ # attr_writer zzz: Array[untyped]
22
+ end
23
+ end
data/exe/irbs ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../lib/irbs'
5
+
6
+ Irbs::CLI.run(ARGV)
data/irbs.gemspec ADDED
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/irbs/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'irbs'
7
+ spec.version = Irbs::VERSION
8
+ spec.authors = ['diaphragm']
9
+ spec.email = ['7163746+diaphragm@users.noreply.github.com']
10
+
11
+ spec.summary = 'Inline RBS'
12
+ # spec.description = 'TODO: Write a longer description or delete this line.'
13
+ spec.homepage = 'https://github.com/diaphragm/irbs'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = '>= 3.1.0'
16
+
17
+ # spec.metadata['allowed_push_host'] = "TODO: Set to your gem server 'https://example.com'"
18
+
19
+ spec.metadata['homepage_uri'] = spec.homepage
20
+ spec.metadata['source_code_uri'] = 'https://github.com/diaphragm'
21
+ # spec.metadata['changelog_uri'] = "TODO: Put your gem's CHANGELOG.md URL here."
22
+ spec.metadata['rubygems_mfa_required'] = 'true'
23
+
24
+ # Specify which files should be added to the gem when it is released.
25
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
26
+ spec.files = Dir.chdir(__dir__){
27
+ `git ls-files -z`.split("\x0").reject do |f|
28
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
29
+ end
30
+ }
31
+ spec.bindir = 'exe'
32
+ spec.executables = spec.files.grep(%r{\Aexe/}){|f| File.basename(f) }
33
+ spec.require_paths = ['lib']
34
+
35
+ # Uncomment to register a new dependency of your gem
36
+ # spec.add_dependency "example-gem", "~> 1.0"
37
+
38
+ # For more information and examples about making a new gem, check out our
39
+ # guide at: https://bundler.io/guides/creating_gem.html
40
+ end
data/isig/irbs.rbs ADDED
@@ -0,0 +1,68 @@
1
+ # Irbs 0.1.0
2
+
3
+ module ::Irbs
4
+ VERSION: String
5
+ end
6
+
7
+ class ::Irbs::CLI
8
+ NO_CONSTANT_HELP_MESSAGE: String
9
+ public def self.run: (Array[String]) -> void
10
+ private def self.parse_opt: (Array[String]) -> Irbs::Config
11
+ end
12
+
13
+ class ::Irbs::Core
14
+ public attr_reader config: Irbs::Config
15
+ public def initialize: (Irbs::Config) -> void
16
+ public def generate: () -> void
17
+ private def registry: () -> singleton(YARD::Registry)
18
+ end
19
+
20
+ class ::Irbs::Config
21
+ public attr_accessor stdout: IO
22
+ public attr_accessor ingore_constant: bool
23
+ public attr_accessor paths: Array[String]
24
+ end
25
+
26
+ module ::Irbs::Template
27
+ public def self.meth: (YARD::CodeObjects::MethodObject) -> String
28
+ public def self.constant: (YARD::CodeObjects::ConstantObject) -> String
29
+ public def self.include: (YARD::CodeObjects::ModuleObject) -> String
30
+ public def self.extend: (YARD::CodeObjects::ModuleObject) -> String
31
+ public def self.attribute: (Irbs::AttributeWrapper) -> String
32
+ public def self.rbs: (YARD::Tags::Tag) -> String
33
+ end
34
+
35
+ class ::Irbs::RbsGenerator
36
+ extend ::Forwardable
37
+ private attr_reader obj: YARD::CodeObjects::NamespaceObject
38
+ private attr_reader config: Irbs::Config
39
+ private attr_reader stdout: IO
40
+ public def initialize: (YARD::CodeObjects::NamespaceObject, Irbs::Config) -> void
41
+ public def generate: () -> void
42
+ private def instance_mixins: () -> Array[YARD::CodeObjects::ModuleObject]
43
+ private def class_mixins: () -> Array[YARD::CodeObjects::ModuleObject]
44
+ private def writeout: () -> void
45
+ private def to_rbs: () -> String
46
+ private def namespace_definition: () -> String
47
+ private def raw_rbss: () -> Array[YARD::Tags::Tag]
48
+ private def child_namespaces: () -> Array[YARD::CodeObjects::NamespaceObject]
49
+ private def constants: () -> Array[YARD::CodeObjects::ConstantObject]
50
+ private def meths: () -> Array[YARD::CodeObjects::MethodObject]
51
+ private def attribute_meths: () -> Array[YARD::CodeObjects::MethodObject]
52
+ private def attributes: () -> Array[Irbs::AttributeWrapper]
53
+ end
54
+
55
+ class ::Irbs::AttributeWrapper
56
+ type attributes = Hash[(:class | :instance), Hash[Symbol, accessors]]
57
+ type accessors = Hash[(:read | :write), YARD::CodeObjects::MethodObject?]
58
+ public attr_reader scope: Symbol
59
+ public attr_reader name: Symbol
60
+ public attr_reader reader: YARD::CodeObjects::MethodObject?
61
+ public attr_reader writer: YARD::CodeObjects::MethodObject?
62
+ public def self.parse: (attributes) -> Array[Irbs::AttributeWrapper]
63
+ public def initialize: (Symbol, Symbol, accessors) -> void
64
+ public def type: () -> Symbol
65
+ public def visibility: () -> Symbol?
66
+ public def sig: () -> String?
67
+ end
68
+
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Irbs
4
+ # return value of `YARD::CodeObjects::NamespaceObject#attributes`
5
+ # @rbs type attributes = Hash[(:class | :instance), Hash[Symbol, accessors]]
6
+ # @rbs type accessors = Hash[(:read | :write), YARD::CodeObjects::MethodObject?]
7
+ class AttributeWrapper
8
+ # @sig (attributes) -> Array[Irbs::AttributeWrapper]
9
+ def self.parse(attributes)
10
+ attributes.map{|scope, attr_data|
11
+ attr_data.map{|name, attr_meths| new(scope, name, attr_meths) }
12
+ }.flatten
13
+ end
14
+
15
+ # @sig Symbol
16
+ attr_reader :scope
17
+ # @sig Symbol
18
+ attr_reader :name
19
+ # @sig YARD::CodeObjects::MethodObject?
20
+ attr_reader :reader
21
+ # @sig YARD::CodeObjects::MethodObject?
22
+ attr_reader :writer
23
+
24
+ # @sig (Symbol, Symbol, accessors) -> void
25
+ def initialize(scope, name, attr_meths)
26
+ @scope = scope
27
+ @name = name
28
+ @reader = attr_meths[:read]
29
+ @writer = attr_meths[:write]
30
+ end
31
+
32
+ # @sig () -> Symbol
33
+ def type
34
+ if reader && writer
35
+ :accessor
36
+ elsif reader
37
+ :reader
38
+ elsif writer
39
+ :writer
40
+ else
41
+ raise StandardError
42
+ end
43
+ end
44
+
45
+ # @sig () -> Symbol?
46
+ def visibility
47
+ (reader || writer)&.visibility
48
+ end
49
+
50
+ # @sig () -> String?
51
+ def sig
52
+ (reader || writer)&.tag(:sig)&.text
53
+ end
54
+ end
55
+ end
data/lib/irbs/cli.rb ADDED
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'optparse'
4
+
5
+ module Irbs
6
+ class CLI
7
+ # @sig String
8
+ NO_CONSTANT_HELP_MESSAGE = 'Generate no constant signatures. ' \
9
+ 'For using TypeProf. ' \
10
+ '(TypeProf genarate duplicate constant signature even if already exists.)'
11
+ private_constant :NO_CONSTANT_HELP_MESSAGE
12
+
13
+ class << self
14
+ # @sig (Array[String]) -> void
15
+ def run(argv)
16
+ config = parse_opt(argv)
17
+ Core.new(config).generate
18
+ config.stdout.close
19
+ end
20
+
21
+ private
22
+
23
+ # @sig (Array[String]) -> Irbs::Config
24
+ def parse_opt(argv)
25
+ config = Irbs::Config.new
26
+ opt = OptionParser.new
27
+
28
+ opt.on('-o output', 'default: stdout') do
29
+ config.stdout = File.open(_1, 'w')
30
+ end
31
+ opt.on('--ignore-constant', NO_CONSTANT_HELP_MESSAGE) do
32
+ config.ingore_constant = _1
33
+ end
34
+ config.paths = opt.parse(argv)
35
+
36
+ config
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Irbs
4
+ class Config
5
+ # @sig IO
6
+ attr_accessor :stdout
7
+ # @sig bool
8
+ attr_accessor :ingore_constant
9
+ # @sig Array[String]
10
+ attr_accessor :paths
11
+
12
+ def initialize
13
+ @stdout = $stdout
14
+ @ingore_constant = false
15
+ @paths = []
16
+ end
17
+ end
18
+ end
data/lib/irbs/core.rb ADDED
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yard'
4
+
5
+ module Irbs
6
+ class Core
7
+ # @sig Irbs::Config
8
+ attr_reader :config
9
+
10
+ # @sig (Irbs::Config) -> void
11
+ def initialize(config)
12
+ @config = config
13
+
14
+ YARD::Tags::Library.define_tag('Signature', :sig)
15
+ YARD::Tags::Library.define_tag('Raw rbs code', :rbs)
16
+ YARD.parse(config.paths)
17
+ YARD::Registry.load_all
18
+ end
19
+
20
+ # @sig () -> void
21
+ def generate
22
+ config.stdout.puts("# Irbs #{VERSION}")
23
+ config.stdout.puts
24
+ RbsGenerator.new(registry.root, config).generate
25
+ end
26
+
27
+ private
28
+
29
+ # @sig () -> singleton(YARD::Registry)
30
+ def registry
31
+ YARD::Registry
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+ require 'yard'
5
+
6
+ module Irbs
7
+ class RbsGenerator
8
+ extend Forwardable
9
+
10
+ # @sig (YARD::CodeObjects::NamespaceObject, Irbs::Config) -> void
11
+ def initialize(namespace_obj, config)
12
+ @obj = namespace_obj
13
+ @config = config
14
+ @stdout = config.stdout
15
+ end
16
+
17
+ # @sig () -> void
18
+ def generate
19
+ writeout unless obj.root?
20
+
21
+ child_namespaces.each do
22
+ self.class.new(_1, config).generate
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ # @sig YARD::CodeObjects::NamespaceObject
29
+ attr_reader :obj
30
+ # @sig Irbs::Config
31
+ attr_reader :config
32
+ # @sig IO
33
+ attr_reader :stdout
34
+
35
+ # @!method instance_mixins
36
+ # @sig () -> Array[YARD::CodeObjects::ModuleObject]
37
+ # @!method class_mixins
38
+ # @sig () -> Array[YARD::CodeObjects::ModuleObject]
39
+ delegate %i[instance_mixins class_mixins] => :obj
40
+
41
+ # @sig () -> void
42
+ def writeout
43
+ stdout.puts(to_rbs)
44
+ stdout.puts
45
+ end
46
+
47
+ # @sig () -> String
48
+ def to_rbs # rubocop:todo Metrics/AbcSize, Metrics/CyclomaticComplexity
49
+ [
50
+ namespace_definition,
51
+ raw_rbss.map{ Template.rbs(_1) },
52
+ class_mixins.map{ Template.extend(_1) },
53
+ instance_mixins.map{ Template.include(_1) },
54
+ config.ingore_constant ? nil : constants.map{ Template.constant(_1) },
55
+ attributes.map{ Template.attribute(_1) },
56
+ meths.map{ Template.meth(_1) },
57
+ 'end',
58
+ ].flatten.compact.join("\n")
59
+ end
60
+
61
+ # @sig () -> String
62
+ def namespace_definition
63
+ "#{obj.type} ::#{obj.path}"
64
+ end
65
+
66
+ # @sig () -> Array[YARD::Tags::Tag]
67
+ def raw_rbss
68
+ obj.tags(:rbs)
69
+ end
70
+
71
+ # @sig () -> Array[YARD::CodeObjects::NamespaceObject]
72
+ def child_namespaces
73
+ # obj.children.select{ _1.kind_of?(YARD::CodeObjects::NamespaceObject) }
74
+ # rewrite without #select to pass typecheck
75
+ obj.children.each.with_object([]){|child, res|
76
+ res.push(child) if child.is_a?(YARD::CodeObjects::NamespaceObject)
77
+ }
78
+ end
79
+
80
+ # @sig () -> Array[YARD::CodeObjects::ConstantObject]
81
+ def constants
82
+ obj.constants.select{ _1.tag(:sig) }
83
+ end
84
+
85
+ # @sig () -> Array[YARD::CodeObjects::MethodObject]
86
+ def meths
87
+ (obj.meths - attribute_meths).select{ _1.tag(:sig) }
88
+ end
89
+
90
+ # @sig () -> Array[YARD::CodeObjects::MethodObject]
91
+ def attribute_meths
92
+ obj.attributes.values.map(&:values).flatten.map(&:values).flatten.compact
93
+ end
94
+
95
+ # @sig () -> Array[Irbs::AttributeWrapper]
96
+ def attributes
97
+ AttributeWrapper.parse(obj.attributes)
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Irbs
4
+ module Template
5
+ class << self
6
+ # @sig (YARD::CodeObjects::MethodObject) -> String
7
+ def meth(meth)
8
+ visibility = meth.visibility
9
+ prefix = meth.scope == :class ? 'self.' : ''
10
+ name = meth.name
11
+ sig = meth.tag(:sig).text
12
+
13
+ " #{visibility} def #{prefix}#{name}: #{sig}"
14
+ end
15
+
16
+ # @sig (YARD::CodeObjects::ConstantObject) -> String
17
+ def constant(constant)
18
+ # visibility = constant.visibility
19
+ name = constant.name
20
+ sig = constant.tag(:sig).text
21
+
22
+ " #{name}: #{sig}"
23
+ end
24
+
25
+ # @sig (YARD::CodeObjects::ModuleObject) -> String
26
+ def include(mod)
27
+ " include ::#{mod.path}"
28
+ end
29
+
30
+ # @sig (YARD::CodeObjects::ModuleObject) -> String
31
+ def extend(mod)
32
+ " extend ::#{mod.path}"
33
+ end
34
+
35
+ # @sig (Irbs::AttributeWrapper) -> String
36
+ def attribute(attr_wrapper)
37
+ return '' unless attr_wrapper.sig
38
+
39
+ visibility = attr_wrapper.visibility
40
+ type = attr_wrapper.type
41
+ prefix = attr_wrapper.scope == :class ? 'self.' : ''
42
+ name = attr_wrapper.name
43
+ sig = attr_wrapper.sig
44
+
45
+ " #{visibility} attr_#{type} #{prefix}#{name}: #{sig}"
46
+ end
47
+
48
+ # @sig (YARD::Tags::Tag) -> String
49
+ def rbs(tag)
50
+ text = tag.text
51
+
52
+ " #{text}"
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Irbs
4
+ # @sig String
5
+ VERSION = '0.1.0'
6
+ end
data/lib/irbs.rb ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'irbs/attribute_wrapper'
4
+ require_relative 'irbs/cli'
5
+ require_relative 'irbs/config'
6
+ require_relative 'irbs/core'
7
+ require_relative 'irbs/rbs_generator'
8
+ require_relative 'irbs/template'
9
+ require_relative 'irbs/version'
10
+
11
+ module Irbs
12
+ end
@@ -0,0 +1,148 @@
1
+ ---
2
+ sources:
3
+ - name: ruby/gem_rbs_collection
4
+ remote: https://github.com/ruby/gem_rbs_collection.git
5
+ revision: main
6
+ repo_dir: gems
7
+ path: ".gem_rbs_collection"
8
+ gems:
9
+ - name: rack
10
+ version: '2.2'
11
+ source:
12
+ type: git
13
+ name: ruby/gem_rbs_collection
14
+ revision: 0a45b6d56b0e1b089731f5eb007912a7c36be121
15
+ remote: https://github.com/ruby/gem_rbs_collection.git
16
+ repo_dir: gems
17
+ - name: activesupport
18
+ version: '6.0'
19
+ source:
20
+ type: git
21
+ name: ruby/gem_rbs_collection
22
+ revision: 0a45b6d56b0e1b089731f5eb007912a7c36be121
23
+ remote: https://github.com/ruby/gem_rbs_collection.git
24
+ repo_dir: gems
25
+ - name: ast
26
+ version: '2.4'
27
+ source:
28
+ type: git
29
+ name: ruby/gem_rbs_collection
30
+ revision: 0a45b6d56b0e1b089731f5eb007912a7c36be121
31
+ remote: https://github.com/ruby/gem_rbs_collection.git
32
+ repo_dir: gems
33
+ - name: csv
34
+ version: '0'
35
+ source:
36
+ type: stdlib
37
+ - name: fileutils
38
+ version: '0'
39
+ source:
40
+ type: stdlib
41
+ - name: i18n
42
+ version: '1.10'
43
+ source:
44
+ type: git
45
+ name: ruby/gem_rbs_collection
46
+ revision: 0a45b6d56b0e1b089731f5eb007912a7c36be121
47
+ remote: https://github.com/ruby/gem_rbs_collection.git
48
+ repo_dir: gems
49
+ - name: json
50
+ version: '0'
51
+ source:
52
+ type: stdlib
53
+ - name: listen
54
+ version: '3.2'
55
+ source:
56
+ type: git
57
+ name: ruby/gem_rbs_collection
58
+ revision: 0a45b6d56b0e1b089731f5eb007912a7c36be121
59
+ remote: https://github.com/ruby/gem_rbs_collection.git
60
+ repo_dir: gems
61
+ - name: logger
62
+ version: '0'
63
+ source:
64
+ type: stdlib
65
+ - name: minitest
66
+ version: '0'
67
+ source:
68
+ type: stdlib
69
+ - name: parallel
70
+ version: '1.20'
71
+ source:
72
+ type: git
73
+ name: ruby/gem_rbs_collection
74
+ revision: 0a45b6d56b0e1b089731f5eb007912a7c36be121
75
+ remote: https://github.com/ruby/gem_rbs_collection.git
76
+ repo_dir: gems
77
+ - name: rainbow
78
+ version: '3.0'
79
+ source:
80
+ type: git
81
+ name: ruby/gem_rbs_collection
82
+ revision: 0a45b6d56b0e1b089731f5eb007912a7c36be121
83
+ remote: https://github.com/ruby/gem_rbs_collection.git
84
+ repo_dir: gems
85
+ - name: securerandom
86
+ version: '0'
87
+ source:
88
+ type: stdlib
89
+ - name: strscan
90
+ version: '0'
91
+ source:
92
+ type: stdlib
93
+ - name: yard
94
+ version: '0.9'
95
+ source:
96
+ type: git
97
+ name: ruby/gem_rbs_collection
98
+ revision: 0a45b6d56b0e1b089731f5eb007912a7c36be121
99
+ remote: https://github.com/ruby/gem_rbs_collection.git
100
+ repo_dir: gems
101
+ - name: cgi
102
+ version: '0'
103
+ source:
104
+ type: stdlib
105
+ - name: uri
106
+ version: '0'
107
+ source:
108
+ type: stdlib
109
+ - name: monitor
110
+ version: '0'
111
+ source:
112
+ type: stdlib
113
+ - name: date
114
+ version: '0'
115
+ source:
116
+ type: stdlib
117
+ - name: singleton
118
+ version: '0'
119
+ source:
120
+ type: stdlib
121
+ - name: mutex_m
122
+ version: '0'
123
+ source:
124
+ type: stdlib
125
+ - name: time
126
+ version: '0'
127
+ source:
128
+ type: stdlib
129
+ - name: pathname
130
+ version: '0'
131
+ source:
132
+ type: stdlib
133
+ - name: forwardable
134
+ version: '0'
135
+ source:
136
+ type: stdlib
137
+ - name: set
138
+ version: '0'
139
+ source:
140
+ type: stdlib
141
+ - name: optparse
142
+ version: '0'
143
+ source:
144
+ type: stdlib
145
+ - name: tempfile
146
+ version: '0'
147
+ source:
148
+ type: stdlib
@@ -0,0 +1,18 @@
1
+ # Download sources
2
+ sources:
3
+ - name: ruby/gem_rbs_collection
4
+ remote: https://github.com/ruby/gem_rbs_collection.git
5
+ revision: main
6
+ repo_dir: gems
7
+
8
+ # A directory to install the downloaded RBSs
9
+ path: .gem_rbs_collection
10
+
11
+ gems:
12
+ # Skip loading rbs gem's RBS.
13
+ # It's unnecessary if you don't use rbs as a library.
14
+ - name: rbs
15
+ ignore: true
16
+ - name: steep
17
+ ignore: true
18
+ - name: rack
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: irbs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - diaphragm
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-11-20 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ - 7163746+diaphragm@users.noreply.github.com
16
+ executables:
17
+ - irbs
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - ".rubocop.yml"
22
+ - Gemfile
23
+ - Gemfile.lock
24
+ - LICENSE.txt
25
+ - README.md
26
+ - Rakefile
27
+ - Steepfile
28
+ - example/app.rb
29
+ - example/irbs.rbs
30
+ - example/typeprof.rbs
31
+ - exe/irbs
32
+ - irbs.gemspec
33
+ - isig/irbs.rbs
34
+ - lib/irbs.rb
35
+ - lib/irbs/attribute_wrapper.rb
36
+ - lib/irbs/cli.rb
37
+ - lib/irbs/config.rb
38
+ - lib/irbs/core.rb
39
+ - lib/irbs/rbs_generator.rb
40
+ - lib/irbs/template.rb
41
+ - lib/irbs/version.rb
42
+ - rbs_collection.lock.yaml
43
+ - rbs_collection.yaml
44
+ homepage: https://github.com/diaphragm/irbs
45
+ licenses:
46
+ - MIT
47
+ metadata:
48
+ homepage_uri: https://github.com/diaphragm/irbs
49
+ source_code_uri: https://github.com/diaphragm
50
+ rubygems_mfa_required: 'true'
51
+ post_install_message:
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 3.1.0
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements: []
66
+ rubygems_version: 3.3.18
67
+ signing_key:
68
+ specification_version: 4
69
+ summary: Inline RBS
70
+ test_files: []