Skip to content

Commit 6edf022

Browse files
authored
Merge pull request #2230 from kavon/inverse-parsing-swiftsyntax
improve parsing for suppression/inverse constraints
2 parents c63b02a + a014540 commit 6edf022

File tree

2 files changed

+141
-22
lines changed

2 files changed

+141
-22
lines changed

Sources/SwiftParser/Types.swift

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,6 @@ extension Parser {
2727
)
2828
}
2929

30-
// Parse without operator preceding a type '~ T'.
31-
if let withoutTilde = self.consumeIfContextualPunctuator("~", remapping: .prefixOperator) {
32-
let type = self.parseTypeScalar(misplacedSpecifiers: misplacedSpecifiers)
33-
return RawTypeSyntax(
34-
RawSuppressedTypeSyntax(
35-
withoutTilde: withoutTilde,
36-
type: type,
37-
arena: self.arena
38-
)
39-
)
40-
}
41-
4230
return self.parseTypeScalar(misplacedSpecifiers: misplacedSpecifiers)
4331
}
4432

@@ -227,6 +215,23 @@ extension Parser {
227215
}
228216
}
229217

218+
// Eat any '~' preceding the type.
219+
let maybeTilde = self.consumeIfContextualPunctuator("~", remapping: .prefixOperator)
220+
221+
// Wrap as a suppressed type if needed.
222+
func wrapInTilde(_ node: RawTypeSyntax) -> RawTypeSyntax {
223+
if let tilde = maybeTilde {
224+
return RawTypeSyntax(
225+
RawSuppressedTypeSyntax(
226+
withoutTilde: tilde,
227+
type: node,
228+
arena: self.arena
229+
)
230+
)
231+
}
232+
return node
233+
}
234+
230235
var base: RawTypeSyntax
231236
switch self.at(anyIn: TypeBaseStart.self)?.spec {
232237
case .Self, .Any, .identifier:
@@ -238,7 +243,7 @@ extension Parser {
238243
case .wildcard:
239244
base = RawTypeSyntax(self.parsePlaceholderType())
240245
case nil:
241-
return RawTypeSyntax(RawMissingTypeSyntax(arena: self.arena))
246+
return wrapInTilde(RawTypeSyntax(RawMissingTypeSyntax(arena: self.arena)))
242247
}
243248

244249
var loopProgress = LoopProgressCondition()
@@ -310,6 +315,8 @@ extension Parser {
310315
break
311316
}
312317

318+
base = wrapInTilde(base)
319+
313320
return base
314321
}
315322

Tests/SwiftParserTest/DeclarationTests.swift

Lines changed: 121 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2317,6 +2317,114 @@ final class DeclarationTests: ParserTestCase {
23172317
)
23182318
)
23192319

