@needle-tools/needle-component-compiler 1.6.3 → 1.7.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/Changelog.md +6 -0
- package/package.json +1 -1
- package/src/component-compiler.js +170 -54
- package/src/component-compiler.ts +170 -46
- package/src/test.ts +14 -2
- package/src/types.js +2 -0
package/Changelog.md
CHANGED
|
@@ -4,6 +4,12 @@ All notable changes to this package will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [1.7.0] - 2022-07-14
|
|
8
|
+
- change: skip non-serializeable variables (private without ``@serializable``)
|
|
9
|
+
- improve member type generation
|
|
10
|
+
- fix bug in type generation for array types
|
|
11
|
+
- add/improve initial assignment codegen for object types
|
|
12
|
+
|
|
7
13
|
## [1.6.3] - 2022-07-12
|
|
8
14
|
- add warning when class type is unknown
|
|
9
15
|
|
package/package.json
CHANGED
|
@@ -218,13 +218,28 @@ function run(program, outputDir, sourceFile) {
|
|
|
218
218
|
break;
|
|
219
219
|
console.log("Found variable", node.getText());
|
|
220
220
|
var vardec = node;
|
|
221
|
+
var varName = "@" + vardec.name.getText();
|
|
222
|
+
var pub = isPublic(vardec);
|
|
223
|
+
var visibility = pub ? "public" : "private";
|
|
224
|
+
var isAccessible = pub;
|
|
225
|
+
if (!pub && serializeField) {
|
|
226
|
+
console.log("[SerializeField]");
|
|
227
|
+
context.appendLine("[UnityEngine.SerializeField]");
|
|
228
|
+
isAccessible = true;
|
|
229
|
+
}
|
|
230
|
+
if (!isAccessible) {
|
|
231
|
+
console.log("Skip because not public or serializeable");
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
221
234
|
var name_1 = vardec.name.getText();
|
|
222
|
-
console.log(name_1);
|
|
235
|
+
console.log("Variable:", name_1);
|
|
223
236
|
if (name_1.startsWith("\"@") || name_1.startsWith("\"$") || name_1.startsWith("$"))
|
|
224
237
|
break;
|
|
225
238
|
var typeString = lastTypeFound !== null && lastTypeFound !== void 0 ? lastTypeFound : tryResolveTypeRecursive(node);
|
|
239
|
+
var postFix = "";
|
|
240
|
+
var typeName = (_c = vardec.type) === null || _c === void 0 ? void 0 : _c.getText();
|
|
226
241
|
if (typeString === undefined) {
|
|
227
|
-
|
|
242
|
+
postFix = " → Could not resolve C# type";
|
|
228
243
|
}
|
|
229
244
|
var prefix = typeString === undefined ? "// " : "";
|
|
230
245
|
var assignment = "";
|
|
@@ -232,6 +247,12 @@ function run(program, outputDir, sourceFile) {
|
|
|
232
247
|
for (var _j = 0, _k = node.getChildren(); _j < _k.length; _j++) {
|
|
233
248
|
var ch = _k[_j];
|
|
234
249
|
switch (ch.kind) {
|
|
250
|
+
default:
|
|
251
|
+
// console.log("Unknown assignment:", ts.SyntaxKind[ch.kind]);
|
|
252
|
+
break;
|
|
253
|
+
case ts.SyntaxKind.NewExpression:
|
|
254
|
+
assignment = " = " + getTypeForAssignment(ch);
|
|
255
|
+
break;
|
|
235
256
|
case ts.SyntaxKind.FalseKeyword:
|
|
236
257
|
case ts.SyntaxKind.TrueKeyword:
|
|
237
258
|
assignment = " = " + ch.getText();
|
|
@@ -248,24 +269,23 @@ function run(program, outputDir, sourceFile) {
|
|
|
248
269
|
break;
|
|
249
270
|
case ts.SyntaxKind.ArrayLiteralExpression:
|
|
250
271
|
var arr = ch;
|
|
251
|
-
assignment = " = new " + typeString
|
|
272
|
+
assignment = " = new " + typeString;
|
|
273
|
+
// if (arr.elements.length > 0) {
|
|
274
|
+
assignment += "{" + arr.elements.map(function (e) { return " " + getTypeForAssignment(e); }) + " }";
|
|
275
|
+
// }
|
|
252
276
|
break;
|
|
253
277
|
}
|
|
254
278
|
}
|
|
255
279
|
}
|
|
256
|
-
var varName = "@" + vardec.name.getText();
|
|
257
|
-
var pub = isPublic(vardec);
|
|
258
|
-
var visibility = pub ? "public" : "private";
|
|
259
|
-
if (!pub && serializeField) {
|
|
260
|
-
console.log("SERIALIZE");
|
|
261
|
-
context.appendLine("[UnityEngine.SerializeField]");
|
|
262
|
-
}
|
|
263
280
|
var requireEndIf = false;
|
|
264
281
|
if (ifdefSections.length > 0) {
|
|
265
282
|
requireEndIf = true;
|
|
266
283
|
context.appendLine("#ifdef " + ifdefSections.pop());
|
|
267
284
|
}
|
|
268
|
-
|
|
285
|
+
if (typeString === undefined)
|
|
286
|
+
typeString = typeName;
|
|
287
|
+
console.log("EMIT member: " + typeString + " " + varName);
|
|
288
|
+
context.append(prefix + visibility + " " + typeString + " " + varName + assignment + ";" + postFix + "\n");
|
|
269
289
|
lastTypeFound = null;
|
|
270
290
|
if (requireEndIf) {
|
|
271
291
|
context.appendLine("#endif");
|
|
@@ -291,13 +311,13 @@ function run(program, outputDir, sourceFile) {
|
|
|
291
311
|
newContext.appendLine("{");
|
|
292
312
|
newContext.indentLevel += 1;
|
|
293
313
|
// newContext.appendLine("// source: " + path.resolve(sourceFile.fileName));
|
|
294
|
-
var
|
|
314
|
+
var typeName_1 = "UnityEngine.MonoBehaviour";
|
|
295
315
|
if (typeof inheritsComponent === "string")
|
|
296
|
-
|
|
316
|
+
typeName_1 = inheritsComponent;
|
|
297
317
|
if (lastTypeFound)
|
|
298
|
-
|
|
299
|
-
console.log(name_2 + " inherits " +
|
|
300
|
-
newContext.appendLine("public partial class " + name_2 + " : " +
|
|
318
|
+
typeName_1 = lastTypeFound;
|
|
319
|
+
console.log(name_2 + " inherits " + typeName_1);
|
|
320
|
+
newContext.appendLine("public partial class " + name_2 + " : " + typeName_1);
|
|
301
321
|
newContext.appendLine("{");
|
|
302
322
|
newContext.indentLevel += 1;
|
|
303
323
|
newContext.classEnd = dec.end;
|
|
@@ -337,6 +357,36 @@ function run(program, outputDir, sourceFile) {
|
|
|
337
357
|
}
|
|
338
358
|
return false;
|
|
339
359
|
}
|
|
360
|
+
function getTypeForAssignment(node) {
|
|
361
|
+
// console.log("-------------------\nAssign", ts.SyntaxKind[node.kind]);
|
|
362
|
+
switch (node.kind) {
|
|
363
|
+
case ts.SyntaxKind.FirstLiteralToken:
|
|
364
|
+
return node.getText();
|
|
365
|
+
case ts.SyntaxKind.NewExpression:
|
|
366
|
+
var type = undefined;
|
|
367
|
+
var args = undefined;
|
|
368
|
+
for (var _i = 0, _a = node.getChildren(); _i < _a.length; _i++) {
|
|
369
|
+
var ch = _a[_i];
|
|
370
|
+
// console.log("child", ts.SyntaxKind[ch.kind]);
|
|
371
|
+
switch (ch.kind) {
|
|
372
|
+
case ts.SyntaxKind.PropertyAccessExpression:
|
|
373
|
+
type = tryGetTypeFromText(ch.getText());
|
|
374
|
+
break;
|
|
375
|
+
case ts.SyntaxKind.SyntaxList:
|
|
376
|
+
args = ch.getText();
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
if (!args)
|
|
381
|
+
args = "";
|
|
382
|
+
if (type)
|
|
383
|
+
return "new " + type + "(" + args + ")";
|
|
384
|
+
// const expType = node.getChildren().find(c => c.kind === ts.SyntaxKind.Identifier);
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
var str = node.getText();
|
|
388
|
+
return str;
|
|
389
|
+
}
|
|
340
390
|
function isPublic(node) {
|
|
341
391
|
if (node.kind === ts.SyntaxKind.PublicKeyword) {
|
|
342
392
|
return true;
|
|
@@ -376,8 +426,21 @@ function run(program, outputDir, sourceFile) {
|
|
|
376
426
|
}
|
|
377
427
|
return namespace;
|
|
378
428
|
}
|
|
429
|
+
function tryGetTypeFromText(typeName) {
|
|
430
|
+
var res = dict[typeName];
|
|
431
|
+
if (res === undefined) {
|
|
432
|
+
switch (typeName) {
|
|
433
|
+
case "Array":
|
|
434
|
+
break;
|
|
435
|
+
default:
|
|
436
|
+
var knownType = tryGetKnownType(typeName);
|
|
437
|
+
res = knownType !== null && knownType !== void 0 ? knownType : undefined;
|
|
438
|
+
break;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return res;
|
|
442
|
+
}
|
|
379
443
|
function tryResolveTypeRecursive(node) {
|
|
380
|
-
var _a;
|
|
381
444
|
if (!node)
|
|
382
445
|
return undefined;
|
|
383
446
|
// skip decorators (e.g. @serializable() may break array generation)
|
|
@@ -388,58 +451,111 @@ function run(program, outputDir, sourceFile) {
|
|
|
388
451
|
if (varDec.type) {
|
|
389
452
|
typeName = varDec.type.getText();
|
|
390
453
|
}
|
|
391
|
-
var res =
|
|
392
|
-
if (res !== undefined) {
|
|
393
|
-
// console.log("FOUND " + res, ts.SyntaxKind[node.kind]);
|
|
394
|
-
// console.log(node);
|
|
395
|
-
return res;
|
|
396
|
-
}
|
|
397
|
-
var knownType = tryGetKnownType(typeName);
|
|
398
|
-
if (knownType)
|
|
399
|
-
return knownType;
|
|
454
|
+
var res = undefined;
|
|
400
455
|
// console.log("Unknown type: " + typeName);
|
|
401
456
|
switch (node.kind) {
|
|
402
|
-
case ts.SyntaxKind.SyntaxList:
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
457
|
+
// case ts.SyntaxKind.SyntaxList:
|
|
458
|
+
// const list = node as ts.SyntaxList;
|
|
459
|
+
// for (const ch of list._children) {
|
|
460
|
+
// res = tryResolveTypeRecursive(ch);
|
|
461
|
+
// }
|
|
462
|
+
// break;
|
|
407
463
|
case ts.SyntaxKind.UnionType:
|
|
408
464
|
var union = node;
|
|
409
|
-
for (var _i = 0,
|
|
410
|
-
var t =
|
|
465
|
+
for (var _i = 0, _a = union.types; _i < _a.length; _i++) {
|
|
466
|
+
var t = _a[_i];
|
|
411
467
|
res = tryResolveTypeRecursive(t);
|
|
412
468
|
if (res !== undefined)
|
|
413
469
|
return res;
|
|
414
470
|
}
|
|
415
471
|
break;
|
|
416
472
|
case ts.SyntaxKind.ArrayType:
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
473
|
+
res = "[]";
|
|
474
|
+
break;
|
|
475
|
+
case ts.SyntaxKind.TypeReference:
|
|
476
|
+
var typeRef = node;
|
|
477
|
+
var typeName_2 = typeRef.typeName.getText();
|
|
478
|
+
console.log("TypeReference:", typeName_2);
|
|
479
|
+
switch (typeName_2) {
|
|
480
|
+
case "Array":
|
|
481
|
+
res = "[]";
|
|
482
|
+
break;
|
|
483
|
+
default:
|
|
484
|
+
res = tryGetTypeFromText(typeName_2);
|
|
485
|
+
break;
|
|
486
|
+
}
|
|
487
|
+
return res;
|
|
488
|
+
case ts.SyntaxKind.BooleanKeyword:
|
|
489
|
+
case ts.SyntaxKind.NumberKeyword:
|
|
490
|
+
case ts.SyntaxKind.StringKeyword:
|
|
491
|
+
case ts.SyntaxKind.ObjectKeyword:
|
|
492
|
+
var keyword = node.getText();
|
|
493
|
+
// the basic keywords are declared in the static dictionary
|
|
494
|
+
// no need for a complex lookup
|
|
495
|
+
res = dict[keyword];
|
|
496
|
+
break;
|
|
497
|
+
case ts.SyntaxKind.Identifier:
|
|
498
|
+
var id = node;
|
|
499
|
+
switch (id.text) {
|
|
500
|
+
// if we have an array we dont want to use the System.Array as a type but just make it to the array syntax
|
|
501
|
+
case "Array":
|
|
502
|
+
res = "[]";
|
|
503
|
+
break;
|
|
504
|
+
default:
|
|
505
|
+
// res = tryGetTypeFromText(id.text);
|
|
506
|
+
break;
|
|
425
507
|
}
|
|
426
|
-
}
|
|
427
|
-
for (var _c = 0, _d = node.getChildren(); _c < _d.length; _c++) {
|
|
428
|
-
var child = _d[_c];
|
|
429
|
-
if (res !== undefined)
|
|
430
508
|
break;
|
|
431
|
-
console.log("Child type: " + ts.SyntaxKind[child.kind]);
|
|
432
|
-
res = tryResolveTypeRecursive(child);
|
|
433
509
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
var
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
510
|
+
var isInGenericDeclaration = false;
|
|
511
|
+
for (var _b = 0, _c = node.getChildren(); _b < _c.length; _b++) {
|
|
512
|
+
var child = _c[_b];
|
|
513
|
+
// if (res !== undefined) break;
|
|
514
|
+
// console.log("Child type: " + ts.SyntaxKind[child.kind]);
|
|
515
|
+
var isGenericStart = false;
|
|
516
|
+
var isAssignment = false;
|
|
517
|
+
switch (child.kind) {
|
|
518
|
+
case ts.SyntaxKind.FirstAssignment:
|
|
519
|
+
isAssignment = true;
|
|
520
|
+
break;
|
|
521
|
+
case ts.SyntaxKind.FirstBinaryOperator:
|
|
522
|
+
// console.log("Generic start: " + child.getText());
|
|
523
|
+
isInGenericDeclaration = true;
|
|
524
|
+
isGenericStart = true;
|
|
525
|
+
break;
|
|
526
|
+
case ts.SyntaxKind.GreaterThanGreaterThanToken:
|
|
527
|
+
isInGenericDeclaration = false;
|
|
528
|
+
// console.log("Generic end: " + child.getText());
|
|
529
|
+
break;
|
|
530
|
+
}
|
|
531
|
+
// if (isAssignment) break;
|
|
532
|
+
var childResult = tryResolveTypeRecursive(child);
|
|
533
|
+
if (childResult !== undefined) {
|
|
534
|
+
if (res === undefined)
|
|
535
|
+
res = "";
|
|
536
|
+
console.log("Child: " + ts.SyntaxKind[child.kind] + " → " + childResult);
|
|
537
|
+
// if the thing is a generic return as generic result
|
|
538
|
+
if (isInGenericDeclaration && !res.includes("[]")) {
|
|
539
|
+
res = "<" + childResult + ">";
|
|
540
|
+
}
|
|
541
|
+
// we got a generic result, these need to be appended
|
|
542
|
+
else if (childResult.startsWith("<")) {
|
|
543
|
+
res += childResult;
|
|
544
|
+
}
|
|
545
|
+
// concat default
|
|
546
|
+
else
|
|
547
|
+
res = childResult + res;
|
|
441
548
|
}
|
|
442
549
|
}
|
|
550
|
+
// if (ts.isTypeReferenceNode(node)) {
|
|
551
|
+
// const typeRef = node as ts.TypeReferenceNode;
|
|
552
|
+
// const typeName = typeRef.typeName.getText();
|
|
553
|
+
// switch (typeName) {
|
|
554
|
+
// case "Array":
|
|
555
|
+
// res += "[]";
|
|
556
|
+
// return res;
|
|
557
|
+
// }
|
|
558
|
+
// }
|
|
443
559
|
return res;
|
|
444
560
|
}
|
|
445
561
|
}
|
|
@@ -30,7 +30,6 @@ function resetExportNextClass() {
|
|
|
30
30
|
|
|
31
31
|
let typesFileContent: object | undefined | null = undefined;
|
|
32
32
|
function tryGetKnownType(str: string): string | null {
|
|
33
|
-
|
|
34
33
|
if (typesFileContent === undefined) {
|
|
35
34
|
typesFileContent = null;
|
|
36
35
|
const filePath = path.dirname(__dirname) + "/src/types.json";
|
|
@@ -241,18 +240,41 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
241
240
|
if (!context) break;
|
|
242
241
|
console.log("Found variable", node.getText());
|
|
243
242
|
const vardec = node as ts.VariableDeclaration;
|
|
243
|
+
|
|
244
|
+
const varName = "@" + vardec.name.getText();
|
|
245
|
+
const pub = isPublic(vardec);
|
|
246
|
+
const visibility = pub ? "public" : "private";
|
|
247
|
+
let isAccessible = pub;
|
|
248
|
+
if (!pub && serializeField) {
|
|
249
|
+
console.log("[SerializeField]");
|
|
250
|
+
context.appendLine("[UnityEngine.SerializeField]");
|
|
251
|
+
isAccessible = true;
|
|
252
|
+
}
|
|
253
|
+
if (!isAccessible) {
|
|
254
|
+
console.log("Skip because not public or serializeable")
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
|
|
244
258
|
const name = vardec.name.getText();
|
|
245
|
-
console.log(name);
|
|
259
|
+
console.log("Variable:", name);
|
|
246
260
|
if (name.startsWith("\"@") || name.startsWith("\"$") || name.startsWith("$")) break;
|
|
247
261
|
let typeString = lastTypeFound ?? tryResolveTypeRecursive(node);
|
|
262
|
+
let postFix = "";
|
|
263
|
+
let typeName = vardec.type?.getText();
|
|
248
264
|
if (typeString === undefined) {
|
|
249
|
-
|
|
265
|
+
postFix = " → Could not resolve C# type";
|
|
250
266
|
}
|
|
251
267
|
const prefix = typeString === undefined ? "// " : "";
|
|
252
268
|
let assignment = "";
|
|
253
269
|
if (typeString !== undefined) {
|
|
254
270
|
for (const ch of node.getChildren()) {
|
|
255
271
|
switch (ch.kind) {
|
|
272
|
+
default:
|
|
273
|
+
// console.log("Unknown assignment:", ts.SyntaxKind[ch.kind]);
|
|
274
|
+
break;
|
|
275
|
+
case ts.SyntaxKind.NewExpression:
|
|
276
|
+
assignment = " = " + getTypeForAssignment(ch);
|
|
277
|
+
break;
|
|
256
278
|
case ts.SyntaxKind.FalseKeyword:
|
|
257
279
|
case ts.SyntaxKind.TrueKeyword:
|
|
258
280
|
assignment = " = " + ch.getText();
|
|
@@ -269,24 +291,22 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
269
291
|
break;
|
|
270
292
|
case ts.SyntaxKind.ArrayLiteralExpression:
|
|
271
293
|
const arr = ch as ts.ArrayLiteralExpression;
|
|
272
|
-
assignment = " = new " + typeString
|
|
294
|
+
assignment = " = new " + typeString;
|
|
295
|
+
// if (arr.elements.length > 0) {
|
|
296
|
+
assignment += "{" + arr.elements.map(e => " " + getTypeForAssignment(e)) + " }";
|
|
297
|
+
// }
|
|
273
298
|
break;
|
|
274
299
|
}
|
|
275
300
|
}
|
|
276
301
|
}
|
|
277
|
-
const varName = "@" + vardec.name.getText();
|
|
278
|
-
const pub = isPublic(vardec);
|
|
279
|
-
const visibility = pub ? "public" : "private";
|
|
280
|
-
if (!pub && serializeField) {
|
|
281
|
-
console.log("SERIALIZE");
|
|
282
|
-
context.appendLine("[UnityEngine.SerializeField]");
|
|
283
|
-
}
|
|
284
302
|
let requireEndIf = false;
|
|
285
303
|
if (ifdefSections.length > 0) {
|
|
286
304
|
requireEndIf = true;
|
|
287
305
|
context.appendLine("#ifdef " + ifdefSections.pop());
|
|
288
306
|
}
|
|
289
|
-
|
|
307
|
+
if (typeString === undefined) typeString = typeName;
|
|
308
|
+
console.log("EMIT member: " + typeString + " " + varName)
|
|
309
|
+
context.append(prefix + visibility + " " + typeString + " " + varName + assignment + ";" + postFix + "\n");
|
|
290
310
|
lastTypeFound = null;
|
|
291
311
|
if (requireEndIf) {
|
|
292
312
|
context.appendLine("#endif");
|
|
@@ -353,6 +373,35 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
353
373
|
return false;
|
|
354
374
|
}
|
|
355
375
|
|
|
376
|
+
function getTypeForAssignment(node: ts.Node) {
|
|
377
|
+
// console.log("-------------------\nAssign", ts.SyntaxKind[node.kind]);
|
|
378
|
+
switch (node.kind) {
|
|
379
|
+
case ts.SyntaxKind.FirstLiteralToken:
|
|
380
|
+
return node.getText();
|
|
381
|
+
case ts.SyntaxKind.NewExpression:
|
|
382
|
+
let type: string | undefined = undefined;
|
|
383
|
+
let args: string | undefined = undefined;
|
|
384
|
+
for (const ch of node.getChildren()) {
|
|
385
|
+
// console.log("child", ts.SyntaxKind[ch.kind]);
|
|
386
|
+
switch (ch.kind) {
|
|
387
|
+
case ts.SyntaxKind.PropertyAccessExpression:
|
|
388
|
+
type = tryGetTypeFromText(ch.getText());
|
|
389
|
+
break;
|
|
390
|
+
case ts.SyntaxKind.SyntaxList:
|
|
391
|
+
args = ch.getText();
|
|
392
|
+
break;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
if (!args) args = "";
|
|
396
|
+
if (type)
|
|
397
|
+
return "new " + type + "(" + args + ")";
|
|
398
|
+
// const expType = node.getChildren().find(c => c.kind === ts.SyntaxKind.Identifier);
|
|
399
|
+
break;
|
|
400
|
+
}
|
|
401
|
+
const str = node.getText();
|
|
402
|
+
return str;
|
|
403
|
+
}
|
|
404
|
+
|
|
356
405
|
function isPublic(node: ts.Node): boolean {
|
|
357
406
|
if (node.kind === ts.SyntaxKind.PublicKeyword) {
|
|
358
407
|
return true;
|
|
@@ -391,6 +440,21 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
391
440
|
return namespace;
|
|
392
441
|
}
|
|
393
442
|
|
|
443
|
+
function tryGetTypeFromText(typeName: string) {
|
|
444
|
+
let res = dict[typeName];
|
|
445
|
+
if (res === undefined) {
|
|
446
|
+
switch (typeName) {
|
|
447
|
+
case "Array":
|
|
448
|
+
break;
|
|
449
|
+
default:
|
|
450
|
+
const knownType = tryGetKnownType(typeName);
|
|
451
|
+
res = knownType ?? undefined;
|
|
452
|
+
break;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
return res;
|
|
456
|
+
}
|
|
457
|
+
|
|
394
458
|
function tryResolveTypeRecursive(node: ts.Node | ts.VariableDeclaration): string | undefined {
|
|
395
459
|
if (!node) return undefined;
|
|
396
460
|
|
|
@@ -405,23 +469,19 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
405
469
|
typeName = varDec.type.getText();
|
|
406
470
|
}
|
|
407
471
|
|
|
408
|
-
let res =
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
return res;
|
|
413
|
-
}
|
|
414
|
-
const knownType = tryGetKnownType(typeName);
|
|
415
|
-
if (knownType)
|
|
416
|
-
return knownType;
|
|
472
|
+
let res: string | undefined = undefined;
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
|
|
417
476
|
// console.log("Unknown type: " + typeName);
|
|
418
477
|
|
|
419
478
|
switch (node.kind) {
|
|
420
|
-
case ts.SyntaxKind.SyntaxList:
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
479
|
+
// case ts.SyntaxKind.SyntaxList:
|
|
480
|
+
// const list = node as ts.SyntaxList;
|
|
481
|
+
// for (const ch of list._children) {
|
|
482
|
+
// res = tryResolveTypeRecursive(ch);
|
|
483
|
+
// }
|
|
484
|
+
// break;
|
|
425
485
|
case ts.SyntaxKind.UnionType:
|
|
426
486
|
const union = node as ts.UnionTypeNode;
|
|
427
487
|
for (const t of union.types) {
|
|
@@ -430,32 +490,96 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
430
490
|
}
|
|
431
491
|
break;
|
|
432
492
|
case ts.SyntaxKind.ArrayType:
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
493
|
+
res = "[]";
|
|
494
|
+
break;
|
|
495
|
+
|
|
496
|
+
case ts.SyntaxKind.TypeReference:
|
|
497
|
+
const typeRef = node as ts.TypeReferenceNode;
|
|
498
|
+
const typeName = typeRef.typeName.getText();
|
|
499
|
+
console.log("TypeReference:", typeName);
|
|
500
|
+
switch (typeName) {
|
|
501
|
+
case "Array":
|
|
502
|
+
res = "[]";
|
|
503
|
+
break;
|
|
504
|
+
default:
|
|
505
|
+
res = tryGetTypeFromText(typeName);
|
|
506
|
+
break;
|
|
441
507
|
}
|
|
442
|
-
|
|
508
|
+
return res;
|
|
509
|
+
|
|
510
|
+
case ts.SyntaxKind.BooleanKeyword:
|
|
511
|
+
case ts.SyntaxKind.NumberKeyword:
|
|
512
|
+
case ts.SyntaxKind.StringKeyword:
|
|
513
|
+
case ts.SyntaxKind.ObjectKeyword:
|
|
514
|
+
const keyword = node.getText();
|
|
515
|
+
// the basic keywords are declared in the static dictionary
|
|
516
|
+
// no need for a complex lookup
|
|
517
|
+
res = dict[keyword];
|
|
518
|
+
break;
|
|
443
519
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
520
|
+
case ts.SyntaxKind.Identifier:
|
|
521
|
+
const id = node as ts.Identifier;
|
|
522
|
+
switch (id.text) {
|
|
523
|
+
// if we have an array we dont want to use the System.Array as a type but just make it to the array syntax
|
|
524
|
+
case "Array":
|
|
525
|
+
res = "[]";
|
|
526
|
+
break;
|
|
527
|
+
default:
|
|
528
|
+
// res = tryGetTypeFromText(id.text);
|
|
529
|
+
break;
|
|
530
|
+
}
|
|
531
|
+
break;
|
|
448
532
|
}
|
|
449
533
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
534
|
+
let isInGenericDeclaration = false;
|
|
535
|
+
for (const child of node.getChildren()) {
|
|
536
|
+
// if (res !== undefined) break;
|
|
537
|
+
// console.log("Child type: " + ts.SyntaxKind[child.kind]);
|
|
538
|
+
let isGenericStart = false;
|
|
539
|
+
let isAssignment = false;
|
|
540
|
+
switch (child.kind) {
|
|
541
|
+
case ts.SyntaxKind.FirstAssignment:
|
|
542
|
+
isAssignment = true;
|
|
543
|
+
break;
|
|
544
|
+
case ts.SyntaxKind.FirstBinaryOperator:
|
|
545
|
+
// console.log("Generic start: " + child.getText());
|
|
546
|
+
isInGenericDeclaration = true;
|
|
547
|
+
isGenericStart = true;
|
|
548
|
+
break;
|
|
549
|
+
case ts.SyntaxKind.GreaterThanGreaterThanToken:
|
|
550
|
+
isInGenericDeclaration = false;
|
|
551
|
+
// console.log("Generic end: " + child.getText());
|
|
552
|
+
break;
|
|
553
|
+
}
|
|
554
|
+
// if (isAssignment) break;
|
|
555
|
+
const childResult = tryResolveTypeRecursive(child);
|
|
556
|
+
if (childResult !== undefined) {
|
|
557
|
+
if (res === undefined) res = "";
|
|
558
|
+
console.log("Child: " + ts.SyntaxKind[child.kind] + " → " + childResult);
|
|
559
|
+
// if the thing is a generic return as generic result
|
|
560
|
+
if (isInGenericDeclaration && !res.includes("[]")) {
|
|
561
|
+
res = "<" + childResult + ">";
|
|
562
|
+
}
|
|
563
|
+
// we got a generic result, these need to be appended
|
|
564
|
+
else if (childResult.startsWith("<")) {
|
|
565
|
+
res += childResult;
|
|
566
|
+
}
|
|
567
|
+
// concat default
|
|
568
|
+
else
|
|
569
|
+
res = childResult + res;
|
|
457
570
|
}
|
|
458
571
|
}
|
|
572
|
+
|
|
573
|
+
// if (ts.isTypeReferenceNode(node)) {
|
|
574
|
+
// const typeRef = node as ts.TypeReferenceNode;
|
|
575
|
+
// const typeName = typeRef.typeName.getText();
|
|
576
|
+
// switch (typeName) {
|
|
577
|
+
// case "Array":
|
|
578
|
+
// res += "[]";
|
|
579
|
+
// return res;
|
|
580
|
+
// }
|
|
581
|
+
// }
|
|
582
|
+
|
|
459
583
|
return res;
|
|
460
584
|
}
|
|
461
585
|
}
|
package/src/test.ts
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
|
+
import { ThisExpression } from "typescript";
|
|
1
2
|
|
|
2
3
|
class Test123 {}
|
|
3
4
|
|
|
4
|
-
export class Bla extends
|
|
5
|
+
export class Bla extends Behaviour
|
|
5
6
|
{
|
|
6
|
-
|
|
7
|
+
myNumber:number = 42;
|
|
8
|
+
myBool:boolean = true;
|
|
9
|
+
myString:string = "test";
|
|
10
|
+
numberArr: number[] = [1,2,3];
|
|
11
|
+
myColor : THREE.Color = new THREE.Color(255, 0, 0);
|
|
12
|
+
renderers = new Array<Renderer>();
|
|
13
|
+
renderers2 : Renderer[] = [];
|
|
14
|
+
objArr : object[];
|
|
15
|
+
colArr: THREE.Color[] = [new THREE.Color(1,2,3)];
|
|
16
|
+
map : Map<string> = new Map<string>();
|
|
17
|
+
map2 : Map<object> = new Map<object>();
|
|
18
|
+
private myThing : Test123;
|
|
7
19
|
}
|
|
8
20
|
|
|
9
21
|
// //@type UnityEngine.MonoBehaviour
|
package/src/types.js
CHANGED
|
@@ -3,9 +3,11 @@ exports.__esModule = true;
|
|
|
3
3
|
exports.delint = void 0;
|
|
4
4
|
|
|
5
5
|
const dict = {
|
|
6
|
+
"object" : "UnityEngine.Object",
|
|
6
7
|
"number": "float",
|
|
7
8
|
"string": "string",
|
|
8
9
|
"boolean": "bool",
|
|
10
|
+
"Map" : "System.Collections.Generic.HashSet",
|
|
9
11
|
// basic
|
|
10
12
|
"Behaviour" : "UnityEngine.Behaviour",
|
|
11
13
|
"Component" : "UnityEngine.Component",
|