lap 0.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
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