Closed HertzDevil closed 4 years ago
Hello,
Cool stuff as always :) Wouldn't it make sense to copy constants which are of primitive type? Pointer-types and non-primitives should stay as they are with this PR, I think they're great :+1:
My concern is that even for primitive types their initializers must be available to the parser. Consider
// test.h
struct T {
static const int X = 1;
static const int Y;
};
// test.cpp (not parsed)
const int T::Y = 2;
class T
X = 1
Y = Binding.bg_T_Y_STATIC_GETTER_() # ???
# do we still need these?
def self.x : Int32 end
def self.y : Int32 end
end
That's a fair point (Gotta love C++!). I think the Crystal part of your sample looks good. I'd then drop the methods for these cases. This hopefully allows the user to e.g. use meta-programming in combination of this in some cases. I think it also makes sense as I've seen libs using constants as replacements for enums - For reasons unknown :)
I did a small test and unfortunately T::Y
is not a constant expression:
extern "C" int f() { return 1; }
lib Binding
fun f : Int32
end
class Wrapper
A = 4
B = Binding.f
# ^-----
# Error: invalid constant value
end
x = StaticArray(Int32, Wrapper::A).new(0)
y = StaticArray(Int32, Wrapper::B).new(0) # triggered by this line
The Crystal constant is still lazily constructed so it behaves like a constant during run-time, but compile-time programming with these constants will be impossible. Thus there is little point in having constants like T::Y
if their initializers are unavailable:
class T
X = 1
# do not define `T.x`
# corresponding C++ static getter will not be generated at all
def self.y() : Int32 # as before
Binding.bg_T_Y_STATIC_GETTER_()
end
end
Should this part go into a separate PR?
Ah that's unfortunate, but I think even with that caveat it's a good feature. I'll leave that up to you if you want to do a split PR or not.
Static constants are in.
Default values (C++11 NSDMI) for non-static fields are also parsed, since they share the same JSON structure as static fields.
Good stuff, thank you!
Generates getters and setters for static variables, just like instance variables. Considerable portions of the changes are just documentation changes to reflect that both static and non-static data members are supported.
produces:
This PR does not map constant members to Crystal constants yet, because in general the constant itself may be altered in Crystal if it is a wrapper (which inherits from
Reference
, and only prevents assignments):Interestingly, Qt uses almost no static members, and the only differences after this PR are
QObject::staticMetaObject
. (Integral constants used anonymous enums a bit.)