@needle-tools/needle-component-compiler 1.7.3 → 1.9.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 +8 -0
- package/DEV.bat +1 -0
- package/{RUNTEST.bat → RUN_MANUAL_TEST.bat} +0 -0
- package/RUN_TESTS.bat +1 -0
- package/Readme.md +2 -1
- package/package.json +21 -3
- package/src/component-compiler.js +146 -71
- package/src/component-compiler.ts +147 -67
- package/src/test.ts +27 -3
- package/test/codegen/abstract method/expected.cs +14 -0
- package/test/codegen/abstract method/input.js +27 -0
- package/test/codegen/abstract method/input.ts +4 -0
- package/test/codegen/abstract method/output.cs +14 -0
- package/test/codegen/basic/expected.cs +13 -0
- package/test/codegen/basic/input.js +26 -0
- package/test/codegen/basic/input.ts +2 -0
- package/test/codegen/basic/output.cs +13 -0
- package/test/codegen/basic-no-export/expected.cs +0 -0
- package/test/codegen/basic-no-export/input.js +27 -0
- package/test/codegen/basic-no-export/input.ts +4 -0
- package/test/codegen/basic-no-export/output.cs +0 -0
- package/test/codegen/bool/expected.cs +14 -0
- package/test/codegen/bool/input.js +26 -0
- package/test/codegen/bool/input.ts +3 -0
- package/test/codegen/bool/output.cs +14 -0
- package/test/codegen/fields with default values/expected.cs +17 -0
- package/test/codegen/fields with default values/input.js +31 -0
- package/test/codegen/fields with default values/input.ts +6 -0
- package/test/codegen/fields with default values/output.cs +17 -0
- package/test/codegen/method ignore inline type declaration/expected.cs +14 -0
- package/test/codegen/method ignore inline type declaration/input.js +27 -0
- package/test/codegen/method ignore inline type declaration/input.ts +3 -0
- package/test/codegen/method ignore inline type declaration/output.cs +14 -0
- package/test/codegen/nonserialized ignore field/expected.cs +13 -0
- package/test/codegen/nonserialized ignore field/input.js +26 -0
- package/test/codegen/nonserialized ignore field/input.ts +4 -0
- package/test/codegen/nonserialized ignore field/output.cs +13 -0
- package/test/codegen/nonserialized on property does not affect method/expected.cs +14 -0
- package/test/codegen/nonserialized on property does not affect method/input.js +34 -0
- package/test/codegen/nonserialized on property does not affect method/input.ts +8 -0
- package/test/codegen/nonserialized on property does not affect method/output.cs +13 -0
- package/test/codegen/number/expected.cs +14 -0
- package/test/codegen/number/input.js +26 -0
- package/test/codegen/number/input.ts +3 -0
- package/test/codegen/number/output.cs +14 -0
- package/test/codegen/object/expected.cs +14 -0
- package/test/codegen/object/input.js +26 -0
- package/test/codegen/object/input.ts +3 -0
- package/test/codegen/object/output.cs +14 -0
- package/test/codegen/private.methods/expected.cs +13 -0
- package/test/codegen/private.methods/input.js +27 -0
- package/test/codegen/private.methods/input.ts +3 -0
- package/test/codegen/private.methods/output.cs +13 -0
- package/test/codegen/protected.methods/expected.cs +13 -0
- package/test/codegen/protected.methods/input.js +27 -0
- package/test/codegen/protected.methods/input.ts +3 -0
- package/test/codegen/protected.methods/output.cs +13 -0
- package/test/codegen/public method with args/expected.cs +14 -0
- package/test/codegen/public method with args/input.js +27 -0
- package/test/codegen/public method with args/input.ts +3 -0
- package/test/codegen/public method with args/output.cs +14 -0
- package/test/codegen/public method with multiple args/expected.cs +14 -0
- package/test/codegen/public method with multiple args/input.js +27 -0
- package/test/codegen/public method with multiple args/input.ts +3 -0
- package/test/codegen/public method with multiple args/output.cs +14 -0
- package/test/codegen/public.methods/expected.cs +14 -0
- package/test/codegen/public.methods/input.js +27 -0
- package/test/codegen/public.methods/input.ts +3 -0
- package/test/codegen/public.methods/output.cs +14 -0
- package/test/codegen/static method/expected.cs +13 -0
- package/test/codegen/static method/input.js +27 -0
- package/test/codegen/static method/input.ts +3 -0
- package/test/codegen/static method/output.cs +14 -0
- package/test/codegen/string/expected.cs +14 -0
- package/test/codegen/string/input.js +26 -0
- package/test/codegen/string/input.ts +3 -0
- package/test/codegen/string/output.cs +14 -0
- package/test/codegen/stringArray/expected.cs +14 -0
- package/test/codegen/stringArray/input.js +26 -0
- package/test/codegen/stringArray/input.ts +3 -0
- package/test/codegen/stringArray/output.cs +14 -0
- package/test/component.basic.test.ts +52 -0
- package/test/component.methods.test.ts +185 -0
- package/test/component.nonserialized.test.ts +45 -0
- package/test/component.primitives.test.ts +121 -0
- package/test/helpers.ts +72 -0
- package/tsconfig.json +8 -0
- package/workspace.code-workspace +7 -7
|
@@ -4,7 +4,6 @@ import * as fs from "fs";
|
|
|
4
4
|
import * as path from 'path';
|
|
5
5
|
|
|
6
6
|
import * as types from "./types";
|
|
7
|
-
import { type } from "os";
|
|
8
7
|
const dict = types.dict;
|
|
9
8
|
|
|
10
9
|
// add either of these two comments above a class to enforce code gen or disable it for the next class
|
|
@@ -12,6 +11,7 @@ const exportNextClassCommand = "@generate-component";
|
|
|
12
11
|
const dontExportNextClassCommand = "@dont-generate-component";
|
|
13
12
|
// add above field to add [SerializeField] attribute
|
|
14
13
|
const serializeCommand = "@serializeField";
|
|
14
|
+
const dontSerializeCommand = "@nonSerialized";
|
|
15
15
|
// https://regex101.com/r/ltpcKT/2
|
|
16
16
|
const typePattern = new RegExp("@type ?(?<type>.+)");
|
|
17
17
|
const ifdefPattern = new RegExp("@ifdef ?(?<ifdef>.+)")
|
|
@@ -19,23 +19,46 @@ const ifdefPattern = new RegExp("@ifdef ?(?<ifdef>.+)")
|
|
|
19
19
|
const CODEGEN_MARKER_START = "// NEEDLE_CODEGEN_START";
|
|
20
20
|
const CODEGEN_MARKER_END = "// NEEDLE_CODEGEN_END";
|
|
21
21
|
|
|
22
|
+
let allowDebugLogs = true;
|
|
23
|
+
|
|
22
24
|
// will be set to true when e.g. a comment for export is found
|
|
23
25
|
let exportNextClass: boolean = false;
|
|
24
26
|
let dontExportNextClass: boolean = false;
|
|
25
27
|
let serializeField: boolean = false;
|
|
28
|
+
let dontSerialize: boolean = false;
|
|
29
|
+
let typesFileContent: object | undefined | null = undefined;
|
|
30
|
+
|
|
31
|
+
// const exportDir = "../dist";
|
|
32
|
+
const commentStarts: Array<number> = [];
|
|
33
|
+
const contexts: ExportContext[] = [];
|
|
34
|
+
let lastTypeFound: string | null = null;
|
|
35
|
+
let ifdefSections: string[] = [];
|
|
36
|
+
|
|
37
|
+
function resetAllState() {
|
|
38
|
+
exportNextClass = false;
|
|
39
|
+
dontExportNextClass = false;
|
|
40
|
+
serializeField = false;
|
|
41
|
+
dontSerialize = false;
|
|
42
|
+
typesFileContent = undefined;
|
|
43
|
+
|
|
44
|
+
commentStarts.length = 0;
|
|
45
|
+
contexts.length = 0;
|
|
46
|
+
lastTypeFound = null;
|
|
47
|
+
ifdefSections.length = 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
26
50
|
function resetExportNextClass() {
|
|
27
51
|
dontExportNextClass = false;
|
|
28
52
|
exportNextClass = false;
|
|
29
53
|
}
|
|
30
54
|
|
|
31
|
-
|
|
32
|
-
let typesFileContent: object | undefined | null = undefined;
|
|
33
55
|
function tryGetKnownType(str: string): string | null {
|
|
34
56
|
if (typesFileContent === undefined) {
|
|
35
57
|
typesFileContent = null;
|
|
36
58
|
const filePath = path.dirname(__dirname) + "/src/types.json";
|
|
37
59
|
if (fs.existsSync(filePath)) {
|
|
38
|
-
|
|
60
|
+
if (allowDebugLogs)
|
|
61
|
+
console.log("Reading types file");
|
|
39
62
|
const content = fs.readFileSync(filePath, "utf8");
|
|
40
63
|
typesFileContent = JSON.parse(content);
|
|
41
64
|
}
|
|
@@ -43,7 +66,7 @@ function tryGetKnownType(str: string): string | null {
|
|
|
43
66
|
|
|
44
67
|
if (typesFileContent) {
|
|
45
68
|
const fullType = typesFileContent[str];
|
|
46
|
-
if (fullType)
|
|
69
|
+
if (fullType && allowDebugLogs)
|
|
47
70
|
console.log(fullType);
|
|
48
71
|
return fullType;
|
|
49
72
|
}
|
|
@@ -52,17 +75,15 @@ function tryGetKnownType(str: string): string | null {
|
|
|
52
75
|
|
|
53
76
|
// https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API
|
|
54
77
|
|
|
55
|
-
// const exportDir = "../dist";
|
|
56
|
-
const commentStarts: Array<number> = [];
|
|
57
78
|
|
|
58
79
|
class ExportContext {
|
|
59
|
-
outputDir: string;
|
|
80
|
+
outputDir: string | null;
|
|
60
81
|
fileName: string;
|
|
61
82
|
textBuffer: string;
|
|
62
83
|
classEnd: number = -1;
|
|
63
84
|
indentLevel: number = 0;
|
|
64
85
|
|
|
65
|
-
constructor(outputDir: string, fileName: string) {
|
|
86
|
+
constructor(outputDir: string | null, fileName: string) {
|
|
66
87
|
this.outputDir = outputDir;
|
|
67
88
|
this.fileName = fileName;
|
|
68
89
|
this.reset();
|
|
@@ -88,14 +109,20 @@ class ExportContext {
|
|
|
88
109
|
this.append(text + "\n");
|
|
89
110
|
}
|
|
90
111
|
|
|
91
|
-
flush() {
|
|
112
|
+
flush(): string {
|
|
92
113
|
if (this.textBuffer.length <= 0) return;
|
|
93
|
-
|
|
94
|
-
const
|
|
95
|
-
this.
|
|
96
|
-
|
|
97
|
-
|
|
114
|
+
this.textBuffer = CODEGEN_MARKER_START + "\n" + this.textBuffer + "\n" + CODEGEN_MARKER_END;
|
|
115
|
+
const code = this.textBuffer;
|
|
116
|
+
if (this.outputDir !== null) {
|
|
117
|
+
const dir = this.outputDir + "/";
|
|
118
|
+
const path = dir + this.fileName;
|
|
119
|
+
this.replaceGeneratedCodeSection(path);
|
|
120
|
+
if (allowDebugLogs)
|
|
121
|
+
console.log("Write to " + path);
|
|
122
|
+
fs.writeFileSync(path, code);
|
|
123
|
+
}
|
|
98
124
|
this.reset();
|
|
125
|
+
return code;
|
|
99
126
|
}
|
|
100
127
|
|
|
101
128
|
reset() {
|
|
@@ -104,13 +131,13 @@ class ExportContext {
|
|
|
104
131
|
}
|
|
105
132
|
|
|
106
133
|
private replaceGeneratedCodeSection(path: string) {
|
|
107
|
-
this.textBuffer = CODEGEN_MARKER_START + "\n" + this.textBuffer + "\n" + CODEGEN_MARKER_END;
|
|
108
134
|
if (fs.existsSync(path)) {
|
|
109
135
|
const existing = fs.readFileSync(path, "utf8");
|
|
110
136
|
const regex = new RegExp("(?<before>.*?)\/\/ ?NEEDLE_CODEGEN_START.+\/\/ ?NEEDLE_CODEGEN_END(?<after>.*)", "s");
|
|
111
137
|
const matches = regex.exec(existing);
|
|
112
138
|
if (matches?.groups) {
|
|
113
|
-
|
|
139
|
+
if (allowDebugLogs)
|
|
140
|
+
console.log("Found codegen sections")
|
|
114
141
|
const before = matches.groups.before;
|
|
115
142
|
const after = matches.groups.after;
|
|
116
143
|
this.textBuffer = before + this.textBuffer + after;
|
|
@@ -119,18 +146,34 @@ class ExportContext {
|
|
|
119
146
|
}
|
|
120
147
|
}
|
|
121
148
|
|
|
122
|
-
|
|
149
|
+
export function compile(code: string, fileName: string, outputDir: string | null, debugLogs: boolean = true): string[] {
|
|
123
150
|
|
|
124
|
-
|
|
125
|
-
|
|
151
|
+
resetAllState();
|
|
152
|
+
allowDebugLogs = debugLogs;
|
|
153
|
+
|
|
154
|
+
// Parse a file
|
|
155
|
+
const sourceFile = ts.createSourceFile(
|
|
156
|
+
fileName,
|
|
157
|
+
code,
|
|
158
|
+
ts.ScriptTarget.ES2015,
|
|
159
|
+
true, /*setParentNodes */
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
const prog = ts.createProgram([fileName], {});
|
|
126
163
|
|
|
127
|
-
|
|
164
|
+
// delint it
|
|
165
|
+
return run(prog, outputDir, sourceFile);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export function run(program: ts.Program, outputDir: string | null, sourceFile: ts.SourceFile): string[] {
|
|
128
169
|
|
|
129
|
-
if (!fs.existsSync(outputDir)) {
|
|
170
|
+
if (outputDir !== null && !fs.existsSync(outputDir)) {
|
|
130
171
|
console.error("Output directory does not exist: \"" + outputDir + "\"");
|
|
131
172
|
return;
|
|
132
173
|
}
|
|
133
174
|
|
|
175
|
+
const results: string[] = [];
|
|
176
|
+
|
|
134
177
|
traverseFile(sourceFile);
|
|
135
178
|
function traverseFile(node: ts.Node) {
|
|
136
179
|
|
|
@@ -138,6 +181,8 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
138
181
|
ts.forEachChild(node, traverseFile);
|
|
139
182
|
}
|
|
140
183
|
|
|
184
|
+
return results;
|
|
185
|
+
|
|
141
186
|
function visit(node: ts.Node) {
|
|
142
187
|
let context: ExportContext | null = contexts.length > 0 ? contexts[contexts.length - 1] : null;
|
|
143
188
|
|
|
@@ -147,12 +192,14 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
147
192
|
context.indentLevel -= 1;
|
|
148
193
|
context.append("}\n");
|
|
149
194
|
}
|
|
150
|
-
context.flush();
|
|
195
|
+
const code = context.flush();
|
|
196
|
+
results.push(code);
|
|
151
197
|
context = null;
|
|
152
198
|
contexts.pop();
|
|
153
199
|
}
|
|
154
200
|
}
|
|
155
|
-
|
|
201
|
+
if (allowDebugLogs)
|
|
202
|
+
console.log("\t", ts.SyntaxKind[node.kind]);
|
|
156
203
|
|
|
157
204
|
const commentRanges = ts.getLeadingCommentRanges(
|
|
158
205
|
sourceFile.getFullText(),
|
|
@@ -171,6 +218,8 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
171
218
|
}
|
|
172
219
|
else if (comment.includes(serializeCommand))
|
|
173
220
|
serializeField = true;
|
|
221
|
+
else if (comment.includes(dontSerializeCommand))
|
|
222
|
+
dontSerialize = true;
|
|
174
223
|
}
|
|
175
224
|
if (comment.includes(exportNextClassCommand))
|
|
176
225
|
exportNextClass = true;
|
|
@@ -182,7 +231,8 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
182
231
|
// so we remove them
|
|
183
232
|
let type = typeMatch.groups["type"];
|
|
184
233
|
type = type.replace(/\(/, "").replace(/\)/, "");
|
|
185
|
-
|
|
234
|
+
if (allowDebugLogs)
|
|
235
|
+
console.log("Found type: ", type);
|
|
186
236
|
lastTypeFound = type;
|
|
187
237
|
}
|
|
188
238
|
|
|
@@ -195,6 +245,7 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
195
245
|
}
|
|
196
246
|
}
|
|
197
247
|
|
|
248
|
+
const skip = dontSerialize;
|
|
198
249
|
switch (node.kind) {
|
|
199
250
|
// Namespace
|
|
200
251
|
// case ts.SyntaxKind.ModuleDeclaration:
|
|
@@ -214,12 +265,16 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
214
265
|
case ts.SyntaxKind.MethodDeclaration:
|
|
215
266
|
lastTypeFound = null;
|
|
216
267
|
serializeField = false;
|
|
268
|
+
dontSerialize = false;
|
|
217
269
|
resetExportNextClass();
|
|
218
270
|
if (!context) break;
|
|
219
271
|
// TODO: always emit at least OnEnable method per class so generated components have toggle in editor
|
|
220
272
|
const meth = node as ts.MethodDeclaration;
|
|
221
273
|
// const isCoroutine = func.asteriskToken;
|
|
222
|
-
if (meth.name) {
|
|
274
|
+
if (!skip && meth.name) {
|
|
275
|
+
const pub = isPublic(meth);
|
|
276
|
+
if(!pub) return;
|
|
277
|
+
|
|
223
278
|
let paramsStr = "";
|
|
224
279
|
for (let param of meth.parameters) {
|
|
225
280
|
if (!param || !param.name) continue;
|
|
@@ -228,8 +283,13 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
228
283
|
if (type === undefined) type = "object";
|
|
229
284
|
paramsStr += type + " @" + param.name.getText();
|
|
230
285
|
}
|
|
231
|
-
|
|
286
|
+
let methodName = meth.name.getText();
|
|
287
|
+
switch (methodName) {
|
|
288
|
+
case "onEnable": methodName = "OnEnable"; break;
|
|
289
|
+
case "onDisable": methodName = "OnDisable"; break;
|
|
290
|
+
}
|
|
232
291
|
context.onBeforeMethod(methodName);
|
|
292
|
+
// let visibility = pub ? "public" : "private";
|
|
233
293
|
context.append("public void " + methodName + "(" + paramsStr + "){}\n");
|
|
234
294
|
}
|
|
235
295
|
break;
|
|
@@ -239,29 +299,38 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
239
299
|
case ts.SyntaxKind.PropertyDeclaration:
|
|
240
300
|
resetExportNextClass();
|
|
241
301
|
if (!context) break;
|
|
242
|
-
|
|
302
|
+
if (allowDebugLogs)
|
|
303
|
+
console.log("Found variable", node.getText());
|
|
243
304
|
const vardec = node as ts.VariableDeclaration;
|
|
244
305
|
|
|
245
306
|
const varName = "@" + vardec.name.getText();
|
|
246
307
|
const pub = isPublic(vardec);
|
|
247
308
|
const visibility = pub ? "public" : "private";
|
|
248
309
|
let isAccessible = pub;
|
|
249
|
-
|
|
250
|
-
|
|
310
|
+
dontSerialize = false;
|
|
311
|
+
if (serializeField) {
|
|
312
|
+
if (allowDebugLogs)
|
|
313
|
+
console.log("[SerializeField]");
|
|
251
314
|
context.appendLine("[UnityEngine.SerializeField]");
|
|
252
315
|
isAccessible = true;
|
|
253
316
|
}
|
|
317
|
+
else if (skip)
|
|
318
|
+
isAccessible = false;
|
|
319
|
+
|
|
254
320
|
if (!isAccessible) {
|
|
255
|
-
|
|
321
|
+
if (allowDebugLogs)
|
|
322
|
+
console.log("Skip because not public or serializeable")
|
|
256
323
|
break;
|
|
257
324
|
}
|
|
258
325
|
|
|
259
326
|
const name = vardec.name.getText();
|
|
260
|
-
|
|
327
|
+
if (allowDebugLogs)
|
|
328
|
+
console.log("Variable:", name);
|
|
261
329
|
if (name.startsWith("\"@") || name.startsWith("\"$") || name.startsWith("$")) break;
|
|
262
330
|
let typeString = lastTypeFound ?? tryResolveTypeRecursive(node);
|
|
263
331
|
let postFix = "";
|
|
264
332
|
let typeName = vardec.type?.getText();
|
|
333
|
+
let shouldCommentTheLine = typeString === undefined;
|
|
265
334
|
if (typeString === undefined) {
|
|
266
335
|
postFix = " → Could not resolve C# type";
|
|
267
336
|
}
|
|
@@ -306,12 +375,15 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
306
375
|
}
|
|
307
376
|
if (typeString === undefined) typeString = typeName;
|
|
308
377
|
if (typeString === "[]") {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
378
|
+
if (allowDebugLogs)
|
|
379
|
+
console.log("Unknown array type for \"" + varName + " " + typeName + "\" - your type is probably not known (did you just create it this session?) and you might need to regenerate the Typemap in Unity. Go to \"Needle Engine/Internal/Generate Type Map for component compiler")
|
|
380
|
+
// typeString = "object[]";
|
|
381
|
+
// assignment = " = new object[0]";
|
|
382
|
+
shouldCommentTheLine = true;
|
|
312
383
|
}
|
|
313
|
-
|
|
314
|
-
|
|
384
|
+
if (allowDebugLogs)
|
|
385
|
+
console.log("EMIT member: \"" + typeString + "\" " + varName, assignment, "Last type found:", lastTypeFound);
|
|
386
|
+
const prefix = shouldCommentTheLine ? "// " : "";
|
|
315
387
|
context.append(prefix + visibility + " " + typeString + " " + varName + assignment + ";" + postFix + "\n");
|
|
316
388
|
lastTypeFound = null;
|
|
317
389
|
if (requireEndIf) {
|
|
@@ -327,9 +399,11 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
327
399
|
if (!dontExportNextClass && (lastTypeFound || exportNextClass || inheritsComponent)) {
|
|
328
400
|
resetExportNextClass();
|
|
329
401
|
const name = dec.name?.escapedText;
|
|
330
|
-
|
|
402
|
+
if (allowDebugLogs)
|
|
403
|
+
console.log("Found class: ", name);
|
|
331
404
|
const namespace = tryParseNamespace(node) ?? "Needle.Typescript.GeneratedComponents";
|
|
332
|
-
|
|
405
|
+
if (allowDebugLogs)
|
|
406
|
+
console.log("NAMESPACE", namespace);
|
|
333
407
|
const newContext = new ExportContext(outputDir, name + ".cs");
|
|
334
408
|
newContext.appendLine("// auto generated code - do not edit directly");
|
|
335
409
|
newContext.appendLine("");
|
|
@@ -342,14 +416,16 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
342
416
|
let typeName = "UnityEngine.MonoBehaviour";
|
|
343
417
|
if (typeof inheritsComponent === "string") typeName = inheritsComponent;
|
|
344
418
|
if (lastTypeFound) typeName = lastTypeFound;
|
|
345
|
-
|
|
419
|
+
if (allowDebugLogs)
|
|
420
|
+
console.log(name + " inherits " + typeName);
|
|
346
421
|
let modifiers = "";
|
|
347
422
|
if (dec.modifiers) {
|
|
348
423
|
for (const mod of dec.modifiers) {
|
|
349
424
|
switch (mod.getText()) {
|
|
350
425
|
case "abstract":
|
|
351
426
|
modifiers += " abstract";
|
|
352
|
-
|
|
427
|
+
if (allowDebugLogs)
|
|
428
|
+
console.log(name + " is abstract");
|
|
353
429
|
break;
|
|
354
430
|
}
|
|
355
431
|
}
|
|
@@ -362,7 +438,8 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
362
438
|
contexts.push(newContext);
|
|
363
439
|
}
|
|
364
440
|
else {
|
|
365
|
-
|
|
441
|
+
if (allowDebugLogs)
|
|
442
|
+
console.log("Class type is unknown and will not generate a component: ", dec.name?.escapedText);
|
|
366
443
|
}
|
|
367
444
|
lastTypeFound = null;
|
|
368
445
|
break;
|
|
@@ -419,7 +496,8 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
419
496
|
break;
|
|
420
497
|
}
|
|
421
498
|
const str = node.getText();
|
|
422
|
-
|
|
499
|
+
if (allowDebugLogs)
|
|
500
|
+
console.log("Unknown assignment:", str, ts.SyntaxKind[node.kind]);
|
|
423
501
|
return str;
|
|
424
502
|
}
|
|
425
503
|
|
|
@@ -427,7 +505,7 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
427
505
|
if (node.kind === ts.SyntaxKind.PublicKeyword) {
|
|
428
506
|
return true;
|
|
429
507
|
}
|
|
430
|
-
else if (node.kind === ts.SyntaxKind.PrivateKeyword) {
|
|
508
|
+
else if (node.kind === ts.SyntaxKind.PrivateKeyword || node.kind === ts.SyntaxKind.ProtectedKeyword) {
|
|
431
509
|
return false;
|
|
432
510
|
}
|
|
433
511
|
|
|
@@ -468,7 +546,8 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
468
546
|
const separatorIndex = typeName.lastIndexOf(".");
|
|
469
547
|
if (separatorIndex > 0) {
|
|
470
548
|
let newName = typeName.substring(separatorIndex + 1);
|
|
471
|
-
|
|
549
|
+
if (allowDebugLogs)
|
|
550
|
+
console.log("Remove import name from type: \"" + typeName + "\" → \"" + newName + "\"");
|
|
472
551
|
typeName = newName;
|
|
473
552
|
}
|
|
474
553
|
|
|
@@ -529,7 +608,8 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
529
608
|
case ts.SyntaxKind.TypeReference:
|
|
530
609
|
const typeRef = node as ts.TypeReferenceNode;
|
|
531
610
|
const typeName = typeRef.typeName.getText();
|
|
532
|
-
|
|
611
|
+
if (allowDebugLogs)
|
|
612
|
+
console.log("TypeReference:", typeName);
|
|
533
613
|
switch (typeName) {
|
|
534
614
|
case "Array":
|
|
535
615
|
break;
|
|
@@ -588,7 +668,8 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
588
668
|
const childResult = tryResolveTypeRecursive(child);
|
|
589
669
|
if (childResult !== undefined) {
|
|
590
670
|
if (res === undefined) res = "";
|
|
591
|
-
|
|
671
|
+
if (allowDebugLogs)
|
|
672
|
+
console.log("Child: " + ts.SyntaxKind[child.kind] + " → " + childResult);
|
|
592
673
|
// if the thing is a generic return as generic result
|
|
593
674
|
if (isInGenericDeclaration && !res.includes("[]")) {
|
|
594
675
|
res = "<" + childResult + ">";
|
|
@@ -618,24 +699,23 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
618
699
|
}
|
|
619
700
|
}
|
|
620
701
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
const
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
});
|
|
702
|
+
|
|
703
|
+
if (process) {
|
|
704
|
+
|
|
705
|
+
if (process.argv.length < 4) {
|
|
706
|
+
console.error("Missing args, call with: <output_dir> <input_files>");
|
|
707
|
+
}
|
|
708
|
+
else {
|
|
709
|
+
const outputDir = process.argv[2];
|
|
710
|
+
const fileNames = process.argv.slice(3);
|
|
711
|
+
fileNames.forEach(fileName => {
|
|
712
|
+
if (!fs.existsSync(fileName)) {
|
|
713
|
+
|
|
714
|
+
}
|
|
715
|
+
else {
|
|
716
|
+
const code = readFileSync(fileName).toString();
|
|
717
|
+
compile(code, fileName, outputDir);
|
|
718
|
+
}
|
|
719
|
+
});
|
|
720
|
+
}
|
|
641
721
|
}
|
package/src/test.ts
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
import { ThisExpression } from "typescript";
|
|
2
2
|
|
|
3
|
+
export class MyTestComponent extends Behaviour {
|
|
4
|
+
private myMethod(){
|
|
5
|
+
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
// export class SkipFieldAndMethod extends Behaviour {
|
|
11
|
+
|
|
12
|
+
// //@nonSerialized
|
|
13
|
+
// myMethod() {
|
|
14
|
+
|
|
15
|
+
// }
|
|
16
|
+
|
|
17
|
+
// // @nonSerialized
|
|
18
|
+
// myField : string;
|
|
19
|
+
|
|
20
|
+
// }
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
// export class ComponentWithUnknownType extends Behaviour {
|
|
24
|
+
// views: SomeUnknownType;
|
|
25
|
+
// }
|
|
26
|
+
|
|
3
27
|
|
|
4
28
|
// export class ComponentWithAnimationClip extends Behaviour implements IPointerClickHandler {
|
|
5
29
|
|
|
@@ -7,9 +31,9 @@ import { ThisExpression } from "typescript";
|
|
|
7
31
|
// animation?: THREE.AnimationClip;
|
|
8
32
|
// }
|
|
9
33
|
|
|
10
|
-
export abstract class MyAbstractComponent extends Behaviour {
|
|
11
|
-
|
|
12
|
-
}
|
|
34
|
+
// export abstract class MyAbstractComponent extends Behaviour {
|
|
35
|
+
// abstract myMethod();
|
|
36
|
+
// }
|
|
13
37
|
|
|
14
38
|
|
|
15
39
|
// export class CameraView extends Behaviour {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// NEEDLE_CODEGEN_START
|
|
2
|
+
// auto generated code - do not edit directly
|
|
3
|
+
|
|
4
|
+
#pragma warning disable
|
|
5
|
+
|
|
6
|
+
namespace Needle.Typescript.GeneratedComponents
|
|
7
|
+
{
|
|
8
|
+
public partial class MyComponent : UnityEngine.MonoBehaviour
|
|
9
|
+
{
|
|
10
|
+
public void OnDisable(){}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// NEEDLE_CODEGEN_END
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __extends = (this && this.__extends) || (function () {
|
|
3
|
+
var extendStatics = function (d, b) {
|
|
4
|
+
extendStatics = Object.setPrototypeOf ||
|
|
5
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
+
return extendStatics(d, b);
|
|
8
|
+
};
|
|
9
|
+
return function (d, b) {
|
|
10
|
+
if (typeof b !== "function" && b !== null)
|
|
11
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
+
extendStatics(d, b);
|
|
13
|
+
function __() { this.constructor = d; }
|
|
14
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
+
};
|
|
16
|
+
})();
|
|
17
|
+
exports.__esModule = true;
|
|
18
|
+
exports.MyComponent = void 0;
|
|
19
|
+
var MyComponent = /** @class */ (function (_super) {
|
|
20
|
+
__extends(MyComponent, _super);
|
|
21
|
+
function MyComponent() {
|
|
22
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
|
23
|
+
}
|
|
24
|
+
MyComponent.prototype.onDisable = function () { };
|
|
25
|
+
return MyComponent;
|
|
26
|
+
}(Behaviour));
|
|
27
|
+
exports.MyComponent = MyComponent;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// NEEDLE_CODEGEN_START
|
|
2
|
+
// auto generated code - do not edit directly
|
|
3
|
+
|
|
4
|
+
#pragma warning disable
|
|
5
|
+
|
|
6
|
+
namespace Needle.Typescript.GeneratedComponents
|
|
7
|
+
{
|
|
8
|
+
public partial class MyComponent : UnityEngine.MonoBehaviour
|
|
9
|
+
{
|
|
10
|
+
public void OnDisable(){}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// NEEDLE_CODEGEN_END
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// NEEDLE_CODEGEN_START
|
|
2
|
+
// auto generated code - do not edit directly
|
|
3
|
+
|
|
4
|
+
#pragma warning disable
|
|
5
|
+
|
|
6
|
+
namespace Needle.Typescript.GeneratedComponents
|
|
7
|
+
{
|
|
8
|
+
public partial class BasicComponet : UnityEngine.MonoBehaviour
|
|
9
|
+
{
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// NEEDLE_CODEGEN_END
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __extends = (this && this.__extends) || (function () {
|
|
3
|
+
var extendStatics = function (d, b) {
|
|
4
|
+
extendStatics = Object.setPrototypeOf ||
|
|
5
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
+
return extendStatics(d, b);
|
|
8
|
+
};
|
|
9
|
+
return function (d, b) {
|
|
10
|
+
if (typeof b !== "function" && b !== null)
|
|
11
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
+
extendStatics(d, b);
|
|
13
|
+
function __() { this.constructor = d; }
|
|
14
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
+
};
|
|
16
|
+
})();
|
|
17
|
+
exports.__esModule = true;
|
|
18
|
+
exports.BasicComponet = void 0;
|
|
19
|
+
var BasicComponet = /** @class */ (function (_super) {
|
|
20
|
+
__extends(BasicComponet, _super);
|
|
21
|
+
function BasicComponet() {
|
|
22
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
|
23
|
+
}
|
|
24
|
+
return BasicComponet;
|
|
25
|
+
}(Behaviour));
|
|
26
|
+
exports.BasicComponet = BasicComponet;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// NEEDLE_CODEGEN_START
|
|
2
|
+
// auto generated code - do not edit directly
|
|
3
|
+
|
|
4
|
+
#pragma warning disable
|
|
5
|
+
|
|
6
|
+
namespace Needle.Typescript.GeneratedComponents
|
|
7
|
+
{
|
|
8
|
+
public partial class BasicComponet : UnityEngine.MonoBehaviour
|
|
9
|
+
{
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// NEEDLE_CODEGEN_END
|
|
File without changes
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __extends = (this && this.__extends) || (function () {
|
|
3
|
+
var extendStatics = function (d, b) {
|
|
4
|
+
extendStatics = Object.setPrototypeOf ||
|
|
5
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
+
return extendStatics(d, b);
|
|
8
|
+
};
|
|
9
|
+
return function (d, b) {
|
|
10
|
+
if (typeof b !== "function" && b !== null)
|
|
11
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
+
extendStatics(d, b);
|
|
13
|
+
function __() { this.constructor = d; }
|
|
14
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
+
};
|
|
16
|
+
})();
|
|
17
|
+
exports.__esModule = true;
|
|
18
|
+
exports.BasicComponet = void 0;
|
|
19
|
+
//@dont-generate-component
|
|
20
|
+
var BasicComponet = /** @class */ (function (_super) {
|
|
21
|
+
__extends(BasicComponet, _super);
|
|
22
|
+
function BasicComponet() {
|
|
23
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
|
24
|
+
}
|
|
25
|
+
return BasicComponet;
|
|
26
|
+
}(Behaviour));
|
|
27
|
+
exports.BasicComponet = BasicComponet;
|
|
File without changes
|