Skip to content

Commit bbd31c9

Browse files
authored
Updates for Swift 6 (#1394)
Updates for building docs with Swift 6 / Xcode 16
1 parent fd0b539 commit bbd31c9

9 files changed

+48
-19
lines changed

.github/workflows/Tests.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,16 @@ jobs:
3434
- uses: actions/checkout@v4
3535
with:
3636
submodules: recursive
37+
persist-credentials: false
3738
- uses: maxim-lobanov/setup-xcode@v1
3839
with:
39-
xcode-version: 15.3
40+
xcode-version: '16.0'
4041
- uses: ruby/setup-ruby@v1
4142
with:
4243
ruby-version: 3.2
4344
bundler-cache: true
4445
- name: Cache cocoapods
45-
uses: actions/cache@v3
46+
uses: actions/cache@v4
4647
env:
4748
cache-name: cocoapods
4849
with:

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
##### Enhancements
88

9-
* None.
9+
* Support Swift 6.0 / Xcode 16.0
10+
[John Fairhurst](https://github.com/johnfairh)
1011

1112
##### Bug Fixes
1213

CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ git push
4949
You'll need push access to the integration specs repo to do this. You can
5050
request access from one of the maintainers when filing your PR.
5151

52-
You must have Xcode 15.3 installed to build the integration specs.
52+
You must have Xcode 16.0 installed to build the integration specs.
5353

5454
## Making changes to SourceKitten
5555

lib/jazzy/podspec_documenter.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def self.github_file_prefix(podspec)
102102
private_class_method :github_file_prefix
103103

104104
# Latest valid value for SWIFT_VERSION.
105-
LATEST_SWIFT_VERSION = '5'
105+
LATEST_SWIFT_VERSION = '6'
106106

107107
# All valid values for SWIFT_VERSION that are longer
108108
# than a major version number. Ordered ascending.

lib/jazzy/sourcekitten.rb

+9
Original file line numberDiff line numberDiff line change
@@ -485,10 +485,19 @@ def self.make_swift_declaration(doc, declaration)
485485
# @available attrs only in compiler 'interface' style
486486
extract_availability(doc['key.doc.declaration'] || '')
487487
.concat(extract_documented_attributes(annotated_decl_attrs))
488+
.concat(fabricate_spi_attributes(doc, annotated_decl_attrs))
488489
.push(decl)
489490
.join("\n")
490491
end
491492

493+
# Swift 6 workaround: @_spi attribute & SPI group missing
494+
def self.fabricate_spi_attributes(doc, attrs)
495+
return [] unless spi_attribute?(doc)
496+
return [] if attrs =~ /@_spi/
497+
498+
['@_spi(<<unknown>>)']
499+
end
500+
492501
# Exclude non-async routines that accept async closures
493502
def self.swift_async?(fully_annotated_decl)
494503
document = REXML::Document.new(fully_annotated_decl)

lib/jazzy/symbol_graph/ext_node.rb

+11-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# frozen_string_literal: true
22

3+
require 'set'
4+
35
module Jazzy
46
module SymbolGraph
57
# For extensions we need to track constraints of the extended type
@@ -26,7 +28,7 @@ class ExtNode < BaseNode
2628
attr_accessor :real_usr
2729
attr_accessor :name
2830
attr_accessor :all_constraints # ExtConstraints
29-
attr_accessor :conformances # array, can be empty
31+
attr_accessor :conformances # set, can be empty
3032

3133
# Deduce an extension from a member of an unknown type or
3234
# of known type with additional constraints
@@ -54,7 +56,7 @@ def initialize(usr, name, constraints)
5456
self.usr = usr
5557
self.name = name
5658
self.all_constraints = constraints
57-
self.conformances = []
59+
self.conformances = Set.new
5860
super()
5961
end
6062

@@ -65,13 +67,13 @@ def constraints
6567
end
6668

6769
def add_conformance(protocol)
68-
conformances.append(protocol).sort!
70+
conformances.add(protocol)
6971
end
7072

7173
def full_declaration
7274
decl = "extension #{name}"
7375
unless conformances.empty?
74-
decl += " : #{conformances.join(', ')}"
76+
decl += " : #{conformances.sort.join(', ')}"
7577
end
7678
decl + all_constraints.ext.to_where_clause
7779
end
@@ -90,7 +92,7 @@ def to_sourcekit(module_name, ext_module_name)
9092
}
9193

9294
unless conformances.empty?
93-
hash['key.inheritedtypes'] = conformances.map do |conformance|
95+
hash['key.inheritedtypes'] = conformances.sort.map do |conformance|
9496
{ 'key.name' => conformance }
9597
end
9698
end
@@ -100,11 +102,13 @@ def to_sourcekit(module_name, ext_module_name)
100102
hash
101103
end
102104

103-
# Sort order - by type name then constraint
105+
# Sort order - by type name then constraint then conformances
106+
# Conformance check needed for stable order with Swift 5.9
107+
# extension symbols that can't merge as well as previously.
104108
include Comparable
105109

106110
def sort_key
107-
name + constraints.map(&:to_swift).join
111+
name + constraints.map(&:to_swift).join + conformances.sort.join
108112
end
109113

110114
def <=>(other)

lib/jazzy/symbol_graph/relationship.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def extension_to?
3434
# Protocol conformances added by compiler to actor decls that
3535
# users aren't interested in.
3636
def actor_protocol?
37-
%w[Actor Sendable].include?(target_fallback)
37+
%w[Actor AnyActor Sendable].include?(target_fallback)
3838
end
3939

4040
def initialize(hash)

spec/integration_spec.rb

+19-5
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,15 @@ def configure_cocoapods
146146
</script>
147147
HTML
148148

149+
realm_jazzy_yaml = <<-YAML
150+
build_tool_arguments:
151+
- "-scheme"
152+
- "RealmSwift"
153+
- "SWIFT_VERSION=4.2"
154+
- "-destination"
155+
- "platform=OS X,arch=x86_64"
156+
YAML
157+
149158
spec_subset = ENV.fetch('JAZZY_SPEC_SUBSET', nil)
150159

151160
# rubocop:disable Style/MultilineIfModifier
@@ -208,9 +217,15 @@ def configure_cocoapods
208217

209218
describe 'Creates Realm Swift docs' do
210219
realm_version = ''
211-
Dir.chdir(ROOT + 'spec/integration_specs/document_realm_swift/before') do
220+
realm_path = ROOT + 'spec/integration_specs/document_realm_swift/before'
221+
realm_jazzy_path = realm_path + '.jazzy.yaml'
222+
223+
Dir.chdir(realm_path) do
212224
realm_version = `./build.sh get-version`.chomp
213225
end
226+
# Xcode 16 workaround
227+
File.write(realm_jazzy_path, realm_jazzy_yaml)
228+
214229
behaves_like cli_spec 'document_realm_swift',
215230
'--author Realm ' \
216231
'--author_url "https://realm.io" ' \
@@ -222,10 +237,8 @@ def configure_cocoapods
222237
"--module-version #{realm_version} " \
223238
'--root-url https://realm.io/docs/swift/' \
224239
"#{realm_version}/api/ " \
225-
'--xcodebuild-arguments ' \
226-
'-scheme,RealmSwift,SWIFT_VERSION=4.2,' \
227-
"-destination,'platform=OS X' " \
228240
"--head #{realm_head.shellescape}"
241+
FileUtils.rm_rf realm_jazzy_path
229242
end
230243

231244
describe 'Creates Siesta docs' do
@@ -249,7 +262,8 @@ def configure_cocoapods
249262
behaves_like cli_spec 'misc_jazzy_symgraph_features',
250263
'--swift-build-tool symbolgraph ' \
251264
'--build-tool-arguments ' \
252-
"-emit-extension-block-symbols,-I,#{module_path}"
265+
'-emit-extension-block-symbols,-I,' \
266+
"#{module_path.chomp}/Modules"
253267
end
254268

255269
describe 'Creates docs for a multiple-module project' do

spec/integration_specs

Submodule integration_specs updated 229 files

0 commit comments

Comments
 (0)