I give up! I tried to create a reflection library but D's traits are just too screwed up!
Alex
AJ at gmail.com
Thu Apr 4 05:18:52 UTC 2019
I went ahead and decided to tidy up the code a bit and fix what
could be fixed. For the most part everything is working pretty
nice. By being careful of what was returned and dealing with any
problems correctly I was able to get most of the code to be as I
intend. So far, assuming everything is right, the only problem is
that overloads are not returning parameter information correctly
which I demonstrate at the bottom(Since the method code is now
using the function code and the function code works it suggests a
subtle issue).
import std.stdio;
import mExModel;
import mModel;
import mReflect;
import mExTraits;
struct attr(T)
{
T name;
int value;
}
@attr!string("test", 432) @(4) void foo(int x, ref double y,
float z = 43234.34) { }
int main()
{
pragma(msg, printModelHierarchy(Reflect!(cDerived!int)));
pragma(msg, printModelHierarchy(Reflect!(foo)));
pragma(msg, printModelHierarchy(Reflect!(eEnum)));
return 0;
}
module mModel;
struct sStruct
{
int Y;
int opIndex(int i)
{
return i;
}
}
@(4) enum eEnum : long
{
X,
Y = 43,
@("sdfdsa") @(3) Z = 4
}
@("fdsa", 4) interface iBase
{
iBase fooBase(iBase);
}
union uUnion
{
int X;
long Y;
}
class cBase : iBase
{
string testField;
cBase fooBase(iBase c) { return cast(cBase)c; }
//cType barBase(cDerived c) { return c.type; }
}
interface iX { };
interface iY { };
@("fdsa",8) class cDerived(Q) : cBase, iX, iY
{
alias type this;
cType type;
@("XXXRRERES") int testField1;
@("XXXRRERES4") private double testField2;
@("A") int foo() { return 2; }
private @("B") int foo(int x, int y) { return x; }
@("VP att") @property int ValueProp() { return 3; }
}
class cType
{
}
module mReflect;
import mExTraits;
import std.meta, std.conv, std.typecons, std.typetuple,
std.string, std.algorithm, std.range, std.variant;
/*
A basic type
*/
struct sTypeReflection
{
string Name;
string Type;
this(string n, string t) { Name = n; Type = t; }
}
/*
A Basic attribute
*/
struct sAttributeReflection
{
string Value;
string Type;
this(string v, string t) { Value = v; Type = t; }
}
/*
Encapsulation of basic reflection
*/
abstract class cBaseReflection
{
// Declared in reverse order for proper output
sAttributeReflection[] Attributes; // Attributes on the type
cBaseReflection[] Uses; // Known types that use this type
as a field, parameter, return type, etc
string Body; // D does not allow getting a body but this
is included if it ever does
string Protection;
string MangledName;
string ModuleName; // The module name
string FullName; // The fully qualified name
string TypeName; // The type name
string Id; // The id = __traits(identifier,T)
string DType() { return "Unknown"; }
auto Reflect(Ts...)()
{
alias T = Ts[0];
static if (__traits(compiles, __traits(identifier, T))) Id =
__traits(identifier, T);
static if (__traits(compiles, T.stringof)) TypeName =
T.stringof;
static if (__traits(compiles, moduleName!T)) ModuleName =
moduleName!(T);
static if (__traits(compiles, fullyQualifiedName!T)) FullName =
fullyQualifiedName!(T);
static if (__traits(compiles, mangledName!T)) MangledName =
mangledName!T;
static if (__traits(compiles, __traits(getProtection, T)))
Protection = __traits(getProtection, T);
// Get the attributes for the type
static if (__traits(compiles, __traits(getAttributes, T)))
static foreach(a; __traits(getAttributes, T)) Attributes ~=
sAttributeReflection(to!string(a), typeof(a).stringof);
return this;
}
}
/*
Encapsulates an Enumeration Reflection
*/
class cEnumReflection : cBaseReflection
{
static struct sValueReflection
{
string Name;
string Value;
sAttributeReflection[] Attributes;
this(string n, string v) { Name = n; Value = v; }
} sValueReflection[] Values;
string BaseType;
override string DType() { return "enum"; }
auto Reflect(alias T)()
{
super.Reflect!T;
BaseType = OriginalType!(T).stringof;
static foreach(e; EnumMembers!T)
{{
Values ~= sValueReflection(to!string(e), e.stringof);
mixin("alias E = __traits(getAttributes,
T."~to!string(e)~");");
static foreach(a; E)
Values[$-1].Attributes ~= sAttributeReflection(to!string(a),
typeof(a).stringof);
}}
return this;
}
}
/*
Encapsulates an Aggregate Type
*/
abstract class cAggregateReflection : cBaseReflection
{
cMethodReflection[] Methods; // The methods
cFieldReflection[] Fields; // The fields
cClassReflection[] DerivedClasses; // Known immedate
derived class that derive this type
cAggregateReflection[] NestedAggregates; // Any nested
aggregates
sTypeReflection[] AliasThis; // The Alias This
sTypeReflection[] TypeParameters; // Any type parameters
used.
bool HasAliasing;
bool HasElaborateAssign;
bool HasElaborateCopyConstructor;
bool HasElaborateDestructor;
bool HasIndirections;
bool HasNested;
bool HasUnsharedAliasing;
bool IsInnerClass;
bool IsNested;
override string DType() { return "Unknown"; }
auto Reflect(alias T)()
{
super.Reflect!T;
// Get the Alias This
static foreach(a; __traits(getAliasThis, T))
{{
mixin("import "~moduleName!T~";");
mixin("AliasThis ~= sTypeReflection(to!string(a),
typeof("~moduleName!T~"."~T.stringof~"."~to!string(a)~").stringof);");
}}
HasAliasing = hasAliasing!T;
HasElaborateAssign = hasElaborateAssign!T;
HasElaborateCopyConstructor = hasElaborateCopyConstructor!T;
HasElaborateDestructor = hasElaborateDestructor!T;
HasIndirections = hasIndirections!T;
HasNested = hasNested!T;
HasUnsharedAliasing = hasUnsharedAliasing!T;
static if (__traits(compiles, isInnerClass!T)) IsInnerClass =
isInnerClass!T;
static if (__traits(compiles, isNested!T)) IsNested =
isNested!T;
// Get the fields
alias n = FieldNameTuple!T;
static foreach(k, f; std.traits.Fields!T)
{{
Fields ~= (new cFieldReflection()).Reflect!(Alias!T, n[k]);
}}
// Get the methods
static foreach(k, m; __traits(derivedMembers, T))
{{
static if (__traits(compiles, __traits(getVirtualMethods, T,
m)))
static foreach(j, v; typeof(__traits(getVirtualMethods, T,
m)))
{{
//Methods ~= (new cMethodReflection()).Reflect!(T, m, v); //
If we could pass the appropriate type, like we can a function,
then everythign would work great.
mixin(`import `~moduleName!T~`;`);
static foreach (f; typeof(__traits(getOverloads, T, m)))
{
mixin(`Methods ~= (new
cMethodReflection()).Reflect!(`~T.stringof~`.`~m~`, f);`);
}
}}
}}
return this;
}
}
/*
Encapsulates a Field Reflection
*/
class cFieldReflection : cBaseReflection
{
override string DType() { return "field"; }
auto Reflect(alias T, string name)()
{
//pragma(msg, "Field: ", T, " -- ", name);
static if (name != "")
{
// There is no field type so must manually construct and
duplicate code, else we could reflect directly
mixin(`import `~moduleName!T~`;`);
// super.Reflect!T
// -------- Cannod delegate work to base class, copy, paste,
fix instead
Id = name;
static if (__traits(compiles, TypeName = T.stringof)) TypeName
= T.stringof~"."~name;
ModuleName = moduleName!(T);
FullName = fullyQualifiedName!(T)~"."~name;
MangledName = mangledName!T;
// Get the attributes for the field
mixin(`Protection = __traits(getProtection,
(`~T.stringof~`).`~name~`);`);
mixin(`static if (__traits(compiles, __traits(getProtection,
`~T.stringof~`.`~name~`)))
static foreach(a; __traits(getAttributes,
`~T.stringof~`.`~name~`)) Attributes ~=
sAttributeReflection(to!string(a), typeof(a).stringof);`);
}
return this;
}
}
/*
Encapsulates a Method Reflection
*/
class cMethodReflection : cFunctionReflection
{
cFunctionReflection[] Overloads;
override string DType() { return "delegate"; }
auto Reflect(Ts...)()
{
alias T = Ts[0];
alias V = Ts[1];
//pragma(msg, "Method: ", T, " -- ", V.stringof);
super.Reflect!V;
(cast(cBaseReflection)this).Reflect!T; // Fill in base
information to get correct information
return this;
}
}
/*
Encapsulates a Union Reflection
*/
class cUnionReflection : cAggregateReflection
{
override string DType() { return "union"; }
auto Reflect(alias T)()
{
super.Reflect!T;
return this;
}
}
/*
Encapsulates a Struct Reflection
*/
class cStructReflection : cAggregateReflection
{
override string DType() { return "struct"; }
auto Reflect(alias T)()
{
super.Reflect!T;
return this;
}
}
/*
Encapsulates a Interface Reflection
*/
class cInterfaceReflection : cAggregateReflection
{
cInterfaceReflection[] InheritedInterfaces; // The inherited
interfaces
override string DType() { return "interface"; }
auto Reflect(alias T)()
{
super.Reflect!T;
// Reflect on inherited interfaces
static foreach(t; BaseTypeTuple!T)
static if (isInterface!t)
InheritedInterfaces ~= (new
cInterfaceReflection()).Reflect!(t);
return this;
}
}
/*
Encapsulates a Class Reflection
*/
class cClassReflection : cInterfaceReflection
{
cClassReflection[] InheritedClasses; // Any Inherited
class(D only allows single class inheritance, but we allow for
possibly more for uniformity)
int Alignment;
bool IsAbstract = false;
override string DType() { return "class"; }
auto Reflect(alias T)()
{
super.Reflect!T;
IsAbstract = isAbstractClass!T;
Alignment = classInstanceAlignment!T;
// Reflect on inherited class
static foreach(t; BaseTypeTuple!T)
static if (isClass!t)
InheritedClasses ~= (new cClassReflection()).Reflect!(t);
return this;
}
}
/*
Encapsulates a Function Reflection
*/
class cFunctionReflection : cBaseReflection
{
static struct sParameterReflection
{
string Name;
string Type;
string DefaultValue = "none";
string DefaultValueType = "void";
struct sStorageClass
{
static foreach(a; EnumMembers!ParameterStorageClass)
mixin(`bool Is`~strip(capitalize(to!string(a)),"_")~";");
} sStorageClass StorageClass;
this(string n, string t, string dv, string dt) { Name = n; Type
= t; DefaultValue = dv; DefaultValueType = dt; }
}
static struct sFunctionAttributes
{
static foreach(a; EnumMembers!FunctionAttribute)
mixin(`bool Is`~strip(capitalize(to!string(a)),"_")~";");
}
sFunctionAttributes FunctionAttributes;
sParameterReflection[] Parameters;
string ReturnType;
string Linkage;
Variadic VariadicFunctionStyle;
int NumArgs;
string Signature;
override string DType() { return "function"; }
auto Reflect(Ts...)()
if (Ts.length == 1 && isCallable!Ts)
{
alias T = Ts[0];
super.Reflect!T; // Note that we can delegate to the function
to a base class, but not the a method
Signature = FunctionTypeOf!T.stringof;
NumArgs = arity!T;
Linkage = functionLinkage!T;
VariadicFunctionStyle = variadicFunctionStyle!T;
ReturnType = std.traits.ReturnType!T.stringof;
static foreach(a; EnumMembers!FunctionAttribute)
mixin(`FunctionAttributes.Is`~strip(capitalize(to!string(a)),"_")~" = (functionAttributes!T & FunctionAttribute."~to!string(a)~") != 0;");
static foreach(k, a; std.traits.Parameters!T)
{{
static if (__traits(compiles,
typeof(ParameterDefaults!T[k]).stringof))
enum dt = typeof(ParameterDefaults!T[k]).stringof;
else
enum dt = "void";
Parameters ~=
sParameterReflection(ParameterIdentifierTuple!T[k], a.stringof,
ParameterDefaults!T[k].stringof, dt);
static foreach(j, a; EnumMembers!ParameterStorageClass)
mixin(`Parameters[k].StorageClass.Is`~strip(capitalize(to!string(a)),"_")~" = (ParameterStorageClassTuple!T[k] & ParameterStorageClass."~to!string(a)~") != 0;");
}}
}
}
/*
Encapsulates a Delegate Reflection
*/
class cDelegateReflection : cFunctionReflection
{
override string DType() { return "delegate"; }
auto Reflect(alias T)()
{
super.Reflect!T;
return this;
}
}
/*
Takes a type and builds it's inheritance and uses hierarchy.
*/
auto Reflect(T...)()
{
static foreach(t; ["class", "interface", "struct", "union",
"function", "delegate", "enum"])
mixin("static if (is"~capitalize(t)~"!(T)) { auto model = new
c"~capitalize(t)~"Reflection(); model.Reflect!T(); } ");
return model;
}
auto printModelHierarchy(T, int depth = 1)(T model)
{static if (depth > 20) return "ERROR"; else {
auto res = "";
auto tab = "\t".replicate(depth);
if (model.TypeName == "Object") return "Object";
// Print out basic info, allMembers returns funky as it returns
the most derived first from top to bottom. Generally we want to
display the least derived from top to bottom. Reversing gets us
bottom to top though so we must declare them in reverse order in
the types.
static foreach(k, m; [Reverse!(__traits(allMembers, T))])
{{
static if (!canFind(["factory", "Monitor", "opEquals", "opCmp",
"toHash", "toString", "Reflect"], m)) // Ignore these
{
mixin(`alias Q = TypeOf!(T.`~m~`);`);
static if (isPrimitive!Q || isString!Q) //
Print primitives
mixin(`res ~= tab~m~" =
"~to!string(model.`~m.stringof[1..$-1]~`)~"\n";`);
else static if (__traits(compiles, is(ReturnType!Q == string))
&& is(ReturnType!Q == string)) // Print functions that return
strings
{
mixin(`res ~= tab~m~" =
"~model.`~m.stringof[1..$-1]~`()~"\n";`);
}
else // Print other types
{
static if (is(Q U : U[]) && !is(U == Object)) //
Print Arrays, handling recursion
{{
mixin("auto arr = model."~m~";");
if (arr.length > 0)
{
string[] r;
foreach(a; arr)
{
static if (is(U : cBaseReflection))
r ~= printModelHierarchy!(U, depth + 1)(a).strip("\t\n
,");
else
r ~= to!string(a).strip("\t\n ,");
}
// Prepare results
auto q = r.join(",");
if (q.length > 60 || r.canFind("\n") || r.canFind(","))
static if (is(U : cBaseReflection))
q =
"\n"~tab~"\t"~r.join("\n"~tab~"\t,\n"~tab~"\t")~"\n"~tab;
else
q = "\n"~tab~"\t"~r.join(",\n"~tab~"\t")~"\n"~tab;
res ~= tab~m~" = ["~q~"]\n";
} else res ~= tab~m~" = []\n";
}}
}
}
}}
return res;
}}
mReflect.d-mixin-207(207): Deprecation:
`mModel.cDerived!int.cDerived.testField2` is not visible from
module `mReflect`
mReflect.d-mixin-208(209): Deprecation:
`mModel.cDerived!int.cDerived.testField2` is not visible from
module `mReflect`
Id = cDerived
TypeName = cDerived!int
FullName = mModel.cDerived!(int)
ModuleName = mModel
MangledName = C6mModel__T8cDerivedTiZQm
Protection = public
Body =
Uses = []
Attributes = [
sAttributeReflection("fdsa", "string"),
sAttributeReflection("8", "int")
]
IsNested = false
IsInnerClass = false
HasUnsharedAliasing = true
HasNested = false
HasIndirections = true
HasElaborateDestructor = false
HasElaborateCopyConstructor = false
HasElaborateAssign = false
HasAliasing = true
TypeParameters = []
AliasThis = [sTypeReflection("type", "cType")]
NestedAggregates = []
DerivedClasses = []
Fields = [
Id = type
TypeName = cDerived!int.type
FullName = mModel.cDerived!(int).type
ModuleName = mModel
MangledName = C6mModel__T8cDerivedTiZQm
Protection = public
Body =
Uses = []
Attributes = []
DType = field
,
Id = testField1
TypeName = cDerived!int.testField1
FullName = mModel.cDerived!(int).testField1
ModuleName = mModel
MangledName = C6mModel__T8cDerivedTiZQm
Protection = public
Body =
Uses = []
Attributes = [sAttributeReflection("XXXRRERES", "string")]
DType = field
,
Id = testField2
TypeName = cDerived!int.testField2
FullName = mModel.cDerived!(int).testField2
ModuleName = mModel
MangledName = C6mModel__T8cDerivedTiZQm
Protection = private
Body =
Uses = []
Attributes = [sAttributeReflection("XXXRRERES4", "string")]
DType = field
]
Methods = [
Id = foo
TypeName = int()
FullName = mModel.cDerived!(int).foo
ModuleName = mModel
MangledName = 6mModel__T8cDerivedTiZQm3foo
Protection = public
Body =
Uses = []
Attributes = [sAttributeReflection("A", "string")]
Signature = int()
NumArgs = 0
Linkage = D
ReturnType = int
Parameters = []
DType = delegate
Overloads = []
,
Id = foo
TypeName = pure nothrow @nogc @safe int(int, int)
FullName = mModel.cDerived!(int).foo
ModuleName = mModel
MangledName = 6mModel__T8cDerivedTiZQm3foo
Protection = public
Body =
Uses = []
Attributes = [sAttributeReflection("A", "string")]
Signature = pure nothrow @nogc @safe int(int, int)
NumArgs = 2
Linkage = D
ReturnType = int
Parameters = [
sParameterReflection("", "int", "void", "void",
sStorageClass(false, false, false, false, false, false)),
sParameterReflection("", "int", "void", "void",
sStorageClass(false, false, false, false, false, false))
]
DType = delegate
Overloads = []
,
Id = ValueProp
TypeName = @property int()
FullName = mModel.cDerived!(int).ValueProp
ModuleName = mModel
MangledName = _D6mModel__T8cDerivedTiZQm9ValuePropMFNdZi
Protection = public
Body =
Uses = []
Attributes = [sAttributeReflection("VP att", "string")]
Signature = @property int()
NumArgs = 0
Linkage = D
ReturnType = int
Parameters = []
DType = delegate
Overloads = []
]
InheritedInterfaces = [
Id = iX
TypeName = iX
FullName = mModel.iX
ModuleName = mModel
MangledName = C6mModel2iX
Protection = public
Body =
Uses = []
Attributes = []
IsNested = false
IsInnerClass = false
HasUnsharedAliasing = true
HasNested = false
HasIndirections = true
HasElaborateDestructor = false
HasElaborateCopyConstructor = false
HasElaborateAssign = false
HasAliasing = true
TypeParameters = []
AliasThis = []
NestedAggregates = []
DerivedClasses = []
Fields = [
Id =
TypeName =
FullName =
ModuleName =
MangledName =
Protection =
Body =
Uses = []
Attributes = []
DType = field
]
Methods = []
DType = interface
InheritedInterfaces = []
,
Id = iY
TypeName = iY
FullName = mModel.iY
ModuleName = mModel
MangledName = C6mModel2iY
Protection = public
Body =
Uses = []
Attributes = []
IsNested = false
IsInnerClass = false
HasUnsharedAliasing = true
HasNested = false
HasIndirections = true
HasElaborateDestructor = false
HasElaborateCopyConstructor = false
HasElaborateAssign = false
HasAliasing = true
TypeParameters = []
AliasThis = []
NestedAggregates = []
DerivedClasses = []
Fields = [
Id =
TypeName =
FullName =
ModuleName =
MangledName =
Protection =
Body =
Uses = []
Attributes = []
DType = field
]
Methods = []
DType = interface
InheritedInterfaces = []
]
DType = class
IsAbstract = false
Alignment = 8
InheritedClasses = [
Id = cBase
TypeName = cBase
FullName = mModel.cBase
ModuleName = mModel
MangledName = C6mModel5cBase
Protection = public
Body =
Uses = []
Attributes = []
IsNested = false
IsInnerClass = false
HasUnsharedAliasing = true
HasNested = false
HasIndirections = true
HasElaborateDestructor = false
HasElaborateCopyConstructor = false
HasElaborateAssign = false
HasAliasing = true
TypeParameters = []
AliasThis = []
NestedAggregates = []
DerivedClasses = []
Fields = [
Id = testField
TypeName = cBase.testField
FullName = mModel.cBase.testField
ModuleName = mModel
MangledName = C6mModel5cBase
Protection = public
Body =
Uses = []
Attributes = []
DType = field
]
Methods = [
Id = fooBase
TypeName = cBase(iBase)
FullName = mModel.cBase.fooBase
ModuleName = mModel
MangledName = _D6mModel5cBase7fooBaseMFCQy5iBaseZCQBiQBe
Protection = public
Body =
Uses = []
Attributes = []
Signature = cBase(iBase)
NumArgs = 1
Linkage = D
ReturnType = cBase
Parameters = [
sParameterReflection("", "iBase", "void", "void",
sStorageClass(false, false, false, false, false, false))
]
DType = delegate
Overloads = []
]
InheritedInterfaces = [
Id = iBase
TypeName = iBase
FullName = mModel.iBase
ModuleName = mModel
MangledName = C6mModel5iBase
Protection = public
Body =
Uses = []
Attributes = [
sAttributeReflection("fdsa", "string"),
sAttributeReflection("4", "int")
]
IsNested = false
IsInnerClass = false
HasUnsharedAliasing = true
HasNested = false
HasIndirections = true
HasElaborateDestructor = false
HasElaborateCopyConstructor = false
HasElaborateAssign = false
HasAliasing = true
TypeParameters = []
AliasThis = []
NestedAggregates = []
DerivedClasses = []
Fields = [
Id =
TypeName =
FullName =
ModuleName =
MangledName =
Protection =
Body =
Uses = []
Attributes = []
DType = field
]
Methods = [
Id = fooBase
TypeName = iBase(iBase)
FullName = mModel.iBase.fooBase
ModuleName = mModel
MangledName = _D6mModel5iBase7fooBaseMFCQyQtZQg
Protection = public
Body =
Uses = []
Attributes = []
Signature = iBase(iBase)
NumArgs = 1
Linkage = D
ReturnType = iBase
Parameters = [
sParameterReflection("", "iBase", "void", "void",
sStorageClass(false, false, false, false, false, false))
]
DType = delegate
Overloads = []
]
DType = interface
InheritedInterfaces = []
]
DType = class
IsAbstract = false
Alignment = 4
InheritedClasses = [Object]
]
Id = foo
TypeName =
FullName = main.foo
ModuleName = main
MangledName = _D4main3fooFiKdfZv
Protection = public
Body =
Uses = []
Attributes = [
sAttributeReflection("attr!string(\"test\", 432)",
"attr!string"),
sAttributeReflection("4", "int")
]
DType = function
Signature = void(int x, ref double y, float z = 43234.3F)
NumArgs = 3
Linkage = D
ReturnType = void
Parameters = [
sParameterReflection("x", "int", "void", "void",
sStorageClass(false, false, false, false, false, false)),
sParameterReflection("y", "double", "void", "void",
sStorageClass(false, false, false, true, false, false)),
sParameterReflection("z", "float", "43234.3F", "float",
sStorageClass(false, false, false, false, false, false))
]
Id = eEnum
TypeName = eEnum
FullName = mModel.eEnum
ModuleName = mModel
MangledName = E6mModel5eEnum
Protection = public
Body =
Uses = []
Attributes = [sAttributeReflection("4", "int")]
DType = enum
BaseType = long
Values = [
sValueReflection("X", "cast(eEnum)0L", []),
sValueReflection("Y", "cast(eEnum)43L", []),
sValueReflection("Z", "cast(eEnum)4L",
[sAttributeReflection("sdfdsa", "string"),
sAttributeReflection("3", "int")])
]
If one looks at the overloads issue, we have:
Methods = [
Id = foo
TypeName = int()
FullName = mModel.cDerived!(int).foo
ModuleName = mModel
MangledName = 6mModel__T8cDerivedTiZQm3foo
Protection = public
Attributes = [sAttributeReflection("A", "string")]
Signature = int()
NumArgs = 0
Linkage = D
ReturnType = int
Parameters = []
DType = delegate
Overloads = []
,
Id = foo
TypeName = pure nothrow @nogc @safe int(int, int)
FullName = mModel.cDerived!(int).foo
ModuleName = mModel
MangledName = 6mModel__T8cDerivedTiZQm3foo
Protection = public
Attributes = [sAttributeReflection("A", "string")]
Signature = pure nothrow @nogc @safe int(int, int)
NumArgs = 2
Linkage = D
ReturnType = int
Parameters = [
sParameterReflection("", "int", "void", "void",
sStorageClass(false, false, false, false, false, false)),
sParameterReflection("", "int", "void", "void",
sStorageClass(false, false, false, false, false, false))
]
DType = delegate
Overloads = []
,
and
Id = foo
TypeName =
FullName = main.foo
ModuleName = main
MangledName = _D4main3fooFiKdfZv
Protection = public
Attributes = [
sAttributeReflection("attr!string(\"test\", 432)",
"attr!string"),
sAttributeReflection("4", "int")
]
DType = function
Signature = void(int x, ref double y, float z = 43234.3F)
NumArgs = 3
Linkage = D
ReturnType = void
Parameters = [
sParameterReflection("x", "int", "void", "void",
sStorageClass(false, false, false, false, false, false)),
sParameterReflection("y", "double", "void", "void",
sStorageClass(false, false, false, true, false, false)),
sParameterReflection("z", "float", "43234.3F", "float",
sStorageClass(false, false, false, false, false, false))
]
I'm having to do a trick to make things work here by using the
method to fill in some information and the overload to fill in
the rest... But regardless the overloads are not returning
Parameter names while the function does(yet it is the exact same
code. This might be a bug in the compiler.
sParameterReflection("", "int", "void", "void",
sStorageClass(false, false, false, false, false, false)),
The first element should be x but is empty. For the local
function it gives "x" which is valid. Same code but fails for
methods.
Another issue is that the protection is wrong for the overload...
mainly because getting the protection of an overload fails.
I will mess with it some more later, it is at least not as bad as
I thought but requires a bit of work to get everything to fall in
place. Would be nice to know though what is going on with the
overloads and why the protection is failing to return the correct
value.
There might be other subtle issues but something is amiss. I have
tried to generalize the code as much as possible and it is much
closer than it as before. Many of the same problems still
exist(protection warnings, field typing, etc).
More information about the Digitalmars-d
mailing list