1 module it.expansion;
2 
3 
4 import it;
5 import common: printChildren, shouldMatch;
6 import dpp.expansion;
7 import clang: parse, TranslationUnit, Cursor, Type;
8 import std.conv: text;
9 import std.array: join;
10 import std.algorithm: map;
11 
12 
13 @("namespace")
14 @safe unittest {
15 
16 
17     auto tu = () {
18 
19         with(immutable IncludeSandbox()) {
20             writeFile(
21                 "foo.cpp",
22                 q{
23                     int globalInt;
24 
25                     namespace outer1 {
26                         namespace inner1 {
27                             struct Foo;
28                             struct Bar;
29 
30                             struct Baz {
31                                 int i;
32                                 double d;
33                             };
34                         }
35                     }
36 
37                     namespace outer2 {
38                         struct Quux { };
39                     }
40 
41                     namespace outer1 {
42                         namespace inner1 {
43                             struct Foo {
44                                 int i;
45                             };
46 
47                             struct Bar {
48                                 double d;
49                             };
50                         }
51                     }
52                 });
53 
54             return parse(inSandboxPath("foo.cpp"));
55         }
56     }();
57 
58     const cursors = canonicalCursors(tu);
59     writelnUt(cursors.map!text.join("\n"));
60     cursors.length.should == 3;
61 
62     const globalInt = cursors[0];
63     globalInt.shouldMatch(Cursor.Kind.VarDecl, "globalInt");
64 
65     const outer1 = cursors[1];
66     outer1.shouldMatch(Cursor.Kind.Namespace, "outer1");
67     printChildren(outer1);
68     outer1.children.length.should == 1;
69 
70     const inner1 = outer1.children[0];
71     inner1.shouldMatch(Cursor.Kind.Namespace, "inner1");
72     printChildren(inner1);
73     inner1.children.length.should == 3;
74     inner1.children.map!(a => a.spelling).shouldBeSameSetAs(["Foo", "Bar", "Baz"]);
75 
76     const outer2 = cursors[2];
77     outer2.shouldMatch(Cursor.Kind.Namespace, "outer2");
78     printChildren(outer2);
79     outer2.children.length.should == 1;
80 
81     const quux = outer2.children[0];
82     quux.shouldMatch(Cursor.Kind.StructDecl, "Quux");
83 }
84 
85 
86 @("issue113")
87 @safe unittest {
88 
89     auto tu = () {
90         with(immutable Sandbox()) {
91             writeFile(
92                 "foo.cpp",
93                 q{
94                     namespace ns1 {
95                         namespace ns2 {
96                             struct Struct;
97 
98                             template<typename T>
99                                 struct Template {
100                             };
101 
102                             class Class;  // should be ignored but isn't
103                             class Class: public Template<Struct> {
104                                 int i;
105                             };
106                         }
107                     }
108                 });
109 
110             return parse(inSandboxPath("foo.cpp"));
111         }
112     }();
113 
114     const cursors = canonicalCursors(tu);
115     writelnUt(cursors.map!text.join("\n"));
116     cursors.length.should == 1;
117 
118     const ns1 = cursors[0];
119     ns1.shouldMatch(Cursor.Kind.Namespace, "ns1");
120     printChildren(ns1);
121     ns1.children.length.should == 1;
122 
123     const ns2 = ns1.children[0];
124     ns2.shouldMatch(Cursor.Kind.Namespace, "ns2");
125     printChildren(ns2);
126     ns2.children.map!(a => a.spelling).shouldBeSameSetAs(["Struct", "Template", "Class"]);
127     ns2.children.length.should == 3;
128 }