-
Notifications
You must be signed in to change notification settings - Fork 2
/
ToMono.cpp
104 lines (97 loc) · 3.17 KB
/
ToMono.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//
// Created by koncord on 20.01.19.
//
#include <sstream>
#include <iostream>
#include "Parser.hpp"
#include "Utils.hpp"
#include "ToMono.hpp"
static std::string CTypeToMono(const Parser &data, CXType type)
{
switch(type.kind)
{
case CXType_Void:
return "void";
case CXType_Bool:
return "bool";
case CXType_Char_U:
case CXType_UChar:
return "byte";
case CXType_Char_S:
case CXType_SChar:
return "sbyte";
case CXType_Short:
return "short";
case CXType_UShort:
return "ushort";
case CXType_Int:
return "int";
case CXType_UInt:
return "uint";
case CXType_Long:
return "long";
case CXType_ULong:
return "ulong";
case CXType_Float:
return "float";
case CXType_Double:
return "double";
case CXType_Pointer:
{
CXType popinteeType = clang_getPointeeType(type);
//bool isConst = clang_isConstQualifiedType(popinteeType);
if (popinteeType.kind == CXType_Char_S || popinteeType.kind == CXType_SChar)
return "string";
else
return "IntPtr";
//throw std::runtime_error("Pointer of \"" + GetCXXString(clang_getTypeSpelling(popinteeType)) + "\" not supported.");
}
case CXType_Typedef: // todo: not the best way.
{
std::string typeName = GetCXXString(clang_getTypeSpelling(type));
if (typeName == "bool") // since headers written on C, and bool type defined in C as uint_8, we need special handler for it
return "bool";
return CTypeToMono(data, data.GetTypeDef(typeName));
}
default:
return "object";
}
}
static std::string indent(int level)
{
std::string out;
for (;level--;)
out += " ";
return out;
}
std::ostream &ToMono::Serialize(std::ostream &out) const
{
out << "using System.Runtime.InteropServices;\n\n"
<< "namespace " << parser.GetNamespace() << "\n{\n"
<< indent(1) << "public static partial class " << parser.GetModule() << "\n" << indent(1) << "{\n";
for (const auto &decl : parser.GetTokens())
{
std::stringstream ss;
std::string retType = CTypeToMono(parser, decl.retType);
bool haveStrings = retType == "string";
ss << "public static extern " << retType << " " << decl.declName << "(";
const auto endIt = decl.args.end();
for (auto it = decl.args.begin(); it != endIt; ++it)
{
std::string type = CTypeToMono(parser, it->type);
if (!haveStrings)
haveStrings = type == "string";
ss << type << " " << it->name;
if (std::next(it) != endIt)
ss << ", ";
}
ss << ");\n\n";
if (haveStrings)
out << indent(2) << "[DllImport(\"__Internal\", CharSet = CharSet.Ansi)]\n";
else
out << indent(2) << "[DllImport(\"__Internal\"]\n";
out << indent(2) << ss.str();
}
out << indent(1) << "}\n}";
return out;
}