ruby-qt6-rice 1.0.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 +7 -0
- data/.rspec +2 -0
- data/.rubocop.yml +15 -0
- data/LICENSE +185 -0
- data/README.md +3 -0
- data/Rakefile +12 -0
- data/include/bando/common.hpp +232 -0
- data/include/bando/qobject/qdbusabstractadaptor.hpp +102 -0
- data/include/bando/qobject/qdbusabstractinterface.hpp +89 -0
- data/include/bando/qobject/qitemdelegate.hpp +138 -0
- data/include/bando/qobject/qlayout.hpp +175 -0
- data/include/bando/qobject.hpp +89 -0
- data/include/bando/qwidget/qspinbox.hpp +207 -0
- data/include/bando/qwidget.hpp +187 -0
- data/include/rice/qt6/qdbusreply.hpp +53 -0
- data/include/rice/qt6/qenum.hpp +51 -0
- data/include/rice/qt6/qflags.hpp +58 -0
- data/include/rice/qt6/qlist.hpp +238 -0
- data/include/rice/rice.hpp +15154 -0
- data/include/rice/stl.hpp +4803 -0
- data/lib/mkmf-rice.rb +101 -0
- data/lib/mkmf-rubyqt6.rb +28 -0
- data/lib/qt6/rice/version.rb +7 -0
- data/lib/qt6/rice.rb +3 -0
- data/lib/qt6/rspec/bando_file_parser.rb +102 -0
- data/lib/qt6/rspec/qlass_file_parser.rb +255 -0
- data/lib/qt6/rspec.rb +275 -0
- metadata +68 -0
data/lib/qt6/rspec.rb
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "rspec/bando_file_parser"
|
|
4
|
+
require_relative "rspec/qlass_file_parser"
|
|
5
|
+
|
|
6
|
+
module RubyQt6
|
|
7
|
+
module RSpec
|
|
8
|
+
VERIFY_QLASS_VIRTUAL_METHODS = [
|
|
9
|
+
"event", "event_filter", # QObject
|
|
10
|
+
"meta_object", # QObject
|
|
11
|
+
"connect_notify", "disconnect_notify", # QObject
|
|
12
|
+
"paint_engine", # QPaintDevice
|
|
13
|
+
"metric", # QPaintDevice
|
|
14
|
+
"has_height_for_width", "height_for_width", # QWidget
|
|
15
|
+
"input_method_query", # QWidget
|
|
16
|
+
"minimum_size_hint", "size_hint", # QWidget
|
|
17
|
+
"init_painter" # QWidget
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
NO_VERIFY_QLASS_DOCS = [
|
|
21
|
+
"QMetaMethodBuilder",
|
|
22
|
+
"QMetaObjectBuilder"
|
|
23
|
+
]
|
|
24
|
+
NO_VERIFY_QLASS_INITIALIZE = QlassFileParser::NESTED_QLASSES + [
|
|
25
|
+
"QVariant"
|
|
26
|
+
]
|
|
27
|
+
NO_VERIFY_QLASS_VIRTUAL_METHODS = {
|
|
28
|
+
"QCoreApplication" => ["post_event", "send_event"],
|
|
29
|
+
"QLayoutItem" => ["size_hint"],
|
|
30
|
+
"QWidgetItem" => ["has_height_for_width", "height_for_width", "size_hint"],
|
|
31
|
+
"QWidget" => ["minimum_size_hint", "size_hint"]
|
|
32
|
+
}
|
|
33
|
+
NO_VERIFY_QLASS_LEADING_UNDERSCORE_METHODS = {
|
|
34
|
+
"QObject" => ["_connect", "_disconnect"],
|
|
35
|
+
"QApplication" => ["_all_widgets", "_top_level_widgets"]
|
|
36
|
+
}
|
|
37
|
+
NO_VERIFY_QLASS_OPERATOR_METHODS = {
|
|
38
|
+
"QTextStream" => ["<<"],
|
|
39
|
+
"QString" => ["[]", "[]="],
|
|
40
|
+
"QPoint" => ["*", "+", "-", "/", "+@", "-@"],
|
|
41
|
+
"QPointF" => ["*", "+", "-", "/", "+@", "-@"],
|
|
42
|
+
"QSize" => ["*", "+", "-", "/"],
|
|
43
|
+
"QSizeF" => ["*", "+", "-", "/"]
|
|
44
|
+
}
|
|
45
|
+
NO_VERIFY_QLASS_QOBJECT_INITIALIZE = [
|
|
46
|
+
"QCoreApplication",
|
|
47
|
+
"QGuiApplication",
|
|
48
|
+
"QApplication",
|
|
49
|
+
"QSettings",
|
|
50
|
+
"QAction",
|
|
51
|
+
"QDoubleValidator",
|
|
52
|
+
"QIntValidator",
|
|
53
|
+
"QRegularExpressionValidator",
|
|
54
|
+
"QGraphicsTextItem",
|
|
55
|
+
"QLabel",
|
|
56
|
+
"QRadioButton",
|
|
57
|
+
"QLineEdit",
|
|
58
|
+
"QTextEdit",
|
|
59
|
+
"QSystemTrayIcon"
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
ACRONYM = [
|
|
63
|
+
"UInt",
|
|
64
|
+
"ULongLong",
|
|
65
|
+
"ULong",
|
|
66
|
+
"UShort",
|
|
67
|
+
"LongLong",
|
|
68
|
+
"MSecs",
|
|
69
|
+
"QBitmap",
|
|
70
|
+
"QMetaObject",
|
|
71
|
+
"QObject"
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
def self.inflector_underscore(str)
|
|
75
|
+
str = str.dup
|
|
76
|
+
ACRONYM.each { |acronym| str.gsub!(acronym, "_" + acronym.downcase) }
|
|
77
|
+
str.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
|
78
|
+
str.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
|
79
|
+
str.downcase!
|
|
80
|
+
str
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def self.verify_bando_cppfile(cppfile, qmod)
|
|
84
|
+
parser = BandoFileParser.new(cppfile, qmod)
|
|
85
|
+
bandoes = parser.parse
|
|
86
|
+
|
|
87
|
+
rs = {}
|
|
88
|
+
bandoes.each do |bando|
|
|
89
|
+
r = Struct.new(:bando).new(bando)
|
|
90
|
+
rs[bando.name] = r
|
|
91
|
+
|
|
92
|
+
rbfile = "lib/qt6/bando/#{bando.name.downcase}.rb"
|
|
93
|
+
rbfile_contents = File.read(rbfile) if File.exist?(rbfile)
|
|
94
|
+
|
|
95
|
+
raise rbfile unless rbfile_contents.include?("class #{bando.name} < RubyQt6::#{qmod.name}::#{bando.name}")
|
|
96
|
+
raise rbfile unless rbfile_contents.match?(/Bando.define_bando_q\w+ Bando::#{bando.name}/)
|
|
97
|
+
end
|
|
98
|
+
rs
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def self.verify_qlass_cppfile(cppfile, qmod)
|
|
102
|
+
parser = QlassFileParser.new(cppfile, qmod)
|
|
103
|
+
qlasses = parser.parse
|
|
104
|
+
|
|
105
|
+
rs = {}
|
|
106
|
+
qlasses.each do |qlass|
|
|
107
|
+
r = Struct.new(:qlass, :verified_initialize, :verified_methods_count, :verified_enums_count, :verified_flags_count).new(qlass, 0, 0, 0, 0)
|
|
108
|
+
rs[qlass.name] = r
|
|
109
|
+
|
|
110
|
+
rbfile = "lib/qt6/#{qmod.name.downcase}/#{qlass.name.downcase}.rb"
|
|
111
|
+
rbfile_contents = File.read(rbfile) if File.exist?(rbfile)
|
|
112
|
+
|
|
113
|
+
verify_qlass_cppfile_qlass_docs(qlass, cppfile, rbfile, rbfile_contents, r)
|
|
114
|
+
verify_qlass_cppfile_qlass_initialize(qlass, cppfile, rbfile, rbfile_contents, r)
|
|
115
|
+
verify_qlass_cppfile_qlass_methods(qlass, cppfile, rbfile, rbfile_contents, r)
|
|
116
|
+
verify_qlass_cppfile_qlass_enums(qlass, cppfile, rbfile, rbfile_contents, r)
|
|
117
|
+
verify_qlass_cppfile_qlass_flags(qlass, cppfile, rbfile, rbfile_contents, r)
|
|
118
|
+
|
|
119
|
+
qobject = true if rbfile_contents&.include?("q_object")
|
|
120
|
+
verify_qlass_cppfile_qlass_qobject_initialize(qlass, cppfile, rbfile, rbfile_contents, r) if qobject
|
|
121
|
+
verify_qlass_cppfile_qlass_qobject_methods(qlass, cppfile, rbfile, rbfile_contents, r) if qobject
|
|
122
|
+
end
|
|
123
|
+
rs
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def self.verify_qlass_cppfile_qlass_docs(qlass, cppfile, rbfile, rbfile_contents, r)
|
|
127
|
+
return if NO_VERIFY_QLASS_DOCS.include?(qlass.name)
|
|
128
|
+
|
|
129
|
+
return if rbfile_contents.nil?
|
|
130
|
+
return if rbfile_contents.include?("# @see https://doc.qt.io/qt-6/#{qlass.name.downcase}.html")
|
|
131
|
+
raise "#{rbfile}: docs: Missing `# @see https://doc.qt.io/qt-6/...`"
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def self.verify_qlass_cppfile_qlass_initialize(qlass, cppfile, rbfile, rbfile_contents, r)
|
|
135
|
+
return if NO_VERIFY_QLASS_INITIALIZE.include?(qlass.name)
|
|
136
|
+
|
|
137
|
+
constructor_methods = qlass.methods.select { |method| method.type == :constructor }
|
|
138
|
+
copy_constructor_method = constructor_methods.find { |method| method.rawline.include?('Arg("other")') }
|
|
139
|
+
|
|
140
|
+
constructor_methods.each do |method|
|
|
141
|
+
rawline = method.rawline
|
|
142
|
+
raise "#{cppfile}: Found default value in constructor method" if rawline.include?("nullptr")
|
|
143
|
+
raise "#{cppfile}: Found default value in constructor method" if rawline.include?("static_cast")
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
constructor_methods_count = constructor_methods.count
|
|
147
|
+
constructor_methods_count -= 1 if copy_constructor_method
|
|
148
|
+
case constructor_methods_count
|
|
149
|
+
when 2..99
|
|
150
|
+
raise "#{rbfile}: initialize: Missing `# @overload initialize...`" unless rbfile_contents.scan("# @overload initialize").count == constructor_methods_count
|
|
151
|
+
raise "#{rbfile}: initialize: Missing `alias_method :_initialize, :initialize`" unless rbfile_contents.include?("alias_method :_initialize, :initialize")
|
|
152
|
+
raise "#{rbfile}: initialize: Missing `def initialize(*args)`" unless rbfile_contents.include?("def initialize(*args)")
|
|
153
|
+
raise "#{rbfile}: initialize: Missing `_initialize(*args)`" unless rbfile_contents.include?("_initialize(*args)")
|
|
154
|
+
r.verified_initialize = 2
|
|
155
|
+
when 1
|
|
156
|
+
raise "#{rbfile}: initialize: Missing `alias_method :_initialize, :initialize`" unless rbfile_contents.include?("alias_method :_initialize, :initialize")
|
|
157
|
+
raise "#{rbfile}: initialize: Missing `def initialize...`" unless rbfile_contents.include?("def initialize")
|
|
158
|
+
raise "#{rbfile}: initialize: Missing `_initialize...`" unless rbfile_contents.include?("_initialize")
|
|
159
|
+
r.verified_initialize = 1
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def self.verify_qlass_cppfile_qlass_methods(qlass, cppfile, rbfile, rbfile_contents, r)
|
|
164
|
+
qlass.methods.each do |method|
|
|
165
|
+
# Expected 'Arg("name")', but got 'Arg("")'
|
|
166
|
+
if method.rawline.include?('Arg("")')
|
|
167
|
+
raise method.inspect
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Expected 'to_qvariant', but got 'to_q_variant'
|
|
171
|
+
if method.rbname.include?("q_")
|
|
172
|
+
raise method.inspect
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# Expected 'valid?', but got 'is_valid'
|
|
176
|
+
# Expected 'user_type', but got 'userType'
|
|
177
|
+
if method.cppname
|
|
178
|
+
expected =
|
|
179
|
+
case method.cppname
|
|
180
|
+
when /^is[A-Z]/ then "#{inflector_underscore(method.cppname)}?".sub(/^is_/, "")
|
|
181
|
+
else inflector_underscore(method.cppname)
|
|
182
|
+
end
|
|
183
|
+
if expected != method.rbname.sub(/^_/, "")
|
|
184
|
+
raise method.inspect
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# No virtual method
|
|
189
|
+
lambda do
|
|
190
|
+
return if NO_VERIFY_QLASS_VIRTUAL_METHODS[qlass.name]&.include?(method.rbname)
|
|
191
|
+
raise method.inspect if method.rbname.end_with?("_event")
|
|
192
|
+
raise method.inspect if VERIFY_QLASS_VIRTUAL_METHODS.include?(method.rbname)
|
|
193
|
+
end.call
|
|
194
|
+
|
|
195
|
+
# No unknonwn leading underscore method
|
|
196
|
+
if method.rbname.start_with?("_")
|
|
197
|
+
lambda do
|
|
198
|
+
return if method.type == :rubyqt6_defined_functions
|
|
199
|
+
return if rbfile_contents.match?(/def (self.)?#{method.rbname.sub(/^_/, "")}/)
|
|
200
|
+
return if NO_VERIFY_QLASS_LEADING_UNDERSCORE_METHODS[qlass.name]&.include?(method.rbname)
|
|
201
|
+
raise method.inspect
|
|
202
|
+
end.call
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# No unknonwn operator method
|
|
206
|
+
unless method.rbname.start_with?(/_?[a-z]/)
|
|
207
|
+
lambda do
|
|
208
|
+
return if NO_VERIFY_QLASS_OPERATOR_METHODS[qlass.name]&.include?(method.rbname)
|
|
209
|
+
raise method.inspect
|
|
210
|
+
end.call
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
r.verified_methods_count ||= 0
|
|
214
|
+
r.verified_methods_count += 1
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def self.verify_qlass_cppfile_qlass_enums(qlass, cppfile, rbfile, rbfile_contents, r)
|
|
219
|
+
qlass.enums.each do |enum|
|
|
220
|
+
raise "#{rbfile}: #{enum.name}: Missing `# @!parse class ...`" unless rbfile_contents.include?("# @!parse class #{enum.name}")
|
|
221
|
+
raise "#{rbfile}: #{enum.name}: Missing `rubyqt6_declare_enum_under ...`" unless rbfile_contents.include?("rubyqt6_declare_enum_under #{qlass.name}, #{qlass.name}::#{enum.name}")
|
|
222
|
+
r.verified_enums_count ||= 0
|
|
223
|
+
r.verified_enums_count += 1
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def self.verify_qlass_cppfile_qlass_flags(qlass, cppfile, rbfile, rbfile_contents, r)
|
|
228
|
+
qlass.flags.each do |flag|
|
|
229
|
+
raise "#{rbfile}: #{flag.name}: Missing `# @!parse class ...`" unless rbfile_contents.include?("# @!parse class #{flag.name}")
|
|
230
|
+
raise "#{rbfile}: #{flag.name}: Missing `rubyqt6_declare_qflags ...`" unless rbfile_contents.include?("rubyqt6_declare_qflags #{qlass.name}::#{flag.name}, #{qlass.name}::#{flag.enum_name}")
|
|
231
|
+
r.verified_flags_count ||= 0
|
|
232
|
+
r.verified_flags_count += 1
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def self.verify_qlass_cppfile_qlass_qobject_initialize(qlass, cppfile, rbfile, rbfile_contents, r)
|
|
237
|
+
constructor_methods = qlass.methods.select { |method| method.type == :constructor }
|
|
238
|
+
return if constructor_methods.size == 0
|
|
239
|
+
raise "#{cppfile}: Too many constructor methods" if constructor_methods.size > 1
|
|
240
|
+
|
|
241
|
+
unless NO_VERIFY_QLASS_QOBJECT_INITIALIZE.include?(qlass.name)
|
|
242
|
+
rawline = constructor_methods[0].rawline
|
|
243
|
+
rawargs = rawline.scan(/Arg\("(\w+)"\)/).map { |arg| arg[0] }
|
|
244
|
+
rawargs.each do |arg|
|
|
245
|
+
line = "@param #{arg} ["
|
|
246
|
+
raise "#{rbfile}: initialize: Missing `#{line}`" unless rbfile_contents.include?(line)
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
line = "@return [#{qlass.name}]"
|
|
250
|
+
raise "#{rbfile}: initialize: Missing `#{line}`" unless rbfile_contents.include?(line)
|
|
251
|
+
|
|
252
|
+
args = rawargs.map { |arg| "#{arg}( = .*)?" }
|
|
253
|
+
line = args.size.zero? ? /def initialize/ : /def initialize\(#{args.join(", ")}\)/
|
|
254
|
+
raise "#{rbfile}: initialize: Mismatch `#{line}`" unless rbfile_contents.match?(line)
|
|
255
|
+
|
|
256
|
+
args = rawargs.map { |arg| ".*#{arg}.*" }
|
|
257
|
+
line = args.size.zero? ? /_initialize/ : /_initialize\(#{args.join(", ")}\)/
|
|
258
|
+
raise "#{rbfile}: initialize: Mismatch `#{line}`" unless rbfile_contents.match?(line)
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def self.verify_qlass_cppfile_qlass_qobject_methods(qlass, cppfile, rbfile, rbfile_contents, r)
|
|
263
|
+
metamethods = [].tap do |methods|
|
|
264
|
+
signal_methods = qlass.methods.select { |method| method.type == :signals }
|
|
265
|
+
signal_methods.each { |method| methods << method.cppname }
|
|
266
|
+
slot_methods = qlass.methods.select { |method| method.type == :public_slots }
|
|
267
|
+
slot_methods.each { |method| methods << method.cppname }
|
|
268
|
+
end.uniq
|
|
269
|
+
|
|
270
|
+
rbfile_metamethods = rbfile_contents.scan(/(signal|slot) "(.*)"/).map { |method| method[1] }
|
|
271
|
+
rbfile_metamethods = rbfile_metamethods.map { |method| method.split("(")[0] }.uniq
|
|
272
|
+
raise "#{rbfile}: q_object: Mismatch `#{rbfile_metamethods}` != `#{metamethods}`" if rbfile_metamethods != metamethods
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ruby-qt6-rice
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- John Doe
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
12
|
+
description: Extend the Rice library with support for the Qt framework.
|
|
13
|
+
email:
|
|
14
|
+
- johndoe@example.com
|
|
15
|
+
executables: []
|
|
16
|
+
extensions: []
|
|
17
|
+
extra_rdoc_files: []
|
|
18
|
+
files:
|
|
19
|
+
- ".rspec"
|
|
20
|
+
- ".rubocop.yml"
|
|
21
|
+
- LICENSE
|
|
22
|
+
- README.md
|
|
23
|
+
- Rakefile
|
|
24
|
+
- include/bando/common.hpp
|
|
25
|
+
- include/bando/qobject.hpp
|
|
26
|
+
- include/bando/qobject/qdbusabstractadaptor.hpp
|
|
27
|
+
- include/bando/qobject/qdbusabstractinterface.hpp
|
|
28
|
+
- include/bando/qobject/qitemdelegate.hpp
|
|
29
|
+
- include/bando/qobject/qlayout.hpp
|
|
30
|
+
- include/bando/qwidget.hpp
|
|
31
|
+
- include/bando/qwidget/qspinbox.hpp
|
|
32
|
+
- include/rice/qt6/qdbusreply.hpp
|
|
33
|
+
- include/rice/qt6/qenum.hpp
|
|
34
|
+
- include/rice/qt6/qflags.hpp
|
|
35
|
+
- include/rice/qt6/qlist.hpp
|
|
36
|
+
- include/rice/rice.hpp
|
|
37
|
+
- include/rice/stl.hpp
|
|
38
|
+
- lib/mkmf-rice.rb
|
|
39
|
+
- lib/mkmf-rubyqt6.rb
|
|
40
|
+
- lib/qt6/rice.rb
|
|
41
|
+
- lib/qt6/rice/version.rb
|
|
42
|
+
- lib/qt6/rspec.rb
|
|
43
|
+
- lib/qt6/rspec/bando_file_parser.rb
|
|
44
|
+
- lib/qt6/rspec/qlass_file_parser.rb
|
|
45
|
+
homepage: https://github.com/souk4711/ruby-qt6/rice
|
|
46
|
+
licenses: []
|
|
47
|
+
metadata:
|
|
48
|
+
homepage_uri: https://github.com/souk4711/ruby-qt6/rice
|
|
49
|
+
source_code_uri: https://github.com/souk4711/ruby-qt6/rice
|
|
50
|
+
changelog_uri: https://github.com/souk4711/ruby-qt6/rice
|
|
51
|
+
rdoc_options: []
|
|
52
|
+
require_paths:
|
|
53
|
+
- lib
|
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
55
|
+
requirements:
|
|
56
|
+
- - ">="
|
|
57
|
+
- !ruby/object:Gem::Version
|
|
58
|
+
version: 3.1.0
|
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
|
+
requirements:
|
|
61
|
+
- - ">="
|
|
62
|
+
- !ruby/object:Gem::Version
|
|
63
|
+
version: '0'
|
|
64
|
+
requirements: []
|
|
65
|
+
rubygems_version: 3.6.9
|
|
66
|
+
specification_version: 4
|
|
67
|
+
summary: Extend the Rice library with support for the Qt framework.
|
|
68
|
+
test_files: []
|