lap 0.1 → 0.2

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: 67d48053cc0e3fe1a6f28c32b764c69497c2a3416e7c21ee7eeedd36b7768e33
4
- data.tar.gz: 86b2d87a47f3e77964f14f6b876553a1365207a0bb1522df8f48cae43cbefd21
3
+ metadata.gz: 2175fa843ad4fa64403068441af0c6ca2be15b930746aa3af383dab7ed670822
4
+ data.tar.gz: d28106befda1f37218423c1ba046934cc31e73025fdd60a1c96e45db646913f1
5
5
  SHA512:
6
- metadata.gz: 1dfe0739b7d757c9d67474b02c2f4c832f217b8a49129c97e068fa048d661dc066883e162462feb5a5b3fd7b8bd60b4f965f4921898a79c374a0db38f299fad4
7
- data.tar.gz: 8b3f3a348b71222475155bfe7271757dbaf6ab505c0e6166e3c31140794f9a3cc25ba9a06d3ac6886af8f2098130cb8a2b503a148c015933afc143e0c43be939
6
+ metadata.gz: 355d4a32d74d86d51cfa2dd9a263c6f72301486a53012fa1873c66e6054d8a90080d1c7b75a6fb9ad1818767f00c72972f880a62979f8c8e14f9e1d26f515b61
7
+ data.tar.gz: 1f63b97bc3a9c19ca9d5f45d159a6166c842ad19bb2f95f04f6b217165a3d9fdc428fa2ea05aa761a2e46100e13b9aaae28a7067b37accab85d849390959f436
data/.lap.yml CHANGED
@@ -1 +1,2 @@
1
1
  indent: 2
2
+ frozen_string_literals: true
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- lap (0.1)
4
+ lap (0.2)
5
5
  rbs
6
6
 
7
7
  GEM
data/Rakefile CHANGED
@@ -4,3 +4,16 @@ require "rspec/core/rake_task"
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
6
  task :default => :spec
7
+
8
+ desc "Build ruby files from rbs files"
9
+ task :make do
10
+ require "find"
11
+ Find.find(File.join(File.expand_path(File.dirname(__FILE__)), "sig")).each do |fname|
12
+ next unless fname.end_with? ".rbs" # TODO: better way to exclude dirs?
13
+
14
+ fname_relative_to_project = fname[%r{sig/.*\.rbs}]
15
+ output_fname = fname_relative_to_project.sub(/sig/, "lib")
16
+ .chomp("s") # turn rbs to rb
17
+ sh "./exe/lap #{fname_relative_to_project} > #{output_fname}"
18
+ end
19
+ end
data/lib/lap.rb CHANGED
@@ -2,19 +2,23 @@
2
2
 
3
3
  require "rbs"
4
4
  require "pathname"
5
+ require "yaml"
5
6
  require "lap/version"
6
7
  require "lap/helpers"
7
8
  require "lap/class"
8
9
  require "lap/method"
9
10
  require "lap/module"
10
- require "pry-byebug"
11
+ require "lap/constant"
11
12
  require "core_ext/string"
12
13
 
13
14
  module Lap
14
15
  CONFIG_FILENAME = ".lap.yml"
15
16
  DEFAULT_CONFIG = {
16
- indent: 2
17
+ indent: 2,
18
+ frozen_string_literals: true,
19
+ preferred_line_length: 100
17
20
  }
21
+ FROZEN_STRING_COMMENT = "# frozen_string_literal: true\n\n"
18
22
  fp = File.join(File.dirname(__FILE__), "..", CONFIG_FILENAME)
19
23
  yml_config = Pathname(fp).exist? ? YAML.safe_load(File.read(fp)) : {}
20
24
  Config = DEFAULT_CONFIG.merge(yml_config.transform_keys(&:to_sym))
@@ -34,10 +38,12 @@ module Lap
34
38
  when RBS::AST::Declarations::Module
35
39
  Lap::Module.new(decl).render
36
40
  else
37
- "TODO: #{decl}"
41
+ warn "TODO: #{decl} not implemented yet"
42
+ nil
38
43
  end
39
44
  end
40
45
 
