rbplusplus 0.1.1 → 0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/Rakefile +31 -15
  2. data/TODO +20 -0
  3. data/lib/rbplusplus/builders/base.rb +148 -8
  4. data/lib/rbplusplus/builders/class.rb +106 -31
  5. data/lib/rbplusplus/builders/enumeration.rb +40 -0
  6. data/lib/rbplusplus/builders/extension.rb +31 -6
  7. data/lib/rbplusplus/builders/module.rb +12 -6
  8. data/lib/rbplusplus/builders/types_manager.rb +93 -0
  9. data/lib/rbplusplus/extension.rb +69 -41
  10. data/lib/rbplusplus/module.rb +3 -1
  11. data/lib/rbplusplus/transformers/class.rb +67 -0
  12. data/lib/rbplusplus/transformers/constructor.rb +4 -0
  13. data/lib/rbplusplus/transformers/function.rb +27 -0
  14. data/lib/rbplusplus/transformers/method.rb +4 -0
  15. data/lib/rbplusplus/transformers/module.rb +71 -0
  16. data/lib/rbplusplus/transformers/node.rb +77 -0
  17. data/lib/rbplusplus/transformers/node_cache.rb +19 -0
  18. data/lib/rbplusplus/transformers/node_reference.rb +30 -0
  19. data/lib/rbplusplus/transformers/rbgccxml.rb +6 -0
  20. data/lib/rbplusplus/writers/extension.rb +33 -25
  21. data/lib/rbplusplus/writers/multiple_files_writer.rb +42 -2
  22. data/lib/rbplusplus/writers/single_file_writer.rb +5 -0
  23. data/lib/rbplusplus.rb +24 -0
  24. data/test/class_methods_test.rb +55 -0
  25. data/test/classes_test.rb +0 -25
  26. data/test/compiling_test.rb +30 -0
  27. data/test/constructors_test.rb +40 -0
  28. data/test/enumerations_test.rb +63 -0
  29. data/test/file_writers_test.rb +56 -4
  30. data/test/generated/extconf.rb +25 -5
  31. data/test/headers/class_methods.h +41 -0
  32. data/test/headers/complex_static_methods.h +25 -0
  33. data/test/headers/constructors.h +47 -0
  34. data/test/headers/enums.h +77 -0
  35. data/test/headers/external_mapping.h +16 -0
  36. data/test/headers/external_mapping_rice.h +20 -0
  37. data/test/headers/include/helper.h +1 -0
  38. data/test/headers/nested_struct.h +20 -0
  39. data/test/headers/overload.h +28 -0
  40. data/test/headers/subclass.h +42 -0
  41. data/test/headers/to_from_ruby.h +78 -0
  42. data/test/headers/to_from_ruby_source.cpp +22 -0
  43. data/test/headers/ugly_helper.h +18 -0
  44. data/test/headers/ugly_interface.h +115 -0
  45. data/test/headers/ugly_interface_ns.h +8 -0
  46. data/test/nested_test.rb +26 -0
  47. data/test/object_persistence_test.rb +44 -0
  48. data/test/overloading_test.rb +36 -0
  49. data/test/struct_test.rb +22 -0
  50. data/test/subclass_test.rb +31 -0
  51. data/test/test_helper.rb +5 -0
  52. data/test/to_from_ruby_test.rb +24 -0
  53. data/test/wrap_as_test.rb +114 -0
  54. metadata +43 -6
