@needle-tools/needle-component-compiler 1.0.1 → 1.1.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/Readme.md +8 -1
- package/dist/PointOfInterest.cs +14 -0
- package/package.json +1 -1
- package/src/component-compiler.js +23 -5
- package/src/component-compiler.ts +25 -9
- package/src/test.ts +18 -3
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.1.0] - 2022-06-13
|
|
8
|
+
- add ``@type(MyNamespace.MyType)`` decorator for fields to specifiy C# type
|
|
9
|
+
- add minimal docs to readme
|
|
10
|
+
- dont emit comments anymore
|
|
11
|
+
- make created classes partial
|
|
12
|
+
|
|
7
13
|
## [1.0.1] - 2022-05-29
|
|
8
14
|
- disable all warnings for generated scripts
|
|
9
15
|
- add mesh and texture types
|
package/Readme.md
CHANGED
|
@@ -4,4 +4,11 @@ Little helper package to transpile typescript files to Unity C# components.
|
|
|
4
4
|
Please run ``npm install`` first before using.
|
|
5
5
|
|
|
6
6
|
### Usage
|
|
7
|
-
``node <path to>/component-compiler.js <output_directory> <path_to/my_script.ts>``
|
|
7
|
+
``node <path to>/component-compiler.js <output_directory> <path_to/my_script.ts>``
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Command decorators
|
|
11
|
+
- ``@dont-generate-component`` add before class to skip generating a component
|
|
12
|
+
- ``@generate-component`` to enforce generating a component (not required)
|
|
13
|
+
- ``@serializeField`` field decorator, similar to ``[SerializeField]``
|
|
14
|
+
- ``@type(MyNamespace.MyType)`` field decorator, specifiy C# type of field
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// auto generated code - do not edit directly
|
|
2
|
+
|
|
3
|
+
#pragma warning disable
|
|
4
|
+
|
|
5
|
+
namespace Needle.Typescript.GeneratedComponents
|
|
6
|
+
{
|
|
7
|
+
public partial class PointOfInterest : UnityEngine.MonoBehaviour
|
|
8
|
+
{
|
|
9
|
+
public float @myVal = 12f;
|
|
10
|
+
public void myFunction(){}
|
|
11
|
+
public UnityEngine.Camera @view;
|
|
12
|
+
public string @test = "123";
|
|
13
|
+
}
|
|
14
|
+
}
|
package/package.json
CHANGED
|
@@ -11,6 +11,7 @@ var exportNextClassCommand = "@generate-component";
|
|
|
11
11
|
var dontExportNextClassCommand = "@dont-generate-component";
|
|
12
12
|
// add above field to add [SerializeField] attribute
|
|
13
13
|
var serializeCommand = "@serializeField";
|
|
14
|
+
var typePattern = new RegExp("@type\((?<type>.+)\)");
|
|
14
15
|
// will be set to true when e.g. a comment for export is found
|
|
15
16
|
var exportNextClass = false;
|
|
16
17
|
var dontExportNextClass = false;
|
|
@@ -65,6 +66,7 @@ var ExportContext = /** @class */ (function () {
|
|
|
65
66
|
return ExportContext;
|
|
66
67
|
}());
|
|
67
68
|
var contexts = [];
|
|
69
|
+
var lastTypeFound = null;
|
|
68
70
|
function run(program, outputDir, sourceFile) {
|
|
69
71
|
if (!fs.existsSync(outputDir)) {
|
|
70
72
|
console.error("Output directory does not exist: \"" + outputDir + "\"");
|
|
@@ -105,8 +107,21 @@ function run(program, outputDir, sourceFile) {
|
|
|
105
107
|
}
|
|
106
108
|
else if (comment.includes(serializeCommand))
|
|
107
109
|
serializeField = true;
|
|
108
|
-
else
|
|
109
|
-
|
|
110
|
+
else {
|
|
111
|
+
console.log(comment);
|
|
112
|
+
var match = typePattern.exec(comment);
|
|
113
|
+
if (match && match.groups) {
|
|
114
|
+
// for some reason our regex does also match surrounding ( ) even tho: https://regex101.com/r/PoWK6V/1
|
|
115
|
+
// so we remove them
|
|
116
|
+
var type = match.groups["type"];
|
|
117
|
+
if (type.startsWith("("))
|
|
118
|
+
type = type.slice(1);
|
|
119
|
+
if (type.endsWith(")"))
|
|
120
|
+
type = type.slice(0, -1);
|
|
121
|
+
console.log("found type: ", type);
|
|
122
|
+
lastTypeFound = type;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
110
125
|
}
|
|
111
126
|
if (comment.includes(exportNextClassCommand))
|
|
112
127
|
exportNextClass = true;
|
|
@@ -122,6 +137,7 @@ function run(program, outputDir, sourceFile) {
|
|
|
122
137
|
case ts.SyntaxKind.Decorator:
|
|
123
138
|
break;
|
|
124
139
|
case ts.SyntaxKind.MethodDeclaration:
|
|
140
|
+
lastTypeFound = null;
|
|
125
141
|
serializeField = false;
|
|
126
142
|
resetExportNextClass();
|
|
127
143
|
if (!context)
|
|
@@ -158,7 +174,7 @@ function run(program, outputDir, sourceFile) {
|
|
|
158
174
|
console.log(name_1);
|
|
159
175
|
if (name_1.startsWith("\"@") || name_1.startsWith("\"$") || name_1.startsWith("$"))
|
|
160
176
|
break;
|
|
161
|
-
var typeString = tryResolveTypeRecursive(node);
|
|
177
|
+
var typeString = lastTypeFound !== null && lastTypeFound !== void 0 ? lastTypeFound : tryResolveTypeRecursive(node);
|
|
162
178
|
if (typeString === undefined) {
|
|
163
179
|
context.append("// Could not resolve type \"" + ((_c = vardec.type) === null || _c === void 0 ? void 0 : _c.getText()) + "\"\n");
|
|
164
180
|
}
|
|
@@ -197,9 +213,11 @@ function run(program, outputDir, sourceFile) {
|
|
|
197
213
|
context.appendLine("[UnityEngine.SerializeField]");
|
|
198
214
|
}
|
|
199
215
|
context.append(prefix + visibility + " " + typeString + " " + varName + assignment + ";\n");
|
|
216
|
+
lastTypeFound = null;
|
|
200
217
|
break;
|
|
201
218
|
case ts.SyntaxKind.ClassDeclaration:
|
|
202
219
|
serializeField = false;
|
|
220
|
+
lastTypeFound = null;
|
|
203
221
|
var dec = node;
|
|
204
222
|
// a class must inherit a component
|
|
205
223
|
if (!dontExportNextClass && (exportNextClass || testInheritsComponent(node))) {
|
|
@@ -207,7 +225,7 @@ function run(program, outputDir, sourceFile) {
|
|
|
207
225
|
var name_2 = dec.name.escapedText;
|
|
208
226
|
console.log("Found class: ", name_2);
|
|
209
227
|
var newContext = new ExportContext(outputDir, name_2 + ".cs");
|
|
210
|
-
newContext.appendLine("// auto generated code - do not edit");
|
|
228
|
+
newContext.appendLine("// auto generated code - do not edit directly");
|
|
211
229
|
newContext.appendLine("");
|
|
212
230
|
newContext.appendLine("#pragma warning disable");
|
|
213
231
|
newContext.appendLine("");
|
|
@@ -215,7 +233,7 @@ function run(program, outputDir, sourceFile) {
|
|
|
215
233
|
newContext.appendLine("{");
|
|
216
234
|
newContext.indentLevel += 1;
|
|
217
235
|
// newContext.appendLine("// source: " + path.resolve(sourceFile.fileName));
|
|
218
|
-
newContext.appendLine("public class " + name_2 + " : UnityEngine.MonoBehaviour");
|
|
236
|
+
newContext.appendLine("public partial class " + name_2 + " : UnityEngine.MonoBehaviour");
|
|
219
237
|
newContext.appendLine("{");
|
|
220
238
|
newContext.indentLevel += 1;
|
|
221
239
|
newContext.classEnd = dec.end;
|
|
@@ -11,6 +11,7 @@ const exportNextClassCommand = "@generate-component";
|
|
|
11
11
|
const dontExportNextClassCommand = "@dont-generate-component";
|
|
12
12
|
// add above field to add [SerializeField] attribute
|
|
13
13
|
const serializeCommand = "@serializeField";
|
|
14
|
+
const typePattern = new RegExp("@type\((?<type>.+)\)");
|
|
14
15
|
|
|
15
16
|
// will be set to true when e.g. a comment for export is found
|
|
16
17
|
let exportNextClass: boolean = false;
|
|
@@ -80,6 +81,8 @@ class ExportContext {
|
|
|
80
81
|
|
|
81
82
|
const contexts: ExportContext[] = [];
|
|
82
83
|
|
|
84
|
+
let lastTypeFound : string | null = null;
|
|
85
|
+
|
|
83
86
|
export function run(program: ts.Program, outputDir: string, sourceFile: ts.SourceFile) {
|
|
84
87
|
|
|
85
88
|
if (!fs.existsSync(outputDir)) {
|
|
@@ -125,8 +128,19 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
125
128
|
}
|
|
126
129
|
else if (comment.includes(serializeCommand))
|
|
127
130
|
serializeField = true;
|
|
128
|
-
else
|
|
129
|
-
|
|
131
|
+
else {
|
|
132
|
+
console.log(comment);
|
|
133
|
+
const match = typePattern.exec(comment);
|
|
134
|
+
if(match && match.groups){
|
|
135
|
+
// for some reason our regex does also match surrounding ( ) even tho: https://regex101.com/r/PoWK6V/1
|
|
136
|
+
// so we remove them
|
|
137
|
+
let type = match.groups["type"];
|
|
138
|
+
if(type.startsWith("(")) type = type.slice(1);
|
|
139
|
+
if(type.endsWith(")")) type = type.slice(0, -1);
|
|
140
|
+
console.log("found type: ", type);
|
|
141
|
+
lastTypeFound = type;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
130
144
|
}
|
|
131
145
|
if (comment.includes(exportNextClassCommand))
|
|
132
146
|
exportNextClass = true;
|
|
@@ -143,6 +157,7 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
143
157
|
case ts.SyntaxKind.Decorator:
|
|
144
158
|
break;
|
|
145
159
|
case ts.SyntaxKind.MethodDeclaration:
|
|
160
|
+
lastTypeFound = null;
|
|
146
161
|
serializeField = false;
|
|
147
162
|
resetExportNextClass();
|
|
148
163
|
if (!context) break;
|
|
@@ -174,7 +189,7 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
174
189
|
const name = vardec.name.getText();
|
|
175
190
|
console.log(name);
|
|
176
191
|
if (name.startsWith("\"@") || name.startsWith("\"$") || name.startsWith("$")) break;
|
|
177
|
-
let typeString = tryResolveTypeRecursive(node);
|
|
192
|
+
let typeString = lastTypeFound ?? tryResolveTypeRecursive(node);
|
|
178
193
|
if (typeString === undefined) {
|
|
179
194
|
context.append("// Could not resolve type \"" + vardec.type?.getText() + "\"\n");
|
|
180
195
|
}
|
|
@@ -212,10 +227,12 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
212
227
|
context.appendLine("[UnityEngine.SerializeField]");
|
|
213
228
|
}
|
|
214
229
|
context.append(prefix + visibility + " " + typeString + " " + varName + assignment + ";\n");
|
|
230
|
+
lastTypeFound = null;
|
|
215
231
|
break;
|
|
216
232
|
|
|
217
233
|
case ts.SyntaxKind.ClassDeclaration:
|
|
218
234
|
serializeField = false;
|
|
235
|
+
lastTypeFound = null;
|
|
219
236
|
const dec = <ts.ClassDeclaration>node;
|
|
220
237
|
// a class must inherit a component
|
|
221
238
|
if (!dontExportNextClass && (exportNextClass || testInheritsComponent(node))) {
|
|
@@ -231,7 +248,7 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
231
248
|
newContext.appendLine("{");
|
|
232
249
|
newContext.indentLevel += 1;
|
|
233
250
|
// newContext.appendLine("// source: " + path.resolve(sourceFile.fileName));
|
|
234
|
-
newContext.appendLine("public class " + name + " : UnityEngine.MonoBehaviour");
|
|
251
|
+
newContext.appendLine("public partial class " + name + " : UnityEngine.MonoBehaviour");
|
|
235
252
|
newContext.appendLine("{");
|
|
236
253
|
newContext.indentLevel += 1;
|
|
237
254
|
newContext.classEnd = dec.end;
|
|
@@ -278,7 +295,7 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
278
295
|
if (!node) return undefined;
|
|
279
296
|
|
|
280
297
|
// skip decorators (e.g. @serializable() may break array generation)
|
|
281
|
-
if(node.kind === ts.SyntaxKind.Decorator)
|
|
298
|
+
if (node.kind === ts.SyntaxKind.Decorator)
|
|
282
299
|
return undefined;
|
|
283
300
|
|
|
284
301
|
let typeName = node?.getText();
|
|
@@ -326,12 +343,11 @@ export function run(program: ts.Program, outputDir: string, sourceFile: ts.Sourc
|
|
|
326
343
|
console.log("Child type: " + ts.SyntaxKind[child.kind]);
|
|
327
344
|
res = tryResolveTypeRecursive(child);
|
|
328
345
|
}
|
|
329
|
-
|
|
330
|
-
if(ts.isTypeReferenceNode(node)){
|
|
346
|
+
|
|
347
|
+
if (ts.isTypeReferenceNode(node)) {
|
|
331
348
|
const typeRef = node as ts.TypeReferenceNode;
|
|
332
349
|
const typeName = typeRef.typeName.getText();
|
|
333
|
-
switch(typeName)
|
|
334
|
-
{
|
|
350
|
+
switch (typeName) {
|
|
335
351
|
case "Array":
|
|
336
352
|
res += "[]";
|
|
337
353
|
return res;
|
package/src/test.ts
CHANGED
|
@@ -2,12 +2,27 @@
|
|
|
2
2
|
// @generate-component
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
export class
|
|
5
|
+
export class PointOfInterest extends Behaviour {
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
myVal:number = 12;
|
|
8
|
+
|
|
9
|
+
// @type(HELLO)
|
|
10
|
+
myFunction(){
|
|
11
|
+
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// @type(UnityEngine.Camera)
|
|
15
|
+
view?:Camera;
|
|
16
|
+
test:string = "123";
|
|
17
|
+
// test
|
|
9
18
|
}
|
|
10
19
|
|
|
20
|
+
// export class MaterialColorHandler extends Behaviour {
|
|
21
|
+
|
|
22
|
+
// @serializeable(Renderer)
|
|
23
|
+
// renderer?: Renderer[];
|
|
24
|
+
// }
|
|
25
|
+
|
|
11
26
|
// export class MyArray extends Behaviour {
|
|
12
27
|
|
|
13
28
|
// arr? : Array<number> = [1,2,3];
|