46
+ puts FROZEN_STRING_COMMENT if Lap::Config[:frozen_string_literals]
41
47
  puts output.join("\n")
42
48
  end
43
49
  end
@@ -45,6 +45,8 @@ module Lap
45
45
  with_comment(m, "include #{m.name}").indent(member_indent)
46
46
  when RBS::AST::Members::Extend
47
47
  with_comment(m, "extend #{m.name}").indent(member_indent)
48
+ when RBS::AST::Declarations::Constant
49
+ Lap::Constant.new(m, @indent_level + 1).render
48
50
  when RBS::AST::Declarations::Alias
49
51
  # no-op: not present in ruby
50
52
  else
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lap
4
+ class Constant
5
+ def initialize(node, indent_level)
6
+ @node = node
7
+ @indent_level = indent_level
8
+ end
9
+
10
+ def render
11
+ "#{name} = #{value}\n".indent(Lap::Config[:indent] * @indent_level)
12
+ end
13
+
14
+ private
15
+
16
+ def name
17
+ @node.name.name
18
+ end
19
+
20
+ def value
21
+ case @node.type
22
+ when RBS::Types::Record
23
+ fields = @node.type.fields
24
+ content = if fields.empty?
25
+ nil
26
+ else
27
+ " #{record_contents(fields)} "
28
+ end
29
+ "{#{content}}"
30
+ when RBS::Types::Literal
31
+ @node.type.literal
32
+ else
33
+ warn "TODO: #{@node.type} not supported yet"
34
+ ""
35
+ end
36
+ end
37
+
38
+ def record_contents(hsh)
39
+ inner_length = 0
40
+ contents = hsh.map do |k, v|
41
+ val = case v
42
+ when RBS::Types::Literal
43
+ v.literal
44
+ else
45
+ "nil"
46
+ end
47
+ pair = k.is_a?(Symbol) ? "#{k}: #{val}" : "#{k} => #{val}"
48
+ inner_length += pair.length
49
+ pair
50
+ end
51
+
52
+ if inner_length > Lap::Config[:preferred_line_length]
53
+ "\n#{contents.join(",\n")}\n"
54
+ else
55
+ contents.join(", ")
56
+ end
57
+ end
58
+ end
59
+ end
@@ -10,7 +10,7 @@ module Lap
10
10
  if [rp, rkw, op, okw].any? { |arg| arg.length.positive? }
11
11
  contents = [
12
12
  rp.map { |pos| pos.name || pos.type.name.name.downcase },
13
- op.map { |pos| "#{pos.name || pos.type.name.name.downcase} = #{CLASS_TO_LITERAL[pos.type.name.name]}" },
13
+ op.map { |pos| "#{pos.name || pos.type.name.name.downcase} = #{CLASS_TO_LITERAL[pos.type.name.name] || "nil"}" },
14
14
  rkw.map { |name, _| "#{name}:" },
15
15
  okw.map { |name, t| "#{name}: #{CLASS_TO_LITERAL[t.type.name.name]}" },
16
16
  ].reject(&:empty?).flatten.join(", ")
@@ -29,6 +29,8 @@ module Lap
29
29
  Lap::Class.new(m, @indent_level + 1).render
30
30
  when RBS::AST::Declarations::Module
31
31
  self.class.new(m, @indent_level + 1).render
32
+ when RBS::AST::Declarations::Constant
33
+ Lap::Constant.new(m, @indent_level + 1).render
32
34
  when RBS::AST::Declarations::Alias
33
35
  # no-op: not present in ruby
34
36
  else
@@ -1,3 +1,3 @@
1
1
  module Lap
2
- VERSION = "0.1"
2
+ VERSION = "0.2"
3
3
  end
