@needle-tools/needle-component-compiler 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMPILE.bat +1 -0
- package/INSTALL.bat +1 -0
- package/RUNTEST.bat +1 -0
- package/Readme.md +7 -0
- package/dist/GltfExport.cs +11 -0
- package/dist/GltfExportBox.cs +11 -0
- package/dist/MyArray.cs +8 -0
- package/dist/MyClass.cs +23 -0
- package/dist/MyClassWithAFloat.cs +10 -0
- package/dist/PrivateSerializedField.cs +9 -0
- package/dist/Test.cs +8 -0
- package/package.json +21 -0
- package/src/component-compiler.js +341 -0
- package/src/component-compiler.ts +362 -0
- package/src/component.cs +1 -0
- package/src/test.ts +97 -0
- package/src/types.js +47 -0
- package/workspace.code-workspace +8 -0
package/COMPILE.bat
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
npm run tsc src/component-compiler
|
package/INSTALL.bat
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
npm install && timeout 10
|
package/RUNTEST.bat
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
npm run tsc src/component-compiler && node src/component-compiler.js dist src/test.ts
|
package/Readme.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// auto generated code - do not edit
|
|
2
|
+
namespace Needle.Typescript.GeneratedComponents
|
|
3
|
+
{
|
|
4
|
+
// source: C:\git\needle-tiny-playground\modules\needle-tiny\component-compiler\src\test.ts
|
|
5
|
+
public class GltfExport : UnityEngine.MonoBehaviour
|
|
6
|
+
{
|
|
7
|
+
public bool @binary = true;
|
|
8
|
+
[UnityEngine.ContextMenu("enable this")]
|
|
9
|
+
public void test(){}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// auto generated code - do not edit
|
|
2
|
+
namespace Needle.Typescript.GeneratedComponents
|
|
3
|
+
{
|
|
4
|
+
// source: C:\git\needle-tiny-playground\modules\needle-tiny\component-compiler\src\test.ts
|
|
5
|
+
public class GltfExportBox : UnityEngine.MonoBehaviour
|
|
6
|
+
{
|
|
7
|
+
public UnityEngine.Transform @sceneRoot;
|
|
8
|
+
public void start(){}
|
|
9
|
+
public void updateGltfBox(){}
|
|
10
|
+
}
|
|
11
|
+
}
|
package/dist/MyArray.cs
ADDED
package/dist/MyClass.cs
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// auto generated code - do not edit
|
|
2
|
+
namespace Needle.Typescript.GeneratedComponents
|
|
3
|
+
{
|
|
4
|
+
// source: C:\git\needle-tiny-playground\projects\Compiled_Export\myProject\src\scripts\MyClass.ts
|
|
5
|
+
public class MyClass : UnityEngine.MonoBehaviour
|
|
6
|
+
{
|
|
7
|
+
public void start(){}
|
|
8
|
+
public float myFloat = 15;
|
|
9
|
+
public bool myBool;
|
|
10
|
+
// just some default values
|
|
11
|
+
public float[] myArray = new float[]{ 1, 2, 3 };
|
|
12
|
+
// comment for myString
|
|
13
|
+
public string myString = "this is a string";
|
|
14
|
+
public UnityEngine.Transform myObject;
|
|
15
|
+
public bool myBool2;
|
|
16
|
+
public void myFunction(){}
|
|
17
|
+
public void myFunctionWithStringParameter(string @string){}
|
|
18
|
+
public void myFunctionWithSomeObjectAndArray(UnityEngine.Transform @obj, float[] @arr){}
|
|
19
|
+
public void myFunctionWithoutParamTypes(object @test){}
|
|
20
|
+
public UnityEngine.Transform[] someOtherStuff;
|
|
21
|
+
public UnityEngine.Events.UnityEvent myEvent;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// auto generated code - do not edit
|
|
2
|
+
namespace Needle.Typescript.GeneratedComponents
|
|
3
|
+
{
|
|
4
|
+
// source: C:\git\needle-tiny-playground\modules\needle-tiny\component-compiler\src\test.ts
|
|
5
|
+
public class MyClassWithAFloat : UnityEngine.MonoBehaviour
|
|
6
|
+
{
|
|
7
|
+
public float @myfloat = 0.5f;
|
|
8
|
+
private string @myString;
|
|
9
|
+
}
|
|
10
|
+
}
|
package/dist/Test.cs
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@needle-tools/needle-component-compiler",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Compile mock unity components from typescript",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"tsc": "tsc"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"typescript": "^4.5.5"
|
|
11
|
+
},
|
|
12
|
+
"devDependencies": {
|
|
13
|
+
"@types/node": "^17.0.16"
|
|
14
|
+
},
|
|
15
|
+
"author": {
|
|
16
|
+
"name": "Needle",
|
|
17
|
+
"email": "help@needle.tools",
|
|
18
|
+
"url": "https://needle.tools/"
|
|
19
|
+
},
|
|
20
|
+
"license": "ISC"
|
|
21
|
+
}
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
exports.__esModule = true;
|
|
3
|
+
exports.run = void 0;
|
|
4
|
+
var fs_1 = require("fs");
|
|
5
|
+
var ts = require("typescript");
|
|
6
|
+
var fs = require("fs");
|
|
7
|
+
var types = require("./types");
|
|
8
|
+
var dict = types.dict;
|
|
9
|
+
// add either of these two comments above a class to enforce code gen or disable it for the next class
|
|
10
|
+
var exportNextClassCommand = "@generate-component";
|
|
11
|
+
var dontExportNextClassCommand = "@dont-generate-component";
|
|
12
|
+
// add above field to add [SerializeField] attribute
|
|
13
|
+
var serializeCommand = "@serializeField";
|
|
14
|
+
// will be set to true when e.g. a comment for export is found
|
|
15
|
+
var exportNextClass = false;
|
|
16
|
+
var dontExportNextClass = false;
|
|
17
|
+
var serializeField = false;
|
|
18
|
+
function resetExportNextClass() {
|
|
19
|
+
dontExportNextClass = false;
|
|
20
|
+
exportNextClass = false;
|
|
21
|
+
}
|
|
22
|
+
// https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API
|
|
23
|
+
// const exportDir = "../dist";
|
|
24
|
+
var commentStarts = [];
|
|
25
|
+
var ExportContext = /** @class */ (function () {
|
|
26
|
+
function ExportContext(outputDir, fileName) {
|
|
27
|
+
this.classEnd = -1;
|
|
28
|
+
this.indentLevel = 0;
|
|
29
|
+
this.emitMethodContextMenu = null;
|
|
30
|
+
this.outputDir = outputDir;
|
|
31
|
+
this.fileName = fileName;
|
|
32
|
+
this.reset();
|
|
33
|
+
}
|
|
34
|
+
ExportContext.prototype.onBeforeMethod = function (name) {
|
|
35
|
+
if (this.emitMethodContextMenu !== undefined) {
|
|
36
|
+
var contextMenuText = this.emitMethodContextMenu === null ? name : this.emitMethodContextMenu;
|
|
37
|
+
this.appendLine("[UnityEngine.ContextMenu(\"" + contextMenuText + "\")]");
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
ExportContext.prototype.append = function (text) {
|
|
41
|
+
for (var i = 0; i < this.indentLevel; i++)
|
|
42
|
+
text = "\t" + text;
|
|
43
|
+
this.textBuffer += text;
|
|
44
|
+
this.emitMethodContextMenu = undefined;
|
|
45
|
+
};
|
|
46
|
+
ExportContext.prototype.appendLine = function (text) {
|
|
47
|
+
this.append(text + "\n");
|
|
48
|
+
};
|
|
49
|
+
ExportContext.prototype.flush = function () {
|
|
50
|
+
if (this.textBuffer.length <= 0)
|
|
51
|
+
return;
|
|
52
|
+
var dir = this.outputDir + "/";
|
|
53
|
+
if (!fs.existsSync(dir)) {
|
|
54
|
+
fs.mkdirSync(dir);
|
|
55
|
+
}
|
|
56
|
+
var path = dir + this.fileName;
|
|
57
|
+
console.log("Write to " + path);
|
|
58
|
+
fs.writeFileSync(path, this.textBuffer);
|
|
59
|
+
this.reset();
|
|
60
|
+
};
|
|
61
|
+
ExportContext.prototype.reset = function () {
|
|
62
|
+
this.textBuffer = "";
|
|
63
|
+
this.classEnd = -1;
|
|
64
|
+
};
|
|
65
|
+
return ExportContext;
|
|
66
|
+
}());
|
|
67
|
+
var contexts = [];
|
|
68
|
+
function run(program, outputDir, sourceFile) {
|
|
69
|
+
if (!fs.existsSync(outputDir)) {
|
|
70
|
+
console.error("Output directory does not exist: \"" + outputDir + "\"");
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
traverseFile(sourceFile);
|
|
74
|
+
function traverseFile(node) {
|
|
75
|
+
visit(node);
|
|
76
|
+
ts.forEachChild(node, traverseFile);
|
|
77
|
+
}
|
|
78
|
+
function visit(node) {
|
|
79
|
+
var _a, _b, _c;
|
|
80
|
+
var context = contexts.length > 0 ? contexts[contexts.length - 1] : null;
|
|
81
|
+
if ((context === null || context === void 0 ? void 0 : context.classEnd) > 0 && node.pos >= (context === null || context === void 0 ? void 0 : context.classEnd)) {
|
|
82
|
+
while (context.indentLevel > 0) {
|
|
83
|
+
context.indentLevel -= 1;
|
|
84
|
+
context.append("}\n");
|
|
85
|
+
}
|
|
86
|
+
context.flush();
|
|
87
|
+
context = null;
|
|
88
|
+
contexts.pop();
|
|
89
|
+
}
|
|
90
|
+
console.log("\t", ts.SyntaxKind[node.kind]);
|
|
91
|
+
var commentRanges = ts.getLeadingCommentRanges(sourceFile.getFullText(), node.getFullStart());
|
|
92
|
+
if (commentRanges === null || commentRanges === void 0 ? void 0 : commentRanges.length) {
|
|
93
|
+
for (var _i = 0, commentRanges_1 = commentRanges; _i < commentRanges_1.length; _i++) {
|
|
94
|
+
var r = commentRanges_1[_i];
|
|
95
|
+
// avoid emitting comments multiple times
|
|
96
|
+
if (commentStarts.includes(r.pos))
|
|
97
|
+
continue;
|
|
98
|
+
commentStarts.push(r.pos);
|
|
99
|
+
var comment = node.getSourceFile().getFullText().slice(r.pos, r.end);
|
|
100
|
+
if (context) {
|
|
101
|
+
// https://regex101.com/r/ud4oev/1
|
|
102
|
+
var emitContextMenu = comment.match("(\/{2,}|\/\*)\s*@contextmenu {0,}(?<text>[a-zA-Z 0-9]+)?");
|
|
103
|
+
if (emitContextMenu) {
|
|
104
|
+
context.emitMethodContextMenu = (_b = (_a = emitContextMenu.groups) === null || _a === void 0 ? void 0 : _a.text) !== null && _b !== void 0 ? _b : null;
|
|
105
|
+
}
|
|
106
|
+
else if (comment.includes(serializeCommand))
|
|
107
|
+
serializeField = true;
|
|
108
|
+
else
|
|
109
|
+
context.appendLine(comment);
|
|
110
|
+
}
|
|
111
|
+
if (comment.includes(exportNextClassCommand))
|
|
112
|
+
exportNextClass = true;
|
|
113
|
+
if (comment.includes(dontExportNextClassCommand))
|
|
114
|
+
dontExportNextClass = true;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
switch (node.kind) {
|
|
118
|
+
// case ts.SyntaxKind.ClassDeclaration:
|
|
119
|
+
// case ts.SyntaxKind.SingleLineCommentTrivia:
|
|
120
|
+
// console.log("comment: " + node.getText())
|
|
121
|
+
// break;
|
|
122
|
+
case ts.SyntaxKind.Decorator:
|
|
123
|
+
break;
|
|
124
|
+
case ts.SyntaxKind.MethodDeclaration:
|
|
125
|
+
serializeField = false;
|
|
126
|
+
resetExportNextClass();
|
|
127
|
+
if (!context)
|
|
128
|
+
break;
|
|
129
|
+
// TODO: always emit at least OnEnable method per class so generated components have toggle in editor
|
|
130
|
+
var meth = node;
|
|
131
|
+
// const isCoroutine = func.asteriskToken;
|
|
132
|
+
if (meth.name) {
|
|
133
|
+
var paramsStr = "";
|
|
134
|
+
for (var _d = 0, _e = meth.parameters; _d < _e.length; _d++) {
|
|
135
|
+
var param = _e[_d];
|
|
136
|
+
if (!param || !param.name)
|
|
137
|
+
continue;
|
|
138
|
+
if (paramsStr.length > 0)
|
|
139
|
+
paramsStr += ", ";
|
|
140
|
+
var type = tryResolveTypeRecursive(param);
|
|
141
|
+
if (type === undefined)
|
|
142
|
+
type = "object";
|
|
143
|
+
paramsStr += type + " @" + param.name.getText();
|
|
144
|
+
}
|
|
145
|
+
var methodName = meth.name.getText();
|
|
146
|
+
context.onBeforeMethod(methodName);
|
|
147
|
+
context.append("public void " + methodName + "(" + paramsStr + "){}\n");
|
|
148
|
+
}
|
|
149
|
+
break;
|
|
150
|
+
case ts.SyntaxKind.SetAccessor:
|
|
151
|
+
case ts.SyntaxKind.PropertyDeclaration:
|
|
152
|
+
resetExportNextClass();
|
|
153
|
+
if (!context)
|
|
154
|
+
break;
|
|
155
|
+
console.log("Found variable", node.getText());
|
|
156
|
+
var vardec = node;
|
|
157
|
+
var name_1 = vardec.name.getText();
|
|
158
|
+
console.log(name_1);
|
|
159
|
+
if (name_1.startsWith("\"@") || name_1.startsWith("\"$") || name_1.startsWith("$"))
|
|
160
|
+
break;
|
|
161
|
+
var typeString = tryResolveTypeRecursive(node);
|
|
162
|
+
if (typeString === undefined) {
|
|
163
|
+
context.append("// Could not resolve type \"" + ((_c = vardec.type) === null || _c === void 0 ? void 0 : _c.getText()) + "\"\n");
|
|
164
|
+
}
|
|
165
|
+
var prefix = typeString === undefined ? "// " : "";
|
|
166
|
+
var assignment = "";
|
|
167
|
+
if (typeString !== undefined) {
|
|
168
|
+
for (var _f = 0, _g = node.getChildren(); _f < _g.length; _f++) {
|
|
169
|
+
var ch = _g[_f];
|
|
170
|
+
switch (ch.kind) {
|
|
171
|
+
case ts.SyntaxKind.FalseKeyword:
|
|
172
|
+
case ts.SyntaxKind.TrueKeyword:
|
|
173
|
+
assignment = " = " + ch.getText();
|
|
174
|
+
break;
|
|
175
|
+
case ts.SyntaxKind.StringLiteral:
|
|
176
|
+
var str = ch;
|
|
177
|
+
assignment = " = \"" + str.text + "\"";
|
|
178
|
+
break;
|
|
179
|
+
case ts.SyntaxKind.FirstLiteralToken:
|
|
180
|
+
var lit = ch;
|
|
181
|
+
assignment = " = " + lit.text;
|
|
182
|
+
if (ts.isNumericLiteral(lit))
|
|
183
|
+
assignment += "f";
|
|
184
|
+
break;
|
|
185
|
+
case ts.SyntaxKind.ArrayLiteralExpression:
|
|
186
|
+
var arr = ch;
|
|
187
|
+
assignment = " = new " + typeString + "{" + arr.elements.map(function (e) { return " " + e.getText(); }) + " }";
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
var varName = "@" + vardec.name.getText();
|
|
193
|
+
var pub = isPublic(vardec);
|
|
194
|
+
var visibility = pub ? "public" : "private";
|
|
195
|
+
if (!pub && serializeField) {
|
|
196
|
+
console.log("SERIALIZE");
|
|
197
|
+
context.appendLine("[UnityEngine.SerializeField]");
|
|
198
|
+
}
|
|
199
|
+
context.append(prefix + visibility + " " + typeString + " " + varName + assignment + ";\n");
|
|
200
|
+
break;
|
|
201
|
+
case ts.SyntaxKind.ClassDeclaration:
|
|
202
|
+
serializeField = false;
|
|
203
|
+
var dec = node;
|
|
204
|
+
// a class must inherit a component
|
|
205
|
+
if (!dontExportNextClass && (exportNextClass || testInheritsComponent(node))) {
|
|
206
|
+
resetExportNextClass();
|
|
207
|
+
var name_2 = dec.name.escapedText;
|
|
208
|
+
console.log("Found class: ", name_2);
|
|
209
|
+
var newContext = new ExportContext(outputDir, name_2 + ".cs");
|
|
210
|
+
newContext.appendLine("// auto generated code - do not edit");
|
|
211
|
+
newContext.appendLine("namespace Needle.Typescript.GeneratedComponents");
|
|
212
|
+
newContext.appendLine("{");
|
|
213
|
+
newContext.indentLevel += 1;
|
|
214
|
+
// newContext.appendLine("// source: " + path.resolve(sourceFile.fileName));
|
|
215
|
+
newContext.appendLine("public class " + name_2 + " : UnityEngine.MonoBehaviour");
|
|
216
|
+
newContext.appendLine("{");
|
|
217
|
+
newContext.indentLevel += 1;
|
|
218
|
+
newContext.classEnd = dec.end;
|
|
219
|
+
contexts.push(newContext);
|
|
220
|
+
}
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
function testInheritsComponent(node) {
|
|
224
|
+
switch (node.kind) {
|
|
225
|
+
case ts.SyntaxKind.ClassDeclaration:
|
|
226
|
+
var dec = node;
|
|
227
|
+
if (dec.heritageClauses) {
|
|
228
|
+
for (var _i = 0, _a = dec.heritageClauses; _i < _a.length; _i++) {
|
|
229
|
+
var h = _a[_i];
|
|
230
|
+
if (h.types.length <= 0)
|
|
231
|
+
continue;
|
|
232
|
+
for (var _b = 0, _c = h.types; _b < _c.length; _b++) {
|
|
233
|
+
var type = _c[_b];
|
|
234
|
+
// const symbol = program.getTypeChecker().getSymbolAtLocation(type.expression);
|
|
235
|
+
// console.log(symbol);
|
|
236
|
+
if (type.expression.getText() === "Component")
|
|
237
|
+
return true;
|
|
238
|
+
if (type.expression.getText() === "Behaviour")
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
function isPublic(node) {
|
|
248
|
+
if (node.kind === ts.SyntaxKind.PublicKeyword) {
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
else if (node.kind === ts.SyntaxKind.PrivateKeyword) {
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
for (var _i = 0, _a = node.getChildren(); _i < _a.length; _i++) {
|
|
255
|
+
var ch = _a[_i];
|
|
256
|
+
if (!isPublic(ch))
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
return true;
|
|
260
|
+
}
|
|
261
|
+
function tryResolveTypeRecursive(node) {
|
|
262
|
+
var _a;
|
|
263
|
+
if (!node)
|
|
264
|
+
return undefined;
|
|
265
|
+
// skip decorators (e.g. @serializable() may break array generation)
|
|
266
|
+
if (node.kind === ts.SyntaxKind.Decorator)
|
|
267
|
+
return undefined;
|
|
268
|
+
var typeName = node === null || node === void 0 ? void 0 : node.getText();
|
|
269
|
+
var varDec = node;
|
|
270
|
+
if (varDec.type) {
|
|
271
|
+
typeName = varDec.type.getText();
|
|
272
|
+
}
|
|
273
|
+
var res = dict[typeName];
|
|
274
|
+
if (res !== undefined) {
|
|
275
|
+
// console.log("FOUND " + res, ts.SyntaxKind[node.kind]);
|
|
276
|
+
// console.log(node);
|
|
277
|
+
return res;
|
|
278
|
+
}
|
|
279
|
+
// console.log("Unknown type: " + typeName);
|
|
280
|
+
switch (node.kind) {
|
|
281
|
+
case ts.SyntaxKind.SyntaxList:
|
|
282
|
+
// const list = node as ts.SyntaxList;
|
|
283
|
+
// for(const ch of list._children)
|
|
284
|
+
// res = tryResolveTypeRecursive(ch);
|
|
285
|
+
break;
|
|
286
|
+
case ts.SyntaxKind.UnionType:
|
|
287
|
+
var union = node;
|
|
288
|
+
for (var _i = 0, _b = union.types; _i < _b.length; _i++) {
|
|
289
|
+
var t = _b[_i];
|
|
290
|
+
res = tryResolveTypeRecursive(t);
|
|
291
|
+
if (res !== undefined)
|
|
292
|
+
return res;
|
|
293
|
+
}
|
|
294
|
+
break;
|
|
295
|
+
case ts.SyntaxKind.ArrayType:
|
|
296
|
+
var arrayType = node;
|
|
297
|
+
var typeName_1 = (_a = arrayType.elementType) === null || _a === void 0 ? void 0 : _a.getText();
|
|
298
|
+
if (typeName_1 !== undefined) {
|
|
299
|
+
res = dict[typeName_1];
|
|
300
|
+
if (res !== undefined) {
|
|
301
|
+
res += "[]";
|
|
302
|
+
return res;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
for (var _c = 0, _d = node.getChildren(); _c < _d.length; _c++) {
|
|
307
|
+
var child = _d[_c];
|
|
308
|
+
if (res !== undefined)
|
|
309
|
+
break;
|
|
310
|
+
console.log("Child type: " + ts.SyntaxKind[child.kind]);
|
|
311
|
+
res = tryResolveTypeRecursive(child);
|
|
312
|
+
}
|
|
313
|
+
if (ts.isTypeReferenceNode(node)) {
|
|
314
|
+
var typeRef = node;
|
|
315
|
+
var typeName_2 = typeRef.typeName.getText();
|
|
316
|
+
switch (typeName_2) {
|
|
317
|
+
case "Array":
|
|
318
|
+
res += "[]";
|
|
319
|
+
return res;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return res;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
exports.run = run;
|
|
327
|
+
if (process.argv.length < 4) {
|
|
328
|
+
console.error("Missing args, call with: <output_dir> <input_files>");
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
var outputDir_1 = process.argv[2];
|
|
332
|
+
var fileNames = process.argv.slice(3);
|
|
333
|
+
fileNames.forEach(function (fileName) {
|
|
334
|
+
// Parse a file
|
|
335
|
+
var sourceFile = ts.createSourceFile(fileName, (0, fs_1.readFileSync)(fileName).toString(), ts.ScriptTarget.ES2015,
|
|
336
|
+
/*setParentNodes */ true);
|
|
337
|
+
var prog = ts.createProgram([fileName], {});
|
|
338
|
+
// delint it
|
|
339
|
+
run(prog, outputDir_1, sourceFile);
|
|
340
|
+
});
|
|
341
|
+
}
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import { readFileSync } from "fs";
|
|
2
|
+
import * as ts from "typescript";
|
|
3
|
+
import * as fs from "fs";
|
|
4
|
+
import * as path from "path";
|
|
5
|
+
|
|
6
|
+
import * as types from "./types";
|
|
7
|
+
const dict = types.dict;
|
|
8
|
+
|
|
9
|
+
// add either of these two comments above a class to enforce code gen or disable it for the next class
|
|
10
|
+
const exportNextClassCommand = "@generate-component";
|
|
11
|
+
const dontExportNextClassCommand = "@dont-generate-component";
|
|
12
|
+
// add above field to add [SerializeField] attribute
|
|
13
|
+
const serializeCommand = "@serializeField";
|
|
14
|
+
|
|
15
|
+
// will be set to true when e.g. a comment for export is found
|
|
16
|
+
let exportNextClass: boolean = false;
|
|
17
|
+
let dontExportNextClass: boolean = false;
|
|
18
|
+
let serializeField: boolean = false;
|
|
19
|
+
function resetExportNextClass() {
|
|
20
|
+
dontExportNextClass = false;
|
|
21
|
+
exportNextClass = false;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
// https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API
|
|
26
|
+
|
|
27
|
+
// const exportDir = "../dist";
|
|
28
|
+
const commentStarts: Array<number> = [];
|
|
29
|
+
|
|
30
|
+
class ExportContext {
|
|
31
|
+
outputDir: string;
|
|
32
|
+
fileName: string;
|
|
33
|
+
textBuffer: string;
|
|
34
|
+
classEnd: number = -1;
|
|
35
|
+
indentLevel: number = 0;
|
|
36
|
+
|
|
37
|
+
constructor(outputDir: string, fileName: string) {
|
|
38
|
+
this.outputDir = outputDir;
|
|
39
|
+
this.fileName = fileName;
|
|
40
|
+
this.reset();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
emitMethodContextMenu: string | null | undefined = null;
|
|
44
|
+
|
|
45
|
+
onBeforeMethod(name: string) {
|
|
46
|
+
if (this.emitMethodContextMenu !== undefined) {
|
|
47
|
+
const contextMenuText = this.emitMethodContextMenu === null ? name : this.emitMethodContextMenu;
|
|
48
|
+
this.appendLine("[UnityEngine.ContextMenu(\"" + contextMenuText + "\")]");
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
append(text: string) {
|
|
53
|
+
for (let i = 0; i < this.indentLevel; i++)
|
|
54
|
+
text = "\t" + text;
|
|
55
|
+
this.textBuffer += text;
|
|
56
|
+
this.emitMethodContextMenu = undefined;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
appendLine(text: string) {
|
|
60
|
+
this.append(text + "\n");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
flush() {
|
|
64
|
+
if (this.textBuffer.length <= 0) return;
|
|
65
|
+
const dir = this.outputDir + "/";
|
|
66
|
+
if (!fs.existsSync(dir)) {
|
|
67
|
+
fs.mkdirSync(dir);
|
|
68
|
+
}
|
|
69
|
+
const path = dir + this.fileName;
|
|
70
|
+
console.log("Write to " + path);
|
|
71
|
+
fs.writeFileSync(path, this.textBuffer);
|
|
72
|
+
this.reset();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
reset() {
|
|
76
|
+
this.textBuffer = "";
|
|
77
|
+
this.classEnd = -1;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const contexts: ExportContext[] = [];
|
|
82
|
+
|
|
83
|
+
export function run(program: ts.Program, outputDir: string, sourceFile: ts.SourceFile) {
|
|
84
|
+
|
|
85
|
+
if (!fs.existsSync(outputDir)) {
|
|
86
|
+
console.error("Output directory does not exist: \"" + outputDir + "\"");
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
traverseFile(sourceFile);
|
|
91
|
+
function traverseFile(node: ts.Node) {
|
|
92
|
+
|
|
93
|
+
visit(node);
|
|
94
|
+
ts.forEachChild(node, traverseFile);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function visit(node: ts.Node) {
|
|
98
|
+
let context: ExportContext | null = contexts.length > 0 ? contexts[contexts.length - 1] : null;
|
|
99
|
+
|
|
100
|
+
if (context?.classEnd > 0 && node.pos >= context?.classEnd) {
|
|
101
|
+
while (context.indentLevel > 0) {
|
|
102
|
+
context.indentLevel -= 1;
|
|
103
|
+
context.append("}\n");
|
|
104
|
+
}
|
|
105
|
+
context.flush();
|
|
106
|
+
context = null;
|
|
107
|
+
contexts.pop();
|
|
108
|
+
}
|
|
109
|
+
console.log("\t", ts.SyntaxKind[node.kind]);
|
|
110
|
+
|
|
111
|
+
const commentRanges = ts.getLeadingCommentRanges(
|
|
112
|
+
sourceFile.getFullText(),
|
|
113
|
+
node.getFullStart());
|
|
114
|
+
if (commentRanges?.length) {
|
|
115
|
+
for (const r of commentRanges) {
|
|
116
|
+
// avoid emitting comments multiple times
|
|
117
|
+
if (commentStarts.includes(r.pos)) continue;
|
|
118
|
+
commentStarts.push(r.pos);
|
|
119
|
+
const comment = node.getSourceFile().getFullText().slice(r.pos, r.end);
|
|
120
|
+
if (context) {
|
|
121
|
+
// https://regex101.com/r/ud4oev/1
|
|
122
|
+
const emitContextMenu = comment.match("(\/{2,}|\/\*)\s*@contextmenu {0,}(?<text>[a-zA-Z 0-9]+)?");
|
|
123
|
+
if (emitContextMenu) {
|
|
124
|
+
context.emitMethodContextMenu = emitContextMenu.groups?.text ?? null;
|
|
125
|
+
}
|
|
126
|
+
else if (comment.includes(serializeCommand))
|
|
127
|
+
serializeField = true;
|
|
128
|
+
else
|
|
129
|
+
context.appendLine(comment);
|
|
130
|
+
}
|
|
131
|
+
if (comment.includes(exportNextClassCommand))
|
|
132
|
+
exportNextClass = true;
|
|
133
|
+
if (comment.includes(dontExportNextClassCommand))
|
|
134
|
+
dontExportNextClass = true;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
switch (node.kind) {
|
|
139
|
+
// case ts.SyntaxKind.ClassDeclaration:
|
|
140
|
+
// case ts.SyntaxKind.SingleLineCommentTrivia:
|
|
141
|
+
// console.log("comment: " + node.getText())
|
|
142
|
+
// break;
|
|
143
|
+
case ts.SyntaxKind.Decorator:
|
|
144
|
+
break;
|
|
145
|
+
case ts.SyntaxKind.MethodDeclaration:
|
|
146
|
+
serializeField = false;
|
|
147
|
+
resetExportNextClass();
|
|
148
|
+
if (!context) break;
|
|
149
|
+
// TODO: always emit at least OnEnable method per class so generated components have toggle in editor
|
|
150
|
+
const meth = node as ts.MethodDeclaration;
|
|
151
|
+
// const isCoroutine = func.asteriskToken;
|
|
152
|
+
if (meth.name) {
|
|
153
|
+
let paramsStr = "";
|
|
154
|
+
for (let param of meth.parameters) {
|
|
155
|
+
if (!param || !param.name) continue;
|
|
156
|
+
if (paramsStr.length > 0) paramsStr += ", ";
|
|
157
|
+
let type = tryResolveTypeRecursive(param);
|
|
158
|
+
if (type === undefined) type = "object";
|
|
159
|
+
paramsStr += type + " @" + param.name.getText();
|
|
160
|
+
}
|
|
161
|
+
const methodName = meth.name.getText();
|
|
162
|
+
context.onBeforeMethod(methodName);
|
|
163
|
+
context.append("public void " + methodName + "(" + paramsStr + "){}\n");
|
|
164
|
+
}
|
|
165
|
+
break;
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
case ts.SyntaxKind.SetAccessor:
|
|
169
|
+
case ts.SyntaxKind.PropertyDeclaration:
|
|
170
|
+
resetExportNextClass();
|
|
171
|
+
if (!context) break;
|
|
172
|
+
console.log("Found variable", node.getText());
|
|
173
|
+
const vardec = node as ts.VariableDeclaration;
|
|
174
|
+
const name = vardec.name.getText();
|
|
175
|
+
console.log(name);
|
|
176
|
+
if (name.startsWith("\"@") || name.startsWith("\"$") || name.startsWith("$")) break;
|
|
177
|
+
let typeString = tryResolveTypeRecursive(node);
|
|
178
|
+
if (typeString === undefined) {
|
|
179
|
+
context.append("// Could not resolve type \"" + vardec.type?.getText() + "\"\n");
|
|
180
|
+
}
|
|
181
|
+
const prefix = typeString === undefined ? "// " : "";
|
|
182
|
+
let assignment = "";
|
|
183
|
+
if (typeString !== undefined) {
|
|
184
|
+
for (const ch of node.getChildren()) {
|
|
185
|
+
switch (ch.kind) {
|
|
186
|
+
case ts.SyntaxKind.FalseKeyword:
|
|
187
|
+
case ts.SyntaxKind.TrueKeyword:
|
|
188
|
+
assignment = " = " + ch.getText();
|
|
189
|
+
break;
|
|
190
|
+
case ts.SyntaxKind.StringLiteral:
|
|
191
|
+
const str = ch as ts.StringLiteral;
|
|
192
|
+
assignment = " = \"" + str.text + "\"";
|
|
193
|
+
break;
|
|
194
|
+
case ts.SyntaxKind.FirstLiteralToken:
|
|
195
|
+
const lit = ch as ts.LiteralExpression;
|
|
196
|
+
assignment = " = " + lit.text;
|
|
197
|
+
if (ts.isNumericLiteral(lit))
|
|
198
|
+
assignment += "f";
|
|
199
|
+
break;
|
|
200
|
+
case ts.SyntaxKind.ArrayLiteralExpression:
|
|
201
|
+
const arr = ch as ts.ArrayLiteralExpression;
|
|
202
|
+
assignment = " = new " + typeString + "{" + arr.elements.map(e => " " + e.getText()) + " }"
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
const varName = "@" + vardec.name.getText();
|
|
208
|
+
const pub = isPublic(vardec);
|
|
209
|
+
const visibility = pub ? "public" : "private";
|
|
210
|
+
if (!pub && serializeField) {
|
|
211
|
+
console.log("SERIALIZE");
|
|
212
|
+
context.appendLine("[UnityEngine.SerializeField]");
|
|
213
|
+
}
|
|
214
|
+
context.append(prefix + visibility + " " + typeString + " " + varName + assignment + ";\n");
|
|
215
|
+
break;
|
|
216
|
+
|
|
217
|
+
case ts.SyntaxKind.ClassDeclaration:
|
|
218
|
+
serializeField = false;
|
|
219
|
+
const dec = <ts.ClassDeclaration>node;
|
|
220
|
+
// a class must inherit a component
|
|
221
|
+
if (!dontExportNextClass && (exportNextClass || testInheritsComponent(node))) {
|
|
222
|
+
resetExportNextClass();
|
|
223
|
+
const name = dec.name.escapedText;
|
|
224
|
+
console.log("Found class: ", name);
|
|
225
|
+
const newContext = new ExportContext(outputDir, name + ".cs");
|
|
226
|
+
newContext.appendLine("// auto generated code - do not edit")
|
|
227
|
+
newContext.appendLine("namespace Needle.Typescript.GeneratedComponents");
|
|
228
|
+
newContext.appendLine("{");
|
|
229
|
+
newContext.indentLevel += 1;
|
|
230
|
+
// newContext.appendLine("// source: " + path.resolve(sourceFile.fileName));
|
|
231
|
+
newContext.appendLine("public class " + name + " : UnityEngine.MonoBehaviour");
|
|
232
|
+
newContext.appendLine("{");
|
|
233
|
+
newContext.indentLevel += 1;
|
|
234
|
+
newContext.classEnd = dec.end;
|
|
235
|
+
contexts.push(newContext);
|
|
236
|
+
}
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function testInheritsComponent(node: ts.Node): boolean {
|
|
241
|
+
switch (node.kind) {
|
|
242
|
+
case ts.SyntaxKind.ClassDeclaration:
|
|
243
|
+
const dec = <ts.ClassDeclaration>node;
|
|
244
|
+
if (dec.heritageClauses) {
|
|
245
|
+
for (const h of dec.heritageClauses) {
|
|
246
|
+
if (h.types.length <= 0) continue;
|
|
247
|
+
for (const type of h.types) {
|
|
248
|
+
// const symbol = program.getTypeChecker().getSymbolAtLocation(type.expression);
|
|
249
|
+
// console.log(symbol);
|
|
250
|
+
if (type.expression.getText() === "Component") return true;
|
|
251
|
+
if (type.expression.getText() === "Behaviour") return true;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return false;
|
|
256
|
+
}
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function isPublic(node: ts.Node): boolean {
|
|
261
|
+
if (node.kind === ts.SyntaxKind.PublicKeyword) {
|
|
262
|
+
return true;
|
|
263
|
+
}
|
|
264
|
+
else if (node.kind === ts.SyntaxKind.PrivateKeyword) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
for (const ch of node.getChildren()) {
|
|
269
|
+
if (!isPublic(ch)) return false;
|
|
270
|
+
}
|
|
271
|
+
return true;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function tryResolveTypeRecursive(node: ts.Node | ts.VariableDeclaration): string | undefined {
|
|
275
|
+
if (!node) return undefined;
|
|
276
|
+
|
|
277
|
+
// skip decorators (e.g. @serializable() may break array generation)
|
|
278
|
+
if(node.kind === ts.SyntaxKind.Decorator)
|
|
279
|
+
return undefined;
|
|
280
|
+
|
|
281
|
+
let typeName = node?.getText();
|
|
282
|
+
|
|
283
|
+
const varDec: ts.VariableDeclaration = node as ts.VariableDeclaration;
|
|
284
|
+
if (varDec.type) {
|
|
285
|
+
typeName = varDec.type.getText();
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
let res = dict[typeName];
|
|
289
|
+
if (res !== undefined) {
|
|
290
|
+
// console.log("FOUND " + res, ts.SyntaxKind[node.kind]);
|
|
291
|
+
// console.log(node);
|
|
292
|
+
return res;
|
|
293
|
+
}
|
|
294
|
+
// console.log("Unknown type: " + typeName);
|
|
295
|
+
|
|
296
|
+
switch (node.kind) {
|
|
297
|
+
case ts.SyntaxKind.SyntaxList:
|
|
298
|
+
// const list = node as ts.SyntaxList;
|
|
299
|
+
// for(const ch of list._children)
|
|
300
|
+
// res = tryResolveTypeRecursive(ch);
|
|
301
|
+
break;
|
|
302
|
+
case ts.SyntaxKind.UnionType:
|
|
303
|
+
const union = node as ts.UnionTypeNode;
|
|
304
|
+
for (const t of union.types) {
|
|
305
|
+
res = tryResolveTypeRecursive(t);
|
|
306
|
+
if (res !== undefined) return res;
|
|
307
|
+
}
|
|
308
|
+
break;
|
|
309
|
+
case ts.SyntaxKind.ArrayType:
|
|
310
|
+
const arrayType = <ts.ArrayTypeNode>node;
|
|
311
|
+
const typeName = arrayType.elementType?.getText();
|
|
312
|
+
if (typeName !== undefined) {
|
|
313
|
+
res = dict[typeName];
|
|
314
|
+
if (res !== undefined) {
|
|
315
|
+
res += "[]";
|
|
316
|
+
return res;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
for (const child of node.getChildren()) {
|
|
322
|
+
if (res !== undefined) break;
|
|
323
|
+
console.log("Child type: " + ts.SyntaxKind[child.kind]);
|
|
324
|
+
res = tryResolveTypeRecursive(child);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if(ts.isTypeReferenceNode(node)){
|
|
328
|
+
const typeRef = node as ts.TypeReferenceNode;
|
|
329
|
+
const typeName = typeRef.typeName.getText();
|
|
330
|
+
switch(typeName)
|
|
331
|
+
{
|
|
332
|
+
case "Array":
|
|
333
|
+
res += "[]";
|
|
334
|
+
return res;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return res;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
if (process.argv.length < 4) {
|
|
343
|
+
console.error("Missing args, call with: <output_dir> <input_files>");
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
const outputDir = process.argv[2];
|
|
347
|
+
const fileNames = process.argv.slice(3);
|
|
348
|
+
fileNames.forEach(fileName => {
|
|
349
|
+
// Parse a file
|
|
350
|
+
const sourceFile = ts.createSourceFile(
|
|
351
|
+
fileName,
|
|
352
|
+
readFileSync(fileName).toString(),
|
|
353
|
+
ts.ScriptTarget.ES2015,
|
|
354
|
+
/*setParentNodes */ true
|
|
355
|
+
);
|
|
356
|
+
|
|
357
|
+
const prog = ts.createProgram([fileName], {});
|
|
358
|
+
|
|
359
|
+
// delint it
|
|
360
|
+
run(prog, outputDir, sourceFile);
|
|
361
|
+
});
|
|
362
|
+
}
|
package/src/component.cs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
public class MyClass : MonoBehaviour {
|
package/src/test.ts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
|
|
2
|
+
// @generate-component
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export class MaterialColorHandler extends Behaviour {
|
|
6
|
+
|
|
7
|
+
@serializeable(Renderer)
|
|
8
|
+
renderer?: Renderer[];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// export class MyArray extends Behaviour {
|
|
12
|
+
|
|
13
|
+
// arr? : Array<number> = [1,2,3];
|
|
14
|
+
// }
|
|
15
|
+
|
|
16
|
+
// export class PrivateSerializedField extends Behaviour {
|
|
17
|
+
|
|
18
|
+
// //@serializeField
|
|
19
|
+
// private color? : THREE.Color;
|
|
20
|
+
// }
|
|
21
|
+
// export class MyPropertyClass extends Behaviour {
|
|
22
|
+
// set color(col: THREE.Color) {
|
|
23
|
+
// }
|
|
24
|
+
// }
|
|
25
|
+
|
|
26
|
+
// export class MyClassWithAFloat extends Behaviour {
|
|
27
|
+
// myfloat:number = .5;
|
|
28
|
+
// private myString : string;
|
|
29
|
+
// }
|
|
30
|
+
|
|
31
|
+
// export class GltfExport extends Behaviour {
|
|
32
|
+
// binary: boolean = true;
|
|
33
|
+
// "$serializedTypes" = {
|
|
34
|
+
// url:null
|
|
35
|
+
// }
|
|
36
|
+
|
|
37
|
+
// // @contextmenu enable this
|
|
38
|
+
// test(){
|
|
39
|
+
|
|
40
|
+
// }
|
|
41
|
+
// }
|
|
42
|
+
|
|
43
|
+
// export class SetColor extends Behaviour {
|
|
44
|
+
|
|
45
|
+
// "@serializedTypes" = {
|
|
46
|
+
// col: Number,
|
|
47
|
+
// }
|
|
48
|
+
// }
|
|
49
|
+
|
|
50
|
+
// class Behaviour {
|
|
51
|
+
|
|
52
|
+
// }
|
|
53
|
+
|
|
54
|
+
// export class PlatformerMusic extends Behaviour implements IPlaymodeChangeListener {
|
|
55
|
+
// source?: AudioSource;
|
|
56
|
+
// editMode?: string;
|
|
57
|
+
// playMode?: string;
|
|
58
|
+
|
|
59
|
+
// onPlaymodeChange(playmode: PlayMode): void {
|
|
60
|
+
// console.log(this);
|
|
61
|
+
// if(!this.source) return;
|
|
62
|
+
// const clip = playmode.isInPlayMode ? this.playMode : this.editMode;
|
|
63
|
+
// console.log("PLAY", clip);
|
|
64
|
+
// this.source.play(clip);
|
|
65
|
+
// }
|
|
66
|
+
|
|
67
|
+
// }
|
|
68
|
+
|
|
69
|
+
// // TODO: export UnityEvent like this
|
|
70
|
+
// // disable codegen
|
|
71
|
+
// class UnityEvent {
|
|
72
|
+
// methods: Function[] = [];
|
|
73
|
+
// invoke() {
|
|
74
|
+
// for (const m of this.methods) {
|
|
75
|
+
// m();
|
|
76
|
+
// }
|
|
77
|
+
// }
|
|
78
|
+
// }
|
|
79
|
+
|
|
80
|
+
// export class MyClass extends Behaviour {
|
|
81
|
+
// myFloat: number = 15;
|
|
82
|
+
// myBool: boolean;
|
|
83
|
+
// // just some default values
|
|
84
|
+
// myArray: number[] = [1, 2, 3];
|
|
85
|
+
// // comment for myString
|
|
86
|
+
// myString: string = "this is a string1";
|
|
87
|
+
// myObject: THREE.Object3D;
|
|
88
|
+
// myBool2: boolean;
|
|
89
|
+
|
|
90
|
+
// myFunction() { }
|
|
91
|
+
// myFunctionWithStringParameter(string: string) { }
|
|
92
|
+
// myFunctionWithSomeObjectAndArray(obj: THREE.Object3D, arr: number[]) { }
|
|
93
|
+
// myFunctionWithoutParamTypes(test) { }
|
|
94
|
+
|
|
95
|
+
// someOtherStuff: THREE.Object3D[] | null = null;
|
|
96
|
+
// myEvent: UnityEvent;
|
|
97
|
+
// }
|
package/src/types.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
exports.__esModule = true;
|
|
3
|
+
exports.delint = void 0;
|
|
4
|
+
|
|
5
|
+
const dict = {
|
|
6
|
+
"number": "float",
|
|
7
|
+
"string": "string",
|
|
8
|
+
"boolean": "bool",
|
|
9
|
+
// basic
|
|
10
|
+
"Behaviour" : "UnityEngine.Behaviour",
|
|
11
|
+
"Component" : "UnityEngine.Component",
|
|
12
|
+
"GameObject" : "UnityEngine.GameObject",
|
|
13
|
+
"Object3D" : "UnityEngine.Transform",
|
|
14
|
+
// Addressables
|
|
15
|
+
"AssetReference" : "UnityEngine.Transform",
|
|
16
|
+
// events
|
|
17
|
+
"EventList" : "UnityEngine.Events.UnityEvent",
|
|
18
|
+
// audio
|
|
19
|
+
"AudioClip" : "UnityEngine.AudioClip",
|
|
20
|
+
"THREE.Object3D" : "UnityEngine.Transform",
|
|
21
|
+
"UnityEvent" : "UnityEngine.Events.UnityEvent",
|
|
22
|
+
"AudioSource" : "UnityEngine.AudioSource",
|
|
23
|
+
"THREE.Color" : "UnityEngine.Color",
|
|
24
|
+
"Color" : "UnityEngine.Color",
|
|
25
|
+
"THREE.Vector2" : "UnityEngine.Vector2",
|
|
26
|
+
"Vector2" : "UnityEngine.Vector2",
|
|
27
|
+
"THREE.Vector3" : "UnityEngine.Vector3",
|
|
28
|
+
"Vector3" : "UnityEngine.Vector3",
|
|
29
|
+
"THREE.Vector4" : "UnityEngine.Vector4",
|
|
30
|
+
"Vector4" : "UnityEngine.Vector4",
|
|
31
|
+
// animation
|
|
32
|
+
"Animator" : "UnityEngine.Animator",
|
|
33
|
+
"Animation" : "UnityEngine.Animation",
|
|
34
|
+
"AnimationClip" : "UnityEngine.AnimationClip",
|
|
35
|
+
"SignalAsset" : "UnityEngine.Timeline.SignalAsset",
|
|
36
|
+
"PlayableDirector" : "UnityEngine.Playables.PlayableDirector",
|
|
37
|
+
// Rendering
|
|
38
|
+
"Renderer" : "UnityEngine.Renderer",
|
|
39
|
+
"Material" : "UnityEngine.Material",
|
|
40
|
+
// UI
|
|
41
|
+
"Text" : "UnityEngine.UI.Text",
|
|
42
|
+
"Image" : "UnityEngine.UI.Image",
|
|
43
|
+
"RawImage": "UnityEngine.UI.RawImage",
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
exports.dict = dict;
|