@@ -0,0 +1,77 @@
1
+ /**
2
+ * This header file is for testing wrapping and using enumerations
3
+ */
4
+
5
+ #ifndef __ENUMS__H__
6
+ #define __ENUMS__H__
7
+
8
+ #include <iostream>
9
+ #include <sstream>
10
+
11
+ namespace enums {
12
+ enum TestEnum {
13
+ VALUE1,
14
+ VALUE2,
15
+ VALUE3
16
+ };
17
+
18
+ namespace inner {
19
+ enum InnerEnum {
20
+ INNER_1,
21
+ INNER_2
22
+ };
23
+ }
24
+
25
+ std::string whatTestEnum(TestEnum e) {
26
+ std::stringstream stream;
27
+ stream << "We gots enum " << e;
28
+ return stream.str();
29
+ }
30
+
31
+ class Tester {
32
+ public:
33
+ Tester() {}
34
+
35
+ enum MyEnum {
36
+ I_LIKE_MONEY = 3,
37
+ YOU_LIKE_MONEY_TOO,
38
+ I_LIKE_YOU = 7
39
+ };
40
+
41
+ std::string getEnumDescription(MyEnum e) {
42
+ std::string ret;
43
+ switch(e) {
44
+ case I_LIKE_MONEY:
45
+ ret = "I like money";
46
+ break;
47
+ case YOU_LIKE_MONEY_TOO:
48
+ ret = "You like money!";
49
+ break;
50
+ case I_LIKE_YOU:
51
+ ret = "I like you too";
52
+ break;
53
+ default:
54
+ ret = "What you say?";
55
+ break;
56
+ }
57
+
58
+ return ret;
59
+ }
60
+
61
+ MyEnum getAnEnum(std::string message) const {
62
+ MyEnum e;
63
+
64
+ if (message == "I like money") {
65
+ e = I_LIKE_MONEY;
66
+ } else if (message == "You like money") {
67
+ e = YOU_LIKE_MONEY_TOO;
68
+ } else if (message == "I like you") {
69
+ e = I_LIKE_YOU;
70
+ }
71
+
72
+ return e;
73
+ }
74
+ };
75
+ }
76
+
77
+ #endif
@@ -0,0 +1,16 @@
1
+ #ifndef EXTERNAL_INCLUDE_TEST
2
+ #define EXTERNAL_INCLUDE_TEST
3
+
4
+ namespace ExternalIncludeTest {
5
+ class MapsToInt {
6
+ public:
7
+ MapsToInt(int x) {value=x;}
8
+ int value;
9
+ };
10
+ inline MapsToInt return100() {
11
+ return MapsToInt(100);
12
+ }
13
+
14
+ }
15
+
16
+ #endif
@@ -0,0 +1,20 @@
1
+ //#ifndef USES_INLINE_DEPENDENCY
2
+ //#define USES_INLINE_DEPENDENCY
3
+
4
+ //#include "external_mapping.h"
5
+
6
+ //#include "rice/Class.hpp"
7
+ //#include "rice/Data_Type.hpp"
8
+ //#include "rice/Constructor.hpp"
9
+ //#include "rice/Enum.hpp"
10
+ //#include "rice/to_from_ruby.hpp"
11
+ //#include "rice/Address_Registration_Guard.hpp"
12
+
13
+ //#include <ruby.h>
14
+
15
+ //template<>
16
+ //Rice::Object to_ruby<MapToInto>(MapToInt & x) {
17
+ // return to_ruby(x.value);
18
+ //}
19
+
20
+ //#endif
@@ -6,3 +6,4 @@ int helper(int a, int b) {
6
6
  }
7
7
 
8
8
  #endif
