@openwebf/webf 0.22.3 → 0.22.4
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/dist/IDLBlob.js +17 -0
- package/dist/analyzer.js +578 -0
- package/dist/analyzer_original.js +467 -0
- package/dist/commands.js +704 -0
- package/dist/dart.js +300 -0
- package/dist/declaration.js +63 -0
- package/dist/generator.js +466 -0
- package/dist/logger.js +103 -0
- package/dist/react.js +283 -0
- package/dist/utils.js +127 -0
- package/dist/vue.js +159 -0
- package/package.json +8 -1
- package/src/dart.ts +138 -7
- package/templates/class.dart.tpl +7 -2
- package/templates/react.package.json.tpl +1 -1
- package/CLAUDE.md +0 -206
- package/README-zhCN.md +0 -256
- package/TYPING_GUIDE.md +0 -208
- package/coverage/clover.xml +0 -1295
- package/coverage/coverage-final.json +0 -12
- package/coverage/lcov-report/IDLBlob.ts.html +0 -142
- package/coverage/lcov-report/analyzer.ts.html +0 -2158
- package/coverage/lcov-report/analyzer_original.ts.html +0 -1450
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/commands.ts.html +0 -700
- package/coverage/lcov-report/dart.ts.html +0 -490
- package/coverage/lcov-report/declaration.ts.html +0 -337
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/generator.ts.html +0 -1171
- package/coverage/lcov-report/index.html +0 -266
- package/coverage/lcov-report/logger.ts.html +0 -424
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/react.ts.html +0 -619
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -196
- package/coverage/lcov-report/utils.ts.html +0 -466
- package/coverage/lcov-report/vue.ts.html +0 -613
- package/coverage/lcov.info +0 -2149
- package/global.d.ts +0 -2
- package/jest.config.js +0 -24
- package/tsconfig.json +0 -30
package/dist/IDLBlob.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IDLBlob = void 0;
|
|
4
|
+
class IDLBlob {
|
|
5
|
+
constructor(source, dist, filename, implement, relativeDir = '') {
|
|
6
|
+
this.raw = '';
|
|
7
|
+
this.relativeDir = '';
|
|
8
|
+
this.objects = [];
|
|
9
|
+
this.source = source;
|
|
10
|
+
this.dist = dist;
|
|
11
|
+
this.filename = filename;
|
|
12
|
+
this.implement = implement;
|
|
13
|
+
this.relativeDir = relativeDir;
|
|
14
|
+
// Don't read file in constructor - let the generator handle it
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.IDLBlob = IDLBlob;
|
package/dist/analyzer.js
ADDED
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.analyzer = analyzer;
|
|
37
|
+
exports.buildClassRelationship = buildClassRelationship;
|
|
38
|
+
exports.clearCaches = clearCaches;
|
|
39
|
+
const typescript_1 = __importStar(require("typescript"));
|
|
40
|
+
const declaration_1 = require("./declaration");
|
|
41
|
+
const utils_1 = require("./utils");
|
|
42
|
+
// Cache for parsed source files to avoid re-parsing
|
|
43
|
+
const sourceFileCache = new Map();
|
|
44
|
+
// Cache for type conversions to avoid redundant processing
|
|
45
|
+
const typeConversionCache = new Map();
|
|
46
|
+
// Type mapping constants for better performance
|
|
47
|
+
const BASIC_TYPE_MAP = {
|
|
48
|
+
[typescript_1.default.SyntaxKind.StringKeyword]: declaration_1.FunctionArgumentType.dom_string,
|
|
49
|
+
[typescript_1.default.SyntaxKind.NumberKeyword]: declaration_1.FunctionArgumentType.double,
|
|
50
|
+
[typescript_1.default.SyntaxKind.BooleanKeyword]: declaration_1.FunctionArgumentType.boolean,
|
|
51
|
+
[typescript_1.default.SyntaxKind.AnyKeyword]: declaration_1.FunctionArgumentType.any,
|
|
52
|
+
[typescript_1.default.SyntaxKind.ObjectKeyword]: declaration_1.FunctionArgumentType.object,
|
|
53
|
+
[typescript_1.default.SyntaxKind.VoidKeyword]: declaration_1.FunctionArgumentType.void,
|
|
54
|
+
[typescript_1.default.SyntaxKind.NullKeyword]: declaration_1.FunctionArgumentType.null,
|
|
55
|
+
[typescript_1.default.SyntaxKind.UndefinedKeyword]: declaration_1.FunctionArgumentType.undefined,
|
|
56
|
+
};
|
|
57
|
+
const TYPE_REFERENCE_MAP = {
|
|
58
|
+
'Function': declaration_1.FunctionArgumentType.function,
|
|
59
|
+
'Promise': declaration_1.FunctionArgumentType.promise,
|
|
60
|
+
'JSArrayProtoMethod': declaration_1.FunctionArgumentType.js_array_proto_methods,
|
|
61
|
+
'int': declaration_1.FunctionArgumentType.int,
|
|
62
|
+
'double': declaration_1.FunctionArgumentType.double,
|
|
63
|
+
};
|
|
64
|
+
function analyzer(blob, definedPropertyCollector, unionTypeCollector) {
|
|
65
|
+
try {
|
|
66
|
+
// Check cache first
|
|
67
|
+
let sourceFile = sourceFileCache.get(blob.source);
|
|
68
|
+
if (!sourceFile) {
|
|
69
|
+
sourceFile = typescript_1.default.createSourceFile(blob.source, blob.raw, typescript_1.ScriptTarget.ES2020);
|
|
70
|
+
sourceFileCache.set(blob.source, sourceFile);
|
|
71
|
+
}
|
|
72
|
+
blob.objects = sourceFile.statements
|
|
73
|
+
.map(statement => {
|
|
74
|
+
try {
|
|
75
|
+
return walkProgram(blob, statement, definedPropertyCollector, unionTypeCollector);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
console.error(`Error processing statement in ${blob.source}:`, error);
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
.filter(o => o instanceof declaration_1.ClassObject || o instanceof declaration_1.FunctionObject || o instanceof declaration_1.TypeAliasObject);
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
console.error(`Error analyzing ${blob.source}:`, error);
|
|
86
|
+
throw new Error(`Failed to analyze ${blob.source}: ${error instanceof Error ? error.message : String(error)}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function buildClassRelationship() {
|
|
90
|
+
const globalClassMap = declaration_1.ClassObject.globalClassMap;
|
|
91
|
+
const globalClassRelationMap = declaration_1.ClassObject.globalClassRelationMap;
|
|
92
|
+
// Use more efficient for...in loop
|
|
93
|
+
for (const key in globalClassMap) {
|
|
94
|
+
const obj = globalClassMap[key];
|
|
95
|
+
if (obj.parent) {
|
|
96
|
+
if (!globalClassRelationMap[obj.parent]) {
|
|
97
|
+
globalClassRelationMap[obj.parent] = [];
|
|
98
|
+
}
|
|
99
|
+
globalClassRelationMap[obj.parent].push(obj.name);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function getInterfaceName(statement) {
|
|
104
|
+
if (!typescript_1.default.isInterfaceDeclaration(statement)) {
|
|
105
|
+
throw new Error('Statement is not an interface declaration');
|
|
106
|
+
}
|
|
107
|
+
return statement.name.escapedText;
|
|
108
|
+
}
|
|
109
|
+
function getHeritageType(heritage) {
|
|
110
|
+
if (!heritage.types.length)
|
|
111
|
+
return null;
|
|
112
|
+
const expression = heritage.types[0].expression;
|
|
113
|
+
if (typescript_1.default.isIdentifier(expression)) {
|
|
114
|
+
return expression.escapedText;
|
|
115
|
+
}
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
function getMixins(heritage) {
|
|
119
|
+
if (heritage.types.length <= 1)
|
|
120
|
+
return null;
|
|
121
|
+
const mixins = [];
|
|
122
|
+
for (let i = 1; i < heritage.types.length; i++) {
|
|
123
|
+
const expression = heritage.types[i].expression;
|
|
124
|
+
if (typescript_1.default.isIdentifier(expression)) {
|
|
125
|
+
mixins.push(expression.escapedText);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return mixins.length > 0 ? mixins : null;
|
|
129
|
+
}
|
|
130
|
+
function getPropName(propName, prop) {
|
|
131
|
+
switch (propName.kind) {
|
|
132
|
+
case typescript_1.default.SyntaxKind.Identifier:
|
|
133
|
+
return propName.escapedText.toString();
|
|
134
|
+
case typescript_1.default.SyntaxKind.StringLiteral:
|
|
135
|
+
return propName.text;
|
|
136
|
+
case typescript_1.default.SyntaxKind.NumericLiteral:
|
|
137
|
+
return propName.text;
|
|
138
|
+
case typescript_1.default.SyntaxKind.ComputedPropertyName:
|
|
139
|
+
if (typescript_1.default.isPropertyAccessExpression(propName.expression)) {
|
|
140
|
+
if (prop)
|
|
141
|
+
prop.isSymbol = true;
|
|
142
|
+
const expression = propName.expression;
|
|
143
|
+
return `${expression.expression.getText()}_${expression.name.getText()}`;
|
|
144
|
+
}
|
|
145
|
+
throw new Error(`Computed property name of type ${typescript_1.default.SyntaxKind[propName.expression.kind]} is not supported`);
|
|
146
|
+
default:
|
|
147
|
+
throw new Error(`Property name of type ${typescript_1.default.SyntaxKind[propName.kind]} is not supported`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function getParameterName(name) {
|
|
151
|
+
if (typescript_1.default.isIdentifier(name)) {
|
|
152
|
+
return name.escapedText.toString();
|
|
153
|
+
}
|
|
154
|
+
// Handle other binding patterns if needed
|
|
155
|
+
console.warn('Non-identifier parameter names are not fully supported');
|
|
156
|
+
return '';
|
|
157
|
+
}
|
|
158
|
+
function getParameterBaseType(type, mode) {
|
|
159
|
+
// Check basic types first (most common case)
|
|
160
|
+
const basicType = BASIC_TYPE_MAP[type.kind];
|
|
161
|
+
if (basicType !== undefined) {
|
|
162
|
+
return basicType;
|
|
163
|
+
}
|
|
164
|
+
if (type.kind === typescript_1.default.SyntaxKind.TypeReference) {
|
|
165
|
+
const typeReference = type;
|
|
166
|
+
const typeName = typeReference.typeName;
|
|
167
|
+
if (!typescript_1.default.isIdentifier(typeName)) {
|
|
168
|
+
console.warn('Non-identifier type references are not supported');
|
|
169
|
+
return declaration_1.FunctionArgumentType.any;
|
|
170
|
+
}
|
|
171
|
+
const identifier = typeName.text;
|
|
172
|
+
// Check simple type references
|
|
173
|
+
const mappedType = TYPE_REFERENCE_MAP[identifier];
|
|
174
|
+
if (mappedType !== undefined) {
|
|
175
|
+
return mappedType;
|
|
176
|
+
}
|
|
177
|
+
// Handle special type wrappers
|
|
178
|
+
switch (identifier) {
|
|
179
|
+
case 'NewObject':
|
|
180
|
+
if (mode)
|
|
181
|
+
mode.newObject = true;
|
|
182
|
+
if (typeReference.typeArguments && typeReference.typeArguments[0]) {
|
|
183
|
+
const argument = typeReference.typeArguments[0];
|
|
184
|
+
if (typescript_1.default.isTypeReferenceNode(argument) && typescript_1.default.isIdentifier(argument.typeName)) {
|
|
185
|
+
return argument.typeName.text;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return declaration_1.FunctionArgumentType.any;
|
|
189
|
+
case 'DartImpl':
|
|
190
|
+
if (mode)
|
|
191
|
+
mode.dartImpl = true;
|
|
192
|
+
return handleDartImplType(typeReference, mode);
|
|
193
|
+
case 'DependentsOnLayout':
|
|
194
|
+
if (mode)
|
|
195
|
+
mode.layoutDependent = true;
|
|
196
|
+
return handleDependentsOnLayoutType(typeReference, mode);
|
|
197
|
+
case 'StaticMember':
|
|
198
|
+
if (mode)
|
|
199
|
+
mode.static = true;
|
|
200
|
+
return handleGenericWrapper(typeReference, mode);
|
|
201
|
+
case 'StaticMethod':
|
|
202
|
+
if (mode)
|
|
203
|
+
mode.staticMethod = true;
|
|
204
|
+
return handleGenericWrapper(typeReference, mode);
|
|
205
|
+
default:
|
|
206
|
+
if (identifier.includes('SupportAsync')) {
|
|
207
|
+
return handleSupportAsyncType(identifier, typeReference, mode);
|
|
208
|
+
}
|
|
209
|
+
return identifier;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
if (type.kind === typescript_1.default.SyntaxKind.LiteralType) {
|
|
213
|
+
// Handle literal types - check if it's a null literal
|
|
214
|
+
const literalType = type;
|
|
215
|
+
if (literalType.literal.kind === typescript_1.default.SyntaxKind.NullKeyword) {
|
|
216
|
+
return declaration_1.FunctionArgumentType.null;
|
|
217
|
+
}
|
|
218
|
+
return declaration_1.FunctionArgumentType.any;
|
|
219
|
+
}
|
|
220
|
+
return declaration_1.FunctionArgumentType.any;
|
|
221
|
+
}
|
|
222
|
+
function handleDartImplType(typeReference, mode) {
|
|
223
|
+
if (!typeReference.typeArguments || !typeReference.typeArguments[0]) {
|
|
224
|
+
return declaration_1.FunctionArgumentType.any;
|
|
225
|
+
}
|
|
226
|
+
let argument = typeReference.typeArguments[0];
|
|
227
|
+
if (typescript_1.default.isTypeReferenceNode(argument)) {
|
|
228
|
+
const typeName = argument.typeName;
|
|
229
|
+
if (typescript_1.default.isIdentifier(typeName) && typeName.text === 'DependentsOnLayout') {
|
|
230
|
+
if (mode)
|
|
231
|
+
mode.layoutDependent = true;
|
|
232
|
+
if (argument.typeArguments && argument.typeArguments[0]) {
|
|
233
|
+
argument = argument.typeArguments[0];
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return getParameterBaseType(argument, mode);
|
|
238
|
+
}
|
|
239
|
+
function handleDependentsOnLayoutType(typeReference, mode) {
|
|
240
|
+
if (!typeReference.typeArguments || !typeReference.typeArguments[0]) {
|
|
241
|
+
return declaration_1.FunctionArgumentType.any;
|
|
242
|
+
}
|
|
243
|
+
const argument = typeReference.typeArguments[0];
|
|
244
|
+
return getParameterBaseType(argument, mode);
|
|
245
|
+
}
|
|
246
|
+
function handleGenericWrapper(typeReference, mode) {
|
|
247
|
+
if (!typeReference.typeArguments || !typeReference.typeArguments[0]) {
|
|
248
|
+
return declaration_1.FunctionArgumentType.any;
|
|
249
|
+
}
|
|
250
|
+
const argument = typeReference.typeArguments[0];
|
|
251
|
+
return getParameterBaseType(argument, mode);
|
|
252
|
+
}
|
|
253
|
+
function handleSupportAsyncType(identifier, typeReference, mode) {
|
|
254
|
+
if (mode) {
|
|
255
|
+
mode.supportAsync = true;
|
|
256
|
+
if (identifier === "SupportAsyncManual") {
|
|
257
|
+
mode.supportAsyncManual = true;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
if (!typeReference.typeArguments || !typeReference.typeArguments[0]) {
|
|
261
|
+
return declaration_1.FunctionArgumentType.any;
|
|
262
|
+
}
|
|
263
|
+
let argument = typeReference.typeArguments[0];
|
|
264
|
+
if (typescript_1.default.isTypeReferenceNode(argument)) {
|
|
265
|
+
const typeName = argument.typeName;
|
|
266
|
+
if (typescript_1.default.isIdentifier(typeName) && typeName.text === 'DartImpl') {
|
|
267
|
+
if (mode)
|
|
268
|
+
mode.dartImpl = true;
|
|
269
|
+
if (argument.typeArguments && argument.typeArguments[0]) {
|
|
270
|
+
argument = argument.typeArguments[0];
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
else if (typescript_1.default.isArrayTypeNode(argument)) {
|
|
275
|
+
if (mode)
|
|
276
|
+
mode.supportAsyncArrayValue = true;
|
|
277
|
+
return getParameterBaseType(argument.elementType, mode);
|
|
278
|
+
}
|
|
279
|
+
return getParameterBaseType(argument, mode);
|
|
280
|
+
}
|
|
281
|
+
function getParameterType(type, unionTypeCollector, mode) {
|
|
282
|
+
// Generate cache key
|
|
283
|
+
const cacheKey = `${type.kind}_${type.pos}_${type.end}`;
|
|
284
|
+
// Check cache first (only for types without mode)
|
|
285
|
+
if (!mode) {
|
|
286
|
+
const cached = typeConversionCache.get(cacheKey);
|
|
287
|
+
if (cached)
|
|
288
|
+
return cached;
|
|
289
|
+
}
|
|
290
|
+
let result;
|
|
291
|
+
if (type.kind === typescript_1.default.SyntaxKind.ParenthesizedType) {
|
|
292
|
+
const typeNode = type;
|
|
293
|
+
result = getParameterType(typeNode.type, unionTypeCollector, mode);
|
|
294
|
+
}
|
|
295
|
+
else if (type.kind === typescript_1.default.SyntaxKind.ArrayType) {
|
|
296
|
+
const arrayType = type;
|
|
297
|
+
result = {
|
|
298
|
+
isArray: true,
|
|
299
|
+
value: getParameterType(arrayType.elementType, unionTypeCollector, mode)
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
else if (type.kind === typescript_1.default.SyntaxKind.UnionType) {
|
|
303
|
+
const unionType = type;
|
|
304
|
+
const types = unionType.types.map(t => getParameterType(t, unionTypeCollector, mode));
|
|
305
|
+
result = {
|
|
306
|
+
isArray: false,
|
|
307
|
+
value: types
|
|
308
|
+
};
|
|
309
|
+
if ((0, utils_1.isUnionType)(result)) {
|
|
310
|
+
unionTypeCollector.types.add(result.value);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
else if (type.kind === typescript_1.default.SyntaxKind.TypeReference) {
|
|
314
|
+
result = handleTypeReferenceForParameter(type, unionTypeCollector, mode);
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
result = {
|
|
318
|
+
isArray: false,
|
|
319
|
+
value: getParameterBaseType(type, mode)
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
// Cache the result if no mode
|
|
323
|
+
if (!mode) {
|
|
324
|
+
typeConversionCache.set(cacheKey, result);
|
|
325
|
+
}
|
|
326
|
+
return result;
|
|
327
|
+
}
|
|
328
|
+
function handleTypeReferenceForParameter(typeReference, unionTypeCollector, mode) {
|
|
329
|
+
const typeName = typeReference.typeName;
|
|
330
|
+
if (!typescript_1.default.isIdentifier(typeName)) {
|
|
331
|
+
return {
|
|
332
|
+
isArray: false,
|
|
333
|
+
value: declaration_1.FunctionArgumentType.any
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
const identifier = typeName.text;
|
|
337
|
+
if (identifier.includes('SupportAsync') && typeReference.typeArguments && typeReference.typeArguments[0]) {
|
|
338
|
+
const argument = typeReference.typeArguments[0];
|
|
339
|
+
if (typescript_1.default.isUnionTypeNode(argument)) {
|
|
340
|
+
if (mode) {
|
|
341
|
+
mode.supportAsync = true;
|
|
342
|
+
if (identifier === 'SupportAsyncManual') {
|
|
343
|
+
mode.supportAsyncManual = true;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
const types = argument.types.map(t => getParameterType(t, unionTypeCollector, mode));
|
|
347
|
+
const result = {
|
|
348
|
+
isArray: false,
|
|
349
|
+
value: types
|
|
350
|
+
};
|
|
351
|
+
if ((0, utils_1.isUnionType)(result)) {
|
|
352
|
+
unionTypeCollector.types.add(result.value);
|
|
353
|
+
}
|
|
354
|
+
return result;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return {
|
|
358
|
+
isArray: false,
|
|
359
|
+
value: getParameterBaseType(typeReference, mode)
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
function paramsNodeToArguments(parameter, unionTypeCollector) {
|
|
363
|
+
const args = new declaration_1.FunctionArguments();
|
|
364
|
+
args.name = getParameterName(parameter.name);
|
|
365
|
+
if (!parameter.type) {
|
|
366
|
+
console.warn(`Parameter ${args.name} has no type annotation, defaulting to any`);
|
|
367
|
+
args.type = { isArray: false, value: declaration_1.FunctionArgumentType.any };
|
|
368
|
+
return args;
|
|
369
|
+
}
|
|
370
|
+
const typeMode = new declaration_1.ParameterMode();
|
|
371
|
+
args.type = getParameterType(parameter.type, unionTypeCollector, typeMode);
|
|
372
|
+
args.isDotDotDot = !!parameter.dotDotDotToken;
|
|
373
|
+
args.typeMode = typeMode;
|
|
374
|
+
args.required = !parameter.questionToken;
|
|
375
|
+
return args;
|
|
376
|
+
}
|
|
377
|
+
function isParamsReadOnly(m) {
|
|
378
|
+
if (!m.modifiers)
|
|
379
|
+
return false;
|
|
380
|
+
return m.modifiers.some(k => k.kind === typescript_1.default.SyntaxKind.ReadonlyKeyword);
|
|
381
|
+
}
|
|
382
|
+
function walkProgram(blob, statement, definedPropertyCollector, unionTypeCollector) {
|
|
383
|
+
switch (statement.kind) {
|
|
384
|
+
case typescript_1.default.SyntaxKind.InterfaceDeclaration:
|
|
385
|
+
return processInterfaceDeclaration(statement, blob, definedPropertyCollector, unionTypeCollector);
|
|
386
|
+
case typescript_1.default.SyntaxKind.VariableStatement:
|
|
387
|
+
return processVariableStatement(statement, unionTypeCollector);
|
|
388
|
+
case typescript_1.default.SyntaxKind.TypeAliasDeclaration:
|
|
389
|
+
return processTypeAliasDeclaration(statement, blob);
|
|
390
|
+
default:
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
function processTypeAliasDeclaration(statement, blob) {
|
|
395
|
+
const typeAlias = new declaration_1.TypeAliasObject();
|
|
396
|
+
typeAlias.name = statement.name.text;
|
|
397
|
+
// Convert the type to a string representation
|
|
398
|
+
const printer = typescript_1.default.createPrinter();
|
|
399
|
+
typeAlias.type = printer.printNode(typescript_1.default.EmitHint.Unspecified, statement.type, statement.getSourceFile());
|
|
400
|
+
return typeAlias;
|
|
401
|
+
}
|
|
402
|
+
function processInterfaceDeclaration(statement, blob, definedPropertyCollector, unionTypeCollector) {
|
|
403
|
+
const interfaceName = statement.name.escapedText.toString();
|
|
404
|
+
const obj = new declaration_1.ClassObject();
|
|
405
|
+
// Process heritage clauses
|
|
406
|
+
if (statement.heritageClauses) {
|
|
407
|
+
const heritage = statement.heritageClauses[0];
|
|
408
|
+
const heritageType = getHeritageType(heritage);
|
|
409
|
+
const mixins = getMixins(heritage);
|
|
410
|
+
if (heritageType)
|
|
411
|
+
obj.parent = heritageType;
|
|
412
|
+
if (mixins)
|
|
413
|
+
obj.mixinParent = mixins;
|
|
414
|
+
}
|
|
415
|
+
obj.name = interfaceName;
|
|
416
|
+
if (obj.kind === declaration_1.ClassObjectKind.interface) {
|
|
417
|
+
definedPropertyCollector.interfaces.add('QJS' + interfaceName);
|
|
418
|
+
definedPropertyCollector.files.add(blob.filename);
|
|
419
|
+
definedPropertyCollector.properties.add(interfaceName);
|
|
420
|
+
}
|
|
421
|
+
// Process members in batches for better performance
|
|
422
|
+
const members = Array.from(statement.members);
|
|
423
|
+
processMembersBatch(members, obj, definedPropertyCollector, unionTypeCollector);
|
|
424
|
+
declaration_1.ClassObject.globalClassMap[interfaceName] = obj;
|
|
425
|
+
return obj;
|
|
426
|
+
}
|
|
427
|
+
function processMembersBatch(members, obj, definedPropertyCollector, unionTypeCollector) {
|
|
428
|
+
for (const member of members) {
|
|
429
|
+
try {
|
|
430
|
+
processMember(member, obj, definedPropertyCollector, unionTypeCollector);
|
|
431
|
+
}
|
|
432
|
+
catch (error) {
|
|
433
|
+
console.error(`Error processing member:`, error);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
function processMember(member, obj, definedPropertyCollector, unionTypeCollector) {
|
|
438
|
+
switch (member.kind) {
|
|
439
|
+
case typescript_1.default.SyntaxKind.PropertySignature:
|
|
440
|
+
processPropertySignature(member, obj, definedPropertyCollector, unionTypeCollector);
|
|
441
|
+
break;
|
|
442
|
+
case typescript_1.default.SyntaxKind.MethodSignature:
|
|
443
|
+
processMethodSignature(member, obj, unionTypeCollector);
|
|
444
|
+
break;
|
|
445
|
+
case typescript_1.default.SyntaxKind.IndexSignature:
|
|
446
|
+
processIndexSignature(member, obj, unionTypeCollector);
|
|
447
|
+
break;
|
|
448
|
+
case typescript_1.default.SyntaxKind.ConstructSignature:
|
|
449
|
+
processConstructSignature(member, obj, unionTypeCollector);
|
|
450
|
+
break;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
function processPropertySignature(member, obj, definedPropertyCollector, unionTypeCollector) {
|
|
454
|
+
const prop = new declaration_1.PropsDeclaration();
|
|
455
|
+
prop.name = getPropName(member.name, prop);
|
|
456
|
+
prop.readonly = isParamsReadOnly(member);
|
|
457
|
+
definedPropertyCollector.properties.add(prop.name);
|
|
458
|
+
if (!member.type) {
|
|
459
|
+
console.warn(`Property ${prop.name} has no type annotation`);
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
const mode = new declaration_1.ParameterMode();
|
|
463
|
+
prop.type = getParameterType(member.type, unionTypeCollector, mode);
|
|
464
|
+
prop.typeMode = mode;
|
|
465
|
+
prop.optional = !!member.questionToken;
|
|
466
|
+
if (prop.type.value === declaration_1.FunctionArgumentType.function && typescript_1.default.isFunctionTypeNode(member.type)) {
|
|
467
|
+
const functionProps = prop;
|
|
468
|
+
functionProps.args = member.type.parameters.map(params => paramsNodeToArguments(params, unionTypeCollector));
|
|
469
|
+
obj.methods.push(functionProps);
|
|
470
|
+
}
|
|
471
|
+
else {
|
|
472
|
+
obj.props.push(prop);
|
|
473
|
+
// Handle async properties
|
|
474
|
+
if (prop.typeMode.supportAsync) {
|
|
475
|
+
const asyncProp = createAsyncProperty(prop, mode);
|
|
476
|
+
definedPropertyCollector.properties.add(asyncProp.name);
|
|
477
|
+
obj.props.push(asyncProp);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
function createAsyncProperty(prop, mode) {
|
|
482
|
+
const asyncProp = Object.assign({}, prop);
|
|
483
|
+
const syncMode = Object.assign({}, mode);
|
|
484
|
+
syncMode.supportAsync = false;
|
|
485
|
+
syncMode.supportAsyncManual = false;
|
|
486
|
+
prop.typeMode = syncMode;
|
|
487
|
+
asyncProp.name = asyncProp.name + '_async';
|
|
488
|
+
asyncProp.async_type = {
|
|
489
|
+
isArray: false,
|
|
490
|
+
value: declaration_1.FunctionArgumentType.promise
|
|
491
|
+
};
|
|
492
|
+
return asyncProp;
|
|
493
|
+
}
|
|
494
|
+
function processMethodSignature(member, obj, unionTypeCollector) {
|
|
495
|
+
var _a;
|
|
496
|
+
const f = new declaration_1.FunctionDeclaration();
|
|
497
|
+
f.name = getPropName(member.name);
|
|
498
|
+
f.args = member.parameters.map(params => paramsNodeToArguments(params, unionTypeCollector));
|
|
499
|
+
if (member.type) {
|
|
500
|
+
const mode = new declaration_1.ParameterMode();
|
|
501
|
+
f.returnType = getParameterType(member.type, unionTypeCollector, mode);
|
|
502
|
+
if (mode.supportAsyncArrayValue) {
|
|
503
|
+
f.returnType = {
|
|
504
|
+
isArray: true,
|
|
505
|
+
value: f.returnType
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
f.returnTypeMode = mode;
|
|
509
|
+
if (f.returnTypeMode.staticMethod) {
|
|
510
|
+
obj.staticMethods.push(f);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
obj.methods.push(f);
|
|
514
|
+
// Handle async methods
|
|
515
|
+
if ((_a = f.returnTypeMode) === null || _a === void 0 ? void 0 : _a.supportAsync) {
|
|
516
|
+
const asyncFunc = createAsyncMethod(member, f, unionTypeCollector);
|
|
517
|
+
obj.methods.push(asyncFunc);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
function createAsyncMethod(member, originalFunc, unionTypeCollector) {
|
|
521
|
+
const asyncFunc = Object.assign({}, originalFunc);
|
|
522
|
+
const mode = Object.assign({}, originalFunc.returnTypeMode);
|
|
523
|
+
mode.supportAsync = false;
|
|
524
|
+
mode.supportAsyncManual = false;
|
|
525
|
+
originalFunc.returnTypeMode = mode;
|
|
526
|
+
asyncFunc.name = getPropName(member.name) + '_async';
|
|
527
|
+
asyncFunc.args = member.parameters.map(params => paramsNodeToArguments(params, unionTypeCollector));
|
|
528
|
+
asyncFunc.async_returnType = {
|
|
529
|
+
isArray: false,
|
|
530
|
+
value: declaration_1.FunctionArgumentType.promise
|
|
531
|
+
};
|
|
532
|
+
return asyncFunc;
|
|
533
|
+
}
|
|
534
|
+
function processIndexSignature(member, obj, unionTypeCollector) {
|
|
535
|
+
const prop = new declaration_1.IndexedPropertyDeclaration();
|
|
536
|
+
const modifier = member.modifiers;
|
|
537
|
+
prop.readonly = !!(modifier && modifier[0].kind === typescript_1.default.SyntaxKind.ReadonlyKeyword);
|
|
538
|
+
const params = member.parameters;
|
|
539
|
+
if (params.length > 0 && params[0].type) {
|
|
540
|
+
prop.indexKeyType = params[0].type.kind === typescript_1.default.SyntaxKind.NumberKeyword ? 'number' : 'string';
|
|
541
|
+
}
|
|
542
|
+
const mode = new declaration_1.ParameterMode();
|
|
543
|
+
prop.type = getParameterType(member.type, unionTypeCollector, mode);
|
|
544
|
+
prop.typeMode = mode;
|
|
545
|
+
obj.indexedProp = prop;
|
|
546
|
+
}
|
|
547
|
+
function processConstructSignature(member, obj, unionTypeCollector) {
|
|
548
|
+
const c = new declaration_1.FunctionDeclaration();
|
|
549
|
+
c.name = 'constructor';
|
|
550
|
+
c.args = member.parameters.map(params => paramsNodeToArguments(params, unionTypeCollector));
|
|
551
|
+
if (member.type) {
|
|
552
|
+
c.returnType = getParameterType(member.type, unionTypeCollector);
|
|
553
|
+
}
|
|
554
|
+
obj.construct = c;
|
|
555
|
+
}
|
|
556
|
+
function processVariableStatement(statement, unionTypeCollector) {
|
|
557
|
+
const declaration = statement.declarationList.declarations[0];
|
|
558
|
+
if (!typescript_1.default.isIdentifier(declaration.name)) {
|
|
559
|
+
console.warn('Variable declaration with non-identifier name is not supported');
|
|
560
|
+
return null;
|
|
561
|
+
}
|
|
562
|
+
const methodName = declaration.name.text;
|
|
563
|
+
const type = declaration.type;
|
|
564
|
+
if (!type || !typescript_1.default.isFunctionTypeNode(type)) {
|
|
565
|
+
return null;
|
|
566
|
+
}
|
|
567
|
+
const functionObject = new declaration_1.FunctionObject();
|
|
568
|
+
functionObject.declare = new declaration_1.FunctionDeclaration();
|
|
569
|
+
functionObject.declare.name = methodName;
|
|
570
|
+
functionObject.declare.args = type.parameters.map(param => paramsNodeToArguments(param, unionTypeCollector));
|
|
571
|
+
functionObject.declare.returnType = getParameterType(type.type, unionTypeCollector);
|
|
572
|
+
return functionObject;
|
|
573
|
+
}
|
|
574
|
+
// Clear caches when needed (e.g., between runs)
|
|
575
|
+
function clearCaches() {
|
|
576
|
+
sourceFileCache.clear();
|
|
577
|
+
typeConversionCache.clear();
|
|
578
|
+
}
|