Skip to content

Commit d8523db

Browse files
Merge pull request #410 from swiftwasm/fix-imported-types-reference-error
2 parents 57a6fa2 + 462205b commit d8523db

File tree

11 files changed

+958
-0
lines changed

11 files changed

+958
-0
lines changed

Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ struct BridgeJSLink {
225225
var dtsLines: [String] = []
226226
dtsLines.append(contentsOf: namespaceDeclarations())
227227
dtsLines.append(contentsOf: dtsClassLines)
228+
dtsLines.append(contentsOf: generateImportedTypeDefinitions())
228229
dtsLines.append("export type Exports = {")
229230
dtsLines.append(contentsOf: dtsExportLines.map { $0.indent(count: 4) })
230231
dtsLines.append("}")
@@ -250,6 +251,38 @@ struct BridgeJSLink {
250251
return (outputJs, outputDts)
251252
}
252253

254+
private func generateImportedTypeDefinitions() -> [String] {
255+
var typeDefinitions: [String] = []
256+
257+
for skeletonSet in importedSkeletons {
258+
for fileSkeleton in skeletonSet.children {
259+
for type in fileSkeleton.types {
260+
typeDefinitions.append("export interface \(type.name) {")
261+
262+
// Add methods
263+
for method in type.methods {
264+
let methodSignature =
265+
"\(method.name)\(renderTSSignature(parameters: method.parameters, returnType: method.returnType));"
266+
typeDefinitions.append(methodSignature.indent(count: 4))
267+
}
268+
269+
// Add properties
270+
for property in type.properties {
271+
let propertySignature =
272+
property.isReadonly
273+
? "readonly \(property.name): \(property.type.tsType);"
274+
: "\(property.name): \(property.type.tsType);"
275+
typeDefinitions.append(propertySignature.indent(count: 4))
276+
}
277+
278+
typeDefinitions.append("}")
279+
}
280+
}
281+
}
282+
283+
return typeDefinitions
284+
}
285+
253286
private func namespaceDeclarations() -> [String] {
254287
var dtsLines: [String] = []
255288
var namespaceFunctions: [String: [ExportedFunction]] = [:]
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Test case for multiple imported types with methods and properties
2+
export interface DatabaseConnection {
3+
connect(url: string): void;
4+
execute(query: string): any;
5+
readonly isConnected: boolean;
6+
connectionTimeout: number;
7+
}
8+
9+
export interface Logger {
10+
log(message: string): void;
11+
error(message: string, error: any): void;
12+
readonly level: string;
13+
}
14+
15+
export interface ConfigManager {
16+
get(key: string): any;
17+
set(key: string, value: any): void;
18+
readonly configPath: string;
19+
}
20+
21+
export function createDatabaseConnection(config: any): DatabaseConnection;
22+
export function createLogger(level: string): Logger;
23+
export function getConfigManager(): ConfigManager;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Test case similar to the TS2Skeleton use case that caused the original bug
2+
export interface TypeScriptProcessor {
3+
convert(ts: string): string;
4+
validate(ts: string): boolean;
5+
readonly version: string;
6+
}
7+
8+
export interface CodeGenerator {
9+
generate(input: any): string;
10+
readonly outputFormat: string;
11+
}
12+
13+
export function createTS2Skeleton(): TypeScriptProcessor;
14+
export function createCodeGenerator(format: string): CodeGenerator;

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Interface.Import.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
// To update this file, just rebuild your project or run
55
// `swift package bridge-js`.
66

7+
export interface Animatable {
8+
animate(keyframes: any, options: any): any;
9+
getAnimations(options: any): any;
10+
}
711
export type Exports = {
812
}
913
export type Imports = {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit,
2+
// DO NOT EDIT.
3+
//
4+
// To update this file, just rebuild your project or run
5+
// `swift package bridge-js`.
6+
7+
export interface DatabaseConnection {
8+
connect(url: string): void;
9+
execute(query: string): any;
10+
readonly isConnected: boolean;
11+
connectionTimeout: number;
12+
}
13+
export interface Logger {
14+
log(message: string): void;
15+
error(message: string, error: any): void;
16+
readonly level: string;
17+
}
18+
export interface ConfigManager {
19+
get(key: string): any;
20+
set(key: string, value: any): void;
21+
readonly configPath: string;
22+
}
23+
export type Exports = {
24+
}
25+
export type Imports = {
26+
createDatabaseConnection(config: any): DatabaseConnection;
27+
createLogger(level: string): Logger;
28+
getConfigManager(): ConfigManager;
29+
}
30+
export function createInstantiator(options: {
31+
imports: Imports;
32+
}, swift: any): Promise<{
33+
addImports: (importObject: WebAssembly.Imports) => void;
34+
setInstance: (instance: WebAssembly.Instance) => void;
35+
createExports: (instance: WebAssembly.Instance) => Exports;
36+
}>;
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit,
2+
// DO NOT EDIT.
3+
//
4+
// To update this file, just rebuild your project or run
5+
// `swift package bridge-js`.
6+
7+
export async function createInstantiator(options, swift) {
8+
let instance;
9+
let memory;
10+
let setException;
11+
const textDecoder = new TextDecoder("utf-8");
12+
const textEncoder = new TextEncoder("utf-8");
13+
14+
let tmpRetString;
15+
let tmpRetBytes;
16+
let tmpRetException;
17+
return {
18+
/** @param {WebAssembly.Imports} importObject */
19+
addImports: (importObject) => {
20+
const bjs = {};
21+
importObject["bjs"] = bjs;
22+
bjs["swift_js_return_string"] = function(ptr, len) {
23+
const bytes = new Uint8Array(memory.buffer, ptr, len);
24+
tmpRetString = textDecoder.decode(bytes);
25+
}
26+
bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) {
27+
const source = swift.memory.getObject(sourceId);
28+
const bytes = new Uint8Array(memory.buffer, bytesPtr);
29+
bytes.set(source);
30+
}
31+
bjs["swift_js_make_js_string"] = function(ptr, len) {
32+
const bytes = new Uint8Array(memory.buffer, ptr, len);
33+
return swift.memory.retain(textDecoder.decode(bytes));
34+
}
35+
bjs["swift_js_init_memory_with_result"] = function(ptr, len) {
36+
const target = new Uint8Array(memory.buffer, ptr, len);
37+
target.set(tmpRetBytes);
38+
tmpRetBytes = undefined;
39+
}
40+
bjs["swift_js_throw"] = function(id) {
41+
tmpRetException = swift.memory.retainByRef(id);
42+
}
43+
bjs["swift_js_retain"] = function(id) {
44+
return swift.memory.retainByRef(id);
45+
}
46+
bjs["swift_js_release"] = function(id) {
47+
swift.memory.release(id);
48+
}
49+
const TestModule = importObject["TestModule"] = {};
50+
TestModule["bjs_createDatabaseConnection"] = function bjs_createDatabaseConnection(config) {
51+
try {
52+
let ret = options.imports.createDatabaseConnection(swift.memory.getObject(config));
53+
return swift.memory.retain(ret);
54+
} catch (error) {
55+
setException(error);
56+
return 0
57+
}
58+
}
59+
TestModule["bjs_createLogger"] = function bjs_createLogger(level) {
60+
try {
61+
const levelObject = swift.memory.getObject(level);
62+
swift.memory.release(level);
63+
let ret = options.imports.createLogger(levelObject);
64+
return swift.memory.retain(ret);
65+
} catch (error) {
66+
setException(error);
67+
return 0
68+
}
69+
}
70+
TestModule["bjs_getConfigManager"] = function bjs_getConfigManager() {
71+
try {
72+
let ret = options.imports.getConfigManager();
73+
return swift.memory.retain(ret);
74+
} catch (error) {
75+
setException(error);
76+
return 0
77+
}
78+
}
79+
TestModule["bjs_DatabaseConnection_isConnected_get"] = function bjs_DatabaseConnection_isConnected_get(self) {
80+
try {
81+
let ret = swift.memory.getObject(self).isConnected;
82+
return ret !== 0;
83+
} catch (error) {
84+
setException(error);
85+
return 0
86+
}
87+
}
88+
TestModule["bjs_DatabaseConnection_connectionTimeout_get"] = function bjs_DatabaseConnection_connectionTimeout_get(self) {
89+
try {
90+
let ret = swift.memory.getObject(self).connectionTimeout;
91+
return ret;
92+
} catch (error) {
93+
setException(error);
94+
return 0
95+
}
96+
}
97+
TestModule["bjs_DatabaseConnection_connectionTimeout_set"] = function bjs_DatabaseConnection_connectionTimeout_set(self, newValue) {
98+
try {
99+
swift.memory.getObject(self).connectionTimeout = newValue;
100+
} catch (error) {
101+
setException(error);
102+
return 0
103+
}
104+
}
105+
TestModule["bjs_DatabaseConnection_connect"] = function bjs_DatabaseConnection_connect(self, url) {
106+
try {
107+
const urlObject = swift.memory.getObject(url);
108+
swift.memory.release(url);
109+
swift.memory.getObject(self).connect(urlObject);
110+
} catch (error) {
111+
setException(error);
112+
}
113+
}
114+
TestModule["bjs_DatabaseConnection_execute"] = function bjs_DatabaseConnection_execute(self, query) {
115+
try {
116+
const queryObject = swift.memory.getObject(query);
117+
swift.memory.release(query);
118+
let ret = swift.memory.getObject(self).execute(queryObject);
119+
return swift.memory.retain(ret);
120+
} catch (error) {
121+
setException(error);
122+
return 0
123+
}
124+
}
125+
TestModule["bjs_Logger_level_get"] = function bjs_Logger_level_get(self) {
126+
try {
127+
let ret = swift.memory.getObject(self).level;
128+
tmpRetBytes = textEncoder.encode(ret);
129+
return tmpRetBytes.length;
130+
} catch (error) {
131+
setException(error);
132+
}
133+
}
134+
TestModule["bjs_Logger_log"] = function bjs_Logger_log(self, message) {
135+
try {
136+
const messageObject = swift.memory.getObject(message);
137+
swift.memory.release(message);
138+
swift.memory.getObject(self).log(messageObject);
139+
} catch (error) {
140+
setException(error);
141+
}
142+
}
143+
TestModule["bjs_Logger_error"] = function bjs_Logger_error(self, message, error) {
144+
try {
145+
const messageObject = swift.memory.getObject(message);
146+
swift.memory.release(message);
147+
swift.memory.getObject(self).error(messageObject, swift.memory.getObject(error));
148+
} catch (error) {
149+
setException(error);
150+
}
151+
}
152+
TestModule["bjs_ConfigManager_configPath_get"] = function bjs_ConfigManager_configPath_get(self) {
153+
try {
154+
let ret = swift.memory.getObject(self).configPath;
155+
tmpRetBytes = textEncoder.encode(ret);
156+
return tmpRetBytes.length;
157+
} catch (error) {
158+
setException(error);
159+
}
160+
}
161+
TestModule["bjs_ConfigManager_get"] = function bjs_ConfigManager_get(self, key) {
162+
try {
163+
const keyObject = swift.memory.getObject(key);
164+
swift.memory.release(key);
165+
let ret = swift.memory.getObject(self).get(keyObject);
166+
return swift.memory.retain(ret);
167+
} catch (error) {
168+
setException(error);
169+
return 0
170+
}
171+
}
172+
TestModule["bjs_ConfigManager_set"] = function bjs_ConfigManager_set(self, key, value) {
173+
try {
174+
const keyObject = swift.memory.getObject(key);
175+
swift.memory.release(key);
176+
swift.memory.getObject(self).set(keyObject, swift.memory.getObject(value));
177+
} catch (error) {
178+
setException(error);
179+
}
180+
}
181+
},
182+
setInstance: (i) => {
183+
instance = i;
184+
memory = instance.exports.memory;
185+
setException = (error) => {
186+
instance.exports._swift_js_exception.value = swift.memory.retain(error)
187+
}
188+
},
189+
/** @param {WebAssembly.Instance} instance */
190+
createExports: (instance) => {
191+
const js = swift.memory.heap;
192+
193+
return {
194+
195+
};
196+
},
197+
}
198+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit,
2+
// DO NOT EDIT.
3+
//
4+
// To update this file, just rebuild your project or run
5+
// `swift package bridge-js`.
6+
7+
export interface TypeScriptProcessor {
8+
convert(ts: string): string;
9+
validate(ts: string): boolean;
10+
readonly version: string;
11+
}
12+
export interface CodeGenerator {
13+
generate(input: any): string;
14+
readonly outputFormat: string;
15+
}
16+
export type Exports = {
17+
}
18+
export type Imports = {
19+
createTS2Skeleton(): TypeScriptProcessor;
20+
createCodeGenerator(format: string): CodeGenerator;
21+
}
22+
export function createInstantiator(options: {
23+
imports: Imports;
24+
}, swift: any): Promise<{
25+
addImports: (importObject: WebAssembly.Imports) => void;
26+
setInstance: (instance: WebAssembly.Instance) => void;
27+
createExports: (instance: WebAssembly.Instance) => Exports;
28+
}>;

0 commit comments

Comments
 (0)