9
+
@@ -0,0 +1,20 @@
1
+ #ifndef __NESTED_STRUCT_H
2
+ #define __NESTED_STRUCT_H
3
+
4
+ namespace nested {
5
+ class Klass {
6
+ public:
7
+ struct NestedStruct {
8
+ public:
9
+ NestedStruct() {}
10
+ inline int one() { return 1; }
11
+ };
12
+ private:
13
+ struct PrivateNestedStruct {
14
+ public:
15
+ PrivateNestedStruct() {}
16
+ };
17
+ };
18
+ }
19
+
20
+ #endif
@@ -0,0 +1,28 @@
1
+ #ifndef __METHOD_OVERLOAD_H__
2
+ #define __METHOD_OVERLOAD_H__
3
+
4
+ namespace overload {
5
+ class Mathy {
6
+ public:
7
+ Mathy() {}
8
+ Mathy(int x) {}
9
+ int times() {
10
+ return 1;
11
+ }
12
+ int times(int x) {
13
+ return x;
14
+ }
15
+ int times(int x, int y) {
16
+ return x*y;
17
+ }
18
+ long times(int x, int y, int z) {
19
+ return x*y*z;
20
+ }
21
+ void nothing() {}
22
+ void nothing(int x) {}
23
+
24
+ const Mathy &self() const { return *this; }
25
+ Mathy &self() { return *this; }
26
+ };
27
+ }
28
+ #endif
@@ -0,0 +1,42 @@
1
+ #ifndef __SUBCLASS_H__
2
+ #define __SUBCLASS_H__
3
+ namespace subclass {
4
+ class SuperSuper {
5
+ public:
6
+ inline int minOne() { return -1; }
7
+ };
8
+ class Super : public SuperSuper {
9
+ public:
10
+ inline int zero() { return 0; }
11
+ };
12
+ class Base : public Super {
13
+ public:
14
+ inline int one() { return 1; }
15
+ Base() {}
16
+ };
17
+ class Sub : public Base {
18
+ public:
19
+ Sub() {}
20
+ };
21
+
22
+ template<class T>
23
+ class TemplateSuper : public Super {
24
+ T val;
25
+ public:
26
+ TemplateSuper(T val) {
27
+ this->val = val;
28
+ }
29
+ inline T custom() { return this->val; }
30
+ };
31
+
32
+ class TemplateSub : public TemplateSuper<int> {
33
+ public:
34
+ TemplateSub() : TemplateSuper<int>(0) {}
35
+ };
36
+
37
+ class TemplatePtr : public TemplateSuper<Base*> {
38
+ public:
39
+ TemplatePtr() : TemplateSuper<Base*>(new Base()) {}
40
+ };
41
+ }
42
+ #endif
@@ -0,0 +1,78 @@
1
+ #ifndef __TO_FROM_RUBY_H__
2
+ #define __TO_FROM_RUBY_H__
3
+
4
+ #include <string>
5
+
6
+ namespace to_from_ruby {
7
+
8
+ // Const methods that return references need an explicit to_ruby
9
+ // definition for the given type
10
+ class MyType {
11
+ public:
12
+ int myValue;
13
+
14
+ MyType() { myValue = 0; }
15
+
16
+ // Exposing attributes not implemented yet
17
+ int value() { return myValue; }
18
+ };
19
+
20
+ const MyType& needsToRuby(int value);
21
+
22
+ // But rb++ should only make one to_ruby definition or the compiler
23
+ // will poop
24
+ const MyType& someOtherMethod(int value);
25
+
26
+ // Should also work with class methods
27
+ class WrappedClass {
28
+ public:
29
+ WrappedClass() {}
30
+
31
+ const MyType& getMyType(int value) {
32
+ MyType *type = new MyType();
33
+ type->myValue = value;
34
+ return *type;
35
+ }
36
+
37
+ const WrappedClass &overload() {
38
+ return *this;
39
+ }
40
+
41
+ const WrappedClass &overload(int arg) {
42
+ return *this;
43
+ }
44
+ };
45
+
46
+ /**
47
+ * Some types, Rice already wraps for us. Make sure this doesn't cause
48
+ * a compiler error
49
+ */
50
+ void usingConstString(const std::string& in);
51
+
52
+ /* template tests */
53
+
54
+ template<class T>
55
+ class TemplateClass {
56
+ T val;
57
+ public:
58
+ TemplateClass(T val) {
59
+ this->val = val;
60
+ }
61
+ const T &overload() {
62
+ return this->val;
63
+ }
64
+ const T &overload(int arg) {
65
+ return this->val;
66
+ }
67
+ };
68
+
69
+ inline const TemplateClass<int> &getTemplate() {
70
+ return *(new TemplateClass<int>(1));
71
+ }
72
+
73
+ inline const TemplateClass<int> &getTemplate(int overload) {
74
+ return *(new TemplateClass<int>(overload));
75
+ }
76
+ }
77
+
78
+ #endif
@@ -0,0 +1,22 @@
1
+ #include "to_from_ruby.h"
2
+
3
+ namespace to_from_ruby {
4
+
5
+ const MyType& needsToRuby(int value) {
6
+ MyType *type = new MyType();
7
+ type->myValue = value;
8
+ return *type;
9
+ }
10
+
11
+ // But rb++ should only make one to_ruby definition or the compiler
12
+ // will poop
13
+ const MyType& someOtherMethod(int value) {
14
+ MyType *type = new MyType();
15
+ type->myValue = value;
16
+ return *type;
17
+ };
18
+
19
+ void usingConstString(const std::string& in) {
20
+
21
+ }
22
+ }
@@ -0,0 +1,18 @@
1
+ #ifndef UGLY_HELPER
2
+ #define UGLY_HELPER
3
+
4
+ #include "rice/Class.hpp"
5
+ #include "rice/Data_Type.hpp"
6
+ #include "rice/Constructor.hpp"
7
+ #include "rice/Enum.hpp"
8
+ #include "rice/to_from_ruby.hpp"
9
+ #include "rice/Address_Registration_Guard.hpp"
10
+
11
+ #include <ruby.h>
12
+ #include "ugly_interface_ns.h"
13
+
14
+ inline UI::C_UIVector *newInstanceButBetter(Rice::Object *self) {
15
+ return new UI::C_UIVector();
16
+ }
17
+
18
+ #endif
@@ -0,0 +1,115 @@
1
+ #ifndef __UGLY_H__
2
+ #define __UGLY_H__
3
+
4
+ /*
5
+ Mapping should work for:
6
+ ruby:
7
+ F = function
8
+ M = module
9
+ C = class
10
+
11
+ c++:
12
+ m = namespace
13
+ f = function
14
+ c = class
15
+
16
+ m f c
17
+ F
18
+ M x x x
19
+ C x
20
+
21
+ */
22
+
23
+ //should be exported as UI::add
24
+ inline int uiAdd(int a, int b) {
25
+ return a+b;
26
+ }
27
+
28
+
29
+ //should be exported as UI::subtract
30
+ inline int ui_Subtract(int a, int b) {
31
+ return a-b;
32
+ }
33
+
34
+ inline void uiIgnore() {}
35
+
36
+ class C_UIVector {
37
+ private:
38
+ int x;
39
+ public:
40
+ C_UIVector() {}
41
+ int x_() {
42
+ return this->x;
43
+ }
44
+ void set_x(int x) {
45
+ this->x = x;
46
+ }
47
+ static int one() {
48
+ return 1;
49
+ }
50
+ int y_() {
51
+ return 0;
52
+ }
53
+ };
54
+
55
+
56
+ inline C_UIVector *IlikeVectors(int i) {
57
+ return new C_UIVector();
58
+ }
59
+
60
+ class NoConstructor {
61
+ public:
62
+ NoConstructor() {}
63
+ };
64
+
65
+ class Inside {
66
+ public:
67
+ Inside() {}
68
+ };
69
+ class Outside {
70
+ };
71
+
72
+
73
+ namespace __UI {
74
+ namespace BAD_UI {
75
+ class Multiplier {
76
+ public:
77
+ Multiplier() {}
78
+ inline int multiply(int a, int b) {
79
+ return a*b;
80
+ }
81
+ };
82
+ inline int multiply(int a, int b, int c) {
83
+ return a*b*c;
84
+ }
85
+ }
86
+ }
87
+
88
+ namespace DMath {
89
+ inline float divide(float a,float b) {
90
+ return a/b;
91
+ }
92
+ }
93
+
94
+ struct C_STRUCT_Quaternion {
95
+ public:
96
+ int i() {
97
+ return -1;
98
+ }
99
+ };
100
+
101
+ namespace I_LEARN_C {
102
+ inline int mod(int a, int b) {
103
+ return a%b;
104
+ }
105
+ inline int mod2(int a, int b) {
106
+ return a%b;
107
+ }
108
+ class Modder {
109
+ public:
110
+ Modder() {}
111
+
112
+ };
113
+ }
114
+
115
+ #endif
@@ -0,0 +1,8 @@
1
+ #ifndef __UI_NS_H__
2
+ #define __UI_NS_H__
3
+
4
+ namespace UI {
5
+ #include "ugly_interface.h"
6
+ }
7
+
8
+ #endif
@@ -0,0 +1,26 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ context "Wrapping Classes within classes" do
4
+ def setup
5
+ if !defined?(@@nested_built)
6
+ super
7
+ @@nested_built = true
8
+ Extension.new "nested" do |e|
9
+ e.sources full_dir("headers/nested_classes.h")
10
+ node = e.namespace "classes"
11
+ end
12
+
13
+ require 'nested'
14
+ end
15
+ end
16
+
17
+ specify "should properly make nested classes available" do
18
+ assert defined?(TestClass)
19
+ assert defined?(TestClass::InnerClass)
20
+ assert defined?(TestClass::InnerClass::Inner2)
21
+
22
+ TestClass.new.should.not.be.nil
23
+ TestClass::InnerClass.new.should.not.be.nil
24
+ TestClass::InnerClass::Inner2.new.should.not.be.nil
25
+ end
26
+ end
@@ -0,0 +1,44 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ context "Object Persistence" do
4
+
5
+ def validate(node)
6
+ namespaces = node.namespaces
7
+
8
+ node.namespaces.each_with_index do |n, i|
9
+
10
+ #puts "#{node.name}::#{n.name}"
11
+ namespaces[i].object_id.should == n.object_id
12
+
13
+ classes = n.classes
14
+ classes.each_with_index do |cls, j|
15
+ namespaces[i].classes[j].object_id.should == cls.object_id
16
+
17
+ methods = cls.methods
18
+ methods.each_with_index do |m, k|
19
+ #puts "#{n.name}::#{cls.name}::#{m.name}"
20
+ namespaces[i].classes[j].methods[k].object_id.should == m.object_id
21
+ end
22
+ end
23
+
24
+ functions = n.functions
25
+ functions.each_with_index do |funct, j|
26
+ # puts "#{n.name}::#{funct.name}"
27
+ namespaces[i].functions[j].object_id.should == funct.object_id
28
+ end
29
+
30
+ validate n
31
+ end
32
+
33
+ end
34
+
35
+ specify "seperate query should lazy initialize objects" do
36
+ Extension.new "ui" do |e|
37
+ e.sources full_dir("headers/ugly_interface_ns.h")
38
+ node = e.namespace("UI")
39
+ validate(node)
40
+ end
41
+ end
42
+ end
43
+
44
+
@@ -0,0 +1,36 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ context "Extension with overloaded methods" do
4
+
5
+ specify "should have all functions available" do
6
+ Extension.new "overload" do |e|
7
+ e.sources full_dir("headers/overload.h")
8
+ node = e.namespace "overload"
9
+ node.classes("Mathy").methods("times")[0].wrap_as("times")
10
+ end
11
+
12
+ require 'overload'
13
+
14
+ math = nil
15
+ should.not.raise NameError do
16
+ #Constructor overloading is broken in rice
17
+ #math = Mathy.new
18
+ math = Mathy.new(1)
19
+ end
20
+
21
+ should.not.raise NameError do
22
+ math.times.should == 1
23
+ math.times_1(3).should == 3
24
+ math.times_2(3,2).should == 6
25
+ math.times_3(3,2,3).should == 18
26
+ end
27
+
28
+ should.not.raise NameError do
29
+ math.nothing_0
30
+ math.nothing_1(1)
31
+ math.self_0.class.should == math.self_1.class
32
+ end
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,22 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ context "Nested Struct" do
4
+
5
+ specify "should be accessible" do
6
+ Extension.new "nested" do |e|
7
+ e.sources full_dir("headers/nested_struct.h")
8
+ e.namespace "nested"
9
+ end
10
+
11
+ require 'nested'
12
+
13
+ should.not.raise NameError do
14
+ Klass::NestedStruct.new.one.should == 1
15
+ end
16
+
17
+ should.raise NameError do
18
+ Klass::PrivateNestedStruct.new
19
+ end
20
+ end
21
+
22
+ end
@@ -0,0 +1,31 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ context "Extension with class hierachies" do
4
+
5
+ specify "should make super classes methods available" do
6
+ Extension.new "subclass" do |e|
7
+ e.sources full_dir("headers/subclass.h")
8
+ node = e.namespace "subclass"
9
+
10
+ node.classes("SuperSuper").ignore
11
+ e.module("Sub") do |m|
12
+ node.classes.each do |c|
13
+ m.includes c
14
+ end
15
+ end
16
+ end
17
+
18
+ require 'subclass'
19
+ should.not.raise NameError do
20
+ Sub::Base.new.one.should == Sub::Sub.new.one
21
+ Sub::Base.new.zero.should == Sub::Sub.new.zero
22
+ end
23
+ should.not.raise NameError do
24
+ Sub::TemplateSub.new.zero.should == Sub::TemplateSub.new.custom
25
+ end
26
+ should.not.raise NameError do
27
+ Sub::TemplatePtr.new.custom
28
+ end
29
+ end
30
+
31
+ end
data/test/test_helper.rb CHANGED
@@ -16,4 +16,9 @@ class Test::Unit::TestCase
16
16
  def setup
17
17
  `rm -rf #{full_dir('generated')}/*`
18
18
  end
19
+
20
+ def teardown
21
+ RbGCCXML::XMLParsing.clear_cache
22
+ NodeCache.instance.clear
23
+ end
19
24
  end
@@ -0,0 +1,24 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ context "Properly build known required to_ruby and from_ruby methods" do
4
+
5
+ specify "should build for const & types as needed" do
6
+ Extension.new "to_from_ruby" do |e|
7
+ e.sources full_dir("headers/to_from_ruby.h"),
8
+ :include_paths => full_dir("headers"),
9
+ :include_source_files => full_dir("headers/to_from_ruby_source.cpp")
10
+ e.namespace "to_from_ruby"
11
+ end
12
+
13
+ require 'to_from_ruby'
14
+
15
+ needs_to_ruby(4).value.should == 4
16
+ some_other_method(7).value.should == 7
17
+
18
+ c = WrappedClass.new
19
+ c.get_my_type(17).value.should == 17
20
+ c.overload_0.class.should == c.overload_1(0).class
21
+
22
+ get_template_0(1).overload_0.should == get_template_1.overload_1(1)
23
+ end
24
+ end