apple / swift-docc

Documentation compiler that produces rich API reference documentation and interactive tutorials for your Swift framework or package.
https://swift.org/documentation/docc
Apache License 2.0
1.14k stars 118 forks source link

Xcode does not provide fix for operator functions #935

Closed wigging closed 1 month ago

wigging commented 1 month ago

Description

I have a package that defines addition operator functions as shown below. The function definitions are similar but the types are different.

public func + (lhs: Float, rhs: Vector<Float>) -> Vector<Float> {
    let result = vDSP.add(lhs, rhs.values)
    return Vector(result)
}

public func + (lhs: Double, rhs: Vector<Double>) -> Vector<Double> {
    let result = vDSP.add(lhs, rhs.values)
    return Vector(result)
}

I tried to link to these functions in a DocC file as shown here. The links are created by Xcode by selecting the appropriate function in the dropdown menu.

### Arithmetic

Vector addition for single and double precision operations.

- ``+(lhs:rhs:)``
- ``+(lhs:rhs:)``

Screenshot 2024-05-30 at 7 59 16 PM

After I build the documentation, Xcode complains that the functions don't exist. Xcode does not provide any suggestions to fix the problem.

Screenshot 2024-05-30 at 8 00 51 PM

If I link to the functions by using an underscore like +(_:_:) and then build the documentation; Xcode complains that the functions are ambiguous. However, it does offer some ways to fix the issue such as

Screenshot 2024-05-30 at 8 03 26 PM

This works but it's definitely not ideal. It seems like Xcode should be able to suggest the correct function link before I have to build the documentation.

Checklist

Expected Behavior

I would expect Xcode to use the correct function link when I select it in the dropdown menu before building the documentation.

Actual behavior

The link for the operator function must be written manually, then a fix is selected in Xcode after building the documentation.

Steps To Reproduce

See main description above.

Swift-DocC Version Information

I'm using the latest DocC version for Swift 5.10.

Swift Compiler Version Information

I'm using Swift version 5.10.
d-ronnqvist commented 1 month ago

This issue happens because Xcode doesn't autocomplete the operator name correctly.

Because this issue is specific to Xcode, it is out of scope for tacking as an issue in the Swift-DocC repo.

wigging commented 1 month ago

Does this occur only for operator functions? I haven't noticed this problem with regular functions, i.e. named functions.

d-ronnqvist commented 1 month ago

I think so but it's possible that it occurs for subscripts as well.

Both operators and subscripts have different default behaviors regarding argument labels than functions.

If I define 3 functions and 3 subscripts like this I will get an error that the second subscript definition is a redeclaration of the first subscript definition:

func doSomething(     number: Int) -> Int { number }
func doSomething(_    number: Int) -> Int { number } 
func doSomething(with number: Int) -> Int { number }

subscript(     number: Int) -> Int { number }
subscript(_    number: Int) -> Int { number } // Invalid redeclaration of 'subscript(_:)'
subscript(with number: Int) -> Int { number }

This is because the doSomething(number: Int) function is considered to have a "number" argument label for its first parameter but subscript(number: Int) is considered to have an unlabeled parameter, just as if it was declared subscript(_ number: Int).

You can observe this at the call site.

myStruct.doSomething(number: 123) // calling 'doSomething(     number: Int)'
myStruct.doSomething(123)         // calling 'doSomething(_    number: Int)'
myStruct.doSomething(with: 123)   // calling 'doSomething(with number: Int)'

myStruct[123]       // calling 'subscript(     number: Int)'
myStruct[with: 123] // calling 'subscript(with number: Int)'

Operators have the same argument label behavior as subscripts, but unlike subscripts it's not possible to label the parameters (the compiler will raise an error) because they'd never be used at the call site regardless:

func + (     lhs: Something,     rhs: Something) -> Something
func + (_    lhs: Something, _   rhs: Something) -> Something // Invalid redeclaration of '+'
func + (with lhs: Something, and rhs: Something) -> Something // Operator cannot have keyword arguments
wigging commented 1 month ago

If this is out of scope for this project then please go ahead and close it.