From bbd31c9d0b54953cb8f7fe77bd78bdab82ea31ca Mon Sep 17 00:00:00 2001 From: John Fairhurst Date: Fri, 20 Sep 2024 11:06:45 +0100 Subject: [PATCH] Updates for Swift 6 (#1394) Updates for building docs with Swift 6 / Xcode 16 --- .github/workflows/Tests.yml | 5 +++-- CHANGELOG.md | 3 ++- CONTRIBUTING.md | 2 +- lib/jazzy/podspec_documenter.rb | 2 +- lib/jazzy/sourcekitten.rb | 9 +++++++++ lib/jazzy/symbol_graph/ext_node.rb | 18 +++++++++++------- lib/jazzy/symbol_graph/relationship.rb | 2 +- spec/integration_spec.rb | 24 +++++++++++++++++++----- spec/integration_specs | 2 +- 9 files changed, 48 insertions(+), 19 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index de08dd726..1896db0f9 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -34,15 +34,16 @@ jobs: - uses: actions/checkout@v4 with: submodules: recursive + persist-credentials: false - uses: maxim-lobanov/setup-xcode@v1 with: - xcode-version: 15.3 + xcode-version: '16.0' - uses: ruby/setup-ruby@v1 with: ruby-version: 3.2 bundler-cache: true - name: Cache cocoapods - uses: actions/cache@v3 + uses: actions/cache@v4 env: cache-name: cocoapods with: diff --git a/CHANGELOG.md b/CHANGELOG.md index 9574fc8af..487f65c7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,8 @@ ##### Enhancements -* None. +* Support Swift 6.0 / Xcode 16.0 + [John Fairhurst](https://github.com/johnfairh) ##### Bug Fixes diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 848654197..764d8962f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -49,7 +49,7 @@ git push You'll need push access to the integration specs repo to do this. You can request access from one of the maintainers when filing your PR. -You must have Xcode 15.3 installed to build the integration specs. +You must have Xcode 16.0 installed to build the integration specs. ## Making changes to SourceKitten diff --git a/lib/jazzy/podspec_documenter.rb b/lib/jazzy/podspec_documenter.rb index 382d40e33..62956bed8 100644 --- a/lib/jazzy/podspec_documenter.rb +++ b/lib/jazzy/podspec_documenter.rb @@ -102,7 +102,7 @@ def self.github_file_prefix(podspec) private_class_method :github_file_prefix # Latest valid value for SWIFT_VERSION. - LATEST_SWIFT_VERSION = '5' + LATEST_SWIFT_VERSION = '6' # All valid values for SWIFT_VERSION that are longer # than a major version number. Ordered ascending. diff --git a/lib/jazzy/sourcekitten.rb b/lib/jazzy/sourcekitten.rb index 7cafce5ee..608dd6102 100644 --- a/lib/jazzy/sourcekitten.rb +++ b/lib/jazzy/sourcekitten.rb @@ -485,10 +485,19 @@ def self.make_swift_declaration(doc, declaration) # @available attrs only in compiler 'interface' style extract_availability(doc['key.doc.declaration'] || '') .concat(extract_documented_attributes(annotated_decl_attrs)) + .concat(fabricate_spi_attributes(doc, annotated_decl_attrs)) .push(decl) .join("\n") end + # Swift 6 workaround: @_spi attribute & SPI group missing + def self.fabricate_spi_attributes(doc, attrs) + return [] unless spi_attribute?(doc) + return [] if attrs =~ /@_spi/ + + ['@_spi(<>)'] + end + # Exclude non-async routines that accept async closures def self.swift_async?(fully_annotated_decl) document = REXML::Document.new(fully_annotated_decl) diff --git a/lib/jazzy/symbol_graph/ext_node.rb b/lib/jazzy/symbol_graph/ext_node.rb index 1ae42c69c..ffc1349fc 100644 --- a/lib/jazzy/symbol_graph/ext_node.rb +++ b/lib/jazzy/symbol_graph/ext_node.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'set' + module Jazzy module SymbolGraph # For extensions we need to track constraints of the extended type @@ -26,7 +28,7 @@ class ExtNode < BaseNode attr_accessor :real_usr attr_accessor :name attr_accessor :all_constraints # ExtConstraints - attr_accessor :conformances # array, can be empty + attr_accessor :conformances # set, can be empty # Deduce an extension from a member of an unknown type or # of known type with additional constraints @@ -54,7 +56,7 @@ def initialize(usr, name, constraints) self.usr = usr self.name = name self.all_constraints = constraints - self.conformances = [] + self.conformances = Set.new super() end @@ -65,13 +67,13 @@ def constraints end def add_conformance(protocol) - conformances.append(protocol).sort! + conformances.add(protocol) end def full_declaration decl = "extension #{name}" unless conformances.empty? - decl += " : #{conformances.join(', ')}" + decl += " : #{conformances.sort.join(', ')}" end decl + all_constraints.ext.to_where_clause end @@ -90,7 +92,7 @@ def to_sourcekit(module_name, ext_module_name) } unless conformances.empty? - hash['key.inheritedtypes'] = conformances.map do |conformance| + hash['key.inheritedtypes'] = conformances.sort.map do |conformance| { 'key.name' => conformance } end end @@ -100,11 +102,13 @@ def to_sourcekit(module_name, ext_module_name) hash end - # Sort order - by type name then constraint + # Sort order - by type name then constraint then conformances + # Conformance check needed for stable order with Swift 5.9 + # extension symbols that can't merge as well as previously. include Comparable def sort_key - name + constraints.map(&:to_swift).join + name + constraints.map(&:to_swift).join + conformances.sort.join end def <=>(other) diff --git a/lib/jazzy/symbol_graph/relationship.rb b/lib/jazzy/symbol_graph/relationship.rb index 1fb48d917..cf86bd968 100644 --- a/lib/jazzy/symbol_graph/relationship.rb +++ b/lib/jazzy/symbol_graph/relationship.rb @@ -34,7 +34,7 @@ def extension_to? # Protocol conformances added by compiler to actor decls that # users aren't interested in. def actor_protocol? - %w[Actor Sendable].include?(target_fallback) + %w[Actor AnyActor Sendable].include?(target_fallback) end def initialize(hash) diff --git a/spec/integration_spec.rb b/spec/integration_spec.rb index c476c0ded..7801bd7bb 100644 --- a/spec/integration_spec.rb +++ b/spec/integration_spec.rb @@ -146,6 +146,15 @@ def configure_cocoapods HTML + realm_jazzy_yaml = <<-YAML +build_tool_arguments: + - "-scheme" + - "RealmSwift" + - "SWIFT_VERSION=4.2" + - "-destination" + - "platform=OS X,arch=x86_64" + YAML + spec_subset = ENV.fetch('JAZZY_SPEC_SUBSET', nil) # rubocop:disable Style/MultilineIfModifier @@ -208,9 +217,15 @@ def configure_cocoapods describe 'Creates Realm Swift docs' do realm_version = '' - Dir.chdir(ROOT + 'spec/integration_specs/document_realm_swift/before') do + realm_path = ROOT + 'spec/integration_specs/document_realm_swift/before' + realm_jazzy_path = realm_path + '.jazzy.yaml' + + Dir.chdir(realm_path) do realm_version = `./build.sh get-version`.chomp end + # Xcode 16 workaround + File.write(realm_jazzy_path, realm_jazzy_yaml) + behaves_like cli_spec 'document_realm_swift', '--author Realm ' \ '--author_url "https://realm.io" ' \ @@ -222,10 +237,8 @@ def configure_cocoapods "--module-version #{realm_version} " \ '--root-url https://realm.io/docs/swift/' \ "#{realm_version}/api/ " \ - '--xcodebuild-arguments ' \ - '-scheme,RealmSwift,SWIFT_VERSION=4.2,' \ - "-destination,'platform=OS X' " \ "--head #{realm_head.shellescape}" + FileUtils.rm_rf realm_jazzy_path end describe 'Creates Siesta docs' do @@ -249,7 +262,8 @@ def configure_cocoapods behaves_like cli_spec 'misc_jazzy_symgraph_features', '--swift-build-tool symbolgraph ' \ '--build-tool-arguments ' \ - "-emit-extension-block-symbols,-I,#{module_path}" + '-emit-extension-block-symbols,-I,' \ + "#{module_path.chomp}/Modules" end describe 'Creates docs for a multiple-module project' do diff --git a/spec/integration_specs b/spec/integration_specs index a6edbb88b..f55774092 160000 --- a/spec/integration_specs +++ b/spec/integration_specs @@ -1 +1 @@ -Subproject commit a6edbb88bb7752702d74f36b6704ab7a6358f3bf +Subproject commit f557740924cf50ef642c7450cc16044071ae6459