1 module dpp.translation.namespace;
2 
3 
4 import dpp.from;
5 
6 
7 string[] translateNamespace(in from!"clang".Cursor cursor,
8                             ref from!"dpp.runtime.context".Context context)
9     @safe
10     in(cursor.kind == from!"clang".Cursor.Kind.Namespace)
11     do
12 {
13     import dpp.translation.translation: translate;
14     import dpp.translation.exception: UntranslatableException;
15     import clang: Cursor;
16     import std.conv: text;
17     import std.algorithm: map, startsWith;
18     import std.array: array;
19 
20     if(shouldSkip(cursor.spelling, context))
21         return [];
22 
23     if(cursor.spelling == "")
24         throw new UntranslatableException("BUG: namespace with no name");
25 
26     string[] lines;
27 
28     lines ~= [
29             `extern(C++, "` ~ cursor.spelling ~ `")`,
30             `{`,
31     ];
32 
33     context.pushNamespace(cursor.spelling);
34     scope(exit) context.popNamespace(cursor.spelling);
35 
36     foreach(child; cursor.children) {
37 
38         if(child.kind == Cursor.Kind.VisibilityAttr) continue;
39         if(cursor.spelling == "std" && child.spelling.startsWith("__")) continue;
40 
41         lines ~= translate(child, context)
42             .map!(a => (child.kind == Cursor.Kind.Namespace ? "    " : "        ") ~ a)
43             .array;
44     }
45 
46     lines ~= `}`;
47 
48     return lines;
49 }
50 
51 
52 private bool shouldSkip(in string spelling, in from!"dpp.runtime.context".Context context)
53     @safe pure
54 {
55     import std.algorithm: canFind;
56     return context.options.ignoredNamespaces.canFind(spelling);
57 }