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