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 : FileName;
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     static auto make() {
44         return ImplData(CppRoot.make);
45     }
46 }
47 
48 struct IgnoreSymbol {
49     FullyQualifiedNameType payload;
50     alias payload this;
51 }
52 
53 struct Code {
54     enum Kind {
55         main,
56         fuzzy,
57         configTemplate,
58     }
59 
60     CppModule cpp;
61     ubyte[] fuzzyData;
62 }
63 
64 /** Encapsulate the xml data that is used to generate the prettified string to
65  * be written to the filesystem.
66  *
67  * Responsible for storing the xml-data and stringification.
68  * Nothing else.
69  */
70 struct TemplateConfig {
71     import std.xml : Document, Element;
72 
73     @disable this(this);
74 
75     Document doc;
76     Element symbols;
77 
78     static auto make() @trusted {
79         import std.xml;
80         import dextool.utility : dextoolVersion;
81 
82         TemplateConfig r;
83         r.doc = new Document(new Tag("dextool"));
84         r.doc.tag.attr["version"] = dextoolVersion;
85         r.symbols = new Element("symbols");
86         r.doc ~= r.symbols;
87         return r;
88     }
89 
90     /// TODO change to @safe when the base compiler is upgraded to 2.074+
91     Element makeSymbol() @trusted {
92         auto elem = new Element("symbol");
93         symbols ~= elem;
94         return elem;
95     }
96 
97     void put(T)(ref T app) {
98         import std.algorithm : joiner, copy;
99         import dextool.xml : makePrelude;
100 
101         makePrelude(app);
102         () @trusted{ doc.pretty(4).joiner("\n").copy(app); }();
103     }
104 }
105 
106 struct GeneratedData {
107     @disable this(this);
108 
109     Code[Code.Kind] data;
110     TemplateConfig templateConfig;
111     FuzzCase[] fuzzCases;
112 
113     /// TODO change to a template to be able to handle making _any_ kind of _data_.
114     auto make(Code.Kind kind) {
115         if (auto c = kind in data) {
116             return *c;
117         }
118 
119         Code m;
120 
121         final switch (kind) {
122         case Code.Kind.main:
123             m.cpp = new CppModule;
124             break;
125         case Code.Kind.fuzzy:
126             m.cpp = new CppModule;
127             break;
128         case Code.Kind.configTemplate:
129             templateConfig = TemplateConfig.make;
130             break;
131         }
132 
133         data[kind] = m;
134         return m;
135     }
136 }
137 
138 struct FuzzCase {
139     /// the root of the file content.
140     CppModule cpp;
141     /// Includes are placed here, before the content of the body
142     CppModule includes;
143     /// The inside of the generated FUZZ_TEST(...) {... }
144     CppModule body_;
145     FileName filename;
146     ulong testCaseId;
147 }
148 
149 struct DextoolHelperRawData {
150     string payload;
151     alias payload this;
152 }
153 
154 struct Prefix {
155     string payload;
156     alias payload this;
157 }
158 
159 struct DextoolHelperFile {
160     string payload;
161     alias payload this;
162 }