Skip to content

Commit afb3f0e

Browse files
committed
Skip namespace forward-declared classes
1 parent a012057 commit afb3f0e

File tree

4 files changed

+68
-0
lines changed

4 files changed

+68
-0
lines changed

lib/ruby-bindgen/generators/rice/rice.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,17 @@ def visit_constructor(cursor)
395395
# constants, embedded types, and any auto-generated template bases needed
396396
# before the class itself can be registered.
397397
def visit_class_decl(cursor)
398+
# Namespace-scope forward-declared C++ classes are often completed in a
399+
# different header. Emitting a Rice class here creates a Ruby constant
400+
# with no superclass, and a later complete definition then conflicts.
401+
# Keep nested incomplete classes on the existing special path, and keep
402+
# opaque structs available for handle-style APIs.
403+
if cursor.kind == :cursor_class_decl &&
404+
cursor.opaque_declaration? &&
405+
![:cursor_class_decl, :cursor_struct].include?(cursor.semantic_parent.kind)
406+
return
407+
end
408+
398409
# Skip explicitly listed symbols
399410
return if skip_symbol?(cursor)
400411

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#include "forward_declared_classes.hpp"
2+
3+
namespace ForwardDeclaredClasses
4+
{
5+
class ActivationLayer : public Layer
6+
{
7+
public:
8+
ActivationLayer() = default;
9+
10+
bool forward() const
11+
{
12+
return true;
13+
}
14+
};
15+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
namespace ForwardDeclaredClasses
2+
{
3+
class ActivationLayer;
4+
5+
class Layer
6+
{
7+
public:
8+
virtual ~Layer() = default;
9+
10+
bool enabled() const
11+
{
12+
return true;
13+
}
14+
};
15+
16+
class Net
17+
{
18+
public:
19+
void setActivation(ActivationLayer* layer);
20+
};
21+
}

test/rice_generator_test.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,4 +175,25 @@ class FunctionTemplate
175175
assert_includes rendered, "Rice::Data_Type<Tests::FunctionTemplate<&Tests::callback_ints>>"
176176
assert_includes rendered, "FunctionTemplate_instantiate<&Tests::callback_ints>"
177177
end
178+
179+
def test_namespace_scope_forward_declared_classes_do_not_generate_bindings
180+
config_dir = File.join(__dir__, "headers", "cpp")
181+
config = load_config(config_dir)
182+
inputter = RubyBindgen::Inputter.new(config_dir, ["forward_declared_classes.hpp",
183+
"forward_declared_all_layers.hpp"])
184+
outputter = create_outputter("cpp")
185+
generator = RubyBindgen::Generators::Rice.new(inputter, outputter, config)
186+
187+
capture_io do
188+
generator.generate
189+
end
190+
191+
classes_cpp = outputter.output_paths.fetch(outputter.output_path("forward_declared_classes-rb.cpp"))
192+
all_layers_cpp = outputter.output_paths.fetch(outputter.output_path("forward_declared_all_layers-rb.cpp"))
193+
194+
refute_includes classes_cpp,
195+
'define_class_under<ForwardDeclaredClasses::ActivationLayer>(rb_mForwardDeclaredClasses, "ActivationLayer")'
196+
assert_includes all_layers_cpp,
197+
'define_class_under<ForwardDeclaredClasses::ActivationLayer, ForwardDeclaredClasses::Layer>(rb_mForwardDeclaredClasses, "ActivationLayer")'
198+
end
178199
end

0 commit comments

Comments
 (0)