Skip to content

Commit c24ba38

Browse files
committed
Depend on SwiftExtract from swift-binding-generator-core
The `SwiftExtract` library (and `SwiftExtractConfigurationShared`, the `_StaticBuildConfigPlugin` build tool, and `SwiftExtractTests`) moved to https://github.com/swiftlang/swift-binding-generator-core, where it is separately versioned so other binding generators can use it without the Java tooling. - Depend on the new package the same way we depend on swift-java-jni-core: `branch: "main"`, overridable locally with `SWIFT_BINDING_GENERATOR_CORE_PATH`, pinned to a tag by `scripts/release.sh` at release time. - The release script fetches the latest generator tag the same way it does for jni-core, and now fails early with a clear message when the generator repo has no tag yet, so a release always pins a specific compatible version (the jq query uses `// empty` since an empty tag list yields null). - Remove the moved products, targets and sources. - `Plugins/PluginsShared/SwiftExtractConfigurationShared` becomes a vendored byte-identical copy (plugins cannot take sources from a dependency); the compatibility job in swift-binding-generator-core diffs it against its sources. - Copy the stdlib/SwiftSyntax convenience helpers jextract uses into `JExtractSwiftLib/Convenience` as `package` (they stay non-public API).
1 parent 301e3da commit c24ba38

61 files changed

Lines changed: 174 additions & 10442 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎CONTRIBUTING.md‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,24 @@ In the case of formatting issues, `git add` the formatting changes and attempt t
106106

107107
Some documentation is generated from source and checked in, so CI can catch it drifting out of date. If you changed `Configuration.swift` or a CLI command's flags/help text, run `scripts/generate-docs.sh` and commit the generated changes.
108108

