Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 25 additions & 6 deletions Examples/PlayBridgeJS/Sources/JavaScript/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,19 +268,38 @@ export class BridgeJSPlayground {

try {
this.hideError();
this.editorSystem.clearDiagnostics();

const inputs = this.editorSystem.getInputs();
const swiftCode = inputs.swift;
const dtsCode = inputs.dts;

// Process the code and get PlayBridgeJSOutput
const result = this.playBridgeJS.update(swiftCode, dtsCode);

// Update outputs using the PlayBridgeJSOutput object
this.editorSystem.updateOutputs(result);

console.log('Code generated successfully');
const result = this.playBridgeJS.updateDetailed(swiftCode, dtsCode);

const diagnostics = result.diagnostics;
if (diagnostics && diagnostics.length > 0) {
const mapped = diagnostics.map(d => ({
file: d.file,
startLineNumber: d.startLine,
startColumn: d.startColumn,
endLineNumber: d.endLine,
endColumn: d.endColumn,
message: d.message
}));
this.editorSystem.showDiagnostics(mapped);
return;
}

const output = result.output;
if (output) {
// Update outputs using the PlayBridgeJSOutput object
this.editorSystem.updateOutputs(output);
this.hideError();
console.log('Code generated successfully');
} else {
this.showError('No output produced.');
}
} catch (error) {
console.error('Error generating code:', error);
this.showError('Error generating code: ' + error.message);
Expand Down
67 changes: 62 additions & 5 deletions Examples/PlayBridgeJS/Sources/JavaScript/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class EditorSystem {
language: 'swift',
placeholder: '// Import Swift Macros will appear here...',
readOnly: true,
modelUri: 'BridgeJS.Macros.swift'
modelUri: 'Playground.Macros.swift'
},
{
key: 'swift-glue',
Expand Down Expand Up @@ -206,10 +206,10 @@ export class EditorSystem {

updateOutputs(result) {
const outputMap = {
'swift-glue': () => result.swiftGlue(),
'swift-import-macros': () => result.importSwiftMacroDecls(),
'js-generated': () => result.outputJs(),
'dts-generated': () => result.outputDts()
'swift-glue': () => result.swiftGlue,
'swift-import-macros': () => result.importSwiftMacroDecls,
'js-generated': () => result.outputJs,
'dts-generated': () => result.outputDts
};

Object.entries(outputMap).forEach(([key, getContent]) => {
Expand All @@ -230,6 +230,63 @@ export class EditorSystem {
});
}

clearDiagnostics() {
// Remove all diagnostics owned by the playground.
this.editors.forEach(editor => {
const model = editor.getModel();
if (!model || typeof monaco === 'undefined') return;
monaco.editor.setModelMarkers(model, 'bridgejs', []);
});
}

/**
* @param {{file: string, startLineNumber: number, startColumn: number, endLineNumber?: number, endColumn?: number, message: string}[]} diagnostics
*/
showDiagnostics(diagnostics) {
if (typeof monaco === 'undefined') return;

// Group diagnostics per model so we can set markers in batches.
const markersByModel = new Map();

diagnostics.forEach(diag => {
const model = this.findModelForFile(diag.file);
if (!model) return;

const markers = markersByModel.get(model) ?? [];
const lineLength = model.getLineMaxColumn(diag.startLineNumber);
const endLine = diag.endLineNumber ?? diag.startLineNumber;
const endColumn = Math.min(lineLength, diag.endColumn ?? diag.startColumn + 1);

markers.push({
severity: monaco.MarkerSeverity.Error,
message: diag.message,
startLineNumber: diag.startLineNumber,
startColumn: diag.startColumn,
endLineNumber: endLine,
endColumn
});

markersByModel.set(model, markers);
});

markersByModel.forEach((markers, model) => {
monaco.editor.setModelMarkers(model, 'bridgejs', markers);
});
}

findModelForFile(fileName) {
const normalized = fileName.startsWith('/') ? fileName.slice(1) : fileName;
for (const editor of this.editors.values()) {
const model = editor.getModel();
if (!model) continue;
const uriPath = model.uri.path.startsWith('/') ? model.uri.path.slice(1) : model.uri.path;
if (uriPath === normalized || uriPath.endsWith('/' + normalized)) {
return model;
}
}
return null;
}

// Utility methods
getConfigByKey(key) {
return [...this.config.input, ...this.config.output].find(c => c.key === key);
Expand Down
226 changes: 152 additions & 74 deletions Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,153 @@

@_spi(BridgeJS) import JavaScriptKit

extension PlayBridgeJSOutput: _BridgedSwiftStruct {
@_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> PlayBridgeJSOutput {
let swiftGlue = String.bridgeJSStackPop()
let importSwiftMacroDecls = String.bridgeJSStackPop()
let outputDts = String.bridgeJSStackPop()
let outputJs = String.bridgeJSStackPop()
return PlayBridgeJSOutput(outputJs: outputJs, outputDts: outputDts, importSwiftMacroDecls: importSwiftMacroDecls, swiftGlue: swiftGlue)
}

@_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() {
self.outputJs.bridgeJSStackPush()
self.outputDts.bridgeJSStackPush()
self.importSwiftMacroDecls.bridgeJSStackPush()
self.swiftGlue.bridgeJSStackPush()
}

init(unsafelyCopying jsObject: JSObject) {
let __bjs_cleanupId = _bjs_struct_lower_PlayBridgeJSOutput(jsObject.bridgeJSLowerParameter())
defer {
_swift_js_struct_cleanup(__bjs_cleanupId)
}
self = Self.bridgeJSStackPop()
}

func toJSObject() -> JSObject {
let __bjs_self = self
__bjs_self.bridgeJSStackPush()
return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_PlayBridgeJSOutput()))
}
}

#if arch(wasm32)
@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_PlayBridgeJSOutput")
fileprivate func _bjs_struct_lower_PlayBridgeJSOutput(_ objectId: Int32) -> Int32
#else
fileprivate func _bjs_struct_lower_PlayBridgeJSOutput(_ objectId: Int32) -> Int32 {
fatalError("Only available on WebAssembly")
}
#endif

#if arch(wasm32)
@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_PlayBridgeJSOutput")
fileprivate func _bjs_struct_lift_PlayBridgeJSOutput() -> Int32
#else
fileprivate func _bjs_struct_lift_PlayBridgeJSOutput() -> Int32 {
fatalError("Only available on WebAssembly")
}
#endif

extension PlayBridgeJSDiagnostic: _BridgedSwiftStruct {
@_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> PlayBridgeJSDiagnostic {
let endColumn = Int.bridgeJSStackPop()
let endLine = Int.bridgeJSStackPop()
let startColumn = Int.bridgeJSStackPop()
let startLine = Int.bridgeJSStackPop()
let message = String.bridgeJSStackPop()
let file = String.bridgeJSStackPop()
return PlayBridgeJSDiagnostic(file: file, message: message, startLine: startLine, startColumn: startColumn, endLine: endLine, endColumn: endColumn)
}

@_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() {
self.file.bridgeJSStackPush()
self.message.bridgeJSStackPush()
self.startLine.bridgeJSStackPush()
self.startColumn.bridgeJSStackPush()
self.endLine.bridgeJSStackPush()
self.endColumn.bridgeJSStackPush()
}

init(unsafelyCopying jsObject: JSObject) {
let __bjs_cleanupId = _bjs_struct_lower_PlayBridgeJSDiagnostic(jsObject.bridgeJSLowerParameter())
defer {
_swift_js_struct_cleanup(__bjs_cleanupId)
}
self = Self.bridgeJSStackPop()
}

func toJSObject() -> JSObject {
let __bjs_self = self
__bjs_self.bridgeJSStackPush()
return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_PlayBridgeJSDiagnostic()))
}
}

#if arch(wasm32)
@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_PlayBridgeJSDiagnostic")
fileprivate func _bjs_struct_lower_PlayBridgeJSDiagnostic(_ objectId: Int32) -> Int32
#else
fileprivate func _bjs_struct_lower_PlayBridgeJSDiagnostic(_ objectId: Int32) -> Int32 {
fatalError("Only available on WebAssembly")
}
#endif

#if arch(wasm32)
@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_PlayBridgeJSDiagnostic")
fileprivate func _bjs_struct_lift_PlayBridgeJSDiagnostic() -> Int32
#else
fileprivate func _bjs_struct_lift_PlayBridgeJSDiagnostic() -> Int32 {
fatalError("Only available on WebAssembly")
}
#endif

extension PlayBridgeJSResult: _BridgedSwiftStruct {
@_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> PlayBridgeJSResult {
let diagnostics = [PlayBridgeJSDiagnostic].bridgeJSStackPop()
let output = Optional<PlayBridgeJSOutput>.bridgeJSStackPop()
return PlayBridgeJSResult(output: output, diagnostics: diagnostics)
}

@_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() {
self.output.bridgeJSStackPush()
self.diagnostics.bridgeJSStackPush()
}

init(unsafelyCopying jsObject: JSObject) {
let __bjs_cleanupId = _bjs_struct_lower_PlayBridgeJSResult(jsObject.bridgeJSLowerParameter())
defer {
_swift_js_struct_cleanup(__bjs_cleanupId)
}
self = Self.bridgeJSStackPop()
}

func toJSObject() -> JSObject {
let __bjs_self = self
__bjs_self.bridgeJSStackPush()
return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_PlayBridgeJSResult()))
}
}

