@needle-tools/needle-component-compiler 1.9.1-exp → 1.9.2-exp
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 +1 -1
- package/package.json +1 -1
- package/src/base-compiler.js +3 -2
- package/src/watcher.js +5 -4
- package/COMPILE.bat +0 -1
- package/DEV.bat +0 -1
- package/INSTALL.bat +0 -1
- package/PUBLISH.bat +0 -8
- package/RUN_MANUAL_BLENDER.bat +0 -1
- package/RUN_MANUAL_TEST.bat +0 -1
- package/RUN_TESTS.bat +0 -1
- package/RUN_WATCHERS.bat +0 -1
- package/schemes/MyTestComponent.component.json +0 -1
- package/src/base-compiler.ts +0 -422
- package/src/blender-compiler.ts +0 -103
- package/src/commands.ts +0 -9
- package/src/component-compiler.ts +0 -734
- package/src/test.ts +0 -239
- package/src/watcher.ts +0 -67
- package/test/component.basic.test.ts +0 -52
- package/test/component.methods.test.ts +0 -185
- package/test/component.nonserialized.test.ts +0 -45
- package/test/component.primitives.test.ts +0 -123
- package/test/helpers.ts +0 -72
package/Changelog.md
CHANGED
|
@@ -4,7 +4,7 @@ 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.9.
|
|
7
|
+
## [1.9.2-exp] - 2022-11-12
|
|
8
8
|
- Add first version of blender scheme compiler
|
|
9
9
|
|
|
10
10
|
## [1.9.1] - 2022-11-05
|
package/package.json
CHANGED
package/src/base-compiler.js
CHANGED
|
@@ -70,11 +70,12 @@ var CodeTextWriter = /** @class */ (function () {
|
|
|
70
70
|
if (!fs.existsSync(directory)) {
|
|
71
71
|
fs.mkdirSync(directory, { recursive: true });
|
|
72
72
|
}
|
|
73
|
+
console.log("Writing " + filename + " to " + directory);
|
|
73
74
|
var content = this.lines.join("\r");
|
|
74
75
|
this.lines.length = 0;
|
|
75
|
-
var fullPath =
|
|
76
|
+
var fullPath = directory + "/" + filename;
|
|
76
77
|
fs.writeFileSync(fullPath, content);
|
|
77
|
-
return fullPath;
|
|
78
|
+
return fs.realpathSync(fullPath);
|
|
78
79
|
};
|
|
79
80
|
return CodeTextWriter;
|
|
80
81
|
}());
|
package/src/watcher.js
CHANGED
|
@@ -14,8 +14,8 @@ var DirectoryWatcher = /** @class */ (function () {
|
|
|
14
14
|
}
|
|
15
15
|
DirectoryWatcher.prototype.startWatching = function (dir, writer) {
|
|
16
16
|
var _this = this;
|
|
17
|
-
console.log("Start watching", dir);
|
|
18
|
-
chokidar.watch(dir + "
|
|
17
|
+
// console.log("Start watching", dir);
|
|
18
|
+
chokidar.watch(dir + "/**/*.ts").on('all', function (event, path) {
|
|
19
19
|
try {
|
|
20
20
|
switch (event) {
|
|
21
21
|
case "add":
|
|
@@ -57,7 +57,8 @@ if (args.length < 2) {
|
|
|
57
57
|
console.error("Missing arguments, usage: node watcher.js <directory> <output>");
|
|
58
58
|
process.exit(1);
|
|
59
59
|
}
|
|
60
|
-
var directoryToWatch = args[0];
|
|
61
|
-
var outputDirectory = args[1];
|
|
60
|
+
var directoryToWatch = args[0].replace("\"", "");
|
|
61
|
+
var outputDirectory = args[1].replace("\"", "");
|
|
62
|
+
console.log("Watch: " + directoryToWatch + " and output to: " + outputDirectory);
|
|
62
63
|
var watcher = new DirectoryWatcher();
|
|
63
64
|
watcher.startWatching(directoryToWatch, new blender_compiler_1.BlenderWriter(outputDirectory));
|
package/COMPILE.bat
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
npm run tsc src/component-compiler
|
package/DEV.bat
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
npm install && npm run dev
|
package/INSTALL.bat
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
npm install && timeout 10
|
package/PUBLISH.bat
DELETED
package/RUN_MANUAL_BLENDER.bat
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
npm run tsc src/blender-compiler && node src/blender-compiler.js dist src/test.ts
|
package/RUN_MANUAL_TEST.bat
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
npm run tsc src/component-compiler && node src/component-compiler.js dist src/test.ts
|
package/RUN_TESTS.bat
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
npm run test & pause
|
package/RUN_WATCHERS.bat
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
npm run tsc src/watcher && node src/watcher.js
|
package/src/base-compiler.ts
DELETED
|
@@ -1,422 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from "fs";
|
|
2
|
-
import * as ts from "typescript";
|
|
3
|
-
import * as fs from "fs";
|
|
4
|
-
|
|
5
|
-
export enum Visibility {
|
|
6
|
-
Public = 0,
|
|
7
|
-
Protected = 1,
|
|
8
|
-
Private = 2,
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
declare type Argument = {
|
|
12
|
-
name: string;
|
|
13
|
-
type: string;
|
|
14
|
-
defaultValue?: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export class CodeTextWriter {
|
|
18
|
-
private indent: number = 0;
|
|
19
|
-
private lines: string[] = [];
|
|
20
|
-
|
|
21
|
-
beginBlock(line: string) {
|
|
22
|
-
this.writeLine(line);
|
|
23
|
-
this.indent++;
|
|
24
|
-
}
|
|
25
|
-
endBlock(line: string) {
|
|
26
|
-
// remove the comma from the last line
|
|
27
|
-
if (this.lines.length > 0) {
|
|
28
|
-
const prevLine = this.lines[this.lines.length - 1];
|
|
29
|
-
if (prevLine.endsWith(",")) {
|
|
30
|
-
this.lines[this.lines.length - 1] = prevLine.substring(0, prevLine.length - 1);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
this.indent--;
|
|
35
|
-
this.writeLine(line);
|
|
36
|
-
}
|
|
37
|
-
writeLine(line: string) {
|
|
38
|
-
let indent = "";
|
|
39
|
-
for (let i = 0; i < this.indent; i++) {
|
|
40
|
-
indent += " ";
|
|
41
|
-
}
|
|
42
|
-
// remove whitespace so we can ensure we correctly end with a comma
|
|
43
|
-
this.lines.push(indent + line?.trim());
|
|
44
|
-
}
|
|
45
|
-
write(text: string) {
|
|
46
|
-
const lines = text.split("\r");
|
|
47
|
-
if (lines.length > 1) {
|
|
48
|
-
for (let i = 0; i < lines.length; i++) {
|
|
49
|
-
this.writeLine(lines[i]);
|
|
50
|
-
}
|
|
51
|
-
} else {
|
|
52
|
-
if (this.lines.length == 0) {
|
|
53
|
-
this.writeLine(text);
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
const lastLine = this.lines[this.lines.length - 1];
|
|
57
|
-
this.lines[this.lines.length - 1] = lastLine + text;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
beginArray() {
|
|
62
|
-
this.writeLine("[");
|
|
63
|
-
this.indent++;
|
|
64
|
-
}
|
|
65
|
-
insertArrayItem(item: string) {
|
|
66
|
-
this.writeLine(item + ",");
|
|
67
|
-
}
|
|
68
|
-
endArray() {
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
flush(directory: string, filename: string): string | void {
|
|
73
|
-
if(this.lines.length === 0) return;
|
|
74
|
-
if (!fs.existsSync(directory)) {
|
|
75
|
-
fs.mkdirSync(directory, { recursive: true });
|
|
76
|
-
}
|
|
77
|
-
const content = this.lines.join("\r");
|
|
78
|
-
this.lines.length = 0;
|
|
79
|
-
const fullPath = fs.realpathSync(directory + "/" + filename);
|
|
80
|
-
fs.writeFileSync(fullPath, content);
|
|
81
|
-
return fullPath;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export interface IWriter {
|
|
86
|
-
resolveTypeName(typescriptTypeName: string): string | void;
|
|
87
|
-
begin(): void;
|
|
88
|
-
end(): void;
|
|
89
|
-
startNewType(typeName: string, baseType: string, comments?: string[]): void | boolean;
|
|
90
|
-
endNewType(typeName: string): void;
|
|
91
|
-
writeMember(visibility: Visibility, name: string, isArray: boolean, type: string, initialValue?: string, comments?: string[]): void
|
|
92
|
-
writeMethod(visibility: Visibility, name: string, returnType: string | undefined, args: Argument[], comments: string[]): void
|
|
93
|
-
writeNewTypeExpression(typeName: string, args?: string[]): void;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export function runFromFile(writer: IWriter, path: string): Compiler {
|
|
97
|
-
if (!fs.existsSync(path)) {
|
|
98
|
-
console.error("File not found", path);
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
const code = readFileSync(path).toString();
|
|
102
|
-
const compiler = new Compiler();
|
|
103
|
-
compiler.compile(writer, code);
|
|
104
|
-
return compiler;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export class Compiler {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
compile(writer: IWriter, code: string) {
|
|
111
|
-
const file = "needle_compiled.ts";
|
|
112
|
-
const sourceFile = ts.createSourceFile(
|
|
113
|
-
file,
|
|
114
|
-
code,
|
|
115
|
-
ts.ScriptTarget.ES2015,
|
|
116
|
-
true, /*setParentNodes */
|
|
117
|
-
ts.ScriptKind.TS
|
|
118
|
-
);
|
|
119
|
-
const prog = ts.createProgram([file], {});
|
|
120
|
-
this.run(prog, writer, sourceFile);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
private run(prog: ts.Program, writer: IWriter, sourceFile: ts.SourceFile) {
|
|
124
|
-
writer.begin();
|
|
125
|
-
ts.forEachChild(sourceFile, (node) => {
|
|
126
|
-
this.visit(node, writer);
|
|
127
|
-
});
|
|
128
|
-
writer.end();
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
private visit(node: ts.Node, writer: IWriter) {
|
|
132
|
-
if (ts.isClassDeclaration(node)) {
|
|
133
|
-
this.visitClassDeclaration(node, writer);
|
|
134
|
-
}
|
|
135
|
-
else if (ts.isPropertyDeclaration(node)) {
|
|
136
|
-
this.visitPropertyDeclaration(node, writer);
|
|
137
|
-
}
|
|
138
|
-
else if (ts.isMethodDeclaration(node)) {
|
|
139
|
-
this.visitMethodDeclaration(node, writer);
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
ts.forEachChild(node, (node) => {
|
|
143
|
-
this.visit(node, writer);
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
private visitClassDeclaration(node: ts.ClassDeclaration, writer: IWriter) {
|
|
149
|
-
const name = node.name.text;
|
|
150
|
-
const base = node.heritageClauses && node.heritageClauses[0].types[0].expression.getText();
|
|
151
|
-
this.debugLog("CLASS START", name, base);
|
|
152
|
-
const res = writer.startNewType(name, base, this.getComments(node));
|
|
153
|
-
if (res === false) {
|
|
154
|
-
this.debugLog("CLASS SKIPPED", name);
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
ts.forEachChild(node, (node) => {
|
|
158
|
-
this.visit(node, writer);
|
|
159
|
-
});
|
|
160
|
-
writer.endNewType(name);
|
|
161
|
-
this.debugLog("CLASS END", name, "\n");
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
private visitPropertyDeclaration(node: ts.PropertyDeclaration, writer: IWriter) {
|
|
165
|
-
const name = node.name.getText();
|
|
166
|
-
let type = this.resolveType(node.type, writer);
|
|
167
|
-
const visibility = this.getVisibility(node);
|
|
168
|
-
const initialValue = node.initializer && this.resolveExpression(node.initializer, writer);
|
|
169
|
-
const isArray = this.isArrayType(node.type);
|
|
170
|
-
if (!type && node.initializer) {
|
|
171
|
-
type = this.tryResolveTypeFromExpression(node.initializer, writer);
|
|
172
|
-
}
|
|
173
|
-
this.debugLog("PROPERTY", Visibility[visibility], name, isArray, type, initialValue);
|
|
174
|
-
writer.writeMember(visibility, name, isArray, type, initialValue, this.getComments(node));
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
private visitMethodDeclaration(node: ts.MethodDeclaration, writer: IWriter) {
|
|
178
|
-
const name = node.name.getText();
|
|
179
|
-
const visibility = this.getVisibility(node);
|
|
180
|
-
const returnType = this.resolveType(node.type, writer);
|
|
181
|
-
let args: Argument[] | undefined;
|
|
182
|
-
if (node.parameters?.length) {
|
|
183
|
-
args = this.resolveParameters(node.parameters, writer);
|
|
184
|
-
}
|
|
185
|
-
this.debugLog("METHOD", Visibility[visibility], name, returnType, args);
|
|
186
|
-
writer.writeMethod(visibility, name, returnType, args, this.getComments(node));
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
private resolveParameters(parameters: ts.NodeArray<ts.ParameterDeclaration>, writer: IWriter): Argument[] {
|
|
190
|
-
const result: Argument[] = [];
|
|
191
|
-
for (const parameter of parameters) {
|
|
192
|
-
const name = parameter.name.getText();
|
|
193
|
-
const type = this.resolveType(parameter.type, writer);
|
|
194
|
-
const defaultValue = parameter.initializer && this.resolveExpression(parameter.initializer, writer);
|
|
195
|
-
result.push({ name, type, defaultValue });
|
|
196
|
-
}
|
|
197
|
-
return result;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
private debugLog(...args: any[]) {
|
|
201
|
-
console.log(...args);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
private getComments(node: ts.Node): string[] | undefined {
|
|
205
|
-
const commentRanges = ts.getLeadingCommentRanges(node.getFullText(), 0);
|
|
206
|
-
if (commentRanges) {
|
|
207
|
-
const comments: string[] = [];
|
|
208
|
-
for (const range of commentRanges) {
|
|
209
|
-
const text = node.getFullText().substring(range.pos, range.end).trimStart();
|
|
210
|
-
// match only lines that starts with //@ or // @
|
|
211
|
-
const match = text.match(/\/\/\s*@(.+)/);
|
|
212
|
-
if (match) {
|
|
213
|
-
comments.push(text.substring(match.index + 2).trim());
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
return comments;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
private getVisibility(node: ts.PropertyDeclaration | ts.MethodDeclaration): Visibility {
|
|
221
|
-
if (node.modifiers) {
|
|
222
|
-
for (const modifier of node.modifiers) {
|
|
223
|
-
if (modifier.kind === ts.SyntaxKind.PublicKeyword) {
|
|
224
|
-
return Visibility.Public;
|
|
225
|
-
}
|
|
226
|
-
else if (modifier.kind === ts.SyntaxKind.ProtectedKeyword) {
|
|
227
|
-
return Visibility.Protected;
|
|
228
|
-
}
|
|
229
|
-
else if (modifier.kind === ts.SyntaxKind.PrivateKeyword) {
|
|
230
|
-
return Visibility.Private;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
return Visibility.Public;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
private tryResolveTypeFromExpression(exp: ts.Expression, write: IWriter): string | undefined {
|
|
238
|
-
if (ts.isNewExpression(exp)) {
|
|
239
|
-
// try get generic type from expression
|
|
240
|
-
if (exp.typeArguments?.length) {
|
|
241
|
-
for (const arg of exp.typeArguments) {
|
|
242
|
-
const type = this.resolveType(arg, write);
|
|
243
|
-
if (type) {
|
|
244
|
-
return type;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
const typeName = exp.expression.getText();
|
|
251
|
-
// const typeName = exp.expression.getText();
|
|
252
|
-
// console.log("NEW EXPRESSION", typeName);
|
|
253
|
-
// const args = exp.arguments?.map(arg => this.resolveExpression(arg, write));
|
|
254
|
-
// write.writeNewTypeExpression(typeName, args);
|
|
255
|
-
return typeName;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
private resolveType(typeNode: ts.TypeNode, writer: IWriter): string | undefined {
|
|
260
|
-
if (!typeNode) return undefined;
|
|
261
|
-
// check if its an array
|
|
262
|
-
if (this.isArrayType(typeNode)) {
|
|
263
|
-
if (typeNode.kind === ts.SyntaxKind.ArrayType) {
|
|
264
|
-
const arrayType = typeNode as ts.ArrayTypeNode;
|
|
265
|
-
return this.resolveType(arrayType.elementType, writer);
|
|
266
|
-
}
|
|
267
|
-
// check if its Array<> or Map
|
|
268
|
-
if (typeNode.kind === ts.SyntaxKind.TypeReference) {
|
|
269
|
-
const typeReference = typeNode as ts.TypeReferenceNode;
|
|
270
|
-
if (typeReference.typeName.getText() === "Array") {
|
|
271
|
-
const typeArgument = typeReference.typeArguments && typeReference.typeArguments[0];
|
|
272
|
-
return this.resolveType(typeArgument, writer);
|
|
273
|
-
}
|
|
274
|
-
else if (typeReference.typeName.getText() === "Map") {
|
|
275
|
-
const typeArgument = typeReference.typeArguments && typeReference.typeArguments[0];
|
|
276
|
-
return this.resolveType(typeArgument, writer);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
// check if its dictionary
|
|
280
|
-
if (typeNode.kind === ts.SyntaxKind.TypeLiteral) {
|
|
281
|
-
const typeLiteral = typeNode as ts.TypeLiteralNode;
|
|
282
|
-
const members = typeLiteral.members;
|
|
283
|
-
if (members.length === 2) {
|
|
284
|
-
const firstMember = members[0];
|
|
285
|
-
const secondMember = members[1];
|
|
286
|
-
if (firstMember.kind === ts.SyntaxKind.IndexSignature && secondMember.kind === ts.SyntaxKind.IndexSignature) {
|
|
287
|
-
const firstIndexSignature = firstMember as ts.IndexSignatureDeclaration;
|
|
288
|
-
const secondIndexSignature = secondMember as ts.IndexSignatureDeclaration;
|
|
289
|
-
const firstIndexType = firstIndexSignature.parameters[0].type;
|
|
290
|
-
const secondIndexType = secondIndexSignature.parameters[0].type;
|
|
291
|
-
if (firstIndexType.kind === ts.SyntaxKind.StringKeyword && secondIndexType.kind === ts.SyntaxKind.NumberKeyword) {
|
|
292
|
-
const valueType = firstIndexSignature.type;
|
|
293
|
-
return this.resolveType(valueType, writer);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
// is generic
|
|
299
|
-
// if (typeNode.kind === ts.SyntaxKind.TypeReference) {
|
|
300
|
-
// const typeReference = typeNode as ts.TypeReferenceNode;
|
|
301
|
-
// const typeArgument = typeReference.typeArguments && typeReference.typeArguments[0];
|
|
302
|
-
// return this.resolveType(typeArgument, writer);
|
|
303
|
-
// }
|
|
304
|
-
console.error("!!!!! ----- Unknown array type", typeNode.getText());
|
|
305
|
-
}
|
|
306
|
-
const type = typeNode.getText();
|
|
307
|
-
return this.resolveTypeFromString(type, writer);
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
private resolveTypeFromString(type: string, writer: IWriter): string | undefined {
|
|
311
|
-
const resolved = writer.resolveTypeName(type);
|
|
312
|
-
return resolved || type;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
private isArrayType(typeNode: ts.TypeNode): boolean {
|
|
316
|
-
if (!typeNode) return false;
|
|
317
|
-
// check if its an array
|
|
318
|
-
if (typeNode.kind === ts.SyntaxKind.ArrayType) {
|
|
319
|
-
return true;
|
|
320
|
-
}
|
|
321
|
-
// check if its Array<> or map
|
|
322
|
-
if (typeNode.kind === ts.SyntaxKind.TypeReference) {
|
|
323
|
-
const typeReference = typeNode as ts.TypeReferenceNode;
|
|
324
|
-
if (typeReference.typeName.getText() === "Array") {
|
|
325
|
-
return true;
|
|
326
|
-
}
|
|
327
|
-
else if (typeReference.typeName.getText() === "Map") {
|
|
328
|
-
return true;
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
// check if its array or dictionary
|
|
332
|
-
if (typeNode.kind === ts.SyntaxKind.TypeLiteral) {
|
|
333
|
-
const typeLiteral = typeNode as ts.TypeLiteralNode;
|
|
334
|
-
if (typeLiteral.members.length === 2) {
|
|
335
|
-
const first = typeLiteral.members[0];
|
|
336
|
-
const second = typeLiteral.members[1];
|
|
337
|
-
if (first.kind === ts.SyntaxKind.IndexSignature && second.kind === ts.SyntaxKind.IndexSignature) {
|
|
338
|
-
return true;
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
return false;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
private resolveExpression(node: ts.Expression, writer: IWriter): string | undefined {
|
|
346
|
-
if (ts.isStringLiteral(node)) {
|
|
347
|
-
return this.resolveTypeFromString(node.text, writer);
|
|
348
|
-
}
|
|
349
|
-
else if (ts.isNumericLiteral(node)) {
|
|
350
|
-
return this.resolveTypeFromString(node.text, writer);
|
|
351
|
-
}
|
|
352
|
-
else if (ts.isIdentifier(node)) {
|
|
353
|
-
return this.resolveTypeFromString(node.text, writer);
|
|
354
|
-
}
|
|
355
|
-
// is true or false
|
|
356
|
-
else if (node.kind === ts.SyntaxKind.TrueKeyword || node.kind === ts.SyntaxKind.FalseKeyword) {
|
|
357
|
-
return this.resolveTypeFromString(node.getText(), writer);
|
|
358
|
-
}
|
|
359
|
-
else if (ts.isPropertyAccessExpression(node)) {
|
|
360
|
-
const left = this.resolveExpression(node.expression, writer);
|
|
361
|
-
if (left) {
|
|
362
|
-
return left + "." + this.resolveTypeFromString(node.name.text, writer);
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
else if (ts.isCallExpression(node)) {
|
|
366
|
-
const left = this.resolveExpression(node.expression, writer);
|
|
367
|
-
if (left) {
|
|
368
|
-
const args = node.arguments.map(a => this.resolveExpression(a, writer)).filter(a => a);
|
|
369
|
-
return left + "(" + args.join(", ") + ")";
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
else if (ts.isBinaryExpression(node)) {
|
|
373
|
-
const left = this.resolveExpression(node.left, writer);
|
|
374
|
-
const right = this.resolveExpression(node.right, writer);
|
|
375
|
-
if (left && right) {
|
|
376
|
-
return left + " " + node.operatorToken.getText() + " " + right;
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
else if (ts.isPrefixUnaryExpression(node)) {
|
|
380
|
-
const operand = this.resolveExpression(node.operand, writer);
|
|
381
|
-
if (operand) {
|
|
382
|
-
return node.operator + operand;
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
else if (ts.isPostfixUnaryExpression(node)) {
|
|
386
|
-
const operand = this.resolveExpression(node.operand, writer);
|
|
387
|
-
if (operand) {
|
|
388
|
-
return operand + node.operator;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
else if (ts.isParenthesizedExpression(node)) {
|
|
392
|
-
return this.resolveExpression(node.expression, writer);
|
|
393
|
-
}
|
|
394
|
-
else if (ts.isArrayLiteralExpression(node)) {
|
|
395
|
-
const elements = node.elements.map(e => this.resolveExpression(e, writer)).filter(e => e);
|
|
396
|
-
return "[" + elements.join(", ") + "]";
|
|
397
|
-
}
|
|
398
|
-
else if (ts.isObjectLiteralExpression(node)) {
|
|
399
|
-
const properties = node.properties.map(p => {
|
|
400
|
-
if (ts.isPropertyAssignment(p)) {
|
|
401
|
-
const name = p.name.getText();
|
|
402
|
-
const value = this.resolveExpression(p.initializer, writer);
|
|
403
|
-
if (value) {
|
|
404
|
-
return name + ": " + value;
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
}).filter(p => p);
|
|
408
|
-
return "{" + properties.join(", ") + "}";
|
|
409
|
-
}
|
|
410
|
-
else if (ts.isNewExpression(node)) {
|
|
411
|
-
const typeName = this.resolveTypeFromString(node.expression.getText(), writer);
|
|
412
|
-
if (typeName) {
|
|
413
|
-
const args = node.arguments.map(a => this.resolveExpression(a, writer)).filter(a => a);
|
|
414
|
-
// writer.writeNewTypeExpression(typeName, args);
|
|
415
|
-
// return;
|
|
416
|
-
return "new " + typeName + "(" + args.join(", ") + ")";
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
console.error("!!!!! ----- Unknown expression", ts.SyntaxKind[node.kind], node.getText());
|
|
421
|
-
}
|
|
422
|
-
}
|
package/src/blender-compiler.ts
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { type } from "os";
|
|
2
|
-
import { isatty } from "tty";
|
|
3
|
-
import { CodeTextWriter, IWriter, runFromFile, Visibility } from "./base-compiler";
|
|
4
|
-
import { sendFileWrittenCommand } from "./commands";
|
|
5
|
-
|
|
6
|
-
const supportedTypes = ["string", "float", "int", "bool", "col", "obj", "evt", "fn"];
|
|
7
|
-
|
|
8
|
-
export class BlenderWriter implements IWriter {
|
|
9
|
-
|
|
10
|
-
private outputDirectory: string;
|
|
11
|
-
private writer: CodeTextWriter = new CodeTextWriter();
|
|
12
|
-
|
|
13
|
-
constructor(outputDirectory: string) {
|
|
14
|
-
this.outputDirectory = outputDirectory;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
resolveTypeName(typeName: string, comments?: string[]): string | void {
|
|
18
|
-
typeName = typeName.toLocaleLowerCase();
|
|
19
|
-
if (typeName.startsWith("three."))
|
|
20
|
-
typeName = typeName.substring("three.".length);
|
|
21
|
-
switch (typeName) {
|
|
22
|
-
case "number":
|
|
23
|
-
return "float";
|
|
24
|
-
case "int":
|
|
25
|
-
return "int";
|
|
26
|
-
case "boolean":
|
|
27
|
-
return "bool";
|
|
28
|
-
case "string":
|
|
29
|
-
return "string";
|
|
30
|
-
case "void":
|
|
31
|
-
return "void";
|
|
32
|
-
case "any":
|
|
33
|
-
return "any";
|
|
34
|
-
case "vector2":
|
|
35
|
-
return "vec2";
|
|
36
|
-
case "color":
|
|
37
|
-
return "col";
|
|
38
|
-
case "renderer":
|
|
39
|
-
return "comp";
|
|
40
|
-
case "eventlist":
|
|
41
|
-
return "evt";
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
begin(): void {
|
|
45
|
-
// this.writer.beginBlock("{")
|
|
46
|
-
}
|
|
47
|
-
end(): void {
|
|
48
|
-
// this.writer.endBlock("}");
|
|
49
|
-
// this.writer.flush(this.outputFilePath);
|
|
50
|
-
}
|
|
51
|
-
startNewType(typeName: string, baseType: string, comments?: string[]): void | boolean {
|
|
52
|
-
if (baseType !== "Behaviour") return false;
|
|
53
|
-
this.writer.beginBlock("{")
|
|
54
|
-
if (comments) console.log(comments);
|
|
55
|
-
this.writer.beginBlock("\"" + typeName + "\": {");
|
|
56
|
-
}
|
|
57
|
-
endNewType(typeName: string): void {
|
|
58
|
-
this.writer.endBlock("},");
|
|
59
|
-
this.writer.endBlock("}");
|
|
60
|
-
this.writeScheme(typeName);
|
|
61
|
-
}
|
|
62
|
-
writeMember(visibility: Visibility, name: string, isArray: boolean, type: string, initialValue?: string, comments?: string[]): void {
|
|
63
|
-
if (!supportedTypes.includes(type)) {
|
|
64
|
-
console.log("-- unsupported type:", type);
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
this.writer.beginBlock("\"" + name + "\": {");
|
|
68
|
-
this.writer.writeLine("\"type\": \"" + type + "\",");
|
|
69
|
-
if (initialValue && !isArray) {
|
|
70
|
-
if (initialValue.startsWith("new ")) initialValue = undefined;
|
|
71
|
-
switch (type) {
|
|
72
|
-
case "bool":
|
|
73
|
-
initialValue = initialValue.toLowerCase();
|
|
74
|
-
break;
|
|
75
|
-
case "string":
|
|
76
|
-
initialValue = "\"" + initialValue + "\"";
|
|
77
|
-
}
|
|
78
|
-
if (initialValue)
|
|
79
|
-
this.writer.writeLine("\"value\": " + initialValue);
|
|
80
|
-
}
|
|
81
|
-
if (isArray) {
|
|
82
|
-
this.writer.writeLine("\"isArray\": true");
|
|
83
|
-
}
|
|
84
|
-
this.writer.endBlock("},");
|
|
85
|
-
}
|
|
86
|
-
writeMethod(visibility: Visibility, name: string, returnType: string | undefined, args: { name: string; type: string; defaultValue?: string }[], comments?: string[]): void {
|
|
87
|
-
this.writer.beginBlock("\"" + name + "\": {");
|
|
88
|
-
this.writer.writeLine("\"type\": \"fn\",");
|
|
89
|
-
this.writer.endBlock("},");
|
|
90
|
-
}
|
|
91
|
-
writeNewTypeExpression(typeName: string, args?: string[]): void {
|
|
92
|
-
console.log("new type:", typeName);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
private writeScheme(component: string) {
|
|
96
|
-
const outputPath = this.writer.flush(this.outputDirectory, component + ".component.json");
|
|
97
|
-
if (outputPath)
|
|
98
|
-
sendFileWrittenCommand(outputPath);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// runFromFile(new BlenderWriter("dist"), "src\\test.ts");
|