Skip to content

Commit a8f1cc9

Browse files
committed
Printing for handles, descriptors and address methods for props
1 parent 258ccff commit a8f1cc9

File tree

7 files changed

+280
-37
lines changed

7 files changed

+280
-37
lines changed

Package.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ let package = Package(
122122
dependencies: [
123123
.package(url: "https://github.com/swiftlang/swift-syntax.git", branch: "main"),
124124
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.5.0"),
125-
.package(url: "https://github.com/apple/swift-system", from: "1.0.0"),
125+
.package(url: "https://github.com/apple/swift-system", from: "1.0.0"), // TODO: remove, we should not need 'nm' or process callouts
126+
.package(url: "https://github.com/apple/swift-collections.git", .upToNextMinor(from: "1.1.0")),
126127
],
127128
targets: [
128129
.macro(
@@ -282,6 +283,7 @@ let package = Package(
282283
.product(name: "SwiftSyntax", package: "swift-syntax"),
283284
.product(name: "SwiftSyntaxBuilder", package: "swift-syntax"),
284285
.product(name: "ArgumentParser", package: "swift-argument-parser"),
286+
.product(name: "Collections", package: "swift-collections"),
285287
"_Subprocess",
286288
"JavaTypes",
287289
],
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import Foundation
16+
import JavaTypes
17+
import SwiftSyntax
18+
import OrderedCollections
19+
20+
extension ImportedFunc {
21+
/// Render a `@{@snippet ... }` comment section that can be put inside a JavaDoc comment
22+
/// when referring to the original declaration a printed method refers to.
23+
var renderCommentSnippet: String? {
24+
if let syntax {
25+
"""
26+
* {@snippet lang=swift :
27+
* \(syntax)
28+
* }
29+
"""
30+
} else {
31+
nil
32+
}
33+
}
34+
}
35+
36+
extension VariableAccessorKind {
37+
public var renderDescFieldName: String {
38+
switch self {
39+
case .get: "DESC_GET"
40+
case .set: "DESC_SET"
41+
}
42+
}
43+
44+
public var renderAddrFieldName: String {
45+
switch self {
46+
case .get: "ADDR_GET"
47+
case .set: "ADDR_SET"
48+
}
49+
}
50+
51+
public var renderHandleFieldName: String {
52+
switch self {
53+
case .get: "HANDLE_GET"
54+
case .set: "HANDLE_SET"
55+
}
56+
}
57+
58+
/// Renders a "$get" part that can be used in a method signature representing this accessor.
59+
public var renderMethodNameSegment: String {
60+
switch self {
61+
case .get: "$get"
62+
case .set: "$set"
63+
}
64+
}
65+
}

Sources/JExtractSwift/ImportedDecls.swift

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import Foundation
1616
import JavaTypes
1717
import SwiftSyntax
18+
import OrderedCollections
1819

1920
/// Any imported (Swift) declaration
2021
protocol ImportedDecl {
@@ -232,13 +233,6 @@ public struct ImportedFunc: ImportedDecl, CustomStringConvertible {
232233
public enum VariableAccessorKind {
233234
case get
234235
case set
235-
236-
public var renderDescFieldName: String {
237-
switch self {
238-
case .get: "DESC_GET"
239-
case .set: "DESC_SET"
240-
}
241-
}
242236
}
243237

244238
public struct ImportedVariable: ImportedDecl, CustomStringConvertible {
@@ -257,7 +251,7 @@ public struct ImportedVariable: ImportedDecl, CustomStringConvertible {
257251
/// Usually this will be all the accessors the variable declares,
258252
/// however if the getter is async or throwing we may not be able to import it
259253
/// (yet), and therefore would skip it from the supported set.
260-
public var supportedAccessorKinds: Set<VariableAccessorKind> = [.get, .set]
254+
public var supportedAccessorKinds: OrderedSet<VariableAccessorKind> = [.get, .set]
261255

262256
/// This is the base identifier for the function, e.g., "init" for an
263257
/// initializer or "f" for "f(a:b:)".

Sources/JExtractSwift/Swift2JavaTranslator+Printing.swift

Lines changed: 74 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -465,54 +465,108 @@ extension Swift2JavaTranslator {
465465
printMethodDowncallHandleForAddrDesc(&printer)
466466
}
467467

468+
printFunctionDescriptorMethod(&printer, decl: decl)
469+
printFunctionMethodHandleMethod(&printer, decl: decl)
470+
printFunctionAddressMethod(&printer, decl: decl)
471+
472+
// Render the basic "make the downcall" function
473+
if decl.hasParent {
474+
printFuncDowncallMethod(&printer, decl: decl, selfVariant: .memorySegment)
475+
printFuncDowncallMethod(&printer, decl: decl, selfVariant: .wrapper)
476+
} else {
477+
printFuncDowncallMethod(&printer, decl: decl, selfVariant: nil)
478+
}
479+
}
480+
481+
private func printFunctionAddressMethod(_ printer: inout CodePrinter,
482+
decl: ImportedFunc,
483+
accessorKind: VariableAccessorKind? = nil) {
484+
485+
let addrName = accessorKind?.renderAddrFieldName ?? "ADDR"
486+
let methodNameSegment = accessorKind?.renderMethodNameSegment ?? ""
487+
let snippet = decl.renderCommentSnippet ?? "* "
488+
468489
printer.print(
469490
"""
470491
/**
471-
* Function descriptor for:
472-
* {@snippet lang=swift :
473-
* \(/*TODO: make a printSnippet func*/decl.syntax ?? "")
474-
* }
492+
* Address for:
493+
\(snippet)
475494
*/
476-
public static FunctionDescriptor \(decl.baseIdentifier)$descriptor() {
477-
return \(decl.baseIdentifier).DESC;
495+
public static MemorySegment \(decl.baseIdentifier)\(methodNameSegment)$address() {
496+
return \(decl.baseIdentifier).\(addrName);
478497
}
479498
"""
480499
)
500+
}
501+
502+
private func printFunctionMethodHandleMethod(_ printer: inout CodePrinter,
503+
decl: ImportedFunc,
504+
accessorKind: VariableAccessorKind? = nil) {
505+
let handleName = accessorKind?.renderHandleFieldName ?? "HANDLE"
506+
let methodNameSegment = accessorKind?.renderMethodNameSegment ?? ""
507+
let snippet = decl.renderCommentSnippet ?? "* "
481508

482509
printer.print(
483510
"""
484511
/**
485512
* Downcall method handle for:
486-
* {@snippet lang=swift :
487-
* \(/*TODO: make a printSnippet func*/decl.syntax ?? "")
488-
* }
513+
\(snippet)
489514
*/
490-
public static MethodHandle \(decl.baseIdentifier)$handle() {
491-
return \(decl.baseIdentifier).HANDLE;
515+
public static MethodHandle \(decl.baseIdentifier)\(methodNameSegment)$handle() {
516+
return \(decl.baseIdentifier).\(handleName);
492517
}
493518
"""
494519
)
520+
}
521+
522+
private func printFunctionDescriptorMethod(_ printer: inout CodePrinter,
523+
decl: ImportedFunc,
524+
accessorKind: VariableAccessorKind? = nil) {
525+
let descName = accessorKind?.renderDescFieldName ?? "DESC"
526+
let methodNameSegment = accessorKind?.renderMethodNameSegment ?? ""
527+
let snippet = decl.renderCommentSnippet ?? "* "
495528

496529
printer.print(
497530
"""
498531
/**
499-
* Address for:
500-
* {@snippet lang=swift :
501-
* \(/*TODO: make a printSnippet func*/decl.syntax ?? "")
502-
* }
532+
* Function descriptor for:
533+
\(snippet)
503534
*/
504-
public static MemorySegment \(decl.baseIdentifier)$address() {
505-
return \(decl.baseIdentifier).ADDR;
535+
public static FunctionDescriptor \(decl.baseIdentifier)\(methodNameSegment)$descriptor() {
536+
return \(decl.baseIdentifier).\(descName);
506537
}
507538
"""
508539
)
540+
}
541+
542+
public func printVariableDowncallMethods(_ printer: inout CodePrinter, _ decl: ImportedVariable) {
543+
printer.printSeparator(decl.identifier)
544+
545+
printer.printTypeDecl("private static class \(decl.baseIdentifier)") { printer in
546+
for accessorKind in decl.supportedAccessorKinds {
547+
printPropertyAccessorDescriptorValue(&printer, decl, accessorKind)
548+
// printFunctionDescriptorValue(&printer, decl);
549+
// printFindMemorySegmentAddrByMangledName(&printer, decl)
550+
// printMethodDowncallHandleForAddrDesc(&printer)
551+
}
552+
}
553+
554+
for accessorKind in decl.supportedAccessorKinds {
555+
guard let accessor = decl.accessorFunc(kind: accessorKind) else {
556+
log.warning("Skip print for \(accessorKind) of \(decl.identifier)!")
557+
continue
558+
}
559+
printFunctionDescriptorMethod(&printer, decl: accessor, accessorKind: accessorKind)
560+
printFunctionMethodHandleMethod(&printer, decl: accessor, accessorKind: accessorKind)
561+
printFunctionAddressMethod(&printer, decl: accessor, accessorKind: accessorKind)
562+
}
509563

510564
// Render the basic "make the downcall" function
511565
if decl.hasParent {
512-
printFuncDowncallMethod(&printer, decl: decl, selfVariant: .memorySegment)
513-
printFuncDowncallMethod(&printer, decl: decl, selfVariant: .wrapper)
566+
// printFuncDowncallMethod(&printer, decl: decl, selfVariant: .memorySegment)
567+
// printFuncDowncallMethod(&printer, decl: decl, selfVariant: .wrapper)
514568
} else {
515-
printFuncDowncallMethod(&printer, decl: decl, selfVariant: nil)
569+
// printFuncDowncallMethod(&printer, decl: decl, selfVariant: nil)
516570
}
517571
}
518572

Tests/JExtractSwiftTests/Asserts/TextAssertions.swift

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import Testing
1717
import struct Foundation.CharacterSet
1818

1919
func assertOutput(
20+
dump: Bool = false,
2021
_ got: String,
2122
expected: String,
2223
fileID: String = #fileID,
@@ -38,7 +39,7 @@ func assertOutput(
3839

3940
let ge = g.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
4041
let ee = e.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
41-
if ge != ee {
42+
if ge.commonPrefix(with: ee) != ee {
4243
// print("")
4344
// print("[\(file):\(line)] " + "Difference found on line: \(no + 1)!".red)
4445
// print("Expected @ \(file):\(Int(line) + no + 3 /*formatting*/ + 1):")
@@ -55,15 +56,19 @@ func assertOutput(
5556

5657
}
5758

58-
if diffLineNumbers.count > 0 {
59+
let hasDiff = diffLineNumbers.count > 0
60+
if hasDiff || dump{
5961
print("")
60-
print("error: Number of not matching lines: \(diffLineNumbers.count)!".red)
62+
if hasDiff {
63+
print("error: Number of not matching lines: \(diffLineNumbers.count)!".red)
6164

62-
print("==== ---------------------------------------------------------------")
63-
print("Expected output:")
64-
for (n, e) in expectedLines.enumerated() {
65-
print("\(e)".yellow(if: diffLineNumbers.contains(n)))
65+
print("==== ---------------------------------------------------------------")
66+
print("Expected output:")
67+
for (n, e) in expectedLines.enumerated() {
68+
print("\(e)".yellow(if: diffLineNumbers.contains(n)))
69+
}
6670
}
71+
6772
print("==== ---------------------------------------------------------------")
6873
print("Got output:")
6974
for (n, g) in gotLines.enumerated() {

Tests/JExtractSwiftTests/FunctionDescriptorImportTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ extension FunctionDescriptorTests {
184184
}
185185
}.first
186186
guard let varDecl else {
187-
fatalError("Cannot find descriptor of: \(methodIdentifier)") as! ImportedVariable
187+
fatalError("Cannot find descriptor of: \(methodIdentifier)")
188188
}
189189

190190
let getOutput = CodePrinter.toString { printer in

0 commit comments

Comments
 (0)