@openwebf/webf 0.22.6 → 0.22.9
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/analyzer.js +117 -17
- package/dist/react.js +47 -2
- package/package.json +3 -1
- package/src/analyzer.ts +145 -10
- package/src/declaration.ts +2 -0
- package/src/react.ts +53 -4
- package/templates/react.component.tsx.tpl +62 -6
- package/templates/vue.component.partial.tpl +3 -0
- package/test/react.test.ts +62 -1
- package/test/standard-props.test.ts +190 -0
- package/test/union-types-jsdoc.test.ts +168 -0
- package/test/vue.test.ts +157 -0
- package/dist/analyzer_original.js +0 -467
package/test/vue.test.ts
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { generateVueTypings } from '../src/vue';
|
|
2
|
+
import { IDLBlob } from '../src/IDLBlob';
|
|
3
|
+
import { ClassObject, ClassObjectKind, PropsDeclaration } from '../src/declaration';
|
|
4
|
+
|
|
5
|
+
describe('Vue Generator', () => {
|
|
6
|
+
describe('generateVueTypings', () => {
|
|
7
|
+
it('should generate Vue component types with standard HTML props', () => {
|
|
8
|
+
const blob = new IDLBlob('/test/source', '/test/target', 'TestComponent', 'test', '');
|
|
9
|
+
|
|
10
|
+
const properties = new ClassObject();
|
|
11
|
+
properties.name = 'TestComponentProperties';
|
|
12
|
+
properties.kind = ClassObjectKind.interface;
|
|
13
|
+
blob.objects = [properties];
|
|
14
|
+
|
|
15
|
+
const result = generateVueTypings([blob]);
|
|
16
|
+
|
|
17
|
+
// Should include standard HTML props in Props type
|
|
18
|
+
expect(result).toContain("'id'?: string;");
|
|
19
|
+
expect(result).toContain("'class'?: string;");
|
|
20
|
+
expect(result).toContain("'style'?: string | Record<string, any>;");
|
|
21
|
+
|
|
22
|
+
// Should generate proper type exports
|
|
23
|
+
expect(result).toContain('export type TestComponentProps = {');
|
|
24
|
+
expect(result).toContain('export interface TestComponentElement {');
|
|
25
|
+
expect(result).toContain('export type TestComponentEvents = {');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should include standard HTML props along with custom properties', () => {
|
|
29
|
+
const blob = new IDLBlob('/test/source', '/test/target', 'TestComponent', 'test', '');
|
|
30
|
+
|
|
31
|
+
const properties = new ClassObject();
|
|
32
|
+
properties.name = 'TestComponentProperties';
|
|
33
|
+
properties.kind = ClassObjectKind.interface;
|
|
34
|
+
const titleProp = new PropsDeclaration();
|
|
35
|
+
titleProp.name = 'title';
|
|
36
|
+
titleProp.type = { value: 'dom_string' };
|
|
37
|
+
titleProp.optional = false;
|
|
38
|
+
titleProp.documentation = 'The component title';
|
|
39
|
+
titleProp.readonly = false;
|
|
40
|
+
titleProp.typeMode = {};
|
|
41
|
+
|
|
42
|
+
const isActiveProp = new PropsDeclaration();
|
|
43
|
+
isActiveProp.name = 'isActive';
|
|
44
|
+
isActiveProp.type = { value: 'boolean' };
|
|
45
|
+
isActiveProp.optional = true;
|
|
46
|
+
isActiveProp.documentation = 'Whether the component is active';
|
|
47
|
+
isActiveProp.readonly = false;
|
|
48
|
+
isActiveProp.typeMode = {};
|
|
49
|
+
|
|
50
|
+
properties.props = [titleProp, isActiveProp];
|
|
51
|
+
blob.objects = [properties];
|
|
52
|
+
|
|
53
|
+
const result = generateVueTypings([blob]);
|
|
54
|
+
|
|
55
|
+
// Should include custom props with kebab-case (dom_string is not converted in type definitions)
|
|
56
|
+
expect(result).toContain("'title': dom_string;");
|
|
57
|
+
expect(result).toContain("'is-active'?: boolean;");
|
|
58
|
+
|
|
59
|
+
// And still include standard HTML props
|
|
60
|
+
expect(result).toContain("'id'?: string;");
|
|
61
|
+
expect(result).toContain("'class'?: string;");
|
|
62
|
+
expect(result).toContain("'style'?: string | Record<string, any>;");
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should generate proper Vue component declarations', () => {
|
|
66
|
+
const blob = new IDLBlob('/test/source', '/test/target', 'WebFListView', 'test', '');
|
|
67
|
+
|
|
68
|
+
const properties = new ClassObject();
|
|
69
|
+
properties.name = 'WebFListViewProperties';
|
|
70
|
+
properties.kind = ClassObjectKind.interface;
|
|
71
|
+
blob.objects = [properties];
|
|
72
|
+
|
|
73
|
+
const result = generateVueTypings([blob]);
|
|
74
|
+
|
|
75
|
+
// Should generate proper component declarations
|
|
76
|
+
expect(result).toContain("declare module 'vue' {");
|
|
77
|
+
expect(result).toContain("interface GlobalComponents {");
|
|
78
|
+
expect(result).toContain("'web-f-list-view': DefineCustomElement<");
|
|
79
|
+
expect(result).toContain("WebFListViewProps,");
|
|
80
|
+
expect(result).toContain("WebFListViewEvents");
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('should handle multiple components', () => {
|
|
84
|
+
const blob1 = new IDLBlob('/test/source', '/test/target', 'ComponentOne', 'test', '');
|
|
85
|
+
const properties1 = new ClassObject();
|
|
86
|
+
properties1.name = 'ComponentOneProperties';
|
|
87
|
+
properties1.kind = ClassObjectKind.interface;
|
|
88
|
+
blob1.objects = [properties1];
|
|
89
|
+
|
|
90
|
+
const blob2 = new IDLBlob('/test/source', '/test/target', 'ComponentTwo', 'test', '');
|
|
91
|
+
const properties2 = new ClassObject();
|
|
92
|
+
properties2.name = 'ComponentTwoProperties';
|
|
93
|
+
properties2.kind = ClassObjectKind.interface;
|
|
94
|
+
blob2.objects = [properties2];
|
|
95
|
+
|
|
96
|
+
const result = generateVueTypings([blob1, blob2]);
|
|
97
|
+
|
|
98
|
+
// Should include both components
|
|
99
|
+
expect(result).toContain('export type ComponentOneProps = {');
|
|
100
|
+
expect(result).toContain('export type ComponentTwoProps = {');
|
|
101
|
+
|
|
102
|
+
// Both should have standard HTML props
|
|
103
|
+
const componentOneMatch = result.match(/export type ComponentOneProps = \{[^}]+\}/);
|
|
104
|
+
const componentTwoMatch = result.match(/export type ComponentTwoProps = \{[^}]+\}/);
|
|
105
|
+
|
|
106
|
+
// Extract content including newlines
|
|
107
|
+
const componentOneSection = result.substring(result.indexOf('export type ComponentOneProps'), result.indexOf('export interface ComponentOneElement'));
|
|
108
|
+
const componentTwoSection = result.substring(result.indexOf('export type ComponentTwoProps'), result.indexOf('export interface ComponentTwoElement'));
|
|
109
|
+
|
|
110
|
+
expect(componentOneSection).toContain("'id'?: string;");
|
|
111
|
+
expect(componentTwoSection).toContain("'id'?: string;");
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('should handle components with events', () => {
|
|
115
|
+
const blob = new IDLBlob('/test/source', '/test/target', 'TestComponent', 'test', '');
|
|
116
|
+
|
|
117
|
+
const properties = new ClassObject();
|
|
118
|
+
properties.name = 'TestComponentProperties';
|
|
119
|
+
properties.kind = ClassObjectKind.interface;
|
|
120
|
+
|
|
121
|
+
const events = new ClassObject();
|
|
122
|
+
events.name = 'TestComponentEvents';
|
|
123
|
+
events.kind = ClassObjectKind.interface;
|
|
124
|
+
const closeProp = new PropsDeclaration();
|
|
125
|
+
closeProp.name = 'close';
|
|
126
|
+
closeProp.type = { value: 'Event', isArray: false };
|
|
127
|
+
closeProp.optional = true;
|
|
128
|
+
closeProp.documentation = 'Close event';
|
|
129
|
+
closeProp.readonly = false;
|
|
130
|
+
closeProp.typeMode = {};
|
|
131
|
+
|
|
132
|
+
const refreshProp = new PropsDeclaration();
|
|
133
|
+
refreshProp.name = 'refresh';
|
|
134
|
+
refreshProp.type = { value: 'CustomEvent', isArray: false };
|
|
135
|
+
refreshProp.optional = true;
|
|
136
|
+
refreshProp.documentation = 'Refresh event';
|
|
137
|
+
refreshProp.readonly = false;
|
|
138
|
+
refreshProp.typeMode = {};
|
|
139
|
+
|
|
140
|
+
events.props = [closeProp, refreshProp];
|
|
141
|
+
|
|
142
|
+
blob.objects = [properties, events];
|
|
143
|
+
|
|
144
|
+
const result = generateVueTypings([blob]);
|
|
145
|
+
|
|
146
|
+
// Should include event types
|
|
147
|
+
expect(result).toContain('export type TestComponentEvents = {');
|
|
148
|
+
expect(result).toContain('close?: Event;');
|
|
149
|
+
expect(result).toContain('refresh?: CustomEvent;');
|
|
150
|
+
|
|
151
|
+
// Props should still have standard HTML props
|
|
152
|
+
expect(result).toContain("'id'?: string;");
|
|
153
|
+
expect(result).toContain("'class'?: string;");
|
|
154
|
+
expect(result).toContain("'style'?: string | Record<string, any>;");
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
});
|
|
@@ -1,467 +0,0 @@
|
|
|
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
|
-
const typescript_1 = __importStar(require("typescript"));
|
|
39
|
-
const declaration_1 = require("./declaration");
|
|
40
|
-
const utils_1 = require("./utils");
|
|
41
|
-
function analyzer(blob, definedPropertyCollector, unionTypeCollector) {
|
|
42
|
-
const sourceFile = typescript_1.default.createSourceFile(blob.source, blob.raw, typescript_1.ScriptTarget.ES2020);
|
|
43
|
-
blob.objects = sourceFile.statements.map(statement => walkProgram(blob, statement, definedPropertyCollector, unionTypeCollector)).filter(o => {
|
|
44
|
-
return o instanceof declaration_1.ClassObject || o instanceof declaration_1.FunctionObject;
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
function buildClassRelationship() {
|
|
48
|
-
const globalClassMap = declaration_1.ClassObject.globalClassMap;
|
|
49
|
-
const globalClassRelationMap = declaration_1.ClassObject.globalClassRelationMap;
|
|
50
|
-
Object.values(globalClassMap).forEach(obj => {
|
|
51
|
-
if (obj.parent) {
|
|
52
|
-
globalClassRelationMap[obj.parent] = globalClassRelationMap[obj.parent] || [];
|
|
53
|
-
globalClassRelationMap[obj.parent].push(obj.name);
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
function getInterfaceName(statement) {
|
|
58
|
-
return statement.name.escapedText;
|
|
59
|
-
}
|
|
60
|
-
function getHeritageType(heritage) {
|
|
61
|
-
let expression = heritage.types[0].expression;
|
|
62
|
-
if (expression.kind === typescript_1.default.SyntaxKind.Identifier) {
|
|
63
|
-
return expression.escapedText;
|
|
64
|
-
}
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
67
|
-
function getMixins(hertage) {
|
|
68
|
-
if (hertage.types.length <= 1)
|
|
69
|
-
return null;
|
|
70
|
-
let mixins = [];
|
|
71
|
-
hertage.types.slice(1).forEach(types => {
|
|
72
|
-
let expression = types.expression;
|
|
73
|
-
if (expression.kind === typescript_1.default.SyntaxKind.Identifier) {
|
|
74
|
-
mixins.push(expression.escapedText);
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
return mixins;
|
|
78
|
-
}
|
|
79
|
-
function getPropName(propName, prop) {
|
|
80
|
-
if (propName.kind == typescript_1.default.SyntaxKind.Identifier) {
|
|
81
|
-
return propName.escapedText.toString();
|
|
82
|
-
}
|
|
83
|
-
else if (propName.kind === typescript_1.default.SyntaxKind.StringLiteral) {
|
|
84
|
-
return propName.text;
|
|
85
|
-
}
|
|
86
|
-
else if (propName.kind === typescript_1.default.SyntaxKind.NumericLiteral) {
|
|
87
|
-
return propName.text;
|
|
88
|
-
// @ts-ignore
|
|
89
|
-
}
|
|
90
|
-
else if (propName.kind === typescript_1.default.SyntaxKind.ComputedPropertyName && propName.expression.kind === typescript_1.default.SyntaxKind.PropertyAccessExpression) {
|
|
91
|
-
prop.isSymbol = true;
|
|
92
|
-
// @ts-ignore
|
|
93
|
-
let expression = propName.expression;
|
|
94
|
-
// @ts-ignore
|
|
95
|
-
return `${expression.expression.text}_${expression.name.text}`;
|
|
96
|
-
}
|
|
97
|
-
throw new Error(`prop name: ${typescript_1.default.SyntaxKind[propName.kind]} is not supported`);
|
|
98
|
-
}
|
|
99
|
-
function getParameterName(name) {
|
|
100
|
-
if (name.kind === typescript_1.default.SyntaxKind.Identifier) {
|
|
101
|
-
return name.escapedText.toString();
|
|
102
|
-
}
|
|
103
|
-
return '';
|
|
104
|
-
}
|
|
105
|
-
function getParameterBaseType(type, mode) {
|
|
106
|
-
if (type.kind === typescript_1.default.SyntaxKind.StringKeyword) {
|
|
107
|
-
return declaration_1.FunctionArgumentType.dom_string;
|
|
108
|
-
}
|
|
109
|
-
else if (type.kind === typescript_1.default.SyntaxKind.NumberKeyword) {
|
|
110
|
-
return declaration_1.FunctionArgumentType.double;
|
|
111
|
-
}
|
|
112
|
-
else if (type.kind === typescript_1.default.SyntaxKind.BooleanKeyword) {
|
|
113
|
-
return declaration_1.FunctionArgumentType.boolean;
|
|
114
|
-
}
|
|
115
|
-
else if (type.kind === typescript_1.default.SyntaxKind.AnyKeyword) {
|
|
116
|
-
return declaration_1.FunctionArgumentType.any;
|
|
117
|
-
}
|
|
118
|
-
else if (type.kind === typescript_1.default.SyntaxKind.ObjectKeyword) {
|
|
119
|
-
return declaration_1.FunctionArgumentType.object;
|
|
120
|
-
// @ts-ignore
|
|
121
|
-
}
|
|
122
|
-
else if (type.kind === typescript_1.default.SyntaxKind.VoidKeyword) {
|
|
123
|
-
return declaration_1.FunctionArgumentType.void;
|
|
124
|
-
}
|
|
125
|
-
else if (type.kind === typescript_1.default.SyntaxKind.NullKeyword) {
|
|
126
|
-
return declaration_1.FunctionArgumentType.null;
|
|
127
|
-
}
|
|
128
|
-
else if (type.kind === typescript_1.default.SyntaxKind.UndefinedKeyword) {
|
|
129
|
-
return declaration_1.FunctionArgumentType.undefined;
|
|
130
|
-
}
|
|
131
|
-
else if (type.kind === typescript_1.default.SyntaxKind.TypeReference) {
|
|
132
|
-
let typeReference = type;
|
|
133
|
-
// @ts-ignore
|
|
134
|
-
let identifier = typeReference.typeName.text;
|
|
135
|
-
if (identifier === 'Function') {
|
|
136
|
-
return declaration_1.FunctionArgumentType.function;
|
|
137
|
-
}
|
|
138
|
-
else if (identifier === 'Promise') {
|
|
139
|
-
return declaration_1.FunctionArgumentType.promise;
|
|
140
|
-
}
|
|
141
|
-
else if (identifier === 'JSArrayProtoMethod') {
|
|
142
|
-
return declaration_1.FunctionArgumentType.js_array_proto_methods;
|
|
143
|
-
}
|
|
144
|
-
else if (identifier === 'int') {
|
|
145
|
-
return declaration_1.FunctionArgumentType.int;
|
|
146
|
-
}
|
|
147
|
-
else if (identifier === 'double') {
|
|
148
|
-
return declaration_1.FunctionArgumentType.double;
|
|
149
|
-
}
|
|
150
|
-
else if (identifier === 'NewObject') {
|
|
151
|
-
if (mode)
|
|
152
|
-
mode.newObject = true;
|
|
153
|
-
let argument = typeReference.typeArguments[0];
|
|
154
|
-
// @ts-ignore
|
|
155
|
-
return argument.typeName.text;
|
|
156
|
-
}
|
|
157
|
-
else if (identifier === 'DartImpl') {
|
|
158
|
-
if (mode)
|
|
159
|
-
mode.dartImpl = true;
|
|
160
|
-
let argument = typeReference.typeArguments[0];
|
|
161
|
-
if (argument.kind == typescript_1.default.SyntaxKind.TypeReference) {
|
|
162
|
-
let typeReference = argument;
|
|
163
|
-
// @ts-ignore
|
|
164
|
-
let identifier = typeReference.typeName.text;
|
|
165
|
-
if (identifier == 'DependentsOnLayout') {
|
|
166
|
-
if (mode) {
|
|
167
|
-
mode.layoutDependent = true;
|
|
168
|
-
}
|
|
169
|
-
argument = typeReference.typeArguments[0];
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
// @ts-ignore
|
|
173
|
-
return getParameterBaseType(argument);
|
|
174
|
-
}
|
|
175
|
-
else if (identifier == 'DependentsOnLayout') {
|
|
176
|
-
if (mode)
|
|
177
|
-
mode.layoutDependent = true;
|
|
178
|
-
let argument = typeReference.typeArguments[0];
|
|
179
|
-
argument = typeReference.typeArguments[0];
|
|
180
|
-
// @ts-ignore
|
|
181
|
-
return getParameterBaseType(argument);
|
|
182
|
-
}
|
|
183
|
-
else if (identifier === 'StaticMember') {
|
|
184
|
-
if (mode)
|
|
185
|
-
mode.static = true;
|
|
186
|
-
let argument = typeReference.typeArguments[0];
|
|
187
|
-
// @ts-ignore
|
|
188
|
-
return getParameterBaseType(argument);
|
|
189
|
-
}
|
|
190
|
-
else if (identifier === 'StaticMethod') {
|
|
191
|
-
if (mode)
|
|
192
|
-
mode.staticMethod = true;
|
|
193
|
-
let argument = typeReference.typeArguments[0];
|
|
194
|
-
// @ts-ignore
|
|
195
|
-
return getParameterBaseType(argument);
|
|
196
|
-
}
|
|
197
|
-
else if (identifier.indexOf('SupportAsync') >= 0) {
|
|
198
|
-
if (mode) {
|
|
199
|
-
mode.supportAsync = true;
|
|
200
|
-
if (identifier === "SupportAsyncManual") {
|
|
201
|
-
mode.supportAsyncManual = true;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
let argument = typeReference.typeArguments[0];
|
|
205
|
-
if (argument.kind == typescript_1.default.SyntaxKind.TypeReference) {
|
|
206
|
-
let typeReference = argument;
|
|
207
|
-
// @ts-ignore
|
|
208
|
-
let identifier = typeReference.typeName.text;
|
|
209
|
-
if (identifier == 'DartImpl') {
|
|
210
|
-
if (mode) {
|
|
211
|
-
mode.dartImpl = true;
|
|
212
|
-
}
|
|
213
|
-
argument = typeReference.typeArguments[0];
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
else if (argument.kind == typescript_1.default.SyntaxKind.ArrayType) {
|
|
217
|
-
let elementType = argument.elementType;
|
|
218
|
-
if (mode)
|
|
219
|
-
mode.supportAsyncArrayValue = true;
|
|
220
|
-
return getParameterBaseType(elementType);
|
|
221
|
-
}
|
|
222
|
-
// @ts-ignore
|
|
223
|
-
return getParameterBaseType(argument);
|
|
224
|
-
}
|
|
225
|
-
return identifier;
|
|
226
|
-
}
|
|
227
|
-
else if (type.kind === typescript_1.default.SyntaxKind.LiteralType) {
|
|
228
|
-
// @ts-ignore
|
|
229
|
-
return getParameterBaseType(type.literal, mode);
|
|
230
|
-
}
|
|
231
|
-
return declaration_1.FunctionArgumentType.any;
|
|
232
|
-
}
|
|
233
|
-
function getParameterType(type, unionTypeCollector, mode) {
|
|
234
|
-
if (type.kind === typescript_1.default.SyntaxKind.ParenthesizedType) {
|
|
235
|
-
let typeNode = type;
|
|
236
|
-
return getParameterType(typeNode.type, unionTypeCollector, mode);
|
|
237
|
-
}
|
|
238
|
-
if (type.kind == typescript_1.default.SyntaxKind.ArrayType) {
|
|
239
|
-
let arrayType = type;
|
|
240
|
-
return {
|
|
241
|
-
isArray: true,
|
|
242
|
-
value: getParameterType(arrayType.elementType, unionTypeCollector, mode)
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
else if (type.kind === typescript_1.default.SyntaxKind.UnionType) {
|
|
246
|
-
let node = type;
|
|
247
|
-
let types = node.types;
|
|
248
|
-
let result = {
|
|
249
|
-
isArray: false,
|
|
250
|
-
value: types.map(type => getParameterType(type, unionTypeCollector, mode))
|
|
251
|
-
};
|
|
252
|
-
if ((0, utils_1.isUnionType)(result)) {
|
|
253
|
-
unionTypeCollector.types.add(result.value);
|
|
254
|
-
}
|
|
255
|
-
return result;
|
|
256
|
-
}
|
|
257
|
-
else if (type.kind === typescript_1.default.SyntaxKind.TypeReference) {
|
|
258
|
-
let typeReference = type;
|
|
259
|
-
// @ts-ignore
|
|
260
|
-
let identifier = typeReference.typeName.text;
|
|
261
|
-
if (identifier.indexOf('SupportAsync') >= 0) {
|
|
262
|
-
let argument = typeReference.typeArguments[0];
|
|
263
|
-
if (argument.kind == typescript_1.default.SyntaxKind.UnionType) {
|
|
264
|
-
if (mode) {
|
|
265
|
-
mode.supportAsync = true;
|
|
266
|
-
if (identifier === 'SupportAsyncManual') {
|
|
267
|
-
mode.supportAsyncManual = true;
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
let node = argument;
|
|
271
|
-
let types = node.types;
|
|
272
|
-
let result = {
|
|
273
|
-
isArray: false,
|
|
274
|
-
value: types.map(type => getParameterType(type, unionTypeCollector, mode))
|
|
275
|
-
};
|
|
276
|
-
if ((0, utils_1.isUnionType)(result)) {
|
|
277
|
-
unionTypeCollector.types.add(result.value);
|
|
278
|
-
}
|
|
279
|
-
return result;
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
return {
|
|
284
|
-
isArray: false,
|
|
285
|
-
value: getParameterBaseType(type, mode)
|
|
286
|
-
};
|
|
287
|
-
}
|
|
288
|
-
function paramsNodeToArguments(parameter, unionTypeCollector) {
|
|
289
|
-
let args = new declaration_1.FunctionArguments();
|
|
290
|
-
args.name = getParameterName(parameter.name);
|
|
291
|
-
let typeMode = new declaration_1.ParameterMode();
|
|
292
|
-
args.type = getParameterType(parameter.type, unionTypeCollector, typeMode);
|
|
293
|
-
args.isDotDotDot = !!parameter.dotDotDotToken;
|
|
294
|
-
args.typeMode = typeMode;
|
|
295
|
-
args.required = !parameter.questionToken;
|
|
296
|
-
return args;
|
|
297
|
-
}
|
|
298
|
-
function isParamsReadOnly(m) {
|
|
299
|
-
if (!m.modifiers)
|
|
300
|
-
return false;
|
|
301
|
-
return m.modifiers.some(k => k.kind === typescript_1.default.SyntaxKind.ReadonlyKeyword);
|
|
302
|
-
}
|
|
303
|
-
function walkProgram(blob, statement, definedPropertyCollector, unionTypeCollector) {
|
|
304
|
-
switch (statement.kind) {
|
|
305
|
-
case typescript_1.default.SyntaxKind.InterfaceDeclaration: {
|
|
306
|
-
let interfaceName = getInterfaceName(statement);
|
|
307
|
-
let s = statement;
|
|
308
|
-
let obj = new declaration_1.ClassObject();
|
|
309
|
-
let constructorDefined = false;
|
|
310
|
-
if (s.heritageClauses) {
|
|
311
|
-
let heritage = s.heritageClauses[0];
|
|
312
|
-
let heritageType = getHeritageType(heritage);
|
|
313
|
-
let mixins = getMixins(heritage);
|
|
314
|
-
if (heritageType)
|
|
315
|
-
obj.parent = heritageType.toString();
|
|
316
|
-
if (mixins)
|
|
317
|
-
obj.mixinParent = mixins;
|
|
318
|
-
}
|
|
319
|
-
obj.name = s.name.escapedText.toString();
|
|
320
|
-
if (obj.kind === declaration_1.ClassObjectKind.interface) {
|
|
321
|
-
definedPropertyCollector.interfaces.add('QJS' + interfaceName);
|
|
322
|
-
definedPropertyCollector.files.add(blob.filename);
|
|
323
|
-
definedPropertyCollector.properties.add(interfaceName);
|
|
324
|
-
}
|
|
325
|
-
s.members.forEach(member => {
|
|
326
|
-
var _a;
|
|
327
|
-
switch (member.kind) {
|
|
328
|
-
case typescript_1.default.SyntaxKind.PropertySignature: {
|
|
329
|
-
let prop = new declaration_1.PropsDeclaration();
|
|
330
|
-
let m = member;
|
|
331
|
-
prop.name = getPropName(m.name, prop);
|
|
332
|
-
prop.readonly = isParamsReadOnly(m);
|
|
333
|
-
definedPropertyCollector.properties.add(prop.name);
|
|
334
|
-
let propKind = m.type;
|
|
335
|
-
if (propKind) {
|
|
336
|
-
let mode = new declaration_1.ParameterMode();
|
|
337
|
-
prop.type = getParameterType(propKind, unionTypeCollector, mode);
|
|
338
|
-
prop.typeMode = mode;
|
|
339
|
-
if (member.questionToken) {
|
|
340
|
-
prop.optional = true;
|
|
341
|
-
}
|
|
342
|
-
if (prop.type.value === declaration_1.FunctionArgumentType.function) {
|
|
343
|
-
let f = m.type;
|
|
344
|
-
let functionProps = prop;
|
|
345
|
-
functionProps.args = [];
|
|
346
|
-
f.parameters.forEach(params => {
|
|
347
|
-
let p = paramsNodeToArguments(params, unionTypeCollector);
|
|
348
|
-
functionProps.args.push(p);
|
|
349
|
-
});
|
|
350
|
-
obj.methods.push(functionProps);
|
|
351
|
-
}
|
|
352
|
-
else {
|
|
353
|
-
obj.props.push(prop);
|
|
354
|
-
if (prop.typeMode.supportAsync) {
|
|
355
|
-
// keep asyncProp supportAsync = true
|
|
356
|
-
let asyncProp = Object.assign({}, prop);
|
|
357
|
-
// set prop supportAsync = false
|
|
358
|
-
let syncMode = Object.assign({}, mode);
|
|
359
|
-
syncMode.supportAsync = false;
|
|
360
|
-
mode.supportAsyncManual = false;
|
|
361
|
-
prop.typeMode = syncMode;
|
|
362
|
-
asyncProp.name = asyncProp.name + '_async';
|
|
363
|
-
definedPropertyCollector.properties.add(asyncProp.name);
|
|
364
|
-
asyncProp.async_type = {
|
|
365
|
-
isArray: false,
|
|
366
|
-
value: declaration_1.FunctionArgumentType.promise
|
|
367
|
-
};
|
|
368
|
-
obj.props.push(asyncProp);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
break;
|
|
373
|
-
}
|
|
374
|
-
case typescript_1.default.SyntaxKind.MethodSignature: {
|
|
375
|
-
let m = member;
|
|
376
|
-
let f = new declaration_1.FunctionDeclaration();
|
|
377
|
-
f.name = getPropName(m.name);
|
|
378
|
-
f.args = [];
|
|
379
|
-
m.parameters.forEach(params => {
|
|
380
|
-
let p = paramsNodeToArguments(params, unionTypeCollector);
|
|
381
|
-
f.args.push(p);
|
|
382
|
-
});
|
|
383
|
-
obj.methods.push(f);
|
|
384
|
-
if (m.type) {
|
|
385
|
-
let mode = new declaration_1.ParameterMode();
|
|
386
|
-
f.returnType = getParameterType(m.type, unionTypeCollector, mode);
|
|
387
|
-
// Override the default type for SupportAsync<Type[]> to support ArrayTypes;
|
|
388
|
-
if (mode.supportAsyncArrayValue) {
|
|
389
|
-
f.returnType = {
|
|
390
|
-
isArray: true,
|
|
391
|
-
value: f.returnType
|
|
392
|
-
};
|
|
393
|
-
}
|
|
394
|
-
f.returnTypeMode = mode;
|
|
395
|
-
if (f.returnTypeMode.staticMethod) {
|
|
396
|
-
obj.staticMethods.push(f);
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
if ((_a = f.returnTypeMode) === null || _a === void 0 ? void 0 : _a.supportAsync) {
|
|
400
|
-
// keep asyncFunc supportAsync = true
|
|
401
|
-
let asyncFunc = Object.assign({}, f);
|
|
402
|
-
let mode = Object.assign({}, f.returnTypeMode);
|
|
403
|
-
mode.supportAsync = false;
|
|
404
|
-
mode.supportAsyncManual = false;
|
|
405
|
-
f.returnTypeMode = mode;
|
|
406
|
-
asyncFunc.name = getPropName(m.name) + '_async';
|
|
407
|
-
asyncFunc.args = [];
|
|
408
|
-
m.parameters.forEach(params => {
|
|
409
|
-
let p = paramsNodeToArguments(params, unionTypeCollector);
|
|
410
|
-
asyncFunc.args.push(p);
|
|
411
|
-
});
|
|
412
|
-
asyncFunc.async_returnType = {
|
|
413
|
-
isArray: false,
|
|
414
|
-
value: declaration_1.FunctionArgumentType.promise
|
|
415
|
-
};
|
|
416
|
-
obj.methods.push(asyncFunc);
|
|
417
|
-
}
|
|
418
|
-
break;
|
|
419
|
-
}
|
|
420
|
-
case typescript_1.default.SyntaxKind.IndexSignature: {
|
|
421
|
-
let m = member;
|
|
422
|
-
let prop = new declaration_1.IndexedPropertyDeclaration();
|
|
423
|
-
let modifier = m.modifiers;
|
|
424
|
-
prop.readonly = !!(modifier && modifier[0].kind == typescript_1.default.SyntaxKind.ReadonlyKeyword);
|
|
425
|
-
let params = m.parameters;
|
|
426
|
-
prop.indexKeyType = params[0].type.kind === typescript_1.default.SyntaxKind.NumberKeyword ? 'number' : 'string';
|
|
427
|
-
let mode = new declaration_1.ParameterMode();
|
|
428
|
-
prop.type = getParameterType(m.type, unionTypeCollector, mode);
|
|
429
|
-
prop.typeMode = mode;
|
|
430
|
-
obj.indexedProp = prop;
|
|
431
|
-
break;
|
|
432
|
-
}
|
|
433
|
-
case typescript_1.default.SyntaxKind.ConstructSignature: {
|
|
434
|
-
let m = member;
|
|
435
|
-
let c = new declaration_1.FunctionDeclaration();
|
|
436
|
-
c.name = 'constructor';
|
|
437
|
-
c.args = [];
|
|
438
|
-
m.parameters.forEach(params => {
|
|
439
|
-
let p = paramsNodeToArguments(params, unionTypeCollector);
|
|
440
|
-
c.args.push(p);
|
|
441
|
-
});
|
|
442
|
-
c.returnType = getParameterType(m.type, unionTypeCollector);
|
|
443
|
-
obj.construct = c;
|
|
444
|
-
constructorDefined = true;
|
|
445
|
-
break;
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
});
|
|
449
|
-
declaration_1.ClassObject.globalClassMap[interfaceName] = obj;
|
|
450
|
-
return obj;
|
|
451
|
-
}
|
|
452
|
-
case typescript_1.default.SyntaxKind.VariableStatement: {
|
|
453
|
-
let declaration = statement.declarationList.declarations[0];
|
|
454
|
-
let methodName = declaration.name.text;
|
|
455
|
-
let type = declaration.type;
|
|
456
|
-
let functionObject = new declaration_1.FunctionObject();
|
|
457
|
-
functionObject.declare = new declaration_1.FunctionDeclaration();
|
|
458
|
-
if ((type === null || type === void 0 ? void 0 : type.kind) == typescript_1.default.SyntaxKind.FunctionType) {
|
|
459
|
-
functionObject.declare.args = type.parameters.map(param => paramsNodeToArguments(param, unionTypeCollector));
|
|
460
|
-
functionObject.declare.returnType = getParameterType(type.type, unionTypeCollector);
|
|
461
|
-
functionObject.declare.name = methodName.toString();
|
|
462
|
-
}
|
|
463
|
-
return functionObject;
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
return null;
|
|
467
|
-
}
|