Skip to content

Formally deprecate additionalSymbolGraphFiles property #777

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 1, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ extension ConvertAction {
// into a dictionary. This will throw with a descriptive error upon failure.
let parsedPlatforms = try PlatformArgumentParser.parse(convert.platforms)

let additionalSymbolGraphFiles = convert.additionalSymbolGraphFiles + symbolGraphFiles(
let additionalSymbolGraphFiles = (convert as _DeprecatedSymbolGraphFilesAccess).additionalSymbolGraphFiles + symbolGraphFiles(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a common Swift idiom?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really. Normally there's no need to cast a value to one of the protocols that it's known to conform to but here I'm leveraging the downcast to shadow the deprecated API with a non-deprecated API to avoid a deprecation warning. This comment explains how it works in more detail.

in: convert.additionalSymbolGraphDirectory
)

Expand Down Expand Up @@ -100,3 +100,8 @@ private func symbolGraphFiles(in directory: URL?) -> [URL] {
return subpaths.map { directory.appendingPathComponent($0) }
.filter { DocumentationBundleFileTypes.isSymbolGraphFile($0) }
}

private protocol _DeprecatedSymbolGraphFilesAccess {
var additionalSymbolGraphFiles: [URL] { get }
}
extension Docc.Convert: _DeprecatedSymbolGraphFilesAccess {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And, how does this actually work? By extending Docc.Convert so it conforms to a private protocol, are we preventing any other code from using the attributes (additionalSymbolGraphFiles) of this private protocol outside of this file?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC the aim here is to force DocC.Convert to expose the additionalSymbolGraphFiles property, for this code here to work (I assume that David audited the code for further uses of additionalSymbolGraphFiles), Once 5.11 is released then we will go back and remove the property entirely which will cause this code to fail to compile and therefore force us to go remove this use of it. This only works if we don't introduce new uses of the property, but I don't see why we would.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docc.Convert already has an additionalSymbolGraphFiles property but it's marked as deprecated here. Since it's deprecated, any code that accesses it will result in a deprecation warning, even within the same module.

That leaves us with 3 choices:

  • Do nothing and live with the added depreciation warnings for a couple of releases.
  • Stop accessing the deprecated API property, breaking the behavior for any client who passes this flag
  • Write a bit of extra code to be able to avoid the deprecation warning.

I opted for the third choice. The way this private protocol avoids the deprecation warning works in 3 steps:

  •  private protocol _DeprecatedSymbolGraphFilesAccess {
         var additionalSymbolGraphFiles: [URL] { get }
     }
    defines a protocol with a property with the same name and type as the deprecated API. This property of this protocol isn't deprecated. This protocol is only available within this source file.
  •  extension Docc.Convert: _DeprecatedSymbolGraphFilesAccess {}
    conforms the Convert command to this private protocol. Since Convert already has a property with this name and type it doesn't need to implement anything new.
  •  (convert as _DeprecatedSymbolGraphFilesAccess).additionalSymbolGraphFiles
    casts the convert value to the deprecated property; thus shadowing the deprecated Convert.additionalSymbolGraphFiles with the not deprecated _DeprecatedSymbolGraphFilesAccess.additionalSymbolGraphFiles

It looks rather strange but it allows us to internally call the deprecated API without warnings about it being deprecated. I know that there aren't other places who access Convert.additionalSymbolGraphFiles because those would result in deprecation warnings. If any new code called Convert.additionalSymbolGraphFiles it would work but result in a deprecation warning.

Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ extension Docc {
help: .hidden,
transform: URL.init(fileURLWithPath:)
)
@available(*, deprecated, renamed: "additionalSymbolGraphDirectory", message: "Use 'additionalSymbolGraphDirectory' instead. This deprecated API will be removed after 5.12 is released")
var additionalSymbolGraphFiles: [URL] = [] // Remove when other tools no longer use it. (rdar://72449411)

@Option(
Expand Down Expand Up @@ -107,7 +108,7 @@ extension Docc {
set { inputsAndOutputs.additionalSymbolGraphDirectory = newValue }
}

/// A user-provided list o path to additional symbol graph files that the convert action will process.
@available(*, deprecated, renamed: "additionalSymbolGraphDirectory", message: "Use 'additionalSymbolGraphDirectory' instead. This deprecated API will be removed after 5.12 is released")
public var additionalSymbolGraphFiles: [URL] { // Remove when other tools no longer use it. (rdar://72449411)
get { inputsAndOutputs.additionalSymbolGraphFiles }
set { inputsAndOutputs.additionalSymbolGraphFiles = newValue }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,9 @@ class ConvertSubcommandTests: XCTestCase {
}
}

// This test calls ``ConvertOptions.additionalSymbolGraphFiles`` which is deprecated.
// Deprecating the test silences the deprecation warning when running the tests. It doesn't skip the test.
@available(*, deprecated)
func testAdditionalSymbolGraphFiles() throws {
SetEnvironmentVariable(TemplateOption.environmentVariableKey, testTemplateURL.path)

Expand Down