rbs2ts 1.0.0.pre.alpha.4 → 1.3.1

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: 19a2022b86feae5d562c59457ea77de37ef3a94f6c32b2b148f278610cf3e64d
4
- data.tar.gz: 94639b023729996b58f6a7ed7f59cbfe58b7738e820ea70fb100ad9e7f079690
3
+ metadata.gz: bce4c75f9675cfc5cccfac710ac9547d5c33153e76e5ef1299bc1f1808612f05
4
+ data.tar.gz: c550da676c3b095c07438e7085f176f8fa150d061ba10803ea9bb0805917067d
5
5
  SHA512:
6
- metadata.gz: 918d61866526af2f4d258fe349c5617dfc65d799086fff57fb32bfa2e6104713fed20558dd2e451ba09c860316aedb07f6637a5cdd650babfa477a61ca490f78
7
- data.tar.gz: 5fd2d4d0c042f9a226f89dd8867d48464ccae74333afb5f77e437eb793f5db85ae2882c49ac600f2abd8caf7f8e948d9cefa23b28ce30b4b8cb54dc8d663321d
6
+ metadata.gz: 34aa7a35786539f22d03e58e25902fdc4a074bd76bc1b54d05dc2a52b9bb1864e27f4a2a1eea916fb6e06e62a1371b9490b40e117f119dd70bb31b250c010769
7
+ data.tar.gz: 76ba38c3514225a63ecd288d17891281c5b1b90a1edea1e8a655b3d91357a62eb6b8c02fa100c93e4505d5819ac8526dfd0d2fc87e9f9eec7dae65633eb15518
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Rbs2ts
2
2
 
3
- Convert RBS to TypeScript type definition.
3
+ A RubyGem that converts Ruby RBS to TypeScript definitions.
4
4
 
5
5
  ## Installation
6
6
 
@@ -33,8 +33,8 @@ type StringLiteral = 'abc'
33
33
  type TrueLiteral = true
34
34
  type FalseLiteral = false
35
35
 
36
- type UnionType = String & Integer & Bool
37
- type IntersectionType = String | Integer | Bool
36
+ type IntersectionType = String & Integer & Bool
37
+ type UnionType = String | Integer | Bool
38
38
 
39
39
  type ArrayType = Array[String]
40
40
 
@@ -52,6 +52,7 @@ type RecordType = {
52
52
  }
53
53
 
54
54
  class Klass
55
+ @val: String
55
56
  attr_accessor a: String
56
57
  attr_reader b: Integer
57
58
  attr_writer c: Bool
@@ -64,8 +65,44 @@ class Klass
64
65
  }?
65
66
  }
66
67
 
67
- def to_s: () -> String
68
- def tuple: () -> [{ s: String, f: Float }?]
68
+ def to_tuple: () -> [{ s: String, f: Float }?]
69
+ def required_positional: (String) -> void
70
+ def required_positional_name: (String str) -> void
71
+ def optional_positional: (?String) -> void
72
+ def optional_positional_name: (?String? str) -> void
73
+ def rest_positional: (*String) -> void
74
+ def rest_positional_name: (*String str) -> void
75
+ def rest_positional_with_trailing: (*String, Integer) -> void
76
+ def rest_positional_name_with_trailing: (*String str, Integer trailing) -> void
77
+ def required_keyword: (str: String) -> void
78
+ def optional_keyword: (?str: String?) -> void
79
+ def rest_keywords: (**String) -> void
80
+ def rest_keywords_name: (**String rest) -> void
81
+
82
+ def all_arguments: (
83
+ String required_positional,
84
+ ?Integer? optional_positional,
85
+ *String rest_positionals_s,
86
+ Integer trailing_positional_s,
87
+ required_keyword: String,
88
+ ?optional_keyword: Integer?,
89
+ **String rest_keywords
90
+ ) -> [{ s: String, f: Float }?]
91
+ end
92
+
93
+ module Module
94
+ @val: String
95
+ type AliasType = String
96
+
97
+ def func: (String, Integer) -> { str: String, int: Integer }
98
+
99
+ class NestedClass
100
+ attr_accessor a: AliasType
101
+ end
102
+ end
103
+
104
+ interface _Interface
105
+ def func: (String, Integer) -> { str: String, int: Integer }
69
106
  end
