TDME2  1.9.200
createminiscriptdocumentation-main.cpp
Go to the documentation of this file.
1 #include <memory>
2 #include <map>
3 #include <set>
4 #include <string>
5 #include <unordered_map>
6 #include <unordered_set>
7 #include <utility>
8 #include <vector>
9 
10 #include <tdme/tdme.h>
13 #include <tdme/engine/Version.h>
15 #include <tdme/utilities/Console.h>
19 
20 using std::make_pair;
21 using std::make_unique;
22 using std::map;
23 using std::pair;
24 using std::set;
25 using std::string;
26 using std::unordered_map;
27 using std::unordered_set;
28 using std::vector;
29 
38 
39 namespace tdme {
40 namespace tools {
41 namespace cli {
43 public:
44 static void generateMiniScriptMethodsDocumentation(const string& heading, int mainHeadingIdx, EngineMiniScript* miniScript, Properties& descriptions, const string& descriptionPrefix, unordered_set<string>& categories, const set<string>& allClassMethods, EngineMiniScript* omitMiniScript = nullptr) {
45  auto scriptMethods = miniScript->getMethods();
46  map<string, vector<pair<string, string>>> methodMarkupByCategory;
47  for (auto scriptMethod: scriptMethods) {
48  if (omitMiniScript != nullptr && omitMiniScript->hasMethod(scriptMethod->getMethodName()) == true) continue;
49  if (allClassMethods.find(scriptMethod->getMethodName()) != allClassMethods.end()) continue;
50  string result;
51  string category;
52  if (scriptMethod->getMethodName().rfind('.') != string::npos) category = StringTools::substring(scriptMethod->getMethodName(), 0, scriptMethod->getMethodName().rfind('.'));
53  string description;
54  description+= "| ";
55  description+= descriptions.get(descriptionPrefix + scriptMethod->getMethodName(), "Not documented");
56  if (scriptMethod->getContextFunctions().empty() == false) {
57  string contextFunctions;
58  for (const auto& contextFunction: scriptMethod->getContextFunctions()) {
59  if (contextFunctions.empty() == false) contextFunctions+= ", ";
60  contextFunctions+= contextFunction + "()";
61  }
62  description+= " - <i>available in " + contextFunctions + "</i>";
63  }
64  while (description.size() < 99) description+= " ";
65  description+= "|";
66  result+= description + "\n";
67  string method;
68  method+= "| <sub>";
69  method+= scriptMethod->getMethodName();
70  method+= "(";
71  method+= scriptMethod->getArgumentsInformation();
72  method+= "): ";
73  method+= EngineMiniScript::ScriptVariable::getReturnTypeAsString(scriptMethod->getReturnValueType(), scriptMethod->isReturnValueNullable());
74  method+= "</sub>";
75  while (method.size() < 99) method+= " ";
76  method+= "|";
77  method+= "\n";
78  result+= method;
79  methodMarkupByCategory[category].push_back(make_pair(scriptMethod->getMethodName(), result));
80  }
81  // collect categories
82  for (const auto& [category, methodMarkup]: methodMarkupByCategory) {
83  categories.insert(category);
84  }
85  //
86  map<string, vector<string>> methodMarkupByCategory2;
87  for (const auto& [category, methods]: methodMarkupByCategory) {
88  if (category.empty() == true) continue;
89  for (const auto& [methodName, methodMarkup]: methods) {
90  methodMarkupByCategory2[category].push_back(methodMarkup);
91  }
92  }
93  {
94  auto emptyCategoryMethodsIt = methodMarkupByCategory.find(string());
95  if (emptyCategoryMethodsIt != methodMarkupByCategory.end()) {
96  const auto& methods = emptyCategoryMethodsIt->second;
97  for (const auto& [methodName, methodMarkup]: methods) {
98  if (categories.contains(methodName) == true) {
99  methodMarkupByCategory2[methodName].insert(methodMarkupByCategory2[methodName].begin(), methodMarkup);
100  } else {
101  methodMarkupByCategory2[string()].push_back(methodMarkup);
102  }
103  }
104  }
105  }
106  Console::println();
107  Console::println("# " + to_string(mainHeadingIdx) + ". " + heading);
108  auto categoryIdx = 1;
109  for (const auto& [category, methodsMarkup]: methodMarkupByCategory2) {
110  auto categoryName = descriptions.get(descriptionPrefix + "group." + (category.empty() == true?"uncategorized":category), "Not documented");
111  Console::println();
112  Console::println("## " + to_string(mainHeadingIdx) + "." + to_string(categoryIdx++) + " " + categoryName);
113  Console::println();
114  Console::println("| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Table of methods &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |");
115  Console::println("|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|");
116  for (const auto& methodMarkup: methodsMarkup) Console::print(methodMarkup);
117  }
118 }
119 
120 static void generateMiniScriptClassesDocumentation(const string& heading, int mainHeadingIdx, EngineMiniScript* miniScript, Properties& descriptions, const string& descriptionPrefix, set<string>& allClassMethods) {
121  auto scriptMethods = miniScript->getMethods();
122  //
123  for (auto typeIdx = static_cast<int>(EngineMiniScript::TYPE_STRING); typeIdx <= static_cast<int>(EngineMiniScript::TYPE_SET); typeIdx++) {
124  const auto& className = EngineMiniScript::ScriptVariable::getClassName(static_cast<EngineMiniScript::ScriptVariableType>(typeIdx));
125  allClassMethods.insert(className);
126  }
127  //
128  for (auto scriptMethod: scriptMethods) {
129  string className;
130  if (scriptMethod->getMethodName().rfind('.') != string::npos) className = StringTools::substring(scriptMethod->getMethodName(), 0, scriptMethod->getMethodName().rfind('.'));
131  if (className.empty() == true && allClassMethods.find(scriptMethod->getMethodName()) == allClassMethods.end()) continue;
132  //
133  auto _class = false;
134  for (auto typeIdx = static_cast<int>(EngineMiniScript::TYPE_STRING); typeIdx <= static_cast<int>(EngineMiniScript::TYPE_SET); typeIdx++) {
135  if (EngineMiniScript::ScriptVariable::getClassName(static_cast<EngineMiniScript::ScriptVariableType>(typeIdx)) == className) {
136  _class = true;
137  break;
138  }
139  }
140  if (_class == false) continue;
141  //
142  string method =
143  StringTools::substring(
144  scriptMethod->getMethodName(),
145  className.empty() == true?0:className.size() + 1,
146  scriptMethod->getMethodName().size());
147  // no arguments or no "this" argument
148  auto _static =
149  scriptMethod->getArgumentTypes().empty() == true ||
150  scriptMethod->getArgumentTypes()[0].name != className ||
151  EngineMiniScript::ScriptVariable::getClassName(scriptMethod->getArgumentTypes()[0].type) != className;
152  //
153  allClassMethods.insert(scriptMethod->getMethodName());
154  }
155  //
156  map<string, array<map<string, string>, 2>> methodMarkupByClassName;
157  for (auto scriptMethod: scriptMethods) {
158  //
159  if (allClassMethods.find(scriptMethod->getMethodName()) == allClassMethods.end()) continue;
160  //
161  string result;
162  string className;
163  if (scriptMethod->getMethodName().rfind('.') != string::npos) className = StringTools::substring(scriptMethod->getMethodName(), 0, scriptMethod->getMethodName().rfind('.'));
164  // constructors
165  auto _static = false;
166  if (className.empty() == true) {
167  for (auto typeIdx = static_cast<int>(EngineMiniScript::TYPE_STRING); typeIdx <= static_cast<int>(EngineMiniScript::TYPE_SET); typeIdx++) {
168  const auto& possibleClassName = EngineMiniScript::ScriptVariable::getClassName(static_cast<EngineMiniScript::ScriptVariableType>(typeIdx));
169  if (scriptMethod->getMethodName() == possibleClassName) {
170  className = possibleClassName;
171  _static = true;
172  break;
173  }
174  }
175  }
176  //
177  if (_static == false) {
178  _static =
179  scriptMethod->getArgumentTypes().empty() == true ||
180  scriptMethod->getArgumentTypes()[0].name != className ||
181  EngineMiniScript::ScriptVariable::getClassName(scriptMethod->getArgumentTypes()[0].type) != className;
182  }
183  //
184  string description;
185  description+= "| ";
186  description+= descriptions.get(descriptionPrefix + scriptMethod->getMethodName(), "Not documented");
187  while (description.size() < 99) description+= " ";
188  description+= "|";
189  result+= description + "\n";
190  string method;
191  method+= "| <sub>";
192  if (_static == true) {
193  method+= "<b>static</b> ";
194  }
195  method+= _static == true?scriptMethod->getMethodName():StringTools::substring(scriptMethod->getMethodName(), className.size() + 1, scriptMethod->getMethodName().size());
196  method+= "(";
197  method+= scriptMethod->getArgumentsInformation(_static == true?0:1);
198  method+= "): ";
199  method+= EngineMiniScript::ScriptVariable::getReturnTypeAsString(scriptMethod->getReturnValueType(), scriptMethod->isReturnValueNullable());
200  method+= "</sub>";
201  while (method.size() < 99) method+= " ";
202  method+= "|";
203  method+= "\n";
204  result+= method;
205  methodMarkupByClassName[className][_static == true?0:1][scriptMethod->getMethodName()] = result;
206  }
207  //
208  auto classIdx = 1;
209  for (auto typeIdx = static_cast<int>(EngineMiniScript::TYPE_STRING); typeIdx <= static_cast<int>(EngineMiniScript::TYPE_SET); typeIdx++) {
210  const auto& className = EngineMiniScript::ScriptVariable::getClassName(static_cast<EngineMiniScript::ScriptVariableType>(typeIdx));
211  auto classNameDescription = descriptions.get("miniscript.baseclass." + (className.empty() == true?"No class":className), "Not documented");
212  //
213  Console::println();
214  Console::println("## " + to_string(mainHeadingIdx) + "." + to_string(classIdx++) + " " + classNameDescription);
215  Console::println();
216  //
217  for (auto staticIdx = 0; staticIdx < 2; staticIdx++) {
218  //
219  if (methodMarkupByClassName[className][staticIdx].empty() == true) continue;
220  //
221  if (staticIdx == 0) {
222  Console::println("| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Table of methods &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |");
223  Console::println("|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|");
224  Console::println("| &nbsp; |");
225  Console::println("| <b>STATIC METHODS</b> |");
226  } else {
227  Console::println("| &nbsp; |");
228  Console::println("| <b>NON STATIC METHODS</b> |");
229  }
230  //
231  for (const auto& [method, methodMarkup]: methodMarkupByClassName[className][staticIdx]) {
232  Console::print(methodMarkup);
233  }
234  }
235  }
236 }
237 
238 };
239 };
240 };
241 };
242 
243 int main(int argc, char** argv)
244 {
245  Console::println(string("createminiscriptdocumentation ") + Version::getVersion());
246  Console::println(Version::getCopyright());
247  Console::println();
248 
249  Properties descriptions;
250  descriptions.load("resources/engine/code-completion", "tscript-methods.properties");
251 
252  //
253  EngineMiniScript::registerDataTypes();
254 
255  //
256  auto baseMiniScript = make_unique<EngineMiniScript>();
257  baseMiniScript->registerMethods();
258 
259  //
260  auto logicMiniScript = make_unique<LogicMiniScript>();
261  logicMiniScript->registerMethods();
262 
263  //
264  auto guiMiniScript = make_unique<GUIMiniScript>(nullptr);
265  guiMiniScript->registerMethods();
266 
267  //
268  unordered_set<string> baseClassesCategories;
269  unordered_set<string> baseMethodCategories;
270  unordered_set<string> logicMethodCategories;
271  unordered_set<string> guiMethodCategories;
272 
273  set<string> allClassMethods;
274  // classes
275  tdme::tools::cli::MiniscriptDocumentation::generateMiniScriptClassesDocumentation("EngineMiniScript Classes", 6, baseMiniScript.get(), descriptions, "miniscript.basemethod.", allClassMethods);
276  // base methods
277  tdme::tools::cli::MiniscriptDocumentation::generateMiniScriptMethodsDocumentation("EngineMiniScript Base Methods", 7, baseMiniScript.get(), descriptions, "miniscript.basemethod.", baseMethodCategories, allClassMethods);
278  // logic methods
279  tdme::tools::cli::MiniscriptDocumentation::generateMiniScriptMethodsDocumentation("EngineMiniScript Logic Methods", 8, logicMiniScript.get(), descriptions, "miniscript.logicmethod.", logicMethodCategories, allClassMethods, baseMiniScript.get());
280  // gui methods
281  tdme::tools::cli::MiniscriptDocumentation::generateMiniScriptMethodsDocumentation("EngineMiniScript GUI Methods", 9, guiMiniScript.get(), descriptions, "miniscript.", guiMethodCategories, allClassMethods, baseMiniScript.get());
282 
283  // operators
284  auto scriptOperatorMethods = baseMiniScript->getOperatorMethods();
285  vector<string> operators;
286  for (auto scriptMethod: scriptOperatorMethods) {
287  string operatorString;
288  operatorString = "| ";
289  operatorString+= StringTools::replace(EngineMiniScript::getOperatorAsString(scriptMethod->getOperator()), "|", "\\|");
290  while (operatorString.size() < 5) operatorString+= " ";
291  operatorString+= "| ";
292  operatorString+= scriptMethod->getMethodName();
293  operatorString+= "(";
294  operatorString+= scriptMethod->getArgumentsInformation();
295  operatorString+= "): ";
296  operatorString+= EngineMiniScript::ScriptVariable::getReturnTypeAsString(scriptMethod->getReturnValueType(), scriptMethod->isReturnValueNullable());
297  while (operatorString.size() < 99) operatorString+= " ";
298  operatorString+= "|";
299  operators.push_back(operatorString);
300  }
301  sort(operators.begin(), operators.end());
302  Console::println();
303  Console::println("# 10. Operators");
304  Console::println();
305  Console::println("| Op | Method |");
306  Console::println("|----|---------------------------------------------------------------------------------------------|");
307  for (const auto& method: operators) Console::println(method);
308 
309  //
310  Console::println();
311  Console::println("# properties methodname=human readable string");
312  //
313  {
314  Console::println("# base methods");
315  //
316  for (const auto& baseMethodCategory: baseMethodCategories) {
317  Console::println("miniscript.basemethod.group." + (baseMethodCategory.empty() == true?"uncategorized":baseMethodCategory) + "=");
318  }
319  //
320  auto scriptMethods = baseMiniScript->getMethods();
321  for (auto scriptMethod: scriptMethods) {
322  Console::println("miniscript.basemethod." + scriptMethod->getMethodName() + "=");
323  }
324  }
325  {
326  Console::println("# miniscript logic methods");
327  //
328  for (const auto& logicMethodCategory: logicMethodCategories) {
329  Console::println("miniscript.logicmethod.group." + (logicMethodCategory.empty() == true?"uncategorized":logicMethodCategory) + "=");
330  }
331  //
332  auto scriptMethods = logicMiniScript->getMethods();
333  for (auto scriptMethod: scriptMethods) {
334  if (baseMiniScript->hasMethod(scriptMethod->getMethodName()) == true) continue;
335  Console::println("miniscript.logicmethod." + scriptMethod->getMethodName() + "=");
336  }
337  }
338  {
339  Console::println("# miniscript gui methods");
340  //
341  for (const auto& guiMethodCategory: guiMethodCategories) {
342  Console::println("miniscript.group." + (guiMethodCategory.empty() == true?"uncategorized":guiMethodCategory) + "=");
343  }
344  //
345  auto scriptMethods = guiMiniScript->getMethods();
346  for (auto scriptMethod: scriptMethods) {
347  if (baseMiniScript->hasMethod(scriptMethod->getMethodName()) == true) continue;
348  Console::println("miniscript." + scriptMethod->getMethodName() + "=");
349  }
350  }
351 
352  //
353  Console::println();
354  Console::println("Keywords: ");
355  set<string> allMethods;
356  {
357  //
358  auto scriptMethods = baseMiniScript->getMethods();
359  for (auto scriptMethod: scriptMethods) {
360  allMethods.insert(scriptMethod->getMethodName());
361  }
362  }
363  {
364  //
365  auto scriptMethods = logicMiniScript->getMethods();
366  for (auto scriptMethod: scriptMethods) {
367  allMethods.insert(scriptMethod->getMethodName());
368  }
369  }
370  {
371  //
372  auto scriptMethods = guiMiniScript->getMethods();
373  for (auto scriptMethod: scriptMethods) {
374  allMethods.insert(scriptMethod->getMethodName());
375  }
376  }
377  //
378  for (const auto& method: allMethods) {
379  Console::print(method + " ");
380  }
381  Console::println();
382 
383  //
384  Application::exit(Application::EXITCODE_SUCCESS);
385 }
Application base class, please make sure to allocate application on heap to have correct application ...
Definition: Application.h:41
static void generateMiniScriptClassesDocumentation(const string &heading, int mainHeadingIdx, EngineMiniScript *miniScript, Properties &descriptions, const string &descriptionPrefix, set< string > &allClassMethods)
static void generateMiniScriptMethodsDocumentation(const string &heading, int mainHeadingIdx, EngineMiniScript *miniScript, Properties &descriptions, const string &descriptionPrefix, unordered_set< string > &categories, const set< string > &allClassMethods, EngineMiniScript *omitMiniScript=nullptr)
Console class.
Definition: Console.h:29
Properties class, which helps out with storeing or loading key value pairs from/to property files.
Definition: Properties.h:23
const string & get(const string &key, const string &defaultValue) const
Get property value by key.
Definition: Properties.h:46
void load(const string &pathName, const string &fileName, FileSystemInterface *fileSystem=nullptr)
Load property file.
Definition: Properties.cpp:24
String tools class.
Definition: StringTools.h:22
int main(int argc, char **argv)
Definition: fwd-tdme.h:4