Skip to content
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

Delete dependsOn support #2876

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
6 changes: 0 additions & 6 deletions CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,6 @@ public enum Keyword: CaseIterable {
case `default`
case `defer`
case `deinit`
case dependsOn
case deprecated
case derivative
case didSet
Expand Down Expand Up @@ -257,7 +256,6 @@ public enum Keyword: CaseIterable {
case reverse
case right
case safe
case scoped
case `self`
case sending
case `Self`
Expand Down Expand Up @@ -476,8 +474,6 @@ public enum Keyword: CaseIterable {
return KeywordSpec("defer", isLexerClassified: true)
case .deinit:
return KeywordSpec("deinit", isLexerClassified: true)
case .dependsOn:
return KeywordSpec("dependsOn", experimentalFeature: .nonescapableTypes)
case .deprecated:
return KeywordSpec("deprecated")
case .derivative:
Expand Down Expand Up @@ -654,8 +650,6 @@ public enum Keyword: CaseIterable {
return KeywordSpec("right")
case .safe:
return KeywordSpec("safe")
case .scoped:
return KeywordSpec("scoped", experimentalFeature: .nonescapableTypes)
case .self:
return KeywordSpec("self", isLexerClassified: true)
case .Self:
Expand Down
6 changes: 6 additions & 0 deletions CodeGeneration/Sources/SyntaxSupport/Node.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public class Node: NodeChoiceConvertible {
/// function that should be invoked to create this node.
public let parserFunction: TokenSyntax?

public let disableSameTypeForUniqueChoice: Bool
Copy link
Member

Choose a reason for hiding this comment

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

Please correct me if I’m wrong but I think we only support this for syntax collections, right? If so, I think it would be a cleaner design to modify Node.Data.collection to

fileprivate enum SyntaxCollectionElement {
  /// The syntax collection can only have a single kind of syntax node as its element.
  case singleOption(SyntaxNodeKind)
  /// Create a `SyntaxChildChoices` enum for the collection’s elements.
  case choices([SyntaxNodeKind])
}

case collection(SyntaxCollectionElement)

And with that CollectionNode can gain

var generateSyntaxChoicesEnum: Bool {
    switch node.data {
    case .layout:
      preconditionFailure("NodeLayoutView must wrap a Node with data `.collection`")
    case .collection(.singleOption(_)): 
      return false
    case .collection(.choices(_)): 
      return true
    }
} 

That way we don’t need to repeat the > 1 || disableSameTypeForUniqueChoice check everywhere.


public var syntaxNodeKind: SyntaxNodeKind {
self.kind
}
Expand Down Expand Up @@ -121,6 +123,7 @@ public class Node: NodeChoiceConvertible {
experimentalFeature: ExperimentalFeature? = nil,
nameForDiagnostics: String?,
documentation: String? = nil,
disableSameTypeForUniqueChoice: Bool = false,
parserFunction: TokenSyntax? = nil,
traits: [String] = [],
children: [Child] = []
Expand All @@ -133,6 +136,7 @@ public class Node: NodeChoiceConvertible {
self.experimentalFeature = experimentalFeature
self.nameForDiagnostics = nameForDiagnostics
self.documentation = SwiftSyntax.Trivia.docCommentTrivia(from: documentation)
self.disableSameTypeForUniqueChoice = disableSameTypeForUniqueChoice
self.parserFunction = parserFunction

let childrenWithUnexpected: [Child]
Expand Down Expand Up @@ -278,6 +282,7 @@ public class Node: NodeChoiceConvertible {
experimentalFeature: ExperimentalFeature? = nil,
nameForDiagnostics: String?,
documentation: String? = nil,
disableSameTypeForUniqueChoice: Bool = false,
parserFunction: TokenSyntax? = nil,
elementChoices: [SyntaxNodeKind]
) {
Expand All @@ -287,6 +292,7 @@ public class Node: NodeChoiceConvertible {
self.experimentalFeature = experimentalFeature
self.nameForDiagnostics = nameForDiagnostics
self.documentation = SwiftSyntax.Trivia.docCommentTrivia(from: documentation)
self.disableSameTypeForUniqueChoice = disableSameTypeForUniqueChoice
self.parserFunction = parserFunction

assert(!elementChoices.isEmpty)
Expand Down
4 changes: 0 additions & 4 deletions CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,6 @@ public enum SyntaxNodeKind: String, CaseIterable, IdentifierConvertible, TypeCon
case labeledSpecializeArgument
case labeledStmt
case layoutRequirement
case lifetimeSpecifierArgument
case lifetimeSpecifierArgumentList
case lifetimeTypeSpecifier
case macroDecl
case macroExpansionDecl
case macroExpansionExpr
Expand Down Expand Up @@ -290,7 +287,6 @@ public enum SyntaxNodeKind: String, CaseIterable, IdentifierConvertible, TypeCon
case typeExpr
case typeInitializerClause
case typeSpecifier
case lifetimeSpecifierArguments
case typeSpecifierList
case unavailableFromAsyncAttributeArguments
case underscorePrivateAttributeArguments
Expand Down
78 changes: 2 additions & 76 deletions CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -500,81 +500,6 @@ public let TYPE_NODES: [Node] = [
]
),

Node(
kind: .lifetimeSpecifierArgument,
base: .syntax,
experimentalFeature: .nonescapableTypes,
nameForDiagnostics: nil,
documentation: """
A single argument that can be added to a lifetime specifier like `borrow`, `mutate`, `consume` or `copy`.

### Example
`data` in `func foo(data: Array<Item>) -> borrow(data) ComplexReferenceType`
""",
traits: [
"WithTrailingComma"
],
children: [
Child(
name: "parameter",
kind: .token(choices: [.token(.identifier), .keyword(.self), .token(.integerLiteral)]),
nameForDiagnostics: "parameter reference",
documentation: """
The parameter on which the lifetime of this type depends.

This can be an identifier referring to an external parameter name, an integer literal to refer to an unnamed
parameter or `self` if the type's lifetime depends on the object the method is called on.
"""
),
Child(
name: "trailingComma",
kind: .token(choices: [.token(.comma)]),
isOptional: true
),
]
),

Node(
kind: .lifetimeSpecifierArgumentList,
base: .syntaxCollection,
experimentalFeature: .nonescapableTypes,
nameForDiagnostics: nil,
elementChoices: [.lifetimeSpecifierArgument]
),

Node(
kind: .lifetimeTypeSpecifier,
base: .syntax,
experimentalFeature: .nonescapableTypes,
nameForDiagnostics: "lifetime specifier",
documentation: "A specifier that specifies function parameter on whose lifetime a type depends",
children: [
Child(
name: "dependsOnKeyword",
kind: .token(choices: [.keyword(.dependsOn)]),
documentation: "lifetime dependence specifier on the return type"
),
Child(
name: "leftParen",
kind: .token(choices: [.token(.leftParen)])
),
Child(
name: "scopedKeyword",
kind: .token(choices: [.keyword(.scoped)]),
documentation: "lifetime of return value is scoped to the lifetime of the original value",
isOptional: true
),
Child(
name: "arguments",
kind: .collection(kind: .lifetimeSpecifierArgumentList, collectionElementName: "Arguments")
),
Child(
name: "rightParen",
kind: .token(choices: [.token(.rightParen)])
),
]
),

Node(
kind: .simpleTypeSpecifier,
base: .syntax,
Expand Down Expand Up @@ -602,6 +527,7 @@ public let TYPE_NODES: [Node] = [
kind: .typeSpecifierList,
base: .syntaxCollection,
nameForDiagnostics: nil,
elementChoices: [.simpleTypeSpecifier, .lifetimeTypeSpecifier]
disableSameTypeForUniqueChoice: true,
elementChoices: [.simpleTypeSpecifier]
),
]
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ extension Node {
return nil
}
}
} else if let node = self.collectionNode, node.elementChoices.count > 1 {
} else if let node = self.collectionNode, node.elementChoices.count == 1, !node.disableSameTypeForUniqueChoice {
return []
} else if let node = self.collectionNode, node.elementChoices.count >= 1 {
Comment on lines +92 to +94
Copy link
Member

Choose a reason for hiding this comment

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

I think this can be simplified to

Suggested change
} else if let node = self.collectionNode, node.elementChoices.count == 1, !node.disableSameTypeForUniqueChoice {
return []
} else if let node = self.collectionNode, node.elementChoices.count >= 1 {
} else if let node = self.collectionNode, (node.elementChoices.count > 1 || node.disableSameTypeForUniqueChoice) {

return [
ChildNodeChoices(
name: "Element",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ func rawSyntaxNodesFile(nodesStartingWith: [Character]) -> SourceFileSyntax {
}

if let node = node.collectionNode {
let element = node.elementChoices.only != nil ? node.elementChoices.only!.raw.syntaxType : "Element"
let element =
node.elementChoices.only != nil && !node.disableSameTypeForUniqueChoice
? node.elementChoices.only!.raw.syntaxType : "Element"
DeclSyntax(
"""
public init(elements: [\(element)], arena: __shared SyntaxArena) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
public struct \(node.kind.syntaxType): SyntaxCollection, SyntaxHashable
"""
) {
if let onlyElement = node.elementChoices.only {
DeclSyntax("public typealias Element = \(onlyElement.syntaxType)")
if node.elementChoices.only != nil && !node.disableSameTypeForUniqueChoice {
DeclSyntax("public typealias Element = \(node.elementChoices.only!.syntaxType)")
} else {
for childNodeChoices in node.node.childrenNodeChoices() {
childNodeChoices.enumDecl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,6 @@ class ValidateSyntaxNodes: XCTestCase {
node: .yieldedExpressionsClause,
message: "could conform to trait 'Parenthesized' but does not"
),
ValidationFailure(node: .lifetimeTypeSpecifier, message: "could conform to trait 'Parenthesized' but does not"),
]
)
}
Expand Down
13 changes: 11 additions & 2 deletions Sources/SwiftParser/Declarations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -995,7 +995,7 @@ extension Parser {
}

// Parse the signature.
let signature = self.parseFunctionSignature()
let signature = self.parseFunctionSignature(allowOutput: false)

let whereClause: RawGenericWhereClauseSyntax?
if self.at(.keyword(.where)) {
Expand Down Expand Up @@ -1159,7 +1159,7 @@ extension Parser {
)
}

mutating func parseFunctionSignature() -> RawFunctionSignatureSyntax {
mutating func parseFunctionSignature(allowOutput: Bool = true) -> RawFunctionSignatureSyntax {
let parameterClause = self.parseParameterClause(RawFunctionParameterClauseSyntax.self) { parser in
parser.parseFunctionParameter()
}
Expand All @@ -1179,10 +1179,19 @@ extension Parser {
returnClause = nil
}

var unexpectedAfterReturnClause: RawUnexpectedNodesSyntax?
if !allowOutput,
let unexpectedOutput = returnClause
{
returnClause = nil
unexpectedAfterReturnClause = RawUnexpectedNodesSyntax([unexpectedOutput], arena: self.arena)
}

return RawFunctionSignatureSyntax(
parameterClause: parameterClause,
effectSpecifiers: effectSpecifiers,
returnClause: returnClause,
unexpectedAfterReturnClause,
arena: self.arena
)
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftParser/TokenPrecedence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ enum TokenPrecedence: Comparable {
.convenience, .override, .package, .open,
.__setter_access, .indirect, .isolated, .nonisolated, .distributed, ._local,
.inout, ._mutating, ._borrow, ._borrowing, .borrowing, ._consuming, .consuming, .consume,
.dependsOn, .scoped, .sending,
.sending,
// Accessors
.get, .set, .didSet, .willSet, .unsafeAddress, .addressWithOwner, .addressWithNativeOwner, .unsafeMutableAddress,
.mutableAddressWithOwner, .mutableAddressWithNativeOwner, ._read, .read, ._modify, .modify,
Expand Down
64 changes: 0 additions & 64 deletions Sources/SwiftParser/Types.swift
Original file line number Diff line number Diff line change
Expand Up @@ -874,64 +874,6 @@ extension Parser.Lookahead {
}

extension Parser {
private mutating func parseLifetimeTypeSpecifier() -> RawTypeSpecifierListSyntax.Element {
let (unexpectedBeforeDependsOnKeyword, dependsOnKeyword) = self.expect(.keyword(.dependsOn))

guard let leftParen = self.consume(if: .leftParen) else {
// If there is no left paren, add an entirely missing detail. Otherwise, we start to consume the following type
// name as a token inside the detail, which leads to confusing recovery results.
let lifetimeSpecifierArgumentList = RawLifetimeSpecifierArgumentListSyntax(
elements: [
RawLifetimeSpecifierArgumentSyntax(parameter: missingToken(.identifier), trailingComma: nil, arena: arena)
],
arena: self.arena
)
let lifetimeSpecifier = RawLifetimeTypeSpecifierSyntax(
unexpectedBeforeDependsOnKeyword,
dependsOnKeyword: dependsOnKeyword,
leftParen: missingToken(.leftParen),
scopedKeyword: nil,
arguments: lifetimeSpecifierArgumentList,
rightParen: missingToken(.rightParen),
arena: self.arena
)
return .lifetimeTypeSpecifier(lifetimeSpecifier)
}

let scoped = self.consume(if: .keyword(.scoped))
var keepGoing: RawTokenSyntax?
var arguments: [RawLifetimeSpecifierArgumentSyntax] = []
var loopProgress = LoopProgressCondition()
repeat {
let (unexpectedBeforeParameter, parameter) = self.expect(
anyIn: LifetimeSpecifierArgumentSyntax.ParameterOptions.self,
default: .identifier
)
keepGoing = self.consume(if: .comma)
arguments.append(
RawLifetimeSpecifierArgumentSyntax(
unexpectedBeforeParameter,
parameter: parameter,
trailingComma: keepGoing,
arena: arena
)
)
} while keepGoing != nil && self.hasProgressed(&loopProgress)
let lifetimeSpecifierArgumentList = RawLifetimeSpecifierArgumentListSyntax(elements: arguments, arena: self.arena)
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
let lifetimeSpecifier = RawLifetimeTypeSpecifierSyntax(
unexpectedBeforeDependsOnKeyword,
dependsOnKeyword: dependsOnKeyword,
leftParen: leftParen,
scopedKeyword: scoped,
arguments: lifetimeSpecifierArgumentList,
unexpectedBeforeRightParen,
rightParen: rightParen,
arena: self.arena
)
return .lifetimeTypeSpecifier(lifetimeSpecifier)
}

private mutating func parseSimpleTypeSpecifier(
specifierHandle: TokenConsumptionHandle
) -> RawTypeSpecifierListSyntax.Element {
Expand All @@ -949,12 +891,6 @@ extension Parser {
SPECIFIER_PARSING: while canHaveParameterSpecifier {
if let (_, specifierHandle) = self.at(anyIn: SimpleTypeSpecifierSyntax.SpecifierOptions.self) {
specifiers.append(parseSimpleTypeSpecifier(specifierHandle: specifierHandle))
} else if self.at(.keyword(.dependsOn)) {
if self.experimentalFeatures.contains(.nonescapableTypes) {
specifiers.append(parseLifetimeTypeSpecifier())
} else {
break SPECIFIER_PARSING
}
} else {
break SPECIFIER_PARSING
}
Expand Down
Loading