109+
### Developing against local dependency checkouts
110+
111+
swift-java depends on [swift-java-jni-core](https://github.com/swiftlang/swift-java-jni-core) and [swift-binding-generator-core](https://github.com/swiftlang/swift-binding-generator-core) (home of the `SwiftExtract` library) from their `main` branches. To develop against local checkouts instead, clone the repositories next to your swift-java checkout and point the corresponding environment variables at them:
112+
113+
```bash
114+
export PROJECT_ROOT=~/code # the directory containing your checkouts
115+
cd $PROJECT_ROOT
116+
ls
117+
> swift-java
118+
> swift-java-jni-core
119+
> swift-binding-generator-core
120+
> # ...and all the others here
121+
122+
export SWIFT_JAVA_JNI_CORE_PATH=$PROJECT_ROOT/swift-java-jni-core
123+
export SWIFT_BINDING_GENERATOR_CORE_PATH=$PROJECT_ROOT/swift-binding-generator-core
124+
swift build
125+
```
126+
109127
## How to contribute your work
110128

111129
Please open a pull request at https://github.com/swiftlang/swift-java. Make sure the CI passes, and then wait for code review.

‎Package.swift‎

Lines changed: 12 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ if let localPath = Context.environment["SWIFT_JAVA_JNI_CORE_PATH"] {
1111
swiftJavaJNICoreDep = .package(url: "https://github.com/swiftlang/swift-java-jni-core", branch: "main")
1212
}
1313

14+
let swiftBindingGeneratorCoreDep: Package.Dependency
15+
if let localPath = Context.environment["SWIFT_BINDING_GENERATOR_CORE_PATH"] {
16+
swiftBindingGeneratorCoreDep = .package(path: localPath)
17+
} else {
18+
swiftBindingGeneratorCoreDep = .package(url: "https://github.com/swiftlang/swift-binding-generator-core", branch: "main")
19+
}
20+
1421
// Set SWIFTJAVA_DOCC_PLUGIN_INSTALL=1 to install the docc-plugin automatically,
1522
// or DOCC_PLUGIN_PATH=<path> to point at a local checkout.
1623
// This is a workaround because swift-subprocess includes the plugin explicitly,
@@ -59,11 +66,6 @@ let package = Package(
5966
targets: ["SwiftJavaConfigurationShared"]
6067
),
6168

62-
.library(
63-
name: "SwiftExtractConfigurationShared",
64-
targets: ["SwiftExtractConfigurationShared"]
65-
),
66-
6769
.library(
6870
name: "JavaUtil",
6971
targets: ["JavaUtil"]
@@ -129,11 +131,6 @@ let package = Package(
129131
targets: ["SwiftRuntimeFunctions"]
130132
),
131133

132-
.library(
133-
name: "SwiftExtract",
134-
targets: ["SwiftExtract"]
135-
),
136-
137134
.library(
138135
name: "CodePrinting",
139136
targets: ["CodePrinting"]
@@ -166,6 +163,7 @@ let package = Package(
166163
],
167164
dependencies: [
168165
swiftJavaJNICoreDep,
166+
swiftBindingGeneratorCoreDep,
169167
.package(url: "https://github.com/swiftlang/swift-syntax", from: "603.0.0"),
170168
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.8.0"),
171169
.package(url: "https://github.com/apple/swift-system", from: "1.4.0"),
@@ -304,14 +302,10 @@ let package = Package(
304302
.target(
305303
name: "SwiftJavaConfigurationShared",
306304
dependencies: [
307-
"SwiftExtractConfigurationShared"
305+
.product(name: "SwiftExtractConfigurationShared", package: "swift-binding-generator-core")
308306
]
309307
),
310308

311-
.target(
312-
name: "SwiftExtractConfigurationShared"
313-
),
314-
315309
.target(
316310
name: "SwiftJavaShared"
317311
),
@@ -352,6 +346,7 @@ let package = Package(
352346
.product(name: "SwiftSyntaxBuilder", package: "swift-syntax"),
353347
.product(name: "ArgumentParser", package: "swift-argument-parser"),
354348
.product(name: "SystemPackage", package: "swift-system"),
349+
.product(name: "SwiftExtract", package: "swift-binding-generator-core"),
355350
"SwiftJava",
356351
"JavaUtilJar",
357352
"JavaNet",
@@ -375,32 +370,6 @@ let package = Package(
375370
]
376371
),
377372

378-
.target(
379-
name: "SwiftExtract",
380-
dependencies: [
381-
.product(name: "SwiftBasicFormat", package: "swift-syntax"),
382-
.product(name: "SwiftIfConfig", package: "swift-syntax"),
383-
.product(name: "SwiftLexicalLookup", package: "swift-syntax"),
384-
.product(name: "SwiftParser", package: "swift-syntax"),
385-
.product(name: "SwiftSyntax", package: "swift-syntax"),
386-
.product(name: "SwiftSyntaxBuilder", package: "swift-syntax"),
387-
"SwiftExtractConfigurationShared",
388-
],
389-
path: "Sources/SwiftExtract",
390-
resources: [
391-
// Holds the `dummy.json` placeholder so SwiftPM emits a `Bundle.module`
392-
// for this target. The real `static-build-config.json` is generated at
393-
// build time by the `_StaticBuildConfigPlugin` build tool below.
394-
.process("Resources")
395-
],
396-
swiftSettings: [
397-
.swiftLanguageMode(.v5)
398-
],
399-
plugins: [
400-
.plugin(name: "_StaticBuildConfigPlugin")
401-
]
402-
),
403-
404373
.target(
405374
name: "JExtractSwiftLib",
406375
dependencies: [
@@ -412,7 +381,7 @@ let package = Package(
412381
.product(name: "ArgumentParser", package: "swift-argument-parser"),
413382
.product(name: "OrderedCollections", package: "swift-collections"),
414383
.product(name: "SwiftJavaJNICore", package: "swift-java-jni-core"),
415-
"SwiftExtract",
384+
.product(name: "SwiftExtract", package: "swift-binding-generator-core"),
416385
"SwiftJavaShared",
417386
"SwiftJavaConfigurationShared",
418387
"CodePrinting",
@@ -423,14 +392,6 @@ let package = Package(
423392
]
424393
),
425394

426-
.executableTarget(
427-
name: "StaticBuildConfigPluginExecutable",
428-
dependencies: [
429-
.product(name: "Subprocess", package: "swift-subprocess"),
430-
.product(name: "SwiftIfConfig", package: "swift-syntax"),
431-
]
432-
),
433-
434395
// Dev-time tool: regenerates the "Supported configuration options" table in
435396
// `Sources/SwiftJavaDocumentation/Documentation.docc/SwiftJavaConfigFile.md`
436397
// straight from the doc comments on `Configuration.swift` and the enums it
@@ -448,14 +409,6 @@ let package = Package(
448409
path: "Sources/GenerateConfigDocs"
449410
),
450411

451-
.plugin(
452-
name: "_StaticBuildConfigPlugin",
453-
capability: .buildTool(),
454-
dependencies: [
455-
"StaticBuildConfigPluginExecutable"
456-
]
457-
),
458-
459412
.plugin(
460413
name: "JExtractSwiftPlugin",
461414
capability: .buildTool(),
@@ -512,23 +465,14 @@ let package = Package(
512465
name: "JExtractSwiftTests",
513466
dependencies: [
514467
"JExtractSwiftLib",
515-
"SwiftExtract",
468+
.product(name: "SwiftExtract", package: "swift-binding-generator-core"),
516469
"CodePrinting",
517470
],
518471
swiftSettings: [
519472
.swiftLanguageMode(.v5)
520473
]
521474
),
522475

523-
.testTarget(
524-
name: "SwiftExtractTests",
525-
dependencies: [
526-
"SwiftExtract",
527-
.product(name: "SwiftSyntax", package: "swift-syntax"),
528-
.product(name: "SwiftParser", package: "swift-syntax"),
529-
]
530-
),
531-
532476
.testTarget(
533477
name: "CodePrintingTests",
534478
dependencies: [

‎Plugins/PluginsShared/SwiftExtractConfigurationShared‎

Lines changed: 0 additions & 1 deletion
This file was deleted.

Sources/SwiftExtractConfigurationShared/AccessLevelMode.swift renamed to Plugins/PluginsShared/SwiftExtractConfigurationShared/AccessLevelMode.swift

File renamed without changes.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
DO NOT EDIT THESE FILES IN THIS REPOSITORY.
2+
3+
The files in this directory are vendored, byte-identical copies of:
4+
5+
https://github.com/swiftlang/swift-binding-generator-core
6+
Sources/SwiftExtractConfigurationShared/
7+
8+
They exist because SwiftPM package plugins cannot take sources from a package
9+
dependency, so the plugins in this repository compile these files directly.
10+
11+
Make any changes in swift-binding-generator-core instead, and then copy the
12+
updated files here. The swift-java compatibility CI job in
13+
swift-binding-generator-core diffs these copies against its own sources and
14+
will flag any drift.

Sources/SwiftExtractConfigurationShared/LogLevel.swift renamed to Plugins/PluginsShared/SwiftExtractConfigurationShared/LogLevel.swift

File renamed without changes.

‎Plugins/_StaticBuildConfigPlugin/_StaticBuildConfigPlugin.swift‎

Lines changed: 0 additions & 34 deletions
This file was deleted.

Sources/SwiftExtract/Convenience/Collection+Extensions.swift renamed to Sources/JExtractSwiftLib/Convenience/Collection+SwiftExtract.swift

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,6 @@
1212
//
1313
//===----------------------------------------------------------------------===//
1414

15-
extension Dictionary {
16-
/// Same values, corresponding to mapped keys.
17-
public func mapKeys<Transformed>(
18-
_ transform: (Key) throws -> Transformed
19-
) rethrows -> [Transformed: Value] {
20-
.init(
21-
uniqueKeysWithValues: try map {
22-
(try transform($0.key), $0.value)
23-
}
24-
)
25-
}
26-
27-
}
28-
2915
extension Collection {
3016
package typealias IsLastElement = Bool
3117
package var withIsLast: any Collection<(Element, IsLastElement)> {
@@ -39,13 +25,3 @@ extension Collection {
3925
}
4026
}
4127
}
42-
43-
extension Collection where Element == Int {
44-
var sum: Int {
45-
var s = 0
46-
for i in self {
47-
s += i
48-
}
49-
return s
50-
}
51-
}

Sources/SwiftExtract/Convenience/String+Extensions.swift renamed to Sources/JExtractSwiftLib/Convenience/String+SwiftExtract.swift

File renamed without changes.
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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 SwiftSyntax
16+
17+
extension DeclSyntaxProtocol {
18+
/// Signature part of the declaration. I.e. without body or member block.
19+
package var signatureString: String {
20+
switch DeclSyntax(self.detached).as(DeclSyntaxEnum.self) {
21+
case .functionDecl(let node):
22+
node.with(\.body, nil).triviaSanitizedDescription
23+
case .initializerDecl(let node):
24+
node.with(\.body, nil).triviaSanitizedDescription
25+
case .classDecl(let node):
26+
node.with(\.memberBlock, "").triviaSanitizedDescription
27+
case .structDecl(let node):
28+
node.with(\.memberBlock, "").triviaSanitizedDescription
29+
case .protocolDecl(let node):
30+
node.with(\.memberBlock, "").triviaSanitizedDescription
31+
case .accessorDecl(let node):
32+
node.with(\.body, nil).triviaSanitizedDescription
33+
case .subscriptDecl(let node):
34+
node.with(\.accessorBlock, nil).triviaSanitizedDescription
35+
case .variableDecl(let node):
36+
node
37+
.with(
38+
\.bindings,
39+
PatternBindingListSyntax(
40+
node.bindings.map {
41+
$0.detached
42+
.with(\.accessorBlock, nil)
43+
.with(\.initializer, nil)
44+
}
45+
),
46+
)
47+
.triviaSanitizedDescription
48+
case .enumCaseDecl(let node):
49+
node.triviaSanitizedDescription
50+
default:
51+
fatalError("unimplemented \(self.kind)")
52+
}
53+
}
54+
55+
56+
/// Syntax text but without unnecessary trivia.
57+
///
58+
/// Connective trivia are condensed into a single whitespace, but no space
59+
/// after opening or before closing parentheses
60+
var triviaSanitizedDescription: String {
61+
let visitor = TriviaSanitizingDescriptionVisitor(viewMode: .sourceAccurate)
62+
visitor.walk(self.trimmed)
63+
return visitor.result
64+
}
65+
}
66+
67+
class TriviaSanitizingDescriptionVisitor: SyntaxVisitor {
68+
var result: String = ""
69+
70+
var prevTokenKind: TokenKind = .endOfFile
71+
var prevHadTrailingSpace: Bool = false
72+
73+
override func visit(_ node: TokenSyntax) -> SyntaxVisitorContinueKind {
74+
let tokenKind = node.tokenKind
75+
switch (prevTokenKind, tokenKind) {
76+
case // No whitespace after open parentheses.
77+
(.leftAngle, _), (.leftParen, _), (.leftSquare, _), (.endOfFile, _),
78+
// No whitespace before close parentheses.
79+
(_, .rightAngle), (_, .rightParen), (_, .rightSquare):
80+
break
81+
default:
82+
if prevHadTrailingSpace || !node.leadingTrivia.isEmpty {
83+
result += " "
84+
}
85+
}
86+
result += node.text
87+
prevTokenKind = tokenKind
88+
prevHadTrailingSpace = !node.trailingTrivia.isEmpty
89+
90+
return .skipChildren
91+
}
92+
}

0 commit comments

Comments
 (0)