@@ -0,0 +1,6 @@
1
+ class String
2
+ # @!begin
3
+ # gsub(/^/, " " * amount)
4
+ # @!end
5
+ def indent: (Integer amount) -> String
6
+ end
@@ -0,0 +1,52 @@
1
+ require "rbs"
2
+ require "pathname"
3
+ require "yaml"
4
+ require "lap/version"
5
+ require "lap/helpers"
6
+ require "lap/class"
7
+ require "lap/method"
8
+ require "lap/module"
9
+ require "lap/constant"
10
+ require "core_ext/string"
11
+
12
+ module Lap
13
+ CONFIG_FILENAME = ".lap.yml"
14
+ DEFAULT_CONFIG = {
15
+ indent: 2,
16
+ frozen_string_literals: true,
17
+ preferred_line_length: 100
18
+ }
19
+ FROZEN_STRING_COMMENT = "# frozen_string_literal: true\n\n"
20
+ Config = DEFAULT_CONFIG
21
+
22
+ class Output
23
+ # @!begin
24
+ # loader = RBS::EnvironmentLoader.new(core_root: nil) # don't pollute the env with ruby stdlib
25
+ # loader.add(path: Pathname(pathname))
26
+ # @env = RBS::Environment.from_loader(loader).resolve_type_names
27
+ #
28
+ # fp = File.join(File.dirname(__FILE__), "..", CONFIG_FILENAME)
29
+ # yml_config = Pathname(fp).exist? ? YAML.safe_load(File.read(fp)) : {}
30
+ # Lap::Config.merge!(yml_config.transform_keys(&:to_sym))
31
+ # @!end
32
+ def initialize: (String pathname) -> void
33
+
34
+ # @!begin
35
+ # output = @env.declarations.map do |decl|
36
+ # case decl
37
+ # when RBS::AST::Declarations::Class
38
+ # Lap::Class.new(decl).render
39
+ # when RBS::AST::Declarations::Module
40
+ # Lap::Module.new(decl).render
41
+ # else
42
+ # warn "TODO: #{decl} not implemented yet"
43
+ # nil
44
+ # end
45
+ # end
46
+ #
47
+ # puts FROZEN_STRING_COMMENT if Lap::Config[:frozen_string_literals]
48
+ # puts output.join("\n")
49
+ # @!end
50
+ def render: () -> String
51
+ end
52
+ end
@@ -0,0 +1,62 @@
1
+ module Lap
2
+ class Class
3
+ include Helpers
4
+
5
+ # @!begin
6
+ # @node = node
7
+ # @indent_level = indent_level || 0
8
+ # @has_contents = !@node.members.empty?
9
+ # @!end
10
+ def initialize: (RBS::AST::Declarations::Class node, ?Integer indent_level) -> void
11
+
12
+ # @!begin
13
+ # superclass = @node.super_class ? " < #{@node.super_class.name.name}" : ""
14
+ # self_indent = " " * (Lap::Config[:indent] * @indent_level)
15
+ # comment = get_comment(@node)
16
+ # "#{comment}#{self_indent}class #{@node.name.name}#{superclass}#{contents}#{self_indent if @has_contents}end\n"
17
+ # @!end
18
+ def render: () -> String
19
+
20
+ private
21
+
22
+ # @!begin
23
+ # @contents ||= begin
24
+ # if @has_contents
25
+ # member_indent = Lap::Config[:indent] * (@indent_level + 1)
26
+ # members = @node.members.map do |m|
27
+ # case m
28
+ # when RBS::AST::Members::MethodDefinition
29
+ # Lap::Method.new(m, @indent_level + 1).render
30
+ # when RBS::AST::Declarations::Class
31
+ # self.class.new(m, @indent_level + 1).render
32
+ # when RBS::AST::Declarations::Module
33
+ # Lap::Module.new(m, @indent_level + 1).render
34
+ # when RBS::AST::Members::AttrReader
35
+ # with_comment(m, "attr_reader :#{m.name}").indent(member_indent)
36
+ # when RBS::AST::Members::AttrWriter
37
+ # with_comment(m, "attr_writer :#{m.name}").indent(member_indent)
38
+ # when RBS::AST::Members::AttrAccessor
39
+ # with_comment(m, "attr_accessor :#{m.name}").indent(member_indent)
40
+ # when RBS::AST::Members::Public
41
+ # "public\n".indent(member_indent)
42
+ # when RBS::AST::Members::Private
43
+ # "private\n".indent(member_indent)
44
+ # when RBS::AST::Members::Include
45
+ # with_comment(m, "include #{m.name}").indent(member_indent)
46
+ # when RBS::AST::Members::Extend
47
+ # with_comment(m, "extend #{m.name}").indent(member_indent)
48
+ # when RBS::AST::Declarations::Alias
49
+ # # no-op: not present in ruby
50
+ # else
51
+ # warn "Unsupported member for classes: #{m}"
52
+ # end
53
+ # end
54
+ # "\n#{members.compact.join("\n")}"
55
+ # else
56
+ # "; "
57
+ # end
58
+ # end
59
+ # @!end
60
+ def contents: () -> String
61
+ end
62
+ end
@@ -0,0 +1,53 @@
1
+ module Lap
2
+ module Helpers
3
+ CLASS_TO_LITERAL: {
4
+ String: '""',
5
+ Array: '[]',
6
+ Hash: "{}"
7
+ }
8
+
9
+ # @!begin
10
+ # if [rp, rkw, op, okw].any? { |arg| arg.length.positive? }
11
+ # contents = [
12
+ # rp.map { |pos| pos.name || pos.type.name.name.downcase },
13
+ # op.map { |pos| "#{pos.name || pos.type.name.name.downcase} = #{CLASS_TO_LITERAL[pos.type.name.name]}" },
14
+ # rkw.map { |name, _| "#{name}:" },
15
+ # okw.map { |name, t| "#{name}: #{CLASS_TO_LITERAL[t.type.name.name]}" },
16
+ # ].reject(&:empty?).flatten.join(", ")
17
+ # "(#{contents})"
18
+ # end
19
+ # @!end
20
+ def args: (
21
+ Array[RBS::Types::Function::Param] rp,
22
+ Hash[Symbol, RBS::Types::Function::Param] rkw,
23
+ Array[RBS::Types::Function::Param] op,
24
+ Hash[Symbol, RBS::Types::Function::Param] okw
25
+ ) -> String
26
+
27
+ # @!begin
28
+ # if (comment = node.comment&.string)
29
+ # "#{comment.lines.map { |l| "# #{l}" }.join}#{output}"
30
+ # else
31
+ # output
32
+ # end
33
+ # @!end
34
+ def with_comment: (RBS::AST node, String output) -> String
35
+
36
+ # @!begin
37
+ # return nil unless node.comment
38
+ #
39
+ # lines = node.comment
40
+ # .string
41
+ # .lines
42
+ # comment = []
43
+ # lines.each do |l|
44
+ # break if l.start_with? "@!begin"
45
+ #
46
+ # comment << "# #{l}"
47
+ # end
48
+ #
49
+ # comment.join
50
+ # @!end
51
+ def get_comment: (RBS::AST node) -> String
52
+ end
53
+ end
@@ -0,0 +1,91 @@
1
+ module Lap
2
+ class Method
3
+ include Helpers
4
+
5
+ # @!begin
6
+ # @node = node
7
+ # @indent_level = indent_level
8
+ # @!end
9
+ def initialize: (RBS::AST::Members::MethodDefinition node, ?Integer indent_level) -> void
10
+
11
+ #@!begin
12
+ # comment = get_comment(@node)
13
+ # result = <<~METHOD
14
+ # #{comment}def #{"self." unless @node.kind == :instance}#{@node.name}#{arguments}
15
+ # #{body}
16
+ # end
17
+ # METHOD
18
+ # result.indent(Lap::Config[:indent] * @indent_level)
19
+ #@!end
20
+ def render: () -> String
21
+
22
+ private
23
+
24
+ # @!begin
25
+ # case t
26
+ # when RBS::Types::Literal
27
+ # t.inspect
28
+ # when ->(t) { t.class.to_s.start_with? "RBS::Types::Bases" }
29
+ # "# returns #{t}"
30
+ # else
31
+ # "# TODO: return #{t.name.name}"
32
+ # end
33
+ # @!end
34
+ def return_type: (RBS::Types type) -> String
35
+
36
+ # @!begin
37
+ # @arguments ||= begin
38
+ # type = @node.types.first.type
39
+ # rp = type.required_positionals
40
+ # rkw = type.required_keywords
41
+ # op = type.optional_positionals
42
+ # okw = type.optional_keywords
43
+ # args(rp, rkw, op, okw)
44
+ # end
45
+ # @!end
46
+ def arguments: () -> String
47
+
48
+ # @!begin
49
+ # @body ||= begin
50
+ # comment = @node.comment
51
+ # logic = ""
52
+ # if comment
53
+ # real_comment = []
54
+ # logic = []
55
+ # has_logic = false
56
+ # comment.string.lines.each do |line|
57
+ # if has_logic
58
+ # break if line.lstrip.start_with? "@!end"
59
+
60
+ # logic << line
61
+ # elsif line.lstrip.start_with? "@!begin"
62
+ # has_logic = true
63
+ # else
64
+ # real_comment << line
65
+ # end
66
+ # end
67
+ # logic = logic.join
68
+ # comment = real_comment.join
69
+ # end
70
+ # if logic.length.positive?
71
+ # logic
72
+ # else
73
+ # block = @node.types.first.block
74
+ # return_type = return_type(@node.types.first.type.return_type)
75
+ # yld = if block
76
+ # bt = block.type
77
+ # a = args(
78
+ # bt.required_positionals,
79
+ # bt.required_keywords,
80
+ # bt.optional_positionals,
81
+ # bt.optional_keywords
82
+ # )
83
+ # "yield#{a}\n"
84
+ # end
85
+ # "#{yld}#{return_type}"
86
+ # end
87
+ # end
88
+ # @!end
89
+ def body: () -> String
90
+ end
91
+ end
@@ -0,0 +1,46 @@
1
+ module Lap
2
+ class Module
3
+ include Helpers
4
+
5
+ # @!begin
6
+ # @node = node
7
+ # @indent_level = indent_level
8
+ # @has_contents = !@node.members.empty?
9
+ # @!end
10
+ def initialize: (RBS::AST::Declarations::Module node, ?Integer indent_level) -> void
11
+
12
+ # @!begin
13
+ # self_indent = " " * (Lap::Config[:indent] * @indent_level)
14
+ # comment = get_comment(@node)
15
+ # "#{comment}#{self_indent}module #{@node.name.name}#{contents}#{self_indent if @has_contents}end\n"
16
+ # @!end
17
+ def render: () -> String
18
+
19
+ private
20
+
21
+ # @!begin
22
+ # @contents ||= begin
23
+ # if @has_contents
24
+ # members = @node.members.map do |m|
25
+ # case m
26
+ # when RBS::AST::Members::MethodDefinition
27
+ # Lap::Method.new(m, @indent_level + 1).render
28
+ # when RBS::AST::Declarations::Class
29
+ # Lap::Class.new(m, @indent_level + 1).render
30
+ # when RBS::AST::Declarations::Module
31
+ # self.class.new(m, @indent_level + 1).render
32
+ # when RBS::AST::Declarations::Alias
33
+ # # no-op: not present in ruby
34
+ # else
35
+ # warn "Unsupported member for modules: #{m}"
36
+ # end
37
+ # end
38
+ # "\n#{members.join("\n")}"
39
+ # else
40
+ # "; "
41
+ # end
42
+ # end
43
+ # @!end
44
+ def contents: () -> String
45
+ end
46
+ end
@@ -0,0 +1,3 @@
1
+ module Lap
2
+ VERSION: "0.2"
3
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lap
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.1'
4
+ version: '0.2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joseph Johansen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-11-29 00:00:00.000000000 Z
11
+ date: 2020-11-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rbs
@@ -63,12 +63,20 @@ files:
63
63
  - lib/core_ext/string.rb
64
64
  - lib/lap.rb
65
65
  - lib/lap/class.rb
66
+ - lib/lap/constant.rb
66
67
  - lib/lap/helpers.rb
67
68
  - lib/lap/method.rb
68
69
  - lib/lap/module.rb
69
70
  - lib/lap/version.rb
70
71
  - sample/a.rbs
71
72
  - sample/bank.rbs
73
+ - sig/core_ext/string.rbs
74
+ - sig/lap.rbs
75
+ - sig/lap/class.rbs
76
+ - sig/lap/helpers.rbs
77
+ - sig/lap/method.rbs
78
+ - sig/lap/module.rbs
79
+ - sig/lap/version.rbs
72
80
  homepage: https://github.com/johansenja/lap
73
81
  licenses:
74
82
  - MIT