On 08/26/2011 02:38 PM, Adam Ruppe wrote:
My pet feature request could do this too. User defined attributes
combined with a list of functions called by a function.
===
@custom("mysafe") void foo() {}
void bar() {}
@custom("mysafe") void main() {
foo();
bar();
}
CheckCustomSafety!("mysafe", main);
template CheckCustomSafety(string attribute, alias func) {
static if(!__traits(hasCustomAttribute(func, attribute))
pragma(error, func.stringof ~ " is not " ~ attribute);
foreach(f; __traits(getCalledFunctions, func))
CheckCustomSafety!(attribute, f);
}
====
And throw in an or for trusted.
The reason I want this is to check for things more like custom
purity, but I think it'd work for your custom safety too.
(and user defined attributes are just useful for other things too!)
The biggest problem I see with using my idea is the error
message will probably suck.
I think it could be possible to provide decent error messages, by
providing some means (via traits) to get line and file numbers of the
calls. The biggest problem I see with this design is, that only
functions reachable from main will be checked. I'd rather see something
in the lines of
mysafe.d
__traits(declareCustomAttribute, "mysafe"); // can detect name clash
__traits(declareCustomAttribute, "mytrusted");
__traits(declareCustomAttribute, "mysystem");
__traits(attribSetMutuallyExclusiveWithDefault, ["mysafe",
"mytrusted","mysystem"],"mysystem");
__traits(registerStaticChecker, "mysafe", CheckMysafe);
(the traits could be replaced by better syntax, of course)
and then we could use int main() @mysafe {} which would automatically be
checked.
There should also be some way to parameterize custom attributes, and to
perform code transformations (probably that would require AST-macros and
AST-pattern matching to be nice)
__traits(declareCustomAttribute, "memoized(int=int.max)"); // maximum
size of hash table.
int foo(int x)@memoized(100){ ... } // memoize at most 100 values