1 /**
2 Copyright: Copyright (c) 2017, Joakim Brännström. All rights reserved.
3 License: MPL-2
4 Author: Joakim Brännström (joakim.brannstrom@gmx.com)
5 
6 This Source Code Form is subject to the terms of the Mozilla Public License,
7 v.2.0. If a copy of the MPL was not distributed with this file, You can obtain
8 one at http://mozilla.org/MPL/2.0/.
9 */
10 module dextool.plugin.fuzzer.backend.type;
11 
12 public import cpptooling.data.symbol.types : FullyQualifiedNameType;
13 import cpptooling.data : CppRoot;
14 
15 import dextool.plugin.fuzzer.backend.unique_sequence : Sequence;
16 import dextool.type : Path;
17 
18 import dsrcgen.cpp : CppModule;
19 
20 @safe:
21 
22 /** Analyzed data transformed to implementation.
23  *
24  * The abstraction is still _high_.
25  */
26 struct ImplData {
27     import dextool.plugin.fuzzer.type : Symbol, FullyQualifiedNameType, Param;
28 
29     @disable this(this);
30 
31     /// DOM
32     CppRoot root;
33 
34     /// All symbols specified in the user configuration.
35     Symbol[FullyQualifiedNameType] symbols;
36 
37     /// User specified symbols to ignore.
38     IgnoreSymbol[] excludedSymbols;
39 
40     /// ID's for all symbols, both user specified and newly discovered.
41     ulong[FullyQualifiedNameType] symbolId;
42 }
43 
44 struct IgnoreSymbol {
45     FullyQualifiedNameType payload;
46     alias payload this;
47 }
48 
49 struct Code {
50     enum Kind {
51         main,
52         fuzzy,
53         configTemplate,
54     }
55 
56     CppModule cpp;
57     ubyte[] fuzzyData;
58 }
59 
60 /** Encapsulate the xml data that is used to generate the prettified string to
61  * be written to the filesystem.
62  *
63  * Responsible for storing the xml-data and stringification.
64  * Nothing else.
65  */
66 struct TemplateConfig {
67     import std.xml : Document, Element;
68 
69     @disable this(this);
70 
71     Document doc;
72     Element symbols;
73 
74     static auto make() @trusted {
75         import std.xml;
76         import dextool.utility : dextoolVersion;
77 
78         TemplateConfig r;
79         r.doc = new Document(new Tag("dextool"));
80         r.doc.tag.attr["version"] = dextoolVersion.get;
81         r.symbols = new Element("symbols");
82         r.doc ~= r.symbols;
83         return r;
84     }
85 
86     /// TODO change to @safe when the base compiler is upgraded to 2.074+
87     Element makeSymbol() @trusted {
88         auto elem = new Element("symbol");
89         symbols ~= elem;
90         return elem;
91     }
92 
93     void put(T)(ref T app) {
94         import std.algorithm : joiner, copy;
95         import dextool.xml : makePrelude;
96 
97         makePrelude(app);
98         () @trusted { doc.pretty(4).joiner("\n").copy(app); }();
99     }
100 }
101 
102 struct GeneratedData {
103     @disable this(this);
104 
105     Code[Code.Kind] data;
106     TemplateConfig templateConfig;
107     FuzzCase[] fuzzCases;
108 
109     /// TODO change to a template to be able to handle making _any_ kind of _data_.
110     auto make(Code.Kind kind) {
111         if (auto c = kind in data) {
112             return *c;
113         }
114 
115         Code m;
116 
117         final switch (kind) {
118         case Code.Kind.main:
119             m.cpp = new CppModule;
120             break;
121         case Code.Kind.fuzzy:
122             m.cpp = new CppModule;
123             break;
124         case Code.Kind.configTemplate:
125             templateConfig = TemplateConfig.make;
126             break;
127         }
128 
129         data[kind] = m;
130         return m;
131     }
132 }
133 
134 struct FuzzCase {
135     /// the root of the file content.
136     CppModule cpp;
137     /// Includes are placed here, before the content of the body
138     CppModule includes;
139     /// The inside of the generated FUZZ_TEST(...) {... }
140     CppModule body_;
141     Path filename;
142     ulong testCaseId;
143 }
144 
145 struct DextoolHelperRawData {
146     string payload;
147     alias payload this;
148 }
149 
150 struct Prefix {
151     string payload;
152     alias payload this;
153 }
154 
155 struct DextoolHelperFile {
156     string payload;
157     alias payload this;
158 }