Off-by-one bug in generic inherited type.
Hey, I'm maintaining Cuckoo and recently a bug surfaced (though it was present all this time, just under our radar) where SourceKitten includes the last > of the generic inherited type.
I've been using SourceKitten 0.23.2 until now; though upgrading to 0.29.0 didn't help, unfortunately.
Xcode 11.5, though it's the same result on 10.2.1.
Some examples:
struct gg<G: T<Int>> {} // "key.inheritedTypes" is "T<Int>>"
func bg<T: G<Void>>() // "key.inheritedTypes" is "G<Void>>"
This applies for any class, struct, or function.
I've tried tracking this bug down inside the project (master) with the intention of filing a PR, though the source code gets increasingly complex for my iOS brain. I found that at Request.swift:88, the string is already incorrect and I'm unsure whether it's a SourceKitten bug or SourceKit provides incorrect numbers.
I've created a general structure test that should go green when this is resolved:
func testGenericInheritedType() throws {
let structure = try Structure(file: File(contents: "class Foo<T, U: V<T>> {}"))
let expected: NSDictionary = [
"key.substructure": [
[
"key.kind": "source.lang.swift.decl.class",
"key.accessibility": "source.lang.swift.accessibility.internal",
"key.offset": 0,
"key.nameoffset": 6,
"key.namelength": 3,
"key.bodyoffset": 23,
"key.bodylength": 0,
"key.length": 24,
"key.name": "Foo",
"key.substructure": [
[
"key.kind": "source.lang.swift.decl.generic_type_param",
"key.length": 1,
"key.name": "T",
"key.namelength": 1,
"key.nameoffset": 10,
"key.offset": 10,
],
[
"key.elements": [
[
"key.kind": "source.lang.swift.structure.elem.typeref",
"key.length": 4,
"key.offset": 16,
]
],
"key.inheritedtypes": [
[
"key.name": "V<T>",
]
],
"key.kind": "source.lang.swift.decl.generic_type_param",
"key.length": 7,
"key.name": "U",
"key.namelength": 1,
"key.nameoffset": 13,
"key.offset": 13,
]
]
]
],
"key.offset": 0,
"key.diagnostic_stage": "source.diagnostic.stage.swift.parse",
"key.length": 24,
]
XCTAssertEqual(toNSDictionary(structure.dictionary), expected, "should generate expected structure")
}
Though I'm not sure about the specific offsets, so I wouldn't trust me on this.
In Cuckoo I added some simple protection against this, but it's pretty fragile (it just checks for >> in the last parameter), so I wanted to get your feedback on the complexity of this issue and whether we should rather compensate on our side rather than waiting for a fix.
Oh and I tried looking for this issue, so forgive me if I overlooked a duplicate, feel free to close this if it's known and/or unfixable. If I forgot to disclose some important info, let me know! 🙂
One last thing, this bug can be sidestepped by adding a space in front of the last >. So <T: G<Void> > actually returns the correct inherited type of just G<Void>.
EDIT: One actually important thing might be, this issue only arises when the inheritance type is generic as well, for example <T: G> correctly returns just G as the inherited type.
This is a Swift bug, it's wrong coming out of SourceKit. Latest swift/master:
; cat Test.swift
struct gg<G: T<Int>> {}
; sourcekitd-test -req structure Test.swift
{
key.request: source.request.configuration.global,
key.optimize_for_ide: 1
}
{
key.request: source.request.editor.open,
key.name: "/Users/johnf/project/SourceKit/Test.swift",
key.sourcefile: "/Users/johnf/project/SourceKit/Test.swift",
key.enablesyntaxmap: 0,
key.syntaxtreetransfermode: source.syntaxtree.transfer.off,
key.enablesubstructure: 1,
key.syntactic_only: 1
}
{
key.offset: 0,
key.length: 24,
key.diagnostic_stage: source.diagnostic.stage.swift.parse,
key.substructure: [
{
key.kind: source.lang.swift.decl.struct,
key.accessibility: source.lang.swift.accessibility.internal,
key.name: "gg",
key.offset: 0,
key.length: 23,
key.nameoffset: 7,
key.namelength: 2,
key.bodyoffset: 22,
key.bodylength: 0,
key.substructure: [
{
key.kind: source.lang.swift.decl.generic_type_param,
key.name: "G",
key.offset: 10,
key.length: 10,
key.nameoffset: 10,
key.namelength: 1,
key.inheritedtypes: [
{
key.name: "T<Int>>"
}
],
...
You could open it on https://bugs.swift.org ?
Thanks for the tip, I haven't had the chance to file a Swift bug issue before, so the link was very helpful.
The issue in question is here: https://bugs.swift.org/browse/SR-13115