70
107
  ```
71
108
 
@@ -96,9 +133,9 @@ export type TrueLiteral = true;
96
133
 
97
134
  export type FalseLiteral = false;
98
135
 
99
- export type UnionType = string & number & boolean;
136
+ export type IntersectionType = string & number & boolean;
100
137
 
101
- export type IntersectionType = string | number | boolean;
138
+ export type UnionType = string | number | boolean;
102
139
 
103
140
  export type ArrayType = string[];
104
141
 
@@ -116,34 +153,56 @@ export type RecordType = {
116
153
  } | null | undefined;
117
154
  };
118
155
 
119
- export namespace Klass {
120
- export type a = string;
121
- export type b = number;
122
- export type r = {
156
+ export declare class Klass {
157
+ val: string;
158
+ a: string;
159
+ readonly b: number;
160
+ c: boolean;
161
+ readonly r: {
123
162
  d: string;
124
163
  e: {
125
164
  f: string;
126
165
  g: string | null | undefined;
127
166
  } | null | undefined;
128
167
  };
129
- export type toSReturnType = string;
130
- export type tupleReturnType = [({
168
+ toTuple(): [({
169
+ s: string;
170
+ f: number;
171
+ } | null | undefined)];
172
+ requiredPositional(arg1: string): void;
173
+ requiredPositionalName(str: string): void;
174
+ optionalPositional(arg1?: string): void;
175
+ optionalPositionalName(str?: string | null | undefined): void;
176
+ restPositional(...arg1: string[]): void;
177
+ restPositionalName(...str: string[]): void;
178
+ restPositionalWithTrailing(arg1: string[], arg2: number): void;
179
+ restPositionalNameWithTrailing(str: string[], trailing: number): void;
180
+ requiredKeyword(arg1: { str: string }): void;
181
+ optionalKeyword(arg1: { str?: string | null | undefined }): void;
182
+ restKeywords(arg1: { [key: string]: unknown; }): void;
183
+ restKeywordsName(arg1: { [key: string]: unknown; }): void;
184
+ allArguments(requiredPositional: string, optionalPositional?: number | null | undefined, restPositionalsS?: string[], trailingPositionalS?: number, arg1?: { requiredKeyword: string, optionalKeyword?: number | null | undefined, [key: string]: unknown; }): [({
131
185
  s: string;
132
186
  f: number;
133
187
  } | null | undefined)];
134
188
  };
135
- ```
136
-
137
- ---
138
189
 
139
- ## ToDo
190
+ export namespace Module {
191
+ export declare let val: string;
192
+ export type AliasType = string;
193
+ export declare function func(arg1: string, arg2: number): {
194
+ str: string;
195
+ int: number;
196
+ };
197
+ export declare class NestedClass {
198
+ a: AliasType;
199
+ };
200
+ };
140
201
 