#if arch(wasm32)
@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_PlayBridgeJSResult")
fileprivate func _bjs_struct_lower_PlayBridgeJSResult(_ objectId: Int32) -> Int32
#else
fileprivate func _bjs_struct_lower_PlayBridgeJSResult(_ objectId: Int32) -> Int32 {
fatalError("Only available on WebAssembly")
}
#endif

#if arch(wasm32)
@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_PlayBridgeJSResult")
fileprivate func _bjs_struct_lift_PlayBridgeJSResult() -> Int32
#else
fileprivate func _bjs_struct_lift_PlayBridgeJSResult() -> Int32 {
fatalError("Only available on WebAssembly")
}
#endif

@_expose(wasm, "bjs_PlayBridgeJS_init")
@_cdecl("bjs_PlayBridgeJS_init")
public func _bjs_PlayBridgeJS_init() -> UnsafeMutableRawPointer {
Expand All @@ -18,12 +165,12 @@ public func _bjs_PlayBridgeJS_init() -> UnsafeMutableRawPointer {
#endif
}

@_expose(wasm, "bjs_PlayBridgeJS_update")
@_cdecl("bjs_PlayBridgeJS_update")
public func _bjs_PlayBridgeJS_update(_ _self: UnsafeMutableRawPointer, _ swiftSourceBytes: Int32, _ swiftSourceLength: Int32, _ dtsSourceBytes: Int32, _ dtsSourceLength: Int32) -> UnsafeMutableRawPointer {
@_expose(wasm, "bjs_PlayBridgeJS_updateDetailed")
@_cdecl("bjs_PlayBridgeJS_updateDetailed")
public func _bjs_PlayBridgeJS_updateDetailed(_ _self: UnsafeMutableRawPointer, _ swiftSourceBytes: Int32, _ swiftSourceLength: Int32, _ dtsSourceBytes: Int32, _ dtsSourceLength: Int32) -> Void {
#if arch(wasm32)
do {
let ret = try PlayBridgeJS.bridgeJSLiftParameter(_self).update(swiftSource: String.bridgeJSLiftParameter(swiftSourceBytes, swiftSourceLength), dtsSource: String.bridgeJSLiftParameter(dtsSourceBytes, dtsSourceLength))
let ret = try PlayBridgeJS.bridgeJSLiftParameter(_self).updateDetailed(swiftSource: String.bridgeJSLiftParameter(swiftSourceBytes, swiftSourceLength), dtsSource: String.bridgeJSLiftParameter(dtsSourceBytes, dtsSourceLength))
return ret.bridgeJSLowerReturn()
} catch let error {
if let error = error.thrownValue.object {
Expand All @@ -36,7 +183,7 @@ public func _bjs_PlayBridgeJS_update(_ _self: UnsafeMutableRawPointer, _ swiftSo
_swift_js_throw(Int32(bitPattern: $0.id))
}
}
return UnsafeMutableRawPointer(bitPattern: -1).unsafelyUnwrapped
return
}
#else
fatalError("Only available on WebAssembly")
Expand Down Expand Up @@ -68,75 +215,6 @@ fileprivate func _bjs_PlayBridgeJS_wrap(_ pointer: UnsafeMutableRawPointer) -> I
}
#endif

@_expose(wasm, "bjs_PlayBridgeJSOutput_outputJs")
@_cdecl("bjs_PlayBridgeJSOutput_outputJs")
public func _bjs_PlayBridgeJSOutput_outputJs(_ _self: UnsafeMutableRawPointer) -> Void {
#if arch(wasm32)
let ret = PlayBridgeJSOutput.bridgeJSLiftParameter(_self).outputJs()
return ret.bridgeJSLowerReturn()
#else
fatalError("Only available on WebAssembly")
#endif
}

@_expose(wasm, "bjs_PlayBridgeJSOutput_outputDts")
@_cdecl("bjs_PlayBridgeJSOutput_outputDts")
public func _bjs_PlayBridgeJSOutput_outputDts(_ _self: UnsafeMutableRawPointer) -> Void {
#if arch(wasm32)
let ret = PlayBridgeJSOutput.bridgeJSLiftParameter(_self).outputDts()
return ret.bridgeJSLowerReturn()
#else
fatalError("Only available on WebAssembly")
#endif
}

@_expose(wasm, "bjs_PlayBridgeJSOutput_importSwiftMacroDecls")
@_cdecl("bjs_PlayBridgeJSOutput_importSwiftMacroDecls")
public func _bjs_PlayBridgeJSOutput_importSwiftMacroDecls(_ _self: UnsafeMutableRawPointer) -> Void {
#if arch(wasm32)
let ret = PlayBridgeJSOutput.bridgeJSLiftParameter(_self).importSwiftMacroDecls()
return ret.bridgeJSLowerReturn()
#else
fatalError("Only available on WebAssembly")
#endif
}

@_expose(wasm, "bjs_PlayBridgeJSOutput_swiftGlue")
@_cdecl("bjs_PlayBridgeJSOutput_swiftGlue")
public func _bjs_PlayBridgeJSOutput_swiftGlue(_ _self: UnsafeMutableRawPointer) -> Void {
#if arch(wasm32)
let ret = PlayBridgeJSOutput.bridgeJSLiftParameter(_self).swiftGlue()
return ret.bridgeJSLowerReturn()
#else
fatalError("Only available on WebAssembly")
#endif
}

@_expose(wasm, "bjs_PlayBridgeJSOutput_deinit")
@_cdecl("bjs_PlayBridgeJSOutput_deinit")
public func _bjs_PlayBridgeJSOutput_deinit(_ pointer: UnsafeMutableRawPointer) -> Void {
#if arch(wasm32)
Unmanaged<PlayBridgeJSOutput>.fromOpaque(pointer).release()
#else
fatalError("Only available on WebAssembly")
#endif
}

extension PlayBridgeJSOutput: ConvertibleToJSValue, _BridgedSwiftHeapObject {
var jsValue: JSValue {
return .object(JSObject(id: UInt32(bitPattern: _bjs_PlayBridgeJSOutput_wrap(Unmanaged.passRetained(self).toOpaque()))))
}
}

#if arch(wasm32)
@_extern(wasm, module: "PlayBridgeJS", name: "bjs_PlayBridgeJSOutput_wrap")
fileprivate func _bjs_PlayBridgeJSOutput_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32
#else
fileprivate func _bjs_PlayBridgeJSOutput_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 {
fatalError("Only available on WebAssembly")
}
#endif

#if arch(wasm32)
@_extern(wasm, module: "PlayBridgeJS", name: "bjs_createTS2Swift")
fileprivate func bjs_createTS2Swift() -> Int32
Expand Down
Loading