2320+
assertParse(
2321+
"""
2322+
let _: any ~Copyable = 0
2323+
""",
2324+
substructure: SomeOrAnyTypeSyntax(
2325+
someOrAnySpecifier: .keyword(.any),
2326+
constraint: SuppressedTypeSyntax(
2327+
withoutTilde: .prefixOperator("~"),
2328+
type: TypeSyntax(stringLiteral: "Copyable")
2329+
)
2330+
)
2331+
)
2332+
2333+
assertParse(
2334+
"""
2335+
typealias Z = ~Copyable.Type
2336+
""",
2337+
substructure: SuppressedTypeSyntax(
2338+
withoutTilde: .prefixOperator("~"),
2339+
type: MetatypeTypeSyntax(
2340+
baseType: TypeSyntax(stringLiteral: "Copyable"),
2341+
metatypeSpecifier: .keyword(.Type)
2342+
)
2343+
)
2344+
)
2345+
2346+
assertParse(
2347+
"""
2348+
typealias Z = ~A.B.C
2349+
""",
2350+
substructure: SuppressedTypeSyntax(
2351+
withoutTilde: .prefixOperator("~"),
2352+
type: MemberTypeSyntax(
2353+
baseType: MemberTypeSyntax(
2354+
baseType: TypeSyntax(stringLiteral: "A"),
2355+
name: .identifier("B")
2356+
),
2357+
name: .identifier("C")
2358+
)
2359+
)
2360+
)
2361+
2362+
assertParse(
2363+
"""
2364+
typealias Z = ~A?
2365+
""",
2366+
substructure: SuppressedTypeSyntax(
2367+
withoutTilde: .prefixOperator("~"),
2368+
type: OptionalTypeSyntax(
2369+
wrappedType: IdentifierTypeSyntax(name: .identifier("A"))
2370+
)
2371+
)
2372+
)
2373+
2374+
assertParse(
2375+
"""
2376+
typealias Z = ~A<T>
2377+
""",
2378+
substructure: SuppressedTypeSyntax(
2379+
withoutTilde: .prefixOperator("~"),
2380+
type: IdentifierTypeSyntax(
2381+
name: .identifier("A"),
2382+
genericArgumentClause: GenericArgumentClauseSyntax(
2383+
arguments: GenericArgumentListSyntax([
2384+
GenericArgumentSyntax(
2385+
argument:
2386+
IdentifierTypeSyntax(name: .identifier("T"))
2387+
)
2388+
])
2389+
)
2390+
)
2391+
)
2392+
)
2393+
2394+
assertParse(
2395+
"""
2396+
struct Hello<T: ~Copyable> {}
2397+
""",
2398+
substructure: GenericParameterListSyntax([
2399+
GenericParameterSyntax(
2400+
attributes: AttributeListSyntax([]),
2401+
name: .identifier("T"),
2402+
colon: .colonToken(),
2403+
inheritedType: SuppressedTypeSyntax(
2404+
withoutTilde: .prefixOperator("~"),
2405+
type: TypeSyntax(stringLiteral: "Copyable")
2406+
)
2407+
)
2408+
])
2409+
)
2410+
2411+
assertParse(
2412+
"""
2413+
func henlo<T: ~Copyable>(_ t: T) {}
2414+
""",
2415+
substructure: GenericParameterListSyntax([
2416+
GenericParameterSyntax(
2417+
attributes: AttributeListSyntax([]),
2418+
name: .identifier("T"),
2419+
colon: .colonToken(),
2420+
inheritedType: SuppressedTypeSyntax(
2421+
withoutTilde: .prefixOperator("~"),
2422+
type: TypeSyntax(stringLiteral: "Copyable")
2423+
)
2424+
)
2425+
])
2426+
)
2427+
23202428
assertParse(
23212429
"""
23222430
enum Whatever: Int, ~ Hashable, Equatable {}
@@ -2342,7 +2450,7 @@ final class DeclarationTests: ParserTestCase {
23422450

23432451
assertParse(
23442452
"""
2345-
typealias T = ~1️⃣Int 2️⃣-> Bool
2453+
typealias T = 1️⃣~Int 2️⃣-> Bool
23462454
""",
23472455
diagnostics: [
23482456
DiagnosticSpec(
@@ -2357,20 +2465,24 @@ final class DeclarationTests: ParserTestCase {
23572465
),
23582466
],
23592467
fixedSource: """
2360-
typealias T = ~(Int) -> Bool
2468+
typealias T = (~Int) -> Bool
23612469
"""
23622470
)
23632471

23642472
assertParse(
23652473
"""
2366-
typealias T = ~(Int) -> Bool
2474+
typealias T = (~Int) -> Bool
23672475
""",
2368-
substructure: SuppressedTypeSyntax(
2369-
withoutTilde: .prefixOperator("~"),
2370-
type: FunctionTypeSyntax(
2371-
parameters: [TupleTypeElementSyntax(type: TypeSyntax("Int"))],
2372-
returnClause: ReturnClauseSyntax(type: TypeSyntax("Bool"))
2373-
)
2476+
substructure: FunctionTypeSyntax(
2477+
parameters: [
2478+
TupleTypeElementSyntax(
2479+
type: SuppressedTypeSyntax(
2480+
withoutTilde: .prefixOperator("~"),
2481+
type: IdentifierTypeSyntax(name: .identifier("Int"))
2482+
)
2483+
)
2484+
],
2485+
returnClause: ReturnClauseSyntax(type: TypeSyntax("Bool"))
23742486
)
23752487
)
23762488
}

0 commit comments

Comments
 (0)