141
- - [x] Literal type
142
- - [ ] Interface type
143
- - [x] Literal type
144
- - [x] Tuple Type
145
- - [x] Base Types
146
- - [x] Method Type (Argument Types and Return Types)
147
- - [x] Class declaration
148
- - [ ] Module declaration
149
- - [ ] Interface declaration
202
+ export interface Interface {
203
+ func(arg1: string, arg2: number): {
204
+ str: string;
205
+ int: number;
206
+ };
207
+ };
208
+ ```
@@ -3,5 +3,7 @@ end
3
3
 
4
4
  require 'case_transform'
5
5
 
6
+ require 'rbs2ts/converter/helper'
6
7
  require 'rbs2ts/converter/declarations'
7
8
  require 'rbs2ts/converter/types'
9
+ require 'rbs2ts/converter/members'
@@ -11,6 +11,10 @@ module Rbs2ts
11
11
  case d
12
12
  when ::RBS::AST::Declarations::Class then
13
13
  Converter::Declarations::Class.new(d).to_ts
14
+ when ::RBS::AST::Declarations::Module then
15
+ Converter::Declarations::Module.new(d).to_ts
16
+ when ::RBS::AST::Declarations::Interface then
17
+ Converter::Declarations::Interface.new(d).to_ts
14
18
  when ::RBS::AST::Declarations::Alias then
15
19
  Converter::Declarations::Alias.new(d).to_ts
16
20
  end
@@ -31,34 +35,23 @@ module Rbs2ts
31
35
  end
32
36
 
33
37
  def name
34
- declaration.name.to_s.gsub(/:/, '')
38
+ declaration.name.name.to_s
35
39
  end
36
40
 
37
41
  private
38
42
 
39
43
  attr_reader :declaration
40
44
  end
41
-
42
- class Class < Base
43
- INDENT = ' '
44
- @@nest = 0
45
45
 
46
+ class Class < Base
46
47
  def to_ts
47
- @@nest = @@nest + 1
48
-
49
48
  members_ts = declaration.members.map {|member|
50
- ts = member_to_ts(member)
51
- ts
52
- .split("\n")
53
- .map {|t| "#{INDENT * @@nest}#{t}" }
54
- .join("\n")
49
+ member_to_ts(member)
55
50
  }.reject(&:empty?).join("\n")
56
51
 
57
- @@nest = @@nest - 1
58
-
59
52
  <<~TS
60
- export namespace #{name} {
61
- #{members_ts}
53
+ export declare class #{Converter::Helper.convert_name(name)} {
54
+ #{Helper.indent(members_ts)}
62
55
  };
63
56
  TS
64
57
  .chomp
@@ -66,10 +59,16 @@ module Rbs2ts
66
59
 
67
60
  def member_to_ts(member)
68
61
  case member
69
- when ::RBS::AST::Members::AttrReader, ::RBS::AST::Members::AttrAccessor then
70
- "export type #{CaseTransform.camel_lower(member.name)} = #{Converter::Types::Resolver.to_ts(member.type)};"
62
+ when ::RBS::AST::Members::InstanceVariable then
63
+ Converter::Members::InstanceVariable.new(member).to_ts
64
+ when ::RBS::AST::Members::AttrReader then
65
+ Converter::Members::AttrReader.new(member).to_ts
66
+ when ::RBS::AST::Members::AttrWriter then
67
+ Converter::Members::AttrWriter.new(member).to_ts
68
+ when ::RBS::AST::Members::AttrAccessor then
69
+ Converter::Members::AttrAccessor.new(member).to_ts
71
70
  when ::RBS::AST::Members::MethodDefinition
72
- "export type #{CaseTransform.camel_lower(member.name)}ReturnType = #{Converter::Types::Resolver.to_ts(member.types.first.type.return_type)};"
71
+ Converter::Members::MethodDefinition.new(member).to_ts
73
72
  else
74
73
  ''
75
74
  end
@@ -77,14 +76,68 @@ module Rbs2ts
77
76
  end
78
77
 
79
78
  class Module < Base
79
+ def to_ts
80
+ members_ts = declaration.members.map {|member|
81
+ member_to_ts(member)
82
+ }.reject(&:empty?).join("\n")
83
+
84
+ <<~TS
85
+ export namespace #{Converter::Helper.convert_name(name)} {
86
+ #{Helper.indent(members_ts)}
87
+ };
88
+ TS
89
+ .chomp
90
+ end
91
+
92
+ def member_to_ts(member)
93
+ case member
94
+ when ::RBS::AST::Declarations::Class then
95
+ Converter::Declarations::Class.new(member).to_ts
96
+ when ::RBS::AST::Declarations::Module then
97
+ Converter::Declarations::Module.new(member).to_ts
98
+ when ::RBS::AST::Declarations::Interface then
99
+ Converter::Declarations::Interface.new(member).to_ts
100
+ when ::RBS::AST::Declarations::Alias then
101
+ Converter::Declarations::Alias.new(member).to_ts
102
+ when ::RBS::AST::Members::InstanceVariable
103
+ ts = Converter::Members::InstanceVariable.new(member).to_ts
104
+ "export declare let #{ts}"
105
+ when ::RBS::AST::Members::MethodDefinition
106
+ ts = Converter::Members::MethodDefinition.new(member).to_ts
107
+ "export declare function #{ts}"
108
+ else
109
+ ''
110
+ end
111
+ end
80
112
  end
81
113
 
82
114
  class Interface < Base
115
+ def to_ts
116
+ members_ts = declaration.members.map {|member|
117
+ member_to_ts(member)
118
+ }.reject(&:empty?).join("\n")
119
+
120
+ <<~TS
121
+ export interface #{Converter::Helper.convert_name(name.gsub(/_/, ''))} {
122
+ #{Helper.indent(members_ts)}
123
+ };
124
+ TS
125
+ .chomp
126
+ end
127
+
128
+ def member_to_ts(member)
129
+ case member
130
+ when ::RBS::AST::Members::MethodDefinition
131
+ Converter::Members::MethodDefinition.new(member).to_ts
132
+ else
133
+ ''
134
+ end
135
+ end
83
136
  end
84
137
 
85
138
  class Alias < Base
86
139
  def to_ts
87
- "export type #{name} = #{Converter::Types::Resolver.to_ts(declaration.type)};"
140
+ "export type #{Converter::Helper.convert_name(name)} = #{Converter::Types::Resolver.to_ts(declaration.type)};"
88
141
  end
89
142
  end
90
143
 
@@ -0,0 +1,38 @@
1
+ module Rbs2ts
2
+ module Converter
3
+ module Helper
4
+ class << self
5
+ INDENT = ' '
6
+
7
+ def indent(text, level = 1)
8
+ text
9
+ .split("\n")
10
+ .map {|t| "#{INDENT * level}#{t}" }
11
+ .join("\n")
12
+ end
13
+
14
+ TS_RESERVED_WORDS = %w(
15
+ any as boolean break case catch class const constructor continue debugger declare
16
+ default delete do else enum export extends false finally for from function get if
17
+ implements import in instanceof interface let module new null number of package
18
+ private protected public require return set static string super switch symbol
19
+ this throw true try type typeof var void while with yield
20
+ )
21
+
22
+ def convert_name(org_name)
23
+ name = org_name.to_s.gsub(/[:@]/, '')
24
+
25
+ unless name =~ /^[A-Z]/
26
+ name = CaseTransform.camel_lower(name)
27
+ end
28
+
29
+ if TS_RESERVED_WORDS.include?(name)
30
+ "#{name}Type"
31
+ else
32
+ name
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,146 @@
1
+ module Rbs2ts
2
+ module Converter
3
+ module Members
4
+ class Base
5
+ def initialize(member)
6
+ @member = member
7
+ end
8
+
9
+ def to_ts
10
+ ''
11
+ end
12
+
13
+ def name
14
+ Converter::Helper.convert_name(member.name)
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :member
20
+ end
21
+
22
+ class InstanceVariable < Base
23
+ def to_ts
24
+ "#{name}: #{Converter::Types::Resolver.to_ts(member.type)};"
25
+ end
26
+ end
27
+
28
+ class AttrReader < Base
29
+ def to_ts
30
+ "readonly #{name}: #{Converter::Types::Resolver.to_ts(member.type)};"
31
+ end
32
+ end
33
+
34
+ class AttrWriter < Base
35
+ def to_ts
36
+ "#{name}: #{Converter::Types::Resolver.to_ts(member.type)};"
37
+ end
38
+ end
39
+
40
+ class AttrAccessor < Base
41
+ def to_ts
42
+ "#{name}: #{Converter::Types::Resolver.to_ts(member.type)};"
43
+ end
44
+ end
45
+
46
+ class MethodDefinition < Base
47
+ def initialize(member)
48
+ super
49
+ @args_count = 0
50
+ end
51
+
52
+ def to_ts
53
+ "#{name}(#{args_to_ts}): #{return_type_to_ts};"
54
+ end
55
+
56
+ def args_to_ts
57
+ [
58
+ *required_positional_to_ts,
59
+ *optional_positional_to_ts,
60
+ *rest_positionals_to_ts,
61
+ *trailing_positionals_to_ts,
62
+ *keyword_args_to_ts
63
+ ].join(", ")
64
+ end
65
+
66
+ def arg_name(arg)
67
+ name = arg.name.nil? ? next_default_arg_name : arg.name.to_s
68
+ CaseTransform.camel_lower(name)
69
+ end
70
+
71
+ def next_default_arg_name
72
+ @args_count = @args_count + 1
73
+ "arg#{@args_count.to_s}"
74
+ end
75
+
76
+ def required_positional_to_ts
77
+ method_type.required_positionals.map {|arg|
78
+ "#{arg_name(arg)}: #{Converter::Types::Resolver.to_ts(arg.type)}"
79
+ }
80
+ end
81
+
82
+ def optional_positional_to_ts
83
+ method_type.optional_positionals.map {|arg|
84
+ "#{arg_name(arg)}?: #{Converter::Types::Resolver.to_ts(arg.type)}"
85
+ }
86
+ end
87
+
88
+ def rest_positionals_to_ts
89
+ arg = method_type.rest_positionals
90
+
91
+ return [] if arg.nil?
92
+
93
+ has_rest_after_arguments ?
94
+ ["#{arg_name(arg)}#{optional_ts_code}: #{Converter::Types::Resolver.to_ts(arg.type)}[]"] :
95
+ ["...#{arg_name(arg)}#{optional_ts_code}: #{Converter::Types::Resolver.to_ts(arg.type)}[]"]
96
+ end
97
+
98
+ def trailing_positionals_to_ts
99
+ method_type.trailing_positionals.map {|arg|
100
+ "#{arg_name(arg)}#{optional_ts_code}: #{Converter::Types::Resolver.to_ts(arg.type)}"
101
+ }
102
+ end
103
+
104
+ def keyword_args_to_ts
105
+ required_keywords_ts = method_type.required_keywords.map {|key, value|
106
+ "#{CaseTransform.camel_lower(key.to_s)}: #{Converter::Types::Resolver.to_ts(value.type)}"
107
+ }
108
+ optional_keywords_ts = method_type.optional_keywords.map {|key, value|
109
+ "#{CaseTransform.camel_lower(key.to_s)}?: #{Converter::Types::Resolver.to_ts(value.type)}"
110
+ }
111
+ rest_keywords_ts = method_type.rest_keywords.nil? ? [] : ["[key: string]: unknown;"]
112
+
113
+ ts_array = [
114
+ *required_keywords_ts,
115
+ *optional_keywords_ts,
116
+ *rest_keywords_ts
117
+ ]
118
+
119
+ return [] if ts_array.empty?
120
+
121
+ ts = ts_array.join(', ')
122
+
123
+ ["#{next_default_arg_name}#{optional_ts_code}: { #{ts} }"]
124
+ end
125
+
126
+ def method_type
127
+ member.types.first.type
128
+ end
129
+
130
+ def return_type_to_ts
131
+ Converter::Types::Resolver.to_ts(method_type.return_type)
132
+ end
133
+
134
+ def optional_ts_code
135
+ method_type.optional_positionals.present? ? '?' : ''
136
+ end
137
+
138
+ def has_rest_after_arguments
139
+ method_type.trailing_positionals.present? ||
140
+ method_type.required_keywords.present? ||
141
+ method_type.optional_keywords.present?
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
@@ -46,27 +46,19 @@ module Rbs2ts
46
46
  end
47
47
 
48
48
  class Record < ConverterBase
49
- INDENT = ' '
50
- @@nest = 0
51
-
52
49
  def to_ts
53
- @@nest = @@nest + 1
54
-
55
- indent = INDENT * @@nest
56
50
  field_lines = type.fields.map { |name, type|
57
- "#{indent}#{CaseTransform.camel_lower(name.to_s)}: #{Types::Resolver.to_ts(type)};"
51
+ "#{Converter::Helper.convert_name(name)}: #{Types::Resolver.to_ts(type)};"
58
52
  }
59
53
 
60
- @@nest = @@nest - 1
61
-
62
54
  return '{}' if field_lines.empty?
63
55
 
64
56
  field_ts = field_lines.join("\n")
65
57
 
66
58
  ts = <<~CODE
67
59
  {
68
- #{field_ts}
69
- #{INDENT * @@nest}}
60
+ #{Helper.indent(field_ts)}
61
+ }
70
62
  CODE
71
63
 
72
64
  ts.chomp
@@ -144,7 +136,7 @@ module Rbs2ts
144
136
  when 'Bool' then
145
137
  Types::Bool.new(type).to_ts
146
138
  else
147
- type.name.to_s.gsub(/:/, '')
139
+ Converter::Helper.convert_name(type.name.name)
148
140
  end
149
141
  end
150
142
  end
@@ -1,3 +1,3 @@
1
1
  module Rbs2ts
2
- VERSION = "1.0.0-alpha.4"
2
+ VERSION = "1.3.1"
3
3
  end
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ["mugi-uno"]
10
10
  spec.email = ["mugi.uno@gmail.com"]
11
11
 
12
- spec.summary = "Convert rbs to typescript"
12
+ spec.summary = "A RubyGem that converts Ruby RBS to TypeScript definitions."
13
13
  spec.homepage = "https://github.com/mugi-uno/rbs2ts"
14
14
  spec.license = "MIT"
15
15
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbs2ts
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre.alpha.4
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - mugi-uno
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-17 00:00:00.000000000 Z
11
+ date: 2021-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rbs
@@ -118,6 +118,8 @@ files:
118
118
  - lib/rbs2ts/cli.rb
119
119
  - lib/rbs2ts/converter.rb
120
120
  - lib/rbs2ts/converter/declarations.rb
121
+ - lib/rbs2ts/converter/helper.rb
122
+ - lib/rbs2ts/converter/members.rb
121
123
  - lib/rbs2ts/converter/types.rb
122
124
  - lib/rbs2ts/version.rb
123
125
  - rbs2ts.gemspec
@@ -136,12 +138,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
136
138
  version: '0'
137
139
  required_rubygems_version: !ruby/object:Gem::Requirement
138
140
  requirements:
139
- - - ">"
141
+ - - ">="
140
142
  - !ruby/object:Gem::Version
141
- version: 1.3.1
143
+ version: '0'
142
144
  requirements: []
143
145
  rubygems_version: 3.1.4
144
146
  signing_key:
145
147
  specification_version: 4
146
- summary: Convert rbs to typescript
148
+ summary: A RubyGem that converts Ruby RBS to TypeScript definitions.
147
149
  test_files: []