describeCallable

Describes a callable

describeCallable
(
size_t overloadIndex = 0
)
()
if (
isCallable!T
)

Examples

It should describe a function with no params that returns void

void test() { }

auto result = describeCallable!test;

result.name.should.equal("test");
result.type.name.should.equal("pure nothrow @nogc @safe void()");
result.returns.name.should.equal("void");
result.parameters.length.should.equal(0);
result.location.file.should.equal("source/introspection/callable.d");
result.location.line.should.be.greaterThan(0);
result.location.column.should.equal(8);
result.variadicStyle.should.equal(Variadic.no);

It should describe a function with variadic args

void test(char c, ...) { }

auto result = describeCallable!test;

result.parameters.length.should.equal(1);
result.parameters[0].name.should.equal("c");
result.parameters[0].type.name.should.equal("char");

result.variadicStyle.should.equal(Variadic.d);

It should describe a function with no params that returns ref int

int val = 0;
ref int test() { return val; }

auto result = describeCallable!test;

result.name.should.equal("test");
result.type.name.should.equal("pure nothrow @nogc ref @safe int()");
result.returns.name.should.equal("int");
result.parameters.length.should.equal(0);

It should describe a function with a parameter without a default value

int val = 0;
ref int test(string a) { return val; }

auto result = describeCallable!test;

result.parameters.length.should.equal(1);
result.parameters[0].name.should.equal("a");
result.parameters[0].type.name.should.equal("string");
result.parameters[0].default_.value.should.equal("");
result.parameters[0].default_.exists.should.equal(false);

It should describe a function with a parameter with a default value

int val = 0;
ref int test(string a = "test") { return val; }

auto result = describeCallable!test;

result.parameters.length.should.equal(1);
result.parameters[0].name.should.equal("a");
result.parameters[0].type.name.should.equal("string");
result.parameters[0].default_.value.should.equal(`"test"`);
result.parameters[0].default_.exists.should.equal(true);

result.parameters[0].isLazy.should.equal(false);
result.parameters[0].isScope.should.equal(false);
result.parameters[0].isOut.should.equal(false);
result.parameters[0].isRef.should.equal(false);
result.parameters[0].isReturn.should.equal(false);

It should describe a function attributes

int attr(int) { return 0; }

@("attribute1") @attr(1)
void test() { }

auto result = describeCallable!test;

result.attributes.length.should.equal(6);
result.attributes[0].name.should.equal(`"attribute1"`);
result.attributes[0].type.name.should.equal(`string`);

result.attributes[1].name.should.equal("0");
result.attributes[1].type.name.should.equal(`int`);

result.attributes[2].name.should.equal(`"pure"`);
result.attributes[2].type.name.should.equal(`string`);

result.attributes[3].name.should.equal(`"nothrow"`);
result.attributes[3].type.name.should.equal(`string`);

result.attributes[4].name.should.equal(`"@nogc"`);
result.attributes[4].type.name.should.equal(`string`);

result.attributes[5].name.should.equal(`"@safe"`);
result.attributes[5].type.name.should.equal(`string`);

It should find the parameter storage classes

void test(scope Object, out int, ref int, lazy int, return Object) { }

auto result = describeCallable!test;

result.parameters[0].isScope.should.equal(true);
result.parameters[1].isOut.should.equal(true);
result.parameters[2].isRef.should.equal(true);
result.parameters[3].isLazy.should.equal(true);
result.parameters[4].isReturn.should.equal(true);

It should describe an aliased function

void test(scope Object, out int, ref int, lazy int, return Object) { }

auto testDescribe(T)(T func){
  return describeCallable!T;
}

auto result = testDescribe(&test);

result.name.should.equal("");
result.parameters[0].isScope.should.equal(true);
result.parameters[1].isOut.should.equal(true);
result.parameters[2].isRef.should.equal(true);
result.parameters[3].isLazy.should.equal(true);
result.parameters[4].isReturn.should.equal(true);

Meta