diff --git a/CodeGeneration/Sources/SyntaxSupport/AttributeNodes.swift b/CodeGeneration/Sources/SyntaxSupport/AttributeNodes.swift index d960ec5db26..cc561d27a49 100644 --- a/CodeGeneration/Sources/SyntaxSupport/AttributeNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/AttributeNodes.swift @@ -581,7 +581,7 @@ public let ATTRIBUTE_NODES: [Node] = [ Node( kind: .implementsAttributeArguments, base: .syntax, - nameForDiagnostics: "@_implements arguemnts", + nameForDiagnostics: "@_implements arguments", documentation: "The arguments for the `@_implements` attribute of the form `Type, methodName(arg1Label:arg2Label:)`", children: [ diff --git a/CodeGeneration/Sources/SyntaxSupport/Child.swift b/CodeGeneration/Sources/SyntaxSupport/Child.swift index ce631b5950e..db65feb9b9a 100644 --- a/CodeGeneration/Sources/SyntaxSupport/Child.swift +++ b/CodeGeneration/Sources/SyntaxSupport/Child.swift @@ -140,6 +140,19 @@ public class Child: NodeChoiceConvertible { } } + /// Should this child be hidden? + /// + /// A hidden child is one that is not accessible in any way at a specific point in the history, but still needs to be + /// (default) initialized. As always, its `newestChildPath` indicates the current way to access it. + /// + /// Hidden children are used for `Refactoring.introduced` and for the implicit changeset that creates + /// non-experimental APIs that ignore experimental children. + public let isHidden: Bool + + /// True if this child was created by a `childHistory` change set. Such children + /// are part of the compatibility layer and are therefore deprecated. + public var isHistorical: Bool + /// A name of this child as an identifier. public var identifier: TokenSyntax { return .identifier(lowercaseFirstWord(name: name)) @@ -161,8 +174,8 @@ public class Child: NodeChoiceConvertible { return "\(raw: newestName.withFirstCharacterUppercased)Options" } - /// If this child is deprecated, describes the sequence of accesses necessary - /// to reach the equivalent value using non-deprecated children; if the child + /// If this child is part of a compatibility layer, describes the sequence of accesses necessary + /// to reach the equivalent value using non-compatibility-layer children; if the child /// is not deprecated, this array is empty. /// /// Think of the elements of this array like components in a key path: @@ -199,12 +212,6 @@ public class Child: NodeChoiceConvertible { /// of the child. That information is not directly available anywhere. public let newestChildPath: [Child] - /// True if this child was created by a `Child.Refactoring`. Such children - /// are part of the compatibility layer and are therefore deprecated. - public var isHistorical: Bool { - !newestChildPath.isEmpty - } - /// Replaces the nodes in `newerChildPath` with their own `newerChildPath`s, /// if any, to form a child path enitrely of non-historical nodes. static private func makeNewestChildPath(from newerChildPath: [Child]) -> [Child] { @@ -214,7 +221,7 @@ public class Child: NodeChoiceConvertible { var workStack = Array(newerChildPath.reversed()) while let elem = workStack.popLast() { - if elem.isHistorical { + if !elem.newestChildPath.isEmpty { // There's an even newer version. Start working on that. workStack.append(contentsOf: elem.newestChildPath.reversed()) } else { @@ -308,7 +315,8 @@ public class Child: NodeChoiceConvertible { documentation: String? = nil, isOptional: Bool = false, providesDefaultInitialization: Bool = true, - newerChildPath: [Child] = [] + newerChildPath: [Child] = [], + isHistorical: Bool = false ) { precondition(name.first?.isLowercase ?? true, "The first letter of a child’s name should be lowercase") self.name = name @@ -320,11 +328,18 @@ public class Child: NodeChoiceConvertible { self.documentationAbstract = String(documentation?.split(whereSeparator: \.isNewline).first ?? "") self.isOptional = isOptional self.providesDefaultInitialization = providesDefaultInitialization + self.isHidden = false + self.isHistorical = isHistorical } /// Create a node that is a copy of the last node in `newerChildPath`, but /// with modifications. - init(renamingTo replacementName: String? = nil, newerChildPath: [Child]) { + init( + renamingTo replacementName: String? = nil, + makingHistorical: Bool = false, + makingHidden: Bool = false, + newerChildPath: [Child] + ) { let other = newerChildPath.last! self.name = replacementName ?? other.name @@ -336,6 +351,8 @@ public class Child: NodeChoiceConvertible { self.documentationAbstract = other.documentationAbstract self.isOptional = other.isOptional self.providesDefaultInitialization = other.providesDefaultInitialization + self.isHidden = makingHidden || other.isHidden + self.isHistorical = makingHistorical || other.isHistorical } /// Create a child for the unexpected nodes between two children (either or @@ -361,7 +378,8 @@ public class Child: NodeChoiceConvertible { documentation: nil, isOptional: true, providesDefaultInitialization: true, - newerChildPath: newerChildPath + newerChildPath: newerChildPath, + isHistorical: (earlier?.isHistorical ?? false) || (later?.isHistorical ?? false) ) } } @@ -417,5 +435,8 @@ extension Child { /// point in the past, so deprecated aliases that flatten the other node's /// children into this node should be provided. case extracted + + /// A new child was added (and it's important to preserve the names around it). + case introduced } } diff --git a/CodeGeneration/Sources/SyntaxSupport/CommonNodes.swift b/CodeGeneration/Sources/SyntaxSupport/CommonNodes.swift index 7247e17a909..03af6a9abc7 100644 --- a/CodeGeneration/Sources/SyntaxSupport/CommonNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/CommonNodes.swift @@ -233,6 +233,14 @@ public let COMMON_NODES: [Node] = [ "MissingNode" ], children: [ + Child( + name: "moduleSelector", + kind: .node(kind: .moduleSelector), + experimentalFeature: .moduleSelector, + documentation: + "A module selector. Some expressions can be prefixed with module selectors, so if one is parsed before an invalid expression, it will be inserted here.", + isOptional: true + ), Child( name: "placeholder", kind: .token(choices: [.token(.identifier)], requiresLeadingSpace: false, requiresTrailingSpace: false), @@ -241,7 +249,7 @@ public let COMMON_NODES: [Node] = [ This token should always have `presence = .missing`. """ - ) + ), ] ), @@ -318,6 +326,14 @@ public let COMMON_NODES: [Node] = [ "MissingNode" ], children: [ + Child( + name: "moduleSelector", + kind: .node(kind: .moduleSelector), + experimentalFeature: .moduleSelector, + documentation: + "A module selector. Some types can be prefixed with module selectors, so if one is parsed before an invalid type, it will be inserted here.", + isOptional: true + ), Child( name: "placeholder", kind: .token(choices: [.token(.identifier)], requiresLeadingSpace: false, requiresTrailingSpace: false), @@ -326,7 +342,26 @@ public let COMMON_NODES: [Node] = [ This token should always have `presence = .missing`. """ - ) + ), + ] + ), + + Node( + kind: .moduleSelector, + base: .syntax, + experimentalFeature: .moduleSelector, + nameForDiagnostics: "module selector", + children: [ + Child( + name: "moduleName", + kind: .token(choices: [.token(.identifier)]), + nameForDiagnostics: "module name" + ), + Child( + name: "colonColon", + kind: .token(choices: [.token(.colonColon)]), + nameForDiagnostics: "'::' operator" + ), ] ), diff --git a/CodeGeneration/Sources/SyntaxSupport/CompatibilityLayer.swift b/CodeGeneration/Sources/SyntaxSupport/CompatibilityLayer.swift index f95f3143669..8d6b9305c80 100644 --- a/CodeGeneration/Sources/SyntaxSupport/CompatibilityLayer.swift +++ b/CodeGeneration/Sources/SyntaxSupport/CompatibilityLayer.swift @@ -18,8 +18,9 @@ public struct CompatibilityLayer { /// Deprecated members that the compatibility layer needs for each trait. public var deprecatedMembersByTrait: [String: DeprecatedMemberInfo] = [:] - /// Cache for `replacementChildren(for:by:)`. Ensures that we don't create two different replacement children even - /// if we refactor the same child twice, so we can reliably equate and hash `Child` objects by object identity. + /// Cache for `replacementChildren(for:by:historical:)`. Ensures that we don't create two different replacement + /// children even if we refactor the same child twice, so we can reliably equate and hash `Child` objects by + /// object identity. private var cachedReplacementChildren: [Child: [Child]] = [:] /// Returns the deprecated members that the compatibility layer needs for `node`. @@ -46,13 +47,23 @@ public struct CompatibilityLayer { /// Returns the child or children that would have existed in place of this /// child before this refactoring was applied. - private mutating func replacementChildren(for newerChild: Child, by refactoring: Child.Refactoring) -> [Child] { + /// + /// - Parameters: + /// - newerChild: The child which is being replaced. + /// - refactoring: The refactoring which created that child and must be + /// reversed. + fileprivate mutating func replacementChildren( + for newerChild: Child, + by refactoring: Child.Refactoring, + historical: Bool + ) -> [Child] { func make() -> [Child] { switch refactoring { case .renamed(from: let deprecatedName): return [ Child( renamingTo: deprecatedName, + makingHistorical: historical, newerChildPath: [newerChild] ) ] @@ -72,8 +83,20 @@ public struct CompatibilityLayer { } return newerGrandchildren.map { newerGrandchild in - Child(newerChildPath: [newerChild, newerGrandchild]) + Child( + makingHistorical: historical, + newerChildPath: [newerChild, newerGrandchild] + ) } + + case .introduced: + return [ + Child( + makingHistorical: historical, + makingHidden: true, + newerChildPath: [newerChild] + ) + ] } } @@ -100,6 +123,7 @@ public struct CompatibilityLayer { deprecatedMembersByNode[node.syntaxNodeKind] = result } + /// Compute and cache compatibility layer information for the given children. private mutating func computeMembers(for trait: Trait) { guard deprecatedMembersByTrait[trait.traitName] == nil else { return @@ -115,58 +139,146 @@ public struct CompatibilityLayer { deprecatedMembersByTrait[trait.traitName] = result } - /// Compute and cache compatibility layer information for the given children. + /// Compute compatibility layer information for the given children. private mutating func computeMembersFor( typeName: String, initialChildren: [Child], history: Child.History, areRequirements: Bool ) -> DeprecatedMemberInfo { - // The results that will ultimately be saved into the DeprecatedMemberInfo. + var builder = DeprecatedMemberInfo.Builder( + typeName: typeName, + children: initialChildren, + areRequirements: areRequirements + ) + + // If any of the children are experimental, apply an initial change set that hides them, ensuring that we generate + // APIs which aren't experimental. + let experimentalChildren = initialChildren.filter { $0.isExperimental && !$0.isUnexpectedNodes } + if !experimentalChildren.isEmpty { + let syntheticChangeSet = experimentalChildren.map { ($0.name, Child.Refactoring.introduced) } + builder.applyChangeSet(syntheticChangeSet, for: &self, historical: false) + } + + // Apply changes in the history + for changeSet in history { + builder.applyChangeSet(changeSet, for: &self, historical: true) + } + + return builder.make() + } +} + +/// Describes the deprecated members of a given type that the compatibility layer ought to provide. +public struct DeprecatedMemberInfo { + /// Properties that are needed in the compatibility layer, in the order they ought to appear in the generated file. + public var vars: [Child] = [] + + /// Initializer signatures that are needed in the compatibility layer, in the order they ought to appear in the generated file. + public var inits: [InitSignature] = [] + + /// Is there anything whatsoever that we ought to generate? + public var isEmpty: Bool { + return vars.isEmpty && inits.isEmpty + } + + fileprivate struct Builder { + /// Properties that are needed in the compatibility layer, in the order they ought to appear in the generated file. + /// This becomes a property of the `DeprecatedMemberInfo`. var vars: [Child] = [] - var initSignatures: [InitSignature] = [] - // Temporary working state for the loop. - var children = initialChildren - var knownVars = Set(children) + /// Initializer signatures that are needed in the compatibility layer, in the order they ought to appear in the generated file. + /// This becomes a property of the `DeprecatedMemberInfo`. + var inits: [InitSignature] = [] - func firstIndexOfChild(named targetName: String) -> Int { - guard let i = children.firstIndex(where: { $0.name == targetName }) else { - fatalError( - "couldn't find '\(targetName)' in current children of \(typeName): \(String(reflecting: children.map(\.name)))" - ) - } - return i + /// Name of the type we're generating a compatibility layer for. + private let typeName: String + + /// Are we building a compatibility layer for requirements of a trait? Traits don't have unexpected children or + /// initializers. + private let areRequirements: Bool + + /// The current set of children after applying all of the change sets ever passed to `applyChangeSet(_:for:historical:)`. + /// This is working state. + private var children: [Child] + + /// The set of all children that have ever been added to `vars`, plus the ones that were originally present. + /// Used to ensure duplicates aren't added to `vars`. This is working state. + private var knownVars: Set + + /// Creates a builder with no deprecated members, but ready to start adding change sets. + init(typeName: String, children: [Child], areRequirements: Bool) { + self.typeName = typeName + self.areRequirements = areRequirements + + self.children = children + self.knownVars = Set(children) } - for changeSet in history { + /// Creates a `DeprecatedMemberInfo` from all the change sets that have been passed to + /// `applyChangeSet(_:for:historical:)`. + func make() -> DeprecatedMemberInfo { + return DeprecatedMemberInfo(vars: vars, inits: inits) + } + + /// Generate the new `vars` and `inits` that are required to maintain compatibility with `changeSet`. + /// + /// - Parameters: + /// - changeSet: The changes to apply. This type is basically a generic form of `Child.ChangeSet`. + /// - compatibilityLayer: The compatibility layer that these children will ultimately belong to. + /// - historical: Should the children created by this change set be marked historical (and thus be deprecated)? + mutating func applyChangeSet( + _ changeSet: some RandomAccessCollection<(key: String, value: Child.Refactoring)>, + for compatibilityLayer: inout CompatibilityLayer, + historical: Bool + ) { var unexpectedChildrenWithNewNames: Set = [] // First pass: Apply the changes explicitly specified in the change set. for (currentName, refactoring) in changeSet { let i = firstIndexOfChild(named: currentName) - let replacementChildren = replacementChildren(for: children[i], by: refactoring) + let replacementChildren = compatibilityLayer.replacementChildren( + for: children[i], + by: refactoring, + historical: historical + ) children.replaceSubrange(i...i, with: replacementChildren) if !areRequirements { + func isDifferent(_ newChild: Child) -> Bool { + newChild.isHidden || currentName != newChild.name + } + // Mark adjacent unexpected node children whose names have changed too. - if currentName != replacementChildren.first?.name { + if let firstNewChild = replacementChildren.first, isDifferent(firstNewChild) { unexpectedChildrenWithNewNames.insert(children[i - 1]) } - if currentName != replacementChildren.last?.name { + if let lastNewChild = replacementChildren.last, isDifferent(lastNewChild) { unexpectedChildrenWithNewNames.insert(children[i + replacementChildren.count]) } } } // Second pass: Update unexpected node children adjacent to those changes whose names have probably changed. - for unexpectedChild in unexpectedChildrenWithNewNames { + for unexpectedChild in unexpectedChildrenWithNewNames where !unexpectedChild.isHidden { precondition(unexpectedChild.isUnexpectedNodes) let i = firstIndexOfChild(named: unexpectedChild.name) - let earlier = children[checked: i - 1] - let later = children[checked: i + 1] + guard i == 0 || !children[i - 1].isHidden else { + // Special case: `unexpectedChild` follows a hidden child and should be hidden too. + children[i] = Child(makingHistorical: historical, makingHidden: true, newerChildPath: [unexpectedChild]) + continue + } + + // Find nearest expected, non-hidden node before `unexpectedChild` + let allEarlier = children.prefix(through: max(i - 1, children.startIndex)) + let earlier = allEarlier.last { !$0.isHidden && !$0.isUnexpectedNodes } + + // Find nearest expected, non-hidden node after `unexpectedChild` + let allLater = children.suffix(from: min(i + 1, children.endIndex)) + let later = allLater.first { !$0.isHidden && !$0.isUnexpectedNodes } + precondition(!(earlier?.isUnexpectedNodes ?? false) && !(later?.isUnexpectedNodes ?? false)) let newChild = Child(forUnexpectedBetween: earlier, and: later, newerChildPath: [unexpectedChild]) @@ -176,33 +288,23 @@ public struct CompatibilityLayer { children[i] = newChild } - // Third pass: Append newly-created children to vars. We do this now so that changes from the first two passes are properly interleaved, preserving source order. - vars += children.filter { knownVars.insert($0).inserted } + // Third pass: Append newly-created children to vars. We do this now so that changes from the first two passes + // are properly interleaved, preserving source order. + self.vars += children.filter { !$0.isHidden && knownVars.insert($0).inserted } // We don't create compatibility layers for protocol requirement inits. if !areRequirements { - initSignatures.append(InitSignature(children: children)) + self.inits.append(InitSignature(children: children)) } } - return DeprecatedMemberInfo(vars: vars, inits: initSignatures) - } -} - -/// Describes the deprecated members of a given type that the compatibility layer ought to provide. -public struct DeprecatedMemberInfo { - /// Properties that are needed in the compatibility layer, in the order they ought to appear in the generated file. - public var vars: [Child] = [] - - /// Initializer signatures that are needed in the compatibility layer, in the order they ought to appear in the generated file. - public var inits: [InitSignature] = [] -} - -extension Array { - /// Returns `nil` if `i` is out of bounds, or the indicated element otherwise. - fileprivate subscript(checked i: Index) -> Element? { - get { - return indices.contains(i) ? self[i] : nil + private func firstIndexOfChild(named targetName: String) -> Int { + guard let i = children.firstIndex(where: { $0.name == targetName }) else { + fatalError( + "couldn't find '\(targetName)' in current children of \(typeName): \(String(reflecting: children.map(\.name)))" + ) + } + return i } } } diff --git a/CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift b/CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift index 25ecbf84785..802301b921e 100644 --- a/CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift @@ -28,7 +28,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "trailingPeriod", - kind: .token(choices: [.token(.period)]), + kind: .token(choices: [.token(.period), .token(.colonColon)]), isOptional: true ), ], @@ -157,7 +157,7 @@ public let DECL_NODES: [Node] = [ Node( kind: .accessorParameters, base: .syntax, - nameForDiagnostics: nil, + nameForDiagnostics: "accessor parameter", traits: [ "Parenthesized" ], @@ -209,6 +209,7 @@ public let DECL_NODES: [Node] = [ Child( name: "name", kind: .token(choices: [.token(.identifier)]), + nameForDiagnostics: "name", documentation: "The name of the actor. If the name matches a reserved keyword use backticks to escape it." ), Child( @@ -301,6 +302,7 @@ public let DECL_NODES: [Node] = [ Child( name: "name", kind: .token(choices: [.token(.identifier)]), + nameForDiagnostics: "name", documentation: "The name of this associated type." ), Child( @@ -389,6 +391,7 @@ public let DECL_NODES: [Node] = [ Child( name: "name", kind: .token(choices: [.token(.identifier)]), + nameForDiagnostics: "name", documentation: "The name of the class." ), Child( @@ -770,6 +773,7 @@ public let DECL_NODES: [Node] = [ Child( name: "name", kind: .token(choices: [.token(.identifier)]), + nameForDiagnostics: "name", documentation: "The name of this case." ), Child( @@ -833,6 +837,7 @@ public let DECL_NODES: [Node] = [ Child( name: "name", kind: .token(choices: [.token(.identifier)]), + nameForDiagnostics: "name", documentation: "Declares the name of this enum. If the name matches a reserved keyword use backticks to escape it." ), @@ -1009,6 +1014,7 @@ public let DECL_NODES: [Node] = [ .token(.prefixOperator), .token(.postfixOperator), ]), + nameForDiagnostics: "name", documentation: "The name of the function. If the name matches a reserved keyword use backticks to escape it." ), Child( @@ -1492,7 +1498,8 @@ public let DECL_NODES: [Node] = [ ), Child( name: "name", - kind: .token(choices: [.token(.identifier)]) + kind: .token(choices: [.token(.identifier)]), + nameForDiagnostics: "name" ), Child( name: "genericParameterClause", @@ -1554,6 +1561,12 @@ public let DECL_NODES: [Node] = [ kind: .token(choices: [.token(.pound)]), documentation: "The `#` sign." ), + Child( + name: "moduleSelector", + kind: .node(kind: .moduleSelector), + experimentalFeature: .moduleSelector, + isOptional: true + ), Child( name: "macroName", kind: .token(choices: [.token(.identifier)]) @@ -1678,7 +1691,8 @@ public let DECL_NODES: [Node] = [ ), Child( name: "name", - kind: .token(choices: [.token(.binaryOperator), .token(.prefixOperator), .token(.postfixOperator)]) + kind: .token(choices: [.token(.binaryOperator), .token(.prefixOperator), .token(.postfixOperator)]), + nameForDiagnostics: "custom operator" ), Child( name: "operatorPrecedenceAndTypes", @@ -1971,7 +1985,7 @@ public let DECL_NODES: [Node] = [ Node( kind: .precedenceGroupDecl, base: .decl, - nameForDiagnostics: "precedencegroup", + nameForDiagnostics: "precedence group", documentation: "A Swift `precedencegroup` declaration.", traits: [ "Braced", @@ -1999,6 +2013,7 @@ public let DECL_NODES: [Node] = [ Child( name: "name", kind: .token(choices: [.token(.identifier)]), + nameForDiagnostics: "name", documentation: "The name of this precedence group." ), Child( @@ -2119,6 +2134,7 @@ public let DECL_NODES: [Node] = [ Child( name: "name", kind: .token(choices: [.token(.identifier)]), + nameForDiagnostics: "name", documentation: "The name of the protocol." ), Child( @@ -2299,6 +2315,7 @@ public let DECL_NODES: [Node] = [ Child( name: "name", kind: .token(choices: [.token(.identifier)]), + nameForDiagnostics: "name", documentation: "Declares the name of this struct. If the name matches a reserved keyword use backticks to escape it." ), @@ -2465,7 +2482,8 @@ public let DECL_NODES: [Node] = [ ), Child( name: "name", - kind: .token(choices: [.token(.identifier)]) + kind: .token(choices: [.token(.identifier)]), + nameForDiagnostics: "name" ), Child( name: "genericParameterClause", diff --git a/CodeGeneration/Sources/SyntaxSupport/ExperimentalFeatures.swift b/CodeGeneration/Sources/SyntaxSupport/ExperimentalFeatures.swift index 70cd36c9a7d..48c76889a5e 100644 --- a/CodeGeneration/Sources/SyntaxSupport/ExperimentalFeatures.swift +++ b/CodeGeneration/Sources/SyntaxSupport/ExperimentalFeatures.swift @@ -23,6 +23,7 @@ public enum ExperimentalFeature: String, CaseIterable { case oldOwnershipOperatorSpellings case inlineArrayTypeSugar case defaultIsolationPerFile + case moduleSelector /// The name of the feature as it is written in the compiler's `Features.def` file. public var featureName: String { @@ -47,6 +48,8 @@ public enum ExperimentalFeature: String, CaseIterable { return "InlineArrayTypeSugar" case .defaultIsolationPerFile: return "DefaultIsolationPerFile" + case .moduleSelector: + return "ModuleSelector" } } @@ -73,6 +76,8 @@ public enum ExperimentalFeature: String, CaseIterable { return "sugar type for InlineArray" case .defaultIsolationPerFile: return "set default actor isolation for a file" + case .moduleSelector: + return "Module selector syntax (`ModName::identifier`)" } } diff --git a/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift b/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift index bfe92058354..5e02ba027d5 100644 --- a/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift @@ -773,7 +773,7 @@ public let EXPR_NODES: [Node] = [ Node( kind: .discardAssignmentExpr, base: .expr, - nameForDiagnostics: nil, + nameForDiagnostics: "wildcard expression", documentation: """ A `_` that discards a value inside an assignment. @@ -1002,6 +1002,12 @@ public let EXPR_NODES: [Node] = [ base: .expr, nameForDiagnostics: nil, children: [ + Child( + name: "moduleSelector", + kind: .node(kind: .moduleSelector), + experimentalFeature: .moduleSelector, + isOptional: true + ), Child( name: "baseName", kind: .token(choices: [ @@ -1358,6 +1364,12 @@ public let EXPR_NODES: [Node] = [ kind: .token(choices: [.token(.pound)]), documentation: "The `#` sign." ), + Child( + name: "moduleSelector", + kind: .node(kind: .moduleSelector), + experimentalFeature: .moduleSelector, + isOptional: true + ), Child( name: "macroName", kind: .token(choices: [.token(.identifier)]) @@ -1504,7 +1516,7 @@ public let EXPR_NODES: [Node] = [ Node( kind: .nilLiteralExpr, base: .expr, - nameForDiagnostics: nil, + nameForDiagnostics: "'nil' keyword", children: [ Child( name: "nilKeyword", @@ -1874,7 +1886,7 @@ public let EXPR_NODES: [Node] = [ Node( kind: .superExpr, base: .expr, - nameForDiagnostics: nil, + nameForDiagnostics: "'super' keyword", children: [ Child( name: "superKeyword", diff --git a/CodeGeneration/Sources/SyntaxSupport/InitSignature.swift b/CodeGeneration/Sources/SyntaxSupport/InitSignature.swift index e93ac4ed12a..799f62b1535 100644 --- a/CodeGeneration/Sources/SyntaxSupport/InitSignature.swift +++ b/CodeGeneration/Sources/SyntaxSupport/InitSignature.swift @@ -12,9 +12,26 @@ /// Represents an initializer that should be generated. public struct InitSignature { - /// The list of children which shoudl be given parameters and initialized by the initializer. + /// The list of children which should be initialized by the initializer. + /// Includes hidden children. public var children: [Child] + /// The list of children which should be given parameters. Excludes hidden + /// children. + public var visibleChildren: LazyFilterSequence<[Child]> { + return children.lazy.filter { !$0.isHidden } + } + + /// Does this initializer cover any experimental features? + public var isExperimental: Bool { + return visibleChildren.contains { $0.isExperimental && !$0.isUnexpectedNodes } + } + + /// Does this initializer cover any historical children (vs. just omitting experimental features)? + public var isHistorical: Bool { + return visibleChildren.contains { $0.isHistorical && !$0.isUnexpectedNodes } + } + /// Create an initializer with an arbitrary array of children. public init(children: [Child]) { self.children = children diff --git a/CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift b/CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift index 011058348cd..85e93c701f1 100644 --- a/CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift +++ b/CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift @@ -206,6 +206,7 @@ public enum SyntaxNodeKind: String, CaseIterable, IdentifierConvertible, TypeCon case missingPattern case missingStmt case missingType + case moduleSelector case multipleTrailingClosureElement case multipleTrailingClosureElementList case namedOpaqueReturnType diff --git a/CodeGeneration/Sources/SyntaxSupport/TokenSpec.swift b/CodeGeneration/Sources/SyntaxSupport/TokenSpec.swift index 2abbc28adc8..b276a715251 100644 --- a/CodeGeneration/Sources/SyntaxSupport/TokenSpec.swift +++ b/CodeGeneration/Sources/SyntaxSupport/TokenSpec.swift @@ -126,6 +126,7 @@ public enum Token: CaseIterable { case backtick case binaryOperator case colon + case colonColon case comma case dollarIdentifier case ellipsis @@ -185,6 +186,8 @@ public enum Token: CaseIterable { return .other(name: "binaryOperator", nameForDiagnostics: "binary operator") case .colon: return .punctuator(name: "colon", text: ":") + case .colonColon: + return .punctuator(name: "colonColon", text: "::") case .comma: return .punctuator(name: "comma", text: ",") case .dollarIdentifier: diff --git a/CodeGeneration/Sources/SyntaxSupport/Traits.swift b/CodeGeneration/Sources/SyntaxSupport/Traits.swift index c9eb2828931..765a58c21a9 100644 --- a/CodeGeneration/Sources/SyntaxSupport/Traits.swift +++ b/CodeGeneration/Sources/SyntaxSupport/Traits.swift @@ -92,6 +92,12 @@ public let TRAITS: [Trait] = [ traitName: "FreestandingMacroExpansion", children: [ Child(name: "pound", kind: .token(choices: [.token(.pound)])), + Child( + name: "moduleSelector", + kind: .node(kind: .moduleSelector), + experimentalFeature: .moduleSelector, + isOptional: true + ), Child(name: "macroName", kind: .token(choices: [.token(.identifier)])), Child(name: "genericArgumentClause", kind: .node(kind: .genericArgumentClause), isOptional: true), Child(name: "leftParen", kind: .token(choices: [.token(.leftParen)]), isOptional: true), diff --git a/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift b/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift index 12dd1d385cc..f9acce4e1d2 100644 --- a/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift @@ -366,6 +366,13 @@ public let TYPE_NODES: [Node] = [ name: "period", kind: .token(choices: [.token(.period)]) ), + Child( + name: "moduleSelector", + kind: .node(kind: .moduleSelector), + experimentalFeature: .moduleSelector, + nameForDiagnostics: "module selector", + isOptional: true + ), Child( name: "name", kind: .token(choices: [.token(.identifier), .keyword(.self)]), @@ -512,6 +519,13 @@ public let TYPE_NODES: [Node] = [ base: .type, nameForDiagnostics: "type", children: [ + Child( + name: "moduleSelector", + kind: .node(kind: .moduleSelector), + experimentalFeature: .moduleSelector, + nameForDiagnostics: "module selector", + isOptional: true + ), Child( name: "name", kind: .token(choices: [ diff --git a/CodeGeneration/Sources/generate-swift-syntax/InitSignature+Extensions.swift b/CodeGeneration/Sources/generate-swift-syntax/InitSignature+Extensions.swift index 97a61847829..5feed8174c0 100644 --- a/CodeGeneration/Sources/generate-swift-syntax/InitSignature+Extensions.swift +++ b/CodeGeneration/Sources/generate-swift-syntax/InitSignature+Extensions.swift @@ -17,7 +17,7 @@ import Utils extension InitSignature { var compoundName: String { - let renamedArguments = children.map { child in + let renamedArguments = visibleChildren.map { child in if child.isUnexpectedNodes { return "_:" } else { @@ -28,8 +28,16 @@ extension InitSignature { return "init(leadingTrivia:\(renamedArguments)trailingTrivia:)" } + func generateInitializerAttributes() -> AttributeListSyntax { + return AttributeListSyntax { + if self.isExperimental { + AttributeSyntax("@_spi(ExperimentalLanguageFeatures)").with(\.trailingTrivia, .space) + } + } + } + func generateInitializerDeclHeader() -> SyntaxNodeString { - if children.isEmpty { + if visibleChildren.isEmpty { return "public init()" } @@ -66,7 +74,7 @@ extension InitSignature { let params = FunctionParameterListSyntax { FunctionParameterSyntax("leadingTrivia: Trivia? = nil") - for child in children { + for child in visibleChildren { createFunctionParameterSyntax(for: child) } @@ -74,8 +82,10 @@ extension InitSignature { .with(\.leadingTrivia, .newline) } + let attributes = generateInitializerAttributes() + return """ - public init( + \(attributes)public init( \(params) ) """ @@ -93,7 +103,7 @@ extension InitSignature { - Parameters: - leadingTrivia: Trivia to be prepended to the leading trivia of the node’s first token. \ If the node is empty, there is no token to attach the trivia to and the parameter is ignored. - \(children.compactMap(generateParamDocComment).joined(separator: "\n")) + \(visibleChildren.compactMap(generateParamDocComment).joined(separator: "\n")) - trailingTrivia: Trivia to be appended to the trailing trivia of the node’s last token. \ If the node is empty, there is no token to attach the trivia to and the parameter is ignored. """.removingEmptyLines @@ -114,7 +124,7 @@ extension InitSignature { var builderParameters: [FunctionParameterSyntax] = [] var delegatedInitArgs: [LabeledExprSyntax] = [] - for child in children { + for child in visibleChildren { /// The expression that is used to call the default initializer defined above. let produceExpr: ExprSyntax let childName = child.identifier @@ -174,10 +184,12 @@ extension InitSignature { FunctionParameterSyntax("trailingTrivia: Trivia? = nil") } + let attributes = generateInitializerAttributes() + return try InitializerDeclSyntax( """ /// A convenience initializer that allows initializing syntax collections using result builders - public init\(params) rethrows + \(attributes)public init\(params) rethrows """ ) { FunctionCallExprSyntax(callee: ExprSyntax("try self.init")) { @@ -209,6 +221,7 @@ extension InitSignature { func makeArgumentsToInitializeNewestChildren() -> [LabeledExprSyntax] { var root: [InitParameterMapping] = [] + // This should also map hidden children. for child in children { InitParameterMapping.addChild(child, to: &root) } @@ -351,7 +364,11 @@ extension InitParameterMapping { let argValue = switch argument { case .decl(olderChild: let olderChild): - ExprSyntax(DeclReferenceExprSyntax(baseName: olderChild.baseCallName)) + if olderChild.isHidden { + olderChild.defaultValue! + } else { + ExprSyntax(DeclReferenceExprSyntax(baseName: olderChild.baseCallName)) + } case .nestedInit(let initArgs): ExprSyntax( diff --git a/CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/RenamedChildrenCompatibilityFile.swift b/CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/RenamedChildrenCompatibilityFile.swift index 77f4548117b..8053ab29c99 100644 --- a/CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/RenamedChildrenCompatibilityFile.swift +++ b/CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/RenamedChildrenCompatibilityFile.swift @@ -16,36 +16,40 @@ import SyntaxSupport import Utils let renamedChildrenCompatibilityFile = try! SourceFileSyntax(leadingTrivia: copyrightHeader) { - for layoutNode in SYNTAX_NODES.compactMap(\.layoutNode).filter({ !$0.childHistory.isEmpty }) { + for layoutNode in SYNTAX_NODES.compactMap(\.layoutNode) { var deprecatedMembers = SYNTAX_COMPATIBILITY_LAYER.deprecatedMembers(for: layoutNode) - try ExtensionDeclSyntax("extension \(layoutNode.type.syntaxBaseName)") { - for child in deprecatedMembers.vars { - makeCompatibilityVar(for: child) - if let addMethod = makeCompatibilityAddMethod(for: child) { - addMethod + if !deprecatedMembers.isEmpty { + try ExtensionDeclSyntax("extension \(layoutNode.type.syntaxBaseName)") { + for child in deprecatedMembers.vars { + makeCompatibilityVar(for: child) + if let addMethod = makeCompatibilityAddMethod(for: child) { + addMethod + } } - } - let renamedName = InitSignature(layoutNode).compoundName - for signature in deprecatedMembers.inits { - makeCompatibilityInit(for: signature, renamedName: renamedName) + let renamedName = InitSignature(layoutNode).compoundName + for signature in deprecatedMembers.inits { + makeCompatibilityInit(for: signature, renamedName: renamedName) + } } } } - for trait in TRAITS.filter({ !$0.childHistory.isEmpty }) { + for trait in TRAITS { var deprecatedMembers = SYNTAX_COMPATIBILITY_LAYER.deprecatedMembers(for: trait) - try ExtensionDeclSyntax("extension \(trait.protocolName)") { - for child in deprecatedMembers.vars { - makeCompatibilityVar(for: child) - if let addMethod = makeCompatibilityAddMethod(for: child) { - addMethod + if !deprecatedMembers.isEmpty { + try ExtensionDeclSyntax("extension \(trait.protocolName)") { + for child in deprecatedMembers.vars { + makeCompatibilityVar(for: child) + if let addMethod = makeCompatibilityAddMethod(for: child) { + addMethod + } } - } - // Not currently generating compatibility inits for traits. + // Not currently generating compatibility inits for traits. + } } } } @@ -63,10 +67,16 @@ func makeCompatibilityVar(for child: Child) -> DeclSyntax { ExprSyntax(MemberAccessExprSyntax(base: base, name: child.baseCallName)) } + let attributes = AttributeListSyntax { + if child.isHistorical { + AttributeSyntax("@available(*, deprecated, renamed: \(literal: childPathString))") + .with(\.trailingTrivia, .newlines(1)) + } + } + return DeclSyntax( """ - @available(*, deprecated, renamed: \(literal: childPathString)) - public var \(child.identifier): \(type) { + \(attributes)public var \(child.identifier): \(type) { get { return \(childAccess) } @@ -105,11 +115,20 @@ func makeCompatibilityAddMethod(for child: Child) -> DeclSyntax? { } func makeCompatibilityInit(for signature: InitSignature, renamedName: String) -> InitializerDeclSyntax { - try! InitializerDeclSyntax( + let prefix: SyntaxNodeString + if signature.isHistorical { + prefix = """ + @available(*, deprecated, renamed: \(literal: renamedName)) + @_disfavoredOverload + + """ + } else { + prefix = "" + } + + return try! InitializerDeclSyntax( """ - @available(*, deprecated, renamed: \(literal: renamedName)) - @_disfavoredOverload - \(signature.generateInitializerDeclHeader()) + \(prefix)\(signature.generateInitializerDeclHeader()) """ ) { FunctionCallExprSyntax(callee: ExprSyntax("self.init")) { diff --git a/CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntaxbuilder/RenamedChildrenBuilderCompatibilityFile.swift b/CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntaxbuilder/RenamedChildrenBuilderCompatibilityFile.swift index 3f08259a46c..4d95acfa33a 100644 --- a/CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntaxbuilder/RenamedChildrenBuilderCompatibilityFile.swift +++ b/CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntaxbuilder/RenamedChildrenBuilderCompatibilityFile.swift @@ -18,25 +18,35 @@ import Utils let renamedChildrenBuilderCompatibilityFile = try! SourceFileSyntax(leadingTrivia: copyrightHeader) { importSwiftSyntax(accessLevel: .public) - for layoutNode in SYNTAX_NODES.compactMap(\.layoutNode).filter({ !$0.childHistory.isEmpty }) { + for layoutNode in SYNTAX_NODES.compactMap(\.layoutNode) { let deprecatedMembers = SYNTAX_COMPATIBILITY_LAYER.deprecatedMembers(for: layoutNode) - - for signature in deprecatedMembers.inits { - if let convenienceInit = try signature.createConvenienceBuilderInitializer() { - let deprecatedNames = layoutNode.children - .filter { !$0.isUnexpectedNodes && !signature.children.contains($0) } - .compactMap { $0.identifier.description } - .joined(separator: ", ") - - DeclSyntax( - """ - extension \(layoutNode.type.syntaxBaseName) { - @available(*, deprecated, message: "Use an initializer with \(raw: deprecatedNames) argument(s).") - @_disfavoredOverload - \(convenienceInit) + if !deprecatedMembers.isEmpty { + for signature in deprecatedMembers.inits { + if let convenienceInit = try signature.createConvenienceBuilderInitializer() { + if signature.isHistorical { + let deprecatedNames = layoutNode.children + .filter { !$0.isUnexpectedNodes && !signature.children.contains($0) } + .compactMap { $0.identifier.description } + .joined(separator: ", ") + DeclSyntax( + """ + extension \(layoutNode.type.syntaxBaseName) { + @available(*, deprecated, message: "Use an initializer with \(raw: deprecatedNames) argument(s).") + @_disfavoredOverload + \(convenienceInit) + } + """ + ) + } else { + DeclSyntax( + """ + extension \(layoutNode.type.syntaxBaseName) { + \(convenienceInit) + } + """ + ) } - """ - ) + } } } } diff --git a/CodeGeneration/Tests/ValidateSyntaxNodes/ValidateSyntaxNodes.swift b/CodeGeneration/Tests/ValidateSyntaxNodes/ValidateSyntaxNodes.swift index e1b9a73df15..ca274656e3a 100644 --- a/CodeGeneration/Tests/ValidateSyntaxNodes/ValidateSyntaxNodes.swift +++ b/CodeGeneration/Tests/ValidateSyntaxNodes/ValidateSyntaxNodes.swift @@ -357,10 +357,6 @@ class ValidateSyntaxNodes: XCTestCase { "child 'leadingComma' has a comma keyword as its only token choice and should thus be named 'comma' or 'trailingComma'" ), // This is similar to `TrailingComma` - ValidationFailure( - node: .importPathComponent, - message: "child 'trailingPeriod' has a token as its only token choice and should thus be named 'period'" - ), // `~` is the only operator that’s allowed here ValidationFailure( node: .suppressedType, diff --git a/Sources/SwiftBasicFormat/BasicFormat.swift b/Sources/SwiftBasicFormat/BasicFormat.swift index 1cf8b170bcb..77f84cfc7a8 100644 --- a/Sources/SwiftBasicFormat/BasicFormat.swift +++ b/Sources/SwiftBasicFormat/BasicFormat.swift @@ -308,10 +308,12 @@ open class BasicFormat: SyntaxRewriter { case (.atSign, _), (.backslash, _), (.backtick, _), + (.colonColon, .identifier), (.dollarIdentifier, .period), // a.b (.endOfFile, _), (.exclamationMark, .period), // myOptionalBar!.foo() (.regexPoundDelimiter, .regexSlash), // opening extended regex delimiter should never be separate by a space + (.identifier, .colonColon), (.identifier, .leftAngle), // MyType (.identifier, .leftSquare), // myArray[1] (.identifier, .period), // a.b diff --git a/Sources/SwiftIDEUtils/SyntaxClassification.swift b/Sources/SwiftIDEUtils/SyntaxClassification.swift index 1979483c777..92a35d91723 100644 --- a/Sources/SwiftIDEUtils/SyntaxClassification.swift +++ b/Sources/SwiftIDEUtils/SyntaxClassification.swift @@ -114,6 +114,8 @@ extension RawTokenKind { return .operator case .colon: return .none + case .colonColon: + return .operator case .comma: return .none case .dollarIdentifier: diff --git a/Sources/SwiftParser/Attributes.swift b/Sources/SwiftParser/Attributes.swift index 5946e76cdff..4656c8b0a9a 100644 --- a/Sources/SwiftParser/Attributes.swift +++ b/Sources/SwiftParser/Attributes.swift @@ -230,7 +230,11 @@ extension Parser { ) } - switch peek(isAtAnyIn: DeclarationAttributeWithSpecialSyntax.self) { + // An attribute qualified by a module selector is *always* a custom attribute, even if it has the same name (or + // module name) as a builtin attribute. + let builtinAttr = self.unlessPeekModuleSelector { $0.peek(isAtAnyIn: DeclarationAttributeWithSpecialSyntax.self) } + + switch builtinAttr { case .abi: return parseAttribute(argumentMode: .required) { parser in return (nil, .abiArguments(parser.parseABIAttributeArguments())) @@ -304,7 +308,12 @@ extension Parser { unexpectedBeforeAtSign, atSign: atSign, unexpectedBeforeAttributeName, - attributeName: RawIdentifierTypeSyntax(name: attributeName, genericArgumentClause: nil, arena: self.arena), + attributeName: RawIdentifierTypeSyntax( + moduleSelector: nil, + name: attributeName, + genericArgumentClause: nil, + arena: self.arena + ), leftParen: nil, arguments: nil, rightParen: nil, @@ -329,7 +338,9 @@ extension Parser { extension RawLabeledExprSyntax { fileprivate init( - _ unexpectedBeforeIdentifier: RawUnexpectedNodesSyntax? = nil, + _ unexpectedBeforeModuleSelector: RawUnexpectedNodesSyntax? = nil, + moduleSelector: RawModuleSelectorSyntax?, + _ unexpectedBetweenModuleSelectorAndIdentifier: RawUnexpectedNodesSyntax? = nil, identifier: RawTokenSyntax, _ unexpectedBetweenIdentifierAndTrailingComma: RawUnexpectedNodesSyntax? = nil, trailingComma: RawTokenSyntax? = nil, @@ -339,7 +350,9 @@ extension RawLabeledExprSyntax { label: nil, colon: nil, expression: RawDeclReferenceExprSyntax( - unexpectedBeforeIdentifier, + unexpectedBeforeModuleSelector, + moduleSelector: moduleSelector, + unexpectedBetweenModuleSelectorAndIdentifier, baseName: identifier, argumentNames: nil, arena: arena @@ -361,6 +374,7 @@ extension Parser { let roleTrailingComma = self.consume(if: .comma) let roleElement = RawLabeledExprSyntax( + moduleSelector: nil, unexpectedBeforeRole, identifier: role, trailingComma: roleTrailingComma, @@ -390,7 +404,12 @@ extension Parser { unexpectedBeforeAtSign, atSign: atSign, unexpectedBeforeDifferentiable, - attributeName: RawIdentifierTypeSyntax(name: differentiable, genericArgumentClause: nil, arena: self.arena), + attributeName: RawIdentifierTypeSyntax( + moduleSelector: nil, + name: differentiable, + genericArgumentClause: nil, + arena: self.arena + ), unexpectedBeforeLeftParen, leftParen: leftParen, arguments: .differentiableArguments(argument), @@ -531,8 +550,13 @@ extension Parser { return RawAttributeSyntax( unexpectedBeforeAtSign, atSign: atSign, - unexpectedBeforeDerivative, - attributeName: RawIdentifierTypeSyntax(name: derivative, genericArgumentClause: nil, arena: self.arena), + attributeName: RawIdentifierTypeSyntax( + moduleSelector: nil, + unexpectedBeforeDerivative, + name: derivative, + genericArgumentClause: nil, + arena: self.arena + ), unexpectedBeforeLeftParen, leftParen: leftParen, arguments: .derivativeRegistrationArguments(argument), @@ -554,7 +578,12 @@ extension Parser { unexpectedBeforeAtSign, atSign: atSign, unexpectedBeforeTranspose, - attributeName: RawIdentifierTypeSyntax(name: transpose, genericArgumentClause: nil, arena: self.arena), + attributeName: RawIdentifierTypeSyntax( + moduleSelector: nil, + name: transpose, + genericArgumentClause: nil, + arena: self.arena + ), unexpectedBeforeLeftParen, leftParen: leftParen, arguments: .derivativeRegistrationArguments(argument), @@ -609,8 +638,8 @@ extension Parser { var elements = [RawObjCSelectorPieceSyntax]() var loopProgress = LoopProgressCondition() while self.hasProgressed(&loopProgress) { - // Empty selector piece. - if let colon = self.consume(if: .colon) { + // Empty selector piece, splitting `::` into two colons. + if let colon = self.consume(ifPrefix: ":", as: .colon) { elements.append( RawObjCSelectorPieceSyntax( name: nil, @@ -634,7 +663,8 @@ extension Parser { break } - let (unexpectedBeforeColon, colon) = self.expect(.colon) + // Match ending colon, spliting `::` into two colons. + let (unexpectedBeforeColon, colon) = self.expect(prefix: ":", as: .colon) elements.append( RawObjCSelectorPieceSyntax( name: name, @@ -666,7 +696,11 @@ extension Parser { case (.target, let handle)?: let label = self.eat(handle) let (unexpectedBeforeColon, colon) = self.expect(.colon) - let declName = self.parseDeclReferenceExpr([.zeroArgCompoundNames, .keywordsUsingSpecialNames, .operators]) + let moduleSelector = self.parseModuleSelector() + let declName = self.parseDeclReferenceExpr( + moduleSelector: moduleSelector, + [.zeroArgCompoundNames, .keywordsUsingSpecialNames, .operators] + ) let comma = self.consume(if: .comma) elements.append( .specializeTargetFunctionArgument( @@ -719,7 +753,7 @@ extension Parser { case (.kind, let handle)?: let label = self.eat(handle) let (unexpectedBeforeColon, colon) = self.expect(.colon) - let valueLabel = self.parseAnyIdentifier() + let (unexpectedBeforeValue, value) = self.parseAnyIdentifier() let comma = self.consume(if: .comma) elements.append( .labeledSpecializeArgument( @@ -727,7 +761,8 @@ extension Parser { label: label, unexpectedBeforeColon, colon: colon, - value: valueLabel, + unexpectedBeforeValue, + value: value, trailingComma: comma, arena: self.arena ) @@ -737,7 +772,7 @@ extension Parser { (.spi, let handle)?: let label = self.eat(handle) let (unexpectedBeforeColon, colon) = self.expect(.colon) - let valueLabel = self.consumeAnyToken() + let (unexpectedBeforeValue, value) = self.expectIdentifier() let comma = self.consume(if: .comma) elements.append( .labeledSpecializeArgument( @@ -745,7 +780,8 @@ extension Parser { label: label, unexpectedBeforeColon, colon: colon, - value: valueLabel, + unexpectedBeforeValue, + value: value, trailingComma: comma, arena: self.arena ) @@ -769,14 +805,17 @@ extension Parser { mutating func parseImplementsAttributeArguments() -> RawImplementsAttributeArgumentsSyntax { let type = self.parseType() let (unexpectedBeforeComma, comma) = self.expect(.comma) - let declName = self.parseDeclReferenceExpr([ - .zeroArgCompoundNames, - .operators, - ]) + + // You can't put a module selector on the member name--it's meaningless because the member has to come from the + // same module as the protocol. + let moduleSelector = self.parseModuleSelector() + let declName = self.parseDeclReferenceExpr(moduleSelector: nil, [.zeroArgCompoundNames, .operators]) + return RawImplementsAttributeArgumentsSyntax( type: type, unexpectedBeforeComma, comma: comma, + unexpected(moduleSelector), declName: declName, arena: self.arena ) @@ -788,6 +827,7 @@ extension Parser { let (unexpectedBeforeIsolationKind, isolationKind) = self.expectIdentifier(allowKeywordsAsIdentifier: true) let isolationKindElement = RawLabeledExprSyntax( + moduleSelector: nil, unexpectedBeforeIsolationKind, identifier: isolationKind, arena: self.arena @@ -915,17 +955,21 @@ extension Parser { mutating func parseDynamicReplacementAttributeArguments() -> RawDynamicReplacementAttributeArgumentsSyntax { let (unexpectedBeforeLabel, label) = self.expect(.keyword(.for)) let (unexpectedBeforeColon, colon) = self.expect(.colon) + let declName: RawDeclReferenceExprSyntax if label.isMissing && colon.isMissing && self.atStartOfLine { declName = RawDeclReferenceExprSyntax( + moduleSelector: nil, baseName: RawTokenSyntax(missing: .identifier, arena: self.arena), argumentNames: nil, arena: self.arena ) } else { - declName = self.parseDeclReferenceExpr([ - .zeroArgCompoundNames, .keywordsUsingSpecialNames, .operators, - ]) + let moduleSelector = self.parseModuleSelector() + declName = self.parseDeclReferenceExpr( + moduleSelector: moduleSelector, + [.zeroArgCompoundNames, .keywordsUsingSpecialNames, .operators] + ) } return RawDynamicReplacementAttributeArgumentsSyntax( unexpectedBeforeLabel, @@ -990,7 +1034,7 @@ extension Parser { unexpectedBeforeValue = unexpected value = .token(token) case "metadata": - unexpectedBeforeValue = nil + unexpectedBeforeValue = unexpected(self.parseModuleSelector()) if let identifier = self.consume(if: .identifier) { value = .token(identifier) } else { diff --git a/Sources/SwiftParser/Declarations.swift b/Sources/SwiftParser/Declarations.swift index 6ffffd81438..7520ddbe663 100644 --- a/Sources/SwiftParser/Declarations.swift +++ b/Sources/SwiftParser/Declarations.swift @@ -163,6 +163,8 @@ extension TokenConsumer { } return true + case .rhs(let introducer): + return subparser.shouldParsePatternBinding(introducer: introducer) case .some(_): // All other decl start keywords unconditionally start a decl. return true @@ -378,11 +380,12 @@ extension Parser { } if self.currentToken.isEditorPlaceholder { - let placeholder = self.parseAnyIdentifier() + let (unexpectedBeforePlaceholder, placeholder) = self.parseAnyIdentifier() return RawDeclSyntax( RawMissingDeclSyntax( attributes: attrs.attributes, modifiers: attrs.modifiers, + unexpectedBeforePlaceholder, placeholder: placeholder, arena: self.arena ) @@ -429,7 +432,7 @@ extension Parser { ) -> RawImportDeclSyntax { let (unexpectedBeforeImportKeyword, importKeyword) = self.eat(handle) let kind = self.parseImportKind() - let path = self.parseImportPath() + let path = self.parseImportPath(hasImportKind: kind != nil) return RawImportDeclSyntax( attributes: attrs.attributes, modifiers: attrs.modifiers, @@ -445,16 +448,26 @@ extension Parser { return self.consume(ifAnyIn: ImportDeclSyntax.ImportKindSpecifierOptions.self) } - mutating func parseImportPath() -> RawImportPathComponentListSyntax { + mutating func parseImportPath(hasImportKind: Bool) -> RawImportPathComponentListSyntax { var elements = [RawImportPathComponentSyntax]() var keepGoing: RawTokenSyntax? = nil var loopProgress = LoopProgressCondition() repeat { - let name = self.parseAnyIdentifier() - keepGoing = self.consume(if: .period) + let (unexpectedBeforeName, name) = self.parseAnyIdentifier(consumingModuleSelector: false) + keepGoing = self.consume(ifAnyIn: ImportPathComponentSyntax.TrailingPeriodOptions.self) + + // If we got `::` when it's not allowed, reject it + var unexpectedBeforeTrailingPeriod: RawUnexpectedNodesSyntax? + if keepGoing?.tokenKind == .colonColon && !hasImportKind { + unexpectedBeforeTrailingPeriod = RawUnexpectedNodesSyntax([keepGoing], arena: self.arena) + keepGoing = missingToken(.period) + } + elements.append( RawImportPathComponentSyntax( + unexpectedBeforeName, name: name, + unexpectedBeforeTrailingPeriod, trailingPeriod: keepGoing, arena: self.arena ) @@ -604,6 +617,7 @@ extension Parser { unexpectedBeforeInherited = RawUnexpectedNodesSyntax([classKeyword], arena: self.arena) inherited = RawTypeSyntax( RawIdentifierTypeSyntax( + moduleSelector: nil, name: missingToken(.identifier, text: "AnyObject"), genericArgumentClause: nil, arena: self.arena @@ -1302,7 +1316,7 @@ extension Parser { (unexpectedBeforeIdentifier, identifier) = self.expectIdentifier(keywordRecovery: true) if currentToken.isEditorPlaceholder { - let editorPlaceholder = self.parseAnyIdentifier() + let (_, editorPlaceholder) = self.parseAnyIdentifier() unexpectedAfterIdentifier = RawUnexpectedNodesSyntax([editorPlaceholder], arena: self.arena) } else { unexpectedAfterIdentifier = nil @@ -2188,11 +2202,15 @@ extension Parser { ) pound = pound.tokenView.withTokenDiagnostic(tokenDiagnostic: diagnostic, arena: self.arena) } + + let moduleSelector: RawModuleSelectorSyntax? let unexpectedBeforeMacro: RawUnexpectedNodesSyntax? let macro: RawTokenSyntax if !self.atStartOfLine { + moduleSelector = self.parseModuleSelector() (unexpectedBeforeMacro, macro) = self.expectIdentifier(allowKeywordsAsIdentifier: true) } else { + moduleSelector = nil unexpectedBeforeMacro = nil macro = self.missingToken(.identifier) } @@ -2240,6 +2258,7 @@ extension Parser { modifiers: attrs.modifiers, unexpectedBeforePound, pound: pound, + moduleSelector: moduleSelector, unexpectedBeforeMacro, macroName: macro, genericArgumentClause: generics, diff --git a/Sources/SwiftParser/Expressions.swift b/Sources/SwiftParser/Expressions.swift index 70e2a433f56..0309a304d0c 100644 --- a/Sources/SwiftParser/Expressions.swift +++ b/Sources/SwiftParser/Expressions.swift @@ -18,6 +18,12 @@ extension TokenConsumer { mutating func atStartOfExpression() -> Bool { + if self.isAtModuleSelector() { + var lookahead = self.lookahead() + _ = lookahead.consumeModuleSelectorTokens() + return lookahead.atStartOfExpression() + } + switch self.at(anyIn: ExpressionStart.self) { case (.awaitTryMove, let handle)?: var lookahead = self.lookahead() @@ -572,6 +578,11 @@ extension Parser { flavor: ExprFlavor, pattern: PatternContext = .none ) -> RawExprSyntax { + if let moduleSelector = self.parseModuleSelector() { + let qualifiedExpr = self.parseUnaryExpression(flavor: flavor, pattern: pattern) + return attach(moduleSelector, to: qualifiedExpr) + } + // Try parse a single value statement as an expression (e.g do/if/switch). // Note we do this here in parseUnaryExpression as we don't allow postfix // syntax to be attached to such expressions to avoid ambiguities such as postfix @@ -652,6 +663,7 @@ extension Parser { if skipMemberName { let missingIdentifier = missingToken(.identifier) let declName = RawDeclReferenceExprSyntax( + moduleSelector: nil, baseName: missingIdentifier, argumentNames: nil, arena: self.arena @@ -659,18 +671,22 @@ extension Parser { return (unexpectedPeriod, period, declName, nil) } + let moduleSelector = parseModuleSelector() + // Parse the name portion. let declName: RawDeclReferenceExprSyntax if let indexOrSelf = self.consume(if: .integerLiteral, .keyword(.self)) { // Handle "x.42" - a tuple index. declName = RawDeclReferenceExprSyntax( + unexpected(moduleSelector), + moduleSelector: nil, baseName: indexOrSelf, argumentNames: nil, arena: self.arena ) } else { // Handle an arbitrary declaration name. - declName = self.parseDeclReferenceExpr([.keywords, .compoundNames]) + declName = self.parseDeclReferenceExpr(moduleSelector: moduleSelector, [.keywords, .compoundNames]) } // Parse the generic arguments, if any. @@ -1246,11 +1262,11 @@ extension Parser { // is the start of an enum or expr pattern. if pattern.admitsBinding && self.lookahead().isInBindingPatternPosition() { let identifier = self.eat(handle) - let pattern = RawIdentifierPatternSyntax( + let patternNode = RawIdentifierPatternSyntax( identifier: identifier, arena: self.arena ) - return RawExprSyntax(RawPatternExprSyntax(pattern: pattern, arena: self.arena)) + return RawExprSyntax(RawPatternExprSyntax(pattern: patternNode, arena: self.arena)) } return self.parseIdentifierExpression(flavor: flavor) @@ -1276,6 +1292,7 @@ extension Parser { let poundAvailable = self.parsePoundAvailableConditionElement() return RawExprSyntax( RawDeclReferenceExprSyntax( + moduleSelector: nil, RawUnexpectedNodesSyntax([poundAvailable], arena: self.arena), baseName: missingToken(.identifier), argumentNames: nil, @@ -1313,7 +1330,10 @@ extension Parser { ) } - let declName = self.parseDeclReferenceExpr([.keywords, .compoundNames]) + // If there's a module selector after the period, parse and use it. + let moduleSelector = self.parseModuleSelector() + let declName = self.parseDeclReferenceExpr(moduleSelector: moduleSelector, [.keywords, .compoundNames]) + return RawExprSyntax( RawMemberAccessExprSyntax( base: nil, @@ -1351,7 +1371,8 @@ extension Parser { case .attributeArguments: options.insert(.keywordsUsingSpecialNames) } - let declName = self.parseDeclReferenceExpr(options) + // If something up the call stack has parsed a module selector, it will be attached using `attach(_:to:)`. + let declName = self.parseDeclReferenceExpr(moduleSelector: nil, options) guard self.withLookahead({ $0.canParseAsGenericArgumentList() }) else { return RawExprSyntax(declName) } @@ -1382,6 +1403,7 @@ extension Parser { ) pound = pound.tokenView.withTokenDiagnostic(tokenDiagnostic: diagnostic, arena: self.arena) } + let moduleSelector = parseModuleSelector() let unexpectedBeforeMacroName: RawUnexpectedNodesSyntax? let macroName: RawTokenSyntax if !self.atStartOfLine { @@ -1429,6 +1451,7 @@ extension Parser { return RawMacroExpansionExprSyntax( unexpectedBeforePound, pound: pound, + moduleSelector: moduleSelector, unexpectedBeforeMacroName, macroName: macroName, genericArgumentClause: generics, @@ -1742,7 +1765,9 @@ extension Parser { extension Parser { mutating func parseAnonymousClosureArgument() -> RawDeclReferenceExprSyntax { let (unexpectedBeforeBaseName, baseName) = self.expect(.dollarIdentifier) + // If something up the call stack has parsed a module selector, it will be attached using `attach(_:to:)`. return RawDeclReferenceExprSyntax( + moduleSelector: nil, unexpectedBeforeBaseName, baseName: baseName, argumentNames: nil, @@ -1874,14 +1899,7 @@ extension Parser { // Parse identifier (',' identifier)* var keepGoing: RawTokenSyntax? = nil repeat { - let unexpected: RawUnexpectedNodesSyntax? - let name: RawTokenSyntax - if let identifier = self.consume(if: .identifier) { - unexpected = nil - name = identifier - } else { - (unexpected, name) = self.expect(.wildcard) - } + let (unexpected, name) = self.expect(.identifier, .wildcard, default: .identifier) keepGoing = consume(if: .comma) params.append( RawClosureShorthandParameterSyntax( @@ -1964,6 +1982,14 @@ extension Parser { } } +extension TokenConsumer { + mutating func atBinaryOperatorArgument() -> Bool { + var lookahead = self.lookahead() + _ = lookahead.consumeModuleSelectorTokens() + return lookahead.at(.binaryOperator) && lookahead.peek(isAt: .comma, .rightParen, .rightSquare) + } +} + extension Parser { /// Parse the elements of an argument list. /// @@ -1998,7 +2024,7 @@ extension Parser { let unexpectedBeforeLabel: RawUnexpectedNodesSyntax? let label: RawTokenSyntax? let colon: RawTokenSyntax? - if self.atArgumentLabel(allowDollarIdentifier: true) && self.peek(isAt: .colon) { + if self.atArgumentLabel(allowDollarIdentifier: true, followedByColon: true) { (unexpectedBeforeLabel, label) = parseArgumentLabel() colon = consumeAnyToken() } else if let _colon = self.consume(if: .colon) { @@ -2015,8 +2041,9 @@ extension Parser { // this case lexes as a binary operator because it neither leads nor // follows a proper subexpression. let expr: RawExprSyntax - if self.at(.binaryOperator) && self.peek(isAt: .comma, .rightParen, .rightSquare) { - expr = RawExprSyntax(self.parseDeclReferenceExpr(.operators)) + if self.atBinaryOperatorArgument() { + let moduleSelector = self.parseModuleSelector() + expr = RawExprSyntax(self.parseDeclReferenceExpr(moduleSelector: moduleSelector, .operators)) } else { expr = self.parseExpression(flavor: flavor, pattern: pattern) } @@ -2080,9 +2107,8 @@ extension Parser.Lookahead { // Fast path: the next two tokens must be a label and a colon. // But 'default:' is ambiguous with switch cases and we disallow it // (unless escaped) even outside of switches. - if !self.atArgumentLabel() + if !self.atArgumentLabel(followedByColon: true) || self.at(.keyword(.default)) - || self.peek().rawTokenKind != .colon { return false } @@ -2395,8 +2421,13 @@ extension Parser { unknownAttr = RawAttributeSyntax( atSign: at, - unexpectedBeforeIdent, - attributeName: RawIdentifierTypeSyntax(name: ident, genericArgumentClause: nil, arena: self.arena), + attributeName: RawIdentifierTypeSyntax( + moduleSelector: nil, + unexpectedBeforeIdent, + name: ident, + genericArgumentClause: nil, + arena: self.arena + ), leftParen: nil, arguments: nil, rightParen: nil, @@ -2577,6 +2608,7 @@ extension Parser.Lookahead { } } else if lookahead.at(.identifier) || lookahead.at(.wildcard) { // Parse identifier (',' identifier)* + _ = lookahead.consumeModuleSelectorTokens() lookahead.consumeAnyToken() /// If the next token is a colon, interpret is as a type annotation and consume a type after it. @@ -2593,6 +2625,7 @@ extension Parser.Lookahead { while consumeOptionalTypeAnnotation() && lookahead.consume(if: .comma) != nil && lookahead.hasProgressed(¶metersProgress) { + _ = lookahead.consumeModuleSelectorTokens() if lookahead.at(.identifier) || lookahead.at(.wildcard) { lookahead.consumeAnyToken() continue diff --git a/Sources/SwiftParser/Lexer/Cursor.swift b/Sources/SwiftParser/Lexer/Cursor.swift index 24262fbbbab..2ea3fd85848 100644 --- a/Sources/SwiftParser/Lexer/Cursor.swift +++ b/Sources/SwiftParser/Lexer/Cursor.swift @@ -255,6 +255,8 @@ extension Lexer { } var position: Position + var experimentalFeatures: Parser.ExperimentalFeatures + /// If we have already lexed a token, the kind of the previously lexed token var previousTokenKind: RawTokenKind? @@ -267,8 +269,9 @@ extension Lexer { private var stateStack: StateStack = StateStack() - init(input: UnsafeBufferPointer, previous: UInt8) { + init(input: UnsafeBufferPointer, previous: UInt8, experimentalFeatures: Parser.ExperimentalFeatures) { self.position = Position(input: input, previous: previous) + self.experimentalFeatures = experimentalFeatures } /// Returns `true` if this cursor is sufficiently different to `other` in a way that indicates that the lexer has @@ -940,9 +943,17 @@ extension Lexer.Cursor { case ",": _ = self.advance(); return Lexer.Result(.comma) case ";": _ = self.advance(); return Lexer.Result(.semicolon) - case ":": _ = self.advance(); return Lexer.Result(.colon) case "\\": _ = self.advance(); return Lexer.Result(.backslash) + case ":": + _ = self.advance() + guard self.experimentalFeatures.contains(.moduleSelector) && self.peek() == ":" else { + return Lexer.Result(.colon) + } + + _ = self.advance() + return Lexer.Result(.colonColon) + case "#": // Try lex shebang. if self.isAtStartOfFile, self.peek(at: 1) == "!" { @@ -2472,7 +2483,7 @@ extension Lexer.Cursor { return false } - guard let end = Self.findConflictEnd(start, markerKind: kind) else { + guard let end = Self.findConflictEnd(start, markerKind: kind, experimentalFeatures: experimentalFeatures) else { // No end of conflict marker found. return false } @@ -2488,13 +2499,18 @@ extension Lexer.Cursor { } /// Find the end of a version control conflict marker. - static func findConflictEnd(_ curPtr: Lexer.Cursor, markerKind: ConflictMarker) -> Lexer.Cursor? { + static func findConflictEnd( + _ curPtr: Lexer.Cursor, + markerKind: ConflictMarker, + experimentalFeatures: Parser.ExperimentalFeatures + ) -> Lexer.Cursor? { // Get a reference to the rest of the buffer minus the length of the start // of the conflict marker. let advanced = curPtr.input.baseAddress?.advanced(by: markerKind.introducer.count) var restOfBuffer = Lexer.Cursor( input: .init(start: advanced, count: curPtr.input.count - markerKind.introducer.count), - previous: curPtr.input[markerKind.introducer.count - 1] + previous: curPtr.input[markerKind.introducer.count - 1], + experimentalFeatures: experimentalFeatures ) let terminator = markerKind.terminator let terminatorStart = terminator.first! @@ -2515,7 +2531,8 @@ extension Lexer.Cursor { let advanced = restOfBuffer.input.baseAddress?.advanced(by: terminator.count) return Lexer.Cursor( input: .init(start: advanced, count: restOfBuffer.input.count - terminator.count), - previous: restOfBuffer.input[terminator.count - 1] + previous: restOfBuffer.input[terminator.count - 1], + experimentalFeatures: experimentalFeatures ) } return nil diff --git a/Sources/SwiftParser/Lexer/LexemeSequence.swift b/Sources/SwiftParser/Lexer/LexemeSequence.swift index e64d976f12d..1f9950aae18 100644 --- a/Sources/SwiftParser/Lexer/LexemeSequence.swift +++ b/Sources/SwiftParser/Lexer/LexemeSequence.swift @@ -152,12 +152,21 @@ extension Lexer { public static func tokenize( _ input: UnsafeBufferPointer, from startIndex: Int = 0, - lookaheadTracker: UnsafeMutablePointer + lookaheadTracker: UnsafeMutablePointer, + experimentalFeatures: Parser.ExperimentalFeatures ) -> LexemeSequence { precondition(input.isEmpty || startIndex < input.endIndex) let startChar = startIndex == input.startIndex ? UInt8(ascii: "\0") : input[startIndex - 1] - let start = Cursor(input: input, previous: UInt8(ascii: "\0")) - let cursor = Cursor(input: UnsafeBufferPointer(rebasing: input[startIndex...]), previous: startChar) - return LexemeSequence(sourceBufferStart: start, cursor: cursor, lookaheadTracker: lookaheadTracker) + let start = Cursor(input: input, previous: UInt8(ascii: "\0"), experimentalFeatures: experimentalFeatures) + let cursor = Cursor( + input: UnsafeBufferPointer(rebasing: input[startIndex...]), + previous: startChar, + experimentalFeatures: experimentalFeatures + ) + return LexemeSequence( + sourceBufferStart: start, + cursor: cursor, + lookaheadTracker: lookaheadTracker + ) } } diff --git a/Sources/SwiftParser/Lexer/RegexLiteralLexer.swift b/Sources/SwiftParser/Lexer/RegexLiteralLexer.swift index c5c565405cd..227b06a27b8 100644 --- a/Sources/SwiftParser/Lexer/RegexLiteralLexer.swift +++ b/Sources/SwiftParser/Lexer/RegexLiteralLexer.swift @@ -643,6 +643,10 @@ extension Lexer.Cursor { case .identifier, .dollarIdentifier, .wildcard: return false + // Module selectors are allowed before an operator, but not a regex. + case .colonColon: + return false + // Literals are themselves expressions and therefore don't sequence expressions. case .floatLiteral, .integerLiteral: return false @@ -737,7 +741,7 @@ extension Lexer.Cursor { // an unapplied operator is legal, and we should prefer to lex as that // instead. switch previousTokenKind { - case .leftParen, .leftSquare, .comma, .colon: + case .leftParen, .leftSquare, .comma, .colon, .colonColon: break default: mustBeRegex = true diff --git a/Sources/SwiftParser/Names.swift b/Sources/SwiftParser/Names.swift index 3a9efe5878f..cd09f3c0484 100644 --- a/Sources/SwiftParser/Names.swift +++ b/Sources/SwiftParser/Names.swift @@ -11,40 +11,373 @@ //===----------------------------------------------------------------------===// #if compiler(>=6) -@_spi(RawSyntax) internal import SwiftSyntax +@_spi(ExperimentalLanguageFeatures) @_spi(RawSyntax) internal import SwiftSyntax #else -@_spi(RawSyntax) import SwiftSyntax +@_spi(ExperimentalLanguageFeatures) @_spi(RawSyntax) import SwiftSyntax #endif extension Parser { - mutating func parseAnyIdentifier() -> RawTokenSyntax { + /// Parse an identifier or operator. + /// + /// - Note: If you expect a module selector, parse it before calling this method; it will consume module selectors + /// as unexpected syntax. + mutating func parseAnyIdentifier(consumingModuleSelector: Bool = true) -> (RawUnexpectedNodesSyntax?, RawTokenSyntax) + { + let moduleSelector = consumingModuleSelector ? unexpected(self.parseModuleSelector()) : nil if let token = self.consume(if: .identifier) { - return token + return (moduleSelector, token) } else if let (_, handle) = self.at(anyIn: Operator.self) { - return self.eat(handle) + return (moduleSelector, self.eat(handle)) } else { - return RawTokenSyntax(missing: .identifier, arena: arena) + return (moduleSelector, RawTokenSyntax(missing: .identifier, arena: arena)) } } mutating func parseArgumentLabel() -> (RawUnexpectedNodesSyntax?, RawTokenSyntax) { + let unexpectedSelector = unexpected(self.parseModuleSelector()) guard self.atArgumentLabel(allowDollarIdentifier: true) else { - return (nil, missingToken(.identifier)) + return (unexpectedSelector, missingToken(.identifier)) } if let dollarIdent = self.consume(if: .dollarIdentifier) { return ( - RawUnexpectedNodesSyntax([dollarIdent], arena: self.arena), + RawUnexpectedNodesSyntax(combining: unexpectedSelector, dollarIdent, arena: self.arena), self.missingToken(.identifier) ) } else { if let wildcardToken = self.consume(if: .wildcard) { - return (nil, wildcardToken) + return (unexpectedSelector, wildcardToken) } - return (nil, self.consumeAnyToken(remapping: .identifier)) + return (unexpectedSelector, self.consumeAnyToken(remapping: .identifier)) } } } +private enum StructuralTokens: TokenSpecSet { + case comma + case colon + case leftParen + case leftBrace + case leftSquare + case leftAngle + case rightParen + case rightBrace + case rightSquare + case rightAngle + + init?(lexeme: Lexer.Lexeme, experimentalFeatures: Parser.ExperimentalFeatures) { + self.init(lexeme.rawTokenKind) + } + + init?(_ rawTokenKind: RawTokenKind) { + switch rawTokenKind { + case .comma: self = .comma + case .colon: self = .colon + case .leftParen: self = .leftParen + case .leftBrace: self = .leftBrace + case .leftSquare: self = .leftSquare + case .leftAngle: self = .leftAngle + case .rightParen: self = .rightParen + case .rightBrace: self = .rightBrace + case .rightSquare: self = .rightSquare + case .rightAngle: self = .rightAngle + default: return nil + } + } + + var spec: TokenSpec { + switch self { + case .comma: return .comma + case .colon: return .colon + case .leftParen: return .leftParen + case .leftBrace: return .leftBrace + case .leftSquare: return .leftSquare + case .leftAngle: return .leftAngle + case .rightParen: return .rightParen + case .rightBrace: return .rightBrace + case .rightSquare: return .rightSquare + case .rightAngle: return .rightAngle + } + } +} + +extension TokenConsumer { + /// Do the subsequent tokens have the form of a module selector? Encompasses some invalid syntax which nonetheless + /// can be handled by `consumeModuleSelectorTokens()`. + /// + /// - Postcondition: If `true`, either the current token or the next token is `.colonColon`. + mutating func isAtModuleSelector() -> Bool { + // If this is a module selector, the next token should be `::`. + guard self.peek(isAt: .colonColon) else { + // ...however, we will also allow the *current* token to be `::`. `consumeModuleSelectorTokens()` will create a + // missing identifier. + return self.at(.colonColon) + } + + // Technically the current token *should* be an identifier, but we also want to diagnose other tokens that might be + // used by accident (particularly keywords and `_`). However, we don't want to consume tokens which would make the + // surrounding structure mis-parse. + return self.at(anyIn: StructuralTokens.self) == nil + } + + mutating func unlessPeekModuleSelector(_ operation: (inout Self) -> T?) -> T? { + var lookahead = self.lookahead() + lookahead.skipSingle() + if lookahead.isAtModuleSelector() { + return nil + } + return operation(&self) + } + + typealias ModuleSelectorTokens = ( + moduleNameOrUnexpected: Token, colonColonToken: Token, extra: [Token] + ) + + /// If the subsequent tokens have the form of a module selector, valid or otherwise, consume and return them; + /// otherwise consume nothing and return `nil`. Additionally consumes invalid chained module selectors. + /// + /// Returns a tuple comprised of: + /// + /// - `moduleNameOrUnexpected`: The module name if present; in a valid module selector, this will be a present + /// identifier, but either of those can be untrue in invalid code. + /// - `colonColonToken`: The `::` indicating this module selector. Always `.colonColon`, always present. + /// - `extra`: Tokens for additional trailing module selectors. There is no situation in which two module selectors + /// can be validly chained. + mutating func consumeModuleSelectorTokens() -> ModuleSelectorTokens? { + guard self.isAtModuleSelector() else { + return nil + } + + let moduleName: Token + let colonColonToken: Token + + // Did we forget the module name? + if let earlyColonColon = self.consume(if: .colonColon) { + moduleName = self.missingToken(.identifier) + colonColonToken = earlyColonColon + } else { + // Consume whatever comes before the `::`, plus the `::` itself. (Whether or not the "name" is an identifier is + // checked elsewhere.) + moduleName = self.consumeAnyToken() + colonColonToken = self.eat(.colonColon) + } + + var extra: [Token] = [] + while self.isAtModuleSelector() { + if !self.at(.colonColon) { + extra.append(self.consumeAnyToken()) + } + extra.append(self.eat(.colonColon)) + } + return (moduleName, colonColonToken, extra) + } +} + +private func tokens(in node: (some RawSyntaxNodeProtocol)?) -> [RawTokenSyntax] { + var tokens: [RawTokenSyntax] = [] + + func collect(from child: (some RawSyntaxNodeProtocol)?) { + guard let child else { return } + + guard let token = child.as(RawTokenSyntax.self) else { + for child in child.raw.layoutView!.children { + collect(from: child) + } + return + } + + if !token.isMissing { + tokens.append(token) + } + } + + collect(from: node) + + return tokens +} + +extension Parser { + /// Helper to form a module selector from a set of tokens, divorced from their source. + private mutating func makeModuleSelector(from tokens: ModuleSelectorTokens) -> RawModuleSelectorSyntax { + let leadingUnexpected: [RawSyntax] + let moduleName: RawTokenSyntax + let trailingUnexpected: [RawSyntax] + + if tokens.moduleNameOrUnexpected.tokenKind == .identifier { + leadingUnexpected = [] + moduleName = tokens.moduleNameOrUnexpected + } else { + leadingUnexpected = [RawSyntax(tokens.moduleNameOrUnexpected)] + moduleName = self.missingToken(.identifier) + } + + trailingUnexpected = tokens.extra.map { RawSyntax($0) } + + return RawModuleSelectorSyntax( + RawUnexpectedNodesSyntax(leadingUnexpected, arena: arena), + moduleName: moduleName, + colonColon: tokens.colonColonToken, + RawUnexpectedNodesSyntax(trailingUnexpected, arena: arena), + arena: arena + ) + } + + /// Parses one or more module selectors, if present. + mutating func parseModuleSelector() -> RawModuleSelectorSyntax? { + guard let tokens = consumeModuleSelectorTokens() else { + return nil + } + return makeModuleSelector(from: tokens) + } + + /// If possible, convert a ``RawUnexpectedNodesSyntax`` back into a module selector. Used in some specialized + /// recovery paths. + mutating func recoverModuleSelector( + from unexpected: RawUnexpectedNodesSyntax? + ) -> (unexpectedBeforeModuleSelector: RawUnexpectedNodesSyntax?, moduleSelector: RawModuleSelectorSyntax?) { + guard let unexpected, unexpected.containsToken(where: { $0.tokenKind == .colonColon }) else { + return (unexpected, nil) + } + + var remainingTokens = tokens(in: unexpected) + let selectorTokens: ModuleSelectorTokens + + // Everything after the first `::` should be either extra (invalid) module selectors or just random extra garbage + // we skipped during recovery. + let afterColonColonIndex = remainingTokens.firstIndex(where: { $0.tokenKind == .colonColon })! + 1 + selectorTokens.extra = Array(remainingTokens[afterColonColonIndex...]) + remainingTokens.removeSubrange(afterColonColonIndex...) + + selectorTokens.colonColonToken = remainingTokens.removeLast() + + // This matches logic from `consumeModuleSelectorTokens()` and `isAtModuleSelector()`. + if let tokenBeforeColonColon = remainingTokens.last, StructuralTokens(tokenBeforeColonColon.tokenKind) != nil { + selectorTokens.moduleNameOrUnexpected = tokenBeforeColonColon + remainingTokens.removeLast() + } else { + selectorTokens.moduleNameOrUnexpected = self.missingToken(.identifier) + } + + return ( + RawUnexpectedNodesSyntax(remainingTokens, arena: self.arena), + self.makeModuleSelector(from: selectorTokens) + ) + } + + /// Convert a raw syntax node to `RawUnexpectedNodesSyntax` by extracting its tokens. + func unexpected(_ node: (some RawSyntaxNodeProtocol)?) -> RawUnexpectedNodesSyntax? { + return RawUnexpectedNodesSyntax(tokens(in: node), arena: self.arena) + } + + /// Inject `moduleSelector` into `node`, its first child, its first child's first child, etc. If necessary, + /// `moduleSelector`'s tokens will be inserted into an unexpected syntax node rather than the selector itself being + /// inserted. This should only be called when `node` comes *immediately* after `moduleSelector`. + /// + /// Use this method to "prepend" a module selector to a tree of syntax nodes. Doing so can avoid threading the module + /// selector through a lot of code, which can consume a lot of stack space and be fairly error-prone. + /// + /// - Precondition: `node` must, at minimum, have a descendant with an unexpected nodes child; it therefore cannot be + /// a token or an empty collection. + func attach(_ moduleSelector: RawModuleSelectorSyntax?, to node: Node) -> Node { + guard let moduleSelector else { + return node + } + + /// Recursively walk `node` and its descendants, looking for a place to attach `moduleSelector`. + /// + /// - Returns: `nil` if no suitable attachment point was found inside `node`; otherwise, a copy of `node` with + /// `moduleSelector` or its tokens injected somewhere. + func rewrite(attachingTo node: ChildNode) -> ChildNode? { + // If we hit a token, we won't be able to insert here. The parent will have to take care of it. + guard let layout = node.raw.layoutView else { + return nil + } + + /// Returns a copy of `node` with the child at `index` replaced by `newChild`. + func makeNode(withChildAt index: Int, replacedBy newChild: (some RawSyntaxNodeProtocol)?) -> ChildNode { + return layout.replacingChild( + at: index, + with: newChild?.raw, + arena: self.arena + ).cast(ChildNode.self) + } + + // Try to incorporate `self` into `node` or one of its children in a node-specific way. + switch node.raw.kind { + case .token: + fatalError("should have early returned") + + case .moduleSelector: + // Don't try to insert within a module selector. + return nil + + case .unexpectedNodes: + // We can just insert `self` here. + return RawUnexpectedNodesSyntax( + combining: unexpected(moduleSelector), + node.cast(RawUnexpectedNodesSyntax.self), + arena: self.arena + )?.cast(ChildNode.self) + + case .declReferenceExpr, .identifierType, .missingExpr, .missingType: + // This node has an expected module selector at child 1. + let nodeUnexpectedBeforeModuleSelector = layout.children[0] + let nodeModuleSelector = layout.children[1] + + // If `node` doesn't already have a module selector or some unexpected syntax before one, attach + // `moduleSelector` there. + // + // Note: The `nodeModuleSelector` check here is defensive. It's probably impossible for only + // `nodeModuleSelector` to be non-nil because the `parseModuleSelector()` call that created `moduleSelector` + // should have consumed the tokens that would have gone into `nodeModuleSelector`. However, if it *does* turn + // out to be possible, we may want to insert `nodeModuleSelector` into + // `moduleSelector.unexpectedAfterColonColon` to get slightly nicer diagnostics. + if nodeUnexpectedBeforeModuleSelector == nil && nodeModuleSelector == nil { + return makeNode(withChildAt: 1, replacedBy: moduleSelector) + } + + default: + // Try to attach `moduleSelector` to the first suitable child. + func isInsertionPoint(_ child: RawSyntax?) -> Bool { + guard let child else { + return false + } + // Skip empty collections, but don't skip nodes with missing tokens (which are also `isEmpty`). + return !child.isEmpty || !child.kind.isSyntaxCollection + } + + if let childIndex = layout.children.firstIndex(where: isInsertionPoint(_:)), + let replacementChild = rewrite(attachingTo: layout.children[childIndex]!) + { + return makeNode(withChildAt: childIndex, replacedBy: replacementChild) + } + } + + // Last chance: If this is *not* a collection, child 0 is unexpected nodes; we can put `moduleSelector` there. + if !node.raw.kind.isSyntaxCollection { + assert(layout.children[0] == nil) + return makeNode(withChildAt: 0, replacedBy: unexpected(moduleSelector)) + } + + // Out of options. + return nil + } + + guard let rewrittenNode = rewrite(attachingTo: node) else { + // We should *never* parse a module selector and then have nothing to attach it to; if there's a situation where + // we do, we should not have parsed it in the first place. + preconditionFailure( + """ + No way to attach module selector to node! + Module selector: \(String(reflecting: moduleSelector)) + Attachment point: \(String(reflecting: node)) + """ + ) + } + + return rewrittenNode + } +} + extension Parser { struct DeclNameOptions: OptionSet { var rawValue: UInt8 @@ -67,7 +400,10 @@ extension Parser { static let zeroArgCompoundNames: Self = [.compoundNames, Self(rawValue: 1 << 5)] } - mutating func parseDeclReferenceExpr(_ flags: DeclNameOptions = []) -> RawDeclReferenceExprSyntax { + mutating func parseDeclReferenceExpr( + moduleSelector: RawModuleSelectorSyntax?, + _ flags: DeclNameOptions = [] + ) -> RawDeclReferenceExprSyntax { // Consume the base name. let base: RawTokenSyntax if let identOrSelf = self.consume(if: .identifier, .keyword(.self), .keyword(.Self)) @@ -89,6 +425,7 @@ extension Parser { // Parse an argument list, if the flags allow it and it's present. let args = self.parseArgLabelList(flags) return RawDeclReferenceExprSyntax( + moduleSelector: moduleSelector, baseName: base, argumentNames: args, arena: self.arena @@ -129,7 +466,7 @@ extension Parser { var loopProgress = LoopProgressCondition() while !self.at(.endOfFile, .rightParen) && self.hasProgressed(&loopProgress) { // Check to see if there is an argument label. - precondition(self.atArgumentLabel() && self.peek(isAt: .colon)) + precondition(self.atArgumentLabel(followedByColon: true)) let name = self.consumeAnyToken() let (unexpectedBeforeColon, colon) = self.expect(.colon) elements.append( @@ -167,11 +504,11 @@ extension Parser { period = nil } - let declName = self.parseDeclReferenceExpr([ - .zeroArgCompoundNames, - .keywordsUsingSpecialNames, - .operators, - ]) + let moduleSelector = self.parseModuleSelector() + let declName = self.parseDeclReferenceExpr( + moduleSelector: moduleSelector, + [.zeroArgCompoundNames, .keywordsUsingSpecialNames, .operators] + ) if let period = period { return RawExprSyntax( RawMemberAccessExprSyntax( @@ -187,41 +524,31 @@ extension Parser { } mutating func parseQualifiedTypeIdentifier() -> RawTypeSyntax { - if self.at(.keyword(.Any)) { - return RawTypeSyntax(self.parseAnyType()) - } + let moduleSelector = self.parseModuleSelector() + let identifierType = attach(moduleSelector, to: self.parseTypeIdentifier()) + var result = RawTypeSyntax(identifierType) - let (unexpectedBeforeName, name) = self.expect(anyIn: IdentifierTypeSyntax.NameOptions.self, default: .identifier) - let generics: RawGenericArgumentClauseSyntax? - if self.at(prefix: "<") { - generics = self.parseGenericArguments() - } else { - generics = nil + // There are no nested types inside `Any`. + if case TokenSpec.keyword(.Any) = identifierType.name { + return result } - var result = RawTypeSyntax( - RawIdentifierTypeSyntax( - unexpectedBeforeName, - name: name, - genericArgumentClause: generics, - arena: self.arena - ) - ) + func hasAnotherMember() -> Bool { + // If qualified name base type cannot be parsed from the current + // point (i.e. the next type identifier is not followed by a '.'), + // then the next identifier is the final declaration name component. + var lookahead = self.lookahead() + return lookahead.consume(ifPrefix: ".", as: .period) != nil && lookahead.canParseBaseTypeForQualifiedDeclName() + } - // If qualified name base type cannot be parsed from the current - // point (i.e. the next type identifier is not followed by a '.'), - // then the next identifier is the final declaration name component. - var lookahead = self.lookahead() - guard - lookahead.consume(ifPrefix: ".", as: .period) != nil, - lookahead.canParseBaseTypeForQualifiedDeclName() - else { + guard hasAnotherMember() else { return result } var keepGoing = self.consume(if: .period) var loopProgress = LoopProgressCondition() while keepGoing != nil && self.hasProgressed(&loopProgress) { + let memberModuleSelector = self.parseModuleSelector() let (unexpectedBeforeName, name) = self.expect( .identifier, .keyword(.self), @@ -238,6 +565,7 @@ extension Parser { RawMemberTypeSyntax( baseType: result, period: keepGoing!, + moduleSelector: memberModuleSelector, unexpectedBeforeName, name: name, genericArgumentClause: generics, @@ -245,14 +573,7 @@ extension Parser { ) ) - // If qualified name base type cannot be parsed from the current - // point (i.e. the next type identifier is not followed by a '.'), - // then the next identifier is the final declaration name component. - var lookahead = self.lookahead() - guard - lookahead.consume(ifPrefix: ".", as: .period) != nil, - lookahead.canParseBaseTypeForQualifiedDeclName() - else { + guard hasAnotherMember() else { break } @@ -266,6 +587,7 @@ extension Parser { extension Parser.Lookahead { func canParseBaseTypeForQualifiedDeclName() -> Bool { var lookahead = self.lookahead() + _ = lookahead.consumeModuleSelectorTokens() guard lookahead.canParseTypeIdentifier() else { return false } @@ -283,7 +605,7 @@ extension Parser.Lookahead { var loopProgress = LoopProgressCondition() while !lookahead.at(.endOfFile, .rightParen) && lookahead.hasProgressed(&loopProgress) { // Check to see if there is an argument label. - guard lookahead.atArgumentLabel() && lookahead.peek().rawTokenKind == .colon else { + guard lookahead.atArgumentLabel(followedByColon: true) else { return false } diff --git a/Sources/SwiftParser/Parameters.swift b/Sources/SwiftParser/Parameters.swift index 1a40901237b..b72239544d7 100644 --- a/Sources/SwiftParser/Parameters.swift +++ b/Sources/SwiftParser/Parameters.swift @@ -129,8 +129,11 @@ extension Parser { secondName.tokenText.isStartingWithUppercase { // Synthesize the secondName parameter as a type node. + let (stillUnexpected, moduleSelector) = recoverModuleSelector(from: names.unexpectedBeforeSecondName) type = RawTypeSyntax( RawIdentifierTypeSyntax( + stillUnexpected, + moduleSelector: moduleSelector, name: secondName, genericArgumentClause: nil, arena: self.arena @@ -297,16 +300,31 @@ extension Parser { // MARK: - Parameter Modifiers extension Parser { + mutating func canParseParameterModifier() -> Bool { + var lookahead = self.lookahead() + _ = lookahead.consumeModuleSelectorTokens() + return lookahead.at(anyIn: ParameterModifier.self) != nil + } + mutating func parseParameterModifiers(isClosure: Bool) -> RawDeclModifierListSyntax { var elements = [RawDeclModifierSyntax]() var loopProgress = LoopProgressCondition() while self.hasProgressed(&loopProgress) { - guard let match = self.at(anyIn: ParameterModifier.self), + + guard self.canParseParameterModifier(), !withLookahead({ $0.startsParameterName(isClosure: isClosure, allowMisplacedSpecifierRecovery: false) }) else { break } - elements.append(RawDeclModifierSyntax(name: self.eat(match.handle), detail: nil, arena: self.arena)) + let moduleSelector = self.parseModuleSelector() + elements.append( + RawDeclModifierSyntax( + unexpected(moduleSelector), + name: self.eat(self.at(anyIn: ParameterModifier.self)!.handle), + detail: nil, + arena: self.arena + ) + ) } if elements.isEmpty { return self.emptyCollection(RawDeclModifierListSyntax.self) diff --git a/Sources/SwiftParser/Parser.swift b/Sources/SwiftParser/Parser.swift index 6d6e8b37cb3..62dc7312626 100644 --- a/Sources/SwiftParser/Parser.swift +++ b/Sources/SwiftParser/Parser.swift @@ -240,7 +240,11 @@ public struct Parser { self.experimentalFeatures = experimentalFeatures self.lookaheadTrackerOwner = LookaheadTrackerOwner() - self.lexemes = Lexer.tokenize(input, lookaheadTracker: lookaheadTrackerOwner.lookaheadTracker) + self.lexemes = Lexer.tokenize( + input, + lookaheadTracker: lookaheadTrackerOwner.lookaheadTracker, + experimentalFeatures: experimentalFeatures + ) self.currentToken = self.lexemes.advance() if let parseTransition { self.parseLookup = IncrementalParseLookup(transition: parseTransition) @@ -556,19 +560,21 @@ extension Parser { /// Implements the paradigm shared across all `expect` methods. @inline(__always) private mutating func expectImpl( + skipUnexpectedModuleSelector: Bool = true, consume: (inout Parser) -> RawTokenSyntax?, canRecoverTo: (inout Lookahead) -> RecoveryConsumptionHandle?, makeMissing: (inout Parser) -> RawTokenSyntax ) -> (unexpected: RawUnexpectedNodesSyntax?, token: RawTokenSyntax) { + let unexpectedSelector = skipUnexpectedModuleSelector ? unexpected(self.parseModuleSelector()) : nil if let tok = consume(&self) { - return (nil, tok) + return (unexpectedSelector, tok) } var lookahead = self.lookahead() if let handle = canRecoverTo(&lookahead) { let (unexpectedTokens, token) = self.eat(handle) - return (unexpectedTokens, token) + return (RawUnexpectedNodesSyntax(combining: unexpectedSelector, unexpectedTokens, arena: self.arena), token) } - return (nil, makeMissing(&self)) + return (unexpectedSelector, makeMissing(&self)) } /// Attempts to consume a token that matches the given `spec`. @@ -577,6 +583,8 @@ extension Parser { /// specified by `spec` and see if the token occurs after that unexpected. /// 2. If the token couldn't be found after skipping unexpected, it synthesizes /// a missing token of the requested kind. + /// - Note: If you expect a module selector, parse it before calling this method; it will consume module selectors + /// as unexpected syntax. @inline(__always) mutating func expect( _ spec: TokenSpec @@ -595,6 +603,8 @@ extension Parser { /// kinds occurs after the unexpected. /// 2. If the token couldn't be found after skipping unexpected, it synthesizes /// a missing token of `defaultKind`. + /// - Note: If you expect a module selector, parse it before calling this method; it will consume module selectors + /// as unexpected syntax. @inline(__always) mutating func expect( _ spec1: TokenSpec, @@ -615,6 +625,8 @@ extension Parser { /// kinds occurs after the unexpected. /// 2. If the token couldn't be found after skipping unexpected, it synthesizes /// a missing token of `defaultKind`. + /// - Note: If you expect a module selector, parse it before calling this method; it will consume module selectors + /// as unexpected syntax. @inline(__always) mutating func expect( _ spec1: TokenSpec, @@ -629,6 +641,15 @@ extension Parser { ) } + /// Attempts to consume a token that matches the given `specSet`. + /// If it cannot be found, the parser tries + /// 1. To eat unexpected tokens that have lower ``TokenPrecedence`` than the + /// lowest precedence of the spec and see if a token of the requested + /// kinds occurs after the unexpected. + /// 2. If the token couldn't be found after skipping unexpected, it synthesizes + /// a missing token of `defaultKind`. + /// - Note: If you expect a module selector, parse it before calling this method; it will consume module selectors + /// as unexpected syntax. @inline(__always) mutating func expect( anyIn specSet: SpecSet.Type, @@ -641,6 +662,29 @@ extension Parser { ) } + /// Attempts to consume a token starting with the given `prefix` and forming it into `tokenKind`. + /// If it cannot be found, the parser tries + /// 1. To eat unexpected tokens that have lower ``TokenPrecedence`` than + /// specified by `TokenSpec(tokenKind)` and see if the token occurs after that unexpected. + /// 2. If the token couldn't be found after skipping unexpected, it synthesizes + /// a missing token of the requested kind. + /// - Note: If you expect a module selector, parse it before calling this method; it will consume module selectors + /// as unexpected syntax (except when used to split a colon). + @inline(__always) + mutating func expect( + prefix: SyntaxText, + as tokenKind: RawTokenKind + ) -> (unexpected: RawUnexpectedNodesSyntax?, token: RawTokenSyntax) { + let spec = TokenSpec(tokenKind) + return expectImpl( + // Don't consume a .colonColon if we're trying to split it + skipUnexpectedModuleSelector: !prefix.hasPrefix(":"), + consume: { $0.consume(ifPrefix: prefix, as: tokenKind) }, + canRecoverTo: { $0.canRecoverTo(spec) }, + makeMissing: { $0.missingToken(spec) } + ) + } + /// If the current token starts with the given prefix, consume the prefis as the given token kind. /// /// Otherwise, synthesize a missing token of the given kind. @@ -668,16 +712,20 @@ extension Parser { /// to and identifier. /// - Returns: The consumed token and any unexpected tokens that were skipped. /// The token is always guaranteed to be of `TokenKind.identifier` + /// - Note: If you expect a module selector, parse it before calling this method; it will consume module selectors + /// as unexpected syntax. mutating func expectIdentifier( keywordRecovery: Bool = false, allowSelfOrCapitalSelfAsIdentifier: Bool = false, allowKeywordsAsIdentifier: Bool = false ) -> (RawUnexpectedNodesSyntax?, RawTokenSyntax) { + let unexpectedSelector = unexpected(self.parseModuleSelector()) + if let identifier = self.consume(if: .identifier) { - return (nil, identifier) + return (unexpectedSelector, identifier) } if allowKeywordsAsIdentifier, self.currentToken.isLexerClassifiedKeyword { - return (nil, self.consumeAnyToken(remapping: .identifier)) + return (unexpectedSelector, self.consumeAnyToken(remapping: .identifier)) } if allowSelfOrCapitalSelfAsIdentifier, let selfOrCapitalSelf = self.consume( @@ -685,17 +733,17 @@ extension Parser { TokenSpec(.Self, remapping: .identifier) ) { - return (nil, selfOrCapitalSelf) + return (unexpectedSelector, selfOrCapitalSelf) } if let unknown = self.consume(if: .unknown) { return ( - RawUnexpectedNodesSyntax([unknown], arena: self.arena), + RawUnexpectedNodesSyntax(combining: unexpectedSelector, unknown, arena: self.arena), self.missingToken(.identifier) ) } if let number = self.consume(if: .integerLiteral, .floatLiteral, .dollarIdentifier) { return ( - RawUnexpectedNodesSyntax([number], arena: self.arena), + RawUnexpectedNodesSyntax(combining: unexpectedSelector, number, arena: self.arena), self.missingToken(.identifier) ) } else if keywordRecovery, @@ -704,12 +752,12 @@ extension Parser { { let keyword = self.consumeAnyToken() return ( - RawUnexpectedNodesSyntax([keyword], arena: self.arena), + RawUnexpectedNodesSyntax(combining: unexpectedSelector, keyword, arena: self.arena), self.missingToken(.identifier) ) } return ( - nil, + unexpectedSelector, self.missingToken(.identifier) ) } diff --git a/Sources/SwiftParser/Patterns.swift b/Sources/SwiftParser/Patterns.swift index b58d68e51b0..063eb07377c 100644 --- a/Sources/SwiftParser/Patterns.swift +++ b/Sources/SwiftParser/Patterns.swift @@ -19,6 +19,10 @@ extension Parser { /// Parse a pattern. mutating func parsePattern() -> RawPatternSyntax { + if let moduleSelector = self.parseModuleSelector() { + return attach(moduleSelector, to: self.parsePattern()) + } + enum PatternOnlyExpectedTokens: TokenSpecSet { case leftParen case wildcard @@ -272,14 +276,19 @@ extension Parser.Lookahead { // than likely need to be made contextual as well before finalizing their // grammar. case ._borrowing, .borrowing: - return peek(isAt: TokenSpec(.identifier, allowAtStartOfLine: false)) + return peek( + isAt: TokenSpec(.identifier, allowAtStartOfLine: false), + TokenSpec(.wildcard, allowAtStartOfLine: false) + ) default: - // Other keywords can be parsed unconditionally. - return true + // Other keywords can be parsed *almost* unconditionally. + return !isAtModuleSelector() } } mutating func canParsePattern() -> Bool { + _ = self.consumeModuleSelectorTokens() + enum PurePatternStartTokens: TokenSpecSet { case identifier case wildcard @@ -359,7 +368,9 @@ extension Parser.Lookahead { } // If the next token is ':', this is a name. - let nextTok = self.peek() + var lookahead = self.lookahead() + _ = lookahead.consumeModuleSelectorTokens() + let nextTok = lookahead.peek() if nextTok.rawTokenKind == .colon { return true } @@ -367,17 +378,17 @@ extension Parser.Lookahead { // If the next token can be an argument label, we might have a name. if nextTok.isArgumentLabel(allowDollarIdentifier: true) { // If the first name wasn't a contextual keyword, we're done. - if !self.at(.keyword(.isolated)) - && !self.at(.keyword(.some)) - && !self.at(.keyword(.any)) - && !self.at(.keyword(.each)) - && !self.at(.keyword(.repeat)) - && !self.at(.keyword(.__shared)) - && !self.at(.keyword(.__owned)) - && !self.at(.keyword(._const)) - && !self.at(.keyword(.borrowing)) - && !self.at(.keyword(.consuming)) - && !self.at(.keyword(.sending)) + if !lookahead.at(.keyword(.isolated)) + && !lookahead.at(.keyword(.some)) + && !lookahead.at(.keyword(.any)) + && !lookahead.at(.keyword(.each)) + && !lookahead.at(.keyword(.repeat)) + && !lookahead.at(.keyword(.__shared)) + && !lookahead.at(.keyword(.__owned)) + && !lookahead.at(.keyword(._const)) + && !lookahead.at(.keyword(.borrowing)) + && !lookahead.at(.keyword(.consuming)) + && !lookahead.at(.keyword(.sending)) { return true } @@ -386,11 +397,11 @@ extension Parser.Lookahead { // so look ahead one more token (two total) see if we have a ':' that would // indicate that this is an argument label. do { - if self.at(.colon) { + if lookahead.at(.colon) { return true // isolated : } self.consumeAnyToken() - return self.atArgumentLabel(allowDollarIdentifier: true) && self.peek().rawTokenKind == .colon + return self.atArgumentLabel(allowDollarIdentifier: true, followedByColon: true) } } diff --git a/Sources/SwiftParser/Statements.swift b/Sources/SwiftParser/Statements.swift index b6834a69af5..474ee8f0008 100644 --- a/Sources/SwiftParser/Statements.swift +++ b/Sources/SwiftParser/Statements.swift @@ -209,6 +209,11 @@ extension Parser { /// /// `lastBindingKind` will be used to get a correct fall back, when there is missing `var` or `let` in a `if` statement etc. mutating func parseConditionElement(lastBindingKind: RawTokenSyntax?) -> RawConditionElementSyntax.Condition { + // Module selectors aren't allowed here except on expressions, but we recover better if we parse them early. + if let moduleSelector = self.parseModuleSelector() { + return attach(moduleSelector, to: self.parseConditionElement(lastBindingKind: lastBindingKind)) + } + // Parse a leading #available/#unavailable condition if present. if self.at(.poundAvailable, .poundUnavailable) { return self.parsePoundAvailableConditionElement() @@ -969,6 +974,9 @@ extension TokenConsumer { return false case .semicolon, .endOfFile, .poundElse, .poundElseif, .poundEndif: return false + case .colonColon: + // E.g. :: + return false case .leftAngle, .rightAngle: // Lexer never produce these token kinds. diff --git a/Sources/SwiftParser/StringLiteralRepresentedLiteralValue.swift b/Sources/SwiftParser/StringLiteralRepresentedLiteralValue.swift index ad7c9d6e944..d4d30e62b50 100644 --- a/Sources/SwiftParser/StringLiteralRepresentedLiteralValue.swift +++ b/Sources/SwiftParser/StringLiteralRepresentedLiteralValue.swift @@ -90,7 +90,7 @@ extension StringSegmentSyntax { } rawText.withBuffer { buffer in - var cursor = Lexer.Cursor(input: buffer, previous: 0) + var cursor = Lexer.Cursor(input: buffer, previous: 0, experimentalFeatures: []) // Put the cursor in the string literal lexing state. This is just // defensive as it's currently not used by `lexCharacterInStringLiteral`. diff --git a/Sources/SwiftParser/TokenConsumer.swift b/Sources/SwiftParser/TokenConsumer.swift index 2a603b77ae1..b5e9cfcfd92 100644 --- a/Sources/SwiftParser/TokenConsumer.swift +++ b/Sources/SwiftParser/TokenConsumer.swift @@ -387,7 +387,12 @@ extension TokenConsumer { } /// Whether the current token can be a function argument label. - func atArgumentLabel(allowDollarIdentifier: Bool = false) -> Bool { - return self.currentToken.isArgumentLabel(allowDollarIdentifier: allowDollarIdentifier) + mutating func atArgumentLabel(allowDollarIdentifier: Bool = false, followedByColon: Bool = false) -> Bool { + var lookahead = self.lookahead() + _ = lookahead.consumeModuleSelectorTokens() + guard lookahead.currentToken.isArgumentLabel(allowDollarIdentifier: allowDollarIdentifier) else { + return false + } + return !followedByColon || lookahead.peek(isAt: .colon) } } diff --git a/Sources/SwiftParser/TokenPrecedence.swift b/Sources/SwiftParser/TokenPrecedence.swift index ca5da85838d..63199682062 100644 --- a/Sources/SwiftParser/TokenPrecedence.swift +++ b/Sources/SwiftParser/TokenPrecedence.swift @@ -128,7 +128,7 @@ enum TokenPrecedence: Comparable { // Pound literals .poundAvailable, .poundSourceLocation, .poundUnavailable, // Identifiers - .dollarIdentifier, .identifier, + .dollarIdentifier, .identifier, .colonColon, // '_' can occur in types to replace a type identifier .wildcard, // String segment, string interpolation anchor, pound, shebang and regex pattern don't really fit anywhere else diff --git a/Sources/SwiftParser/TriviaParser.swift b/Sources/SwiftParser/TriviaParser.swift index e6fe482c8d8..4ef4d3fe9f5 100644 --- a/Sources/SwiftParser/TriviaParser.swift +++ b/Sources/SwiftParser/TriviaParser.swift @@ -25,7 +25,9 @@ public struct TriviaParser { var pieces: [RawTriviaPiece] = [] var cursor = Lexer.Cursor( input: UnsafeBufferPointer(start: source.baseAddress, count: source.count), - previous: 0 + previous: 0, + // There are currently no experimental features that affect trivia parsing. + experimentalFeatures: [] ) while true { diff --git a/Sources/SwiftParser/Types.swift b/Sources/SwiftParser/Types.swift index deb3ef9a617..724a5d8746a 100644 --- a/Sources/SwiftParser/Types.swift +++ b/Sources/SwiftParser/Types.swift @@ -19,6 +19,10 @@ extension Parser { /// Parse a type. mutating func parseType(misplacedSpecifiers: [RawTokenSyntax] = []) -> RawTypeSyntax { + if let moduleSelector = self.parseModuleSelector() { + return attach(moduleSelector, to: self.parseType(misplacedSpecifiers: misplacedSpecifiers)) + } + // Parse pack expansion 'repeat T'. if let repeatKeyword = self.consume(if: .keyword(.repeat)) { let repetitionPattern = self.parseTypeScalar(misplacedSpecifiers: misplacedSpecifiers) @@ -35,6 +39,10 @@ extension Parser { } mutating func parseTypeScalar(misplacedSpecifiers: [RawTokenSyntax] = []) -> RawTypeSyntax { + if let moduleSelector = self.parseModuleSelector() { + return attach(moduleSelector, to: self.parseTypeScalar(misplacedSpecifiers: misplacedSpecifiers)) + } + let specifiersAndAttributes = self.parseTypeAttributeList(misplacedSpecifiers: misplacedSpecifiers) var base = self.parseSimpleOrCompositionType() if self.withLookahead({ $0.canParseFunctionTypeArrow() }) { @@ -112,6 +120,10 @@ extension Parser { /// Parse a protocol composition involving at least one element. mutating func parseSimpleOrCompositionType() -> RawTypeSyntax { + if let moduleSelector = self.parseModuleSelector() { + return attach(moduleSelector, to: self.parseSimpleOrCompositionType()) + } + // 'each' is a contextual keyword for a pack reference. if let each = consume(if: .keyword(.each)) { let packType = parseSimpleType() @@ -195,6 +207,34 @@ extension Parser { allowMemberTypes: Bool = true, forAttributeName: Bool = false ) -> RawTypeSyntax { + let tilde = self.consumeIfContextualPunctuator("~", remapping: .prefixOperator) + + let baseType = self.parseUnsuppressedSimpleType( + allowMemberTypes: allowMemberTypes, + forAttributeName: forAttributeName + ) + + guard let tilde else { + return baseType + } + + return RawTypeSyntax( + RawSuppressedTypeSyntax(withoutTilde: tilde, type: baseType, arena: self.arena) + ) + } + + mutating func parseUnsuppressedSimpleType( + allowMemberTypes: Bool = true, + forAttributeName: Bool = false + ) -> RawTypeSyntax { + if let moduleSelector = self.parseModuleSelector() { + let qualifiedType = parseUnsuppressedSimpleType( + allowMemberTypes: allowMemberTypes, + forAttributeName: forAttributeName + ) + return attach(moduleSelector, to: qualifiedType) + } + enum TypeBaseStart: TokenSpecSet { case `Self` case `Any` @@ -227,27 +267,10 @@ extension Parser { } } - // Eat any '~' preceding the type. - let maybeTilde = self.consumeIfContextualPunctuator("~", remapping: .prefixOperator) - - // Wrap as a suppressed type if needed. - func wrapInTilde(_ node: RawTypeSyntax) -> RawTypeSyntax { - if let tilde = maybeTilde { - return RawTypeSyntax( - RawSuppressedTypeSyntax( - withoutTilde: tilde, - type: node, - arena: self.arena - ) - ) - } - return node - } - var base: RawTypeSyntax switch self.at(anyIn: TypeBaseStart.self)?.spec { case .Self, .Any, .identifier: - base = self.parseTypeIdentifier() + base = RawTypeSyntax(self.parseTypeIdentifier()) case .leftParen: base = RawTypeSyntax(self.parseTupleTypeBody()) case .leftSquare: @@ -255,7 +278,7 @@ extension Parser { case .wildcard: base = RawTypeSyntax(self.parsePlaceholderType()) case nil: - return wrapInTilde(RawTypeSyntax(RawMissingTypeSyntax(arena: self.arena))) + return RawTypeSyntax(RawMissingTypeSyntax(arena: self.arena)) } var loopProgress = LoopProgressCondition() @@ -269,19 +292,24 @@ extension Parser { baseType: base, unexpectedPeriod, period: period, + moduleSelector: nil, name: missingIdentifier, genericArgumentClause: nil, arena: self.arena ) ) break - } else if self.at(.keyword(.Type)) || self.at(.keyword(.Protocol)) { + } + + let memberModuleSelector = self.parseModuleSelector() + if self.at(.keyword(.Type)) || self.at(.keyword(.Protocol)) { let metatypeSpecifier = self.consume(if: .keyword(.Type)) ?? self.consume(if: .keyword(.Protocol))! base = RawTypeSyntax( RawMetatypeTypeSyntax( baseType: base, unexpectedPeriod, period: period, + unexpected(memberModuleSelector), metatypeSpecifier: metatypeSpecifier, arena: self.arena ) @@ -306,6 +334,7 @@ extension Parser { baseType: base, unexpectedPeriod, period: period, + moduleSelector: memberModuleSelector, name: name, genericArgumentClause: generics, arena: self.arena @@ -332,8 +361,6 @@ extension Parser { break } - base = wrapInTilde(base) - return base } @@ -362,9 +389,9 @@ extension Parser { } /// Parse a type identifier. - mutating func parseTypeIdentifier() -> RawTypeSyntax { + mutating func parseTypeIdentifier() -> RawIdentifierTypeSyntax { if self.at(.keyword(.Any)) { - return RawTypeSyntax(self.parseAnyType()) + return self.parseAnyType() } let (unexpectedBeforeName, name) = self.expect(anyIn: IdentifierTypeSyntax.NameOptions.self, default: .identifier) @@ -375,13 +402,13 @@ extension Parser { generics = nil } - return RawTypeSyntax( - RawIdentifierTypeSyntax( - unexpectedBeforeName, - name: name, - genericArgumentClause: generics, - arena: self.arena - ) + return RawIdentifierTypeSyntax( + // Will be attached by caller if present. + moduleSelector: nil, + unexpectedBeforeName, + name: name, + genericArgumentClause: generics, + arena: self.arena ) } @@ -389,6 +416,7 @@ extension Parser { mutating func parseAnyType() -> RawIdentifierTypeSyntax { let (unexpectedBeforeName, name) = self.expect(.keyword(.Any)) return RawIdentifierTypeSyntax( + moduleSelector: nil, unexpectedBeforeName, name: name, genericArgumentClause: nil, @@ -400,6 +428,7 @@ extension Parser { mutating func parsePlaceholderType() -> RawIdentifierTypeSyntax { let (unexpectedBeforeName, name) = self.expect(.wildcard) return RawIdentifierTypeSyntax( + moduleSelector: nil, unexpectedBeforeName, name: name, genericArgumentClause: nil, @@ -419,7 +448,9 @@ extension Parser { repeat { let argument = self.parseGenericArgumentType() - if arguments.isEmpty, argument.raw.is(RawMissingTypeSyntax.self) { + if arguments.isEmpty, let missingType = argument.raw.as(RawMissingTypeSyntax.self), + missingType.moduleSelector == nil + { break } @@ -502,7 +533,7 @@ extension Parser { second = nil unexpectedBeforeColon = nil colon = parsedColon - } else if self.atArgumentLabel(allowDollarIdentifier: true) && self.peek(isAt: .colon) { + } else if self.atArgumentLabel(allowDollarIdentifier: true, followedByColon: true) { (unexpectedBeforeSecond, second) = self.parseArgumentLabel() (unexpectedBeforeColon, colon) = self.expect(.colon) } else { @@ -535,7 +566,12 @@ extension Parser { secondName: nil, RawUnexpectedNodesSyntax(combining: misplacedSpecifiers, unexpectedBeforeColon, arena: self.arena), colon: nil, - type: RawIdentifierTypeSyntax(name: first, genericArgumentClause: nil, arena: self.arena), + type: RawIdentifierTypeSyntax( + moduleSelector: nil, + name: first, + genericArgumentClause: nil, + arena: self.arena + ), ellipsis: nil, trailingComma: self.missingToken(.comma), arena: self.arena @@ -1305,7 +1341,11 @@ extension Parser { } mutating func parseTypeAttribute() -> RawAttributeListSyntax.Element { - switch peek(isAtAnyIn: TypeAttribute.self) { + // An attribute qualified by a module selector is *always* a custom attribute, even if it has the same name (or + // module name) as a builtin attribute. + let builtinAttr = self.unlessPeekModuleSelector { $0.peek(isAtAnyIn: TypeAttribute.self) } + + switch builtinAttr { case ._local, ._noMetadata, .async, .escaping, .noDerivative, .noescape, .preconcurrency, .retroactive, .Sendable, .unchecked, .autoclosure: // Known type attribute that doesn't take any arguments @@ -1332,9 +1372,7 @@ extension Parser { extension Parser { mutating func parseResultType() -> RawTypeSyntax { - if self.currentToken.isEditorPlaceholder { - return self.parseTypeIdentifier() - } else if self.at(prefix: "<") { + if self.at(prefix: "<") && !self.currentToken.isEditorPlaceholder { let generics = self.parseGenericParameters() let baseType = self.parseType() return RawTypeSyntax( @@ -1351,6 +1389,9 @@ extension Parser { return result } + // The rest of this tries to recover from a missing left square bracket like ` -> [Int]]? {`. We can do this for + // result types because we know there isn't an enclosing expression context. + // If the right square bracket is at a new line, we should just return the result if let rightSquare = self.consume(if: TokenSpec(.rightSquare, allowAtStartOfLine: false)) { result = RawTypeSyntax( diff --git a/Sources/SwiftParser/generated/ExperimentalFeatures.swift b/Sources/SwiftParser/generated/ExperimentalFeatures.swift index c8c8c373856..ed9af2bd788 100644 --- a/Sources/SwiftParser/generated/ExperimentalFeatures.swift +++ b/Sources/SwiftParser/generated/ExperimentalFeatures.swift @@ -55,6 +55,9 @@ extension Parser.ExperimentalFeatures { /// Whether to enable the parsing of set default actor isolation for a file. public static let defaultIsolationPerFile = Self (rawValue: 1 << 9) + /// Whether to enable the parsing of Module selector syntax (`ModName::identifier`). + public static let moduleSelector = Self (rawValue: 1 << 10) + /// Creates a new value representing the experimental feature with the /// given name, or returns nil if the name is not recognized. public init?(name: String) { @@ -79,6 +82,8 @@ extension Parser.ExperimentalFeatures { self = .inlineArrayTypeSugar case "DefaultIsolationPerFile": self = .defaultIsolationPerFile + case "ModuleSelector": + self = .moduleSelector default: return nil } diff --git a/Sources/SwiftParser/generated/Parser+TokenSpecSet.swift b/Sources/SwiftParser/generated/Parser+TokenSpecSet.swift index bcdb11f0b95..ecc4bea5e93 100644 --- a/Sources/SwiftParser/generated/Parser+TokenSpecSet.swift +++ b/Sources/SwiftParser/generated/Parser+TokenSpecSet.swift @@ -2378,6 +2378,58 @@ extension ImportPathComponentSyntax { } } +extension ImportPathComponentSyntax { + @_spi(Diagnostics) + public enum TrailingPeriodOptions: TokenSpecSet { + case period + case colonColon + + init?(lexeme: Lexer.Lexeme, experimentalFeatures: Parser.ExperimentalFeatures) { + switch PrepareForKeywordMatch(lexeme) { + case TokenSpec(.period): + self = .period + case TokenSpec(.colonColon): + self = .colonColon + default: + return nil + } + } + + public init?(token: TokenSyntax) { + switch token { + case TokenSpec(.period): + self = .period + case TokenSpec(.colonColon): + self = .colonColon + default: + return nil + } + } + + var spec: TokenSpec { + switch self { + case .period: + return .period + case .colonColon: + return .colonColon + } + } + + /// Returns a token that satisfies the `TokenSpec` of this case. + /// + /// If the token kind of this spec has variable text, e.g. for an identifier, this returns a token with empty text. + @_spi(Diagnostics) + public var tokenSyntax: TokenSyntax { + switch self { + case .period: + return .periodToken() + case .colonColon: + return .colonColonToken() + } + } + } +} + extension InitializerDeclSyntax { @_spi(Diagnostics) public enum OptionalMarkOptions: TokenSpecSet { diff --git a/Sources/SwiftParser/generated/TokenSpecStaticMembers.swift b/Sources/SwiftParser/generated/TokenSpecStaticMembers.swift index 853e2fbb690..13b547bb2ca 100644 --- a/Sources/SwiftParser/generated/TokenSpecStaticMembers.swift +++ b/Sources/SwiftParser/generated/TokenSpecStaticMembers.swift @@ -44,6 +44,10 @@ extension TokenSpec { return TokenSpec(.colon) } + static var colonColon: TokenSpec { + return TokenSpec(.colonColon) + } + static var comma: TokenSpec { return TokenSpec(.comma) } diff --git a/Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift b/Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift index 20b7c7702fd..990489dd4d3 100644 --- a/Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift +++ b/Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift @@ -497,6 +497,73 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor { ], handledNodes: [node.id, otherNode.id] ) + } else if let (moduleName, colonColon) = node.twoPresentTokens( + firstSatisfying: { $0.tokenKind.isIdentifier }, + secondSatisfying: { $0.tokenKind == .colonColon } + ) { + // Looks like a module selector. + var fixIts: [FixIt] = [] + + func canExplicitlyInitializeVariable() -> TokenSyntax? { + if let capture = node.parent?.as(ClosureCaptureSyntax.self), + capture.unexpectedBeforeSpecifier == node || capture.unexpectedBetweenSpecifierAndName == node, + capture.initializer == nil + { + return capture.name + } + + if let pattern = node.parent?.as(IdentifierPatternSyntax.self), + pattern.unexpectedBeforeIdentifier == node, + pattern.parent?.is(OptionalBindingConditionSyntax.self) ?? false + { + return pattern.identifier + } + + return nil + } + + if let explicitVarName = canExplicitlyInitializeVariable() { + // Suggest turning `Foo::bar` into `bar = Foo::bar` + fixIts.append( + FixIt( + message: ExplicitlyInitializeFixIt(newVariableName: explicitVarName), + changes: [ + FixIt.MultiNodeChange( + .replace( + oldNode: Syntax(node), + newNode: Syntax( + UnexpectedNodesSyntax( + [ + Syntax( + explicitVarName + .with(\.leadingTrivia, moduleName.leadingTrivia) + .with(\.trailingTrivia, [.spaces(1)]) + ), + Syntax(TokenSyntax.equalToken(trailingTrivia: [.spaces(1)])), + Syntax(moduleName.with(\.leadingTrivia, [])), + Syntax(colonColon), + ] + ) + ) + ) + ) + ] + ) + ) + } + // Suggest removing the module selector. + fixIts.append( + FixIt( + message: RemoveNodesFixIt([Syntax(node)]), + changes: [.makeMissing(node, transferTrivia: true)] + ) + ) + addDiagnostic( + node, + CannotUseModuleSelectorError(unexpectedNodes: node), + highlights: [Syntax(node)], + fixIts: fixIts + ) } else { addDiagnostic(node, UnexpectedNodesError(unexpectedNodes: node), highlights: [Syntax(node)]) } @@ -1085,53 +1152,65 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor { if shouldSkip(node) { return .skipChildren } - if node.baseName.isMissing, let unexpected = node.unexpectedBeforeBaseName { - if unexpected.first?.as(TokenSyntax.self)?.tokenKind == .pound { - addDiagnostic( - unexpected, - UnknownDirectiveError(unexpected: unexpected), - handledNodes: [unexpected.id, node.baseName.id] - ) - } else if let availability = unexpected.first?.as(AvailabilityConditionSyntax.self) { - if let prefixOperatorExpr = node.parent?.as(PrefixOperatorExprSyntax.self), - prefixOperatorExpr.operator.text == "!", - let conditionElement = prefixOperatorExpr.parent?.as(ConditionElementSyntax.self) - { - // Diagnose !#available(...) and !#unavailable(...) - let negatedAvailabilityKeyword = availability.availabilityKeyword.negatedAvailabilityKeyword - let negatedConditionElement = ConditionElementSyntax( - condition: .availability(availability.with(\.availabilityKeyword, negatedAvailabilityKeyword)), - trailingComma: conditionElement.trailingComma - ) - addDiagnostic( - unexpected, - NegatedAvailabilityCondition( - availabilityCondition: availability, - negatedAvailabilityKeyword: negatedAvailabilityKeyword - ), - fixIts: [ - FixIt( - message: ReplaceTokensFixIt( - replaceTokens: [prefixOperatorExpr.operator, availability.availabilityKeyword], - replacements: [negatedAvailabilityKeyword] - ), - changes: [ - .replace(oldNode: Syntax(conditionElement), newNode: Syntax(negatedConditionElement)) - ] - ) - ], - handledNodes: [unexpected.id, node.baseName.id] - ) - } else { + if node.baseName.isMissing { + func considerUnexpectedBeforeBaseName(_ unexpected: UnexpectedNodesSyntax) { + if unexpected.first?.as(TokenSyntax.self)?.tokenKind == .pound { addDiagnostic( unexpected, - AvailabilityConditionInExpression(availabilityCondition: availability), + UnknownDirectiveError(unexpected: unexpected), handledNodes: [unexpected.id, node.baseName.id] ) + } else if let availability = unexpected.first?.as(AvailabilityConditionSyntax.self) { + if let prefixOperatorExpr = node.parent?.as(PrefixOperatorExprSyntax.self), + prefixOperatorExpr.operator.text == "!", + let conditionElement = prefixOperatorExpr.parent?.as(ConditionElementSyntax.self) + { + // Diagnose !#available(...) and !#unavailable(...) + + let negatedAvailabilityKeyword = availability.availabilityKeyword.negatedAvailabilityKeyword + let negatedConditionElement = ConditionElementSyntax( + condition: .availability(availability.with(\.availabilityKeyword, negatedAvailabilityKeyword)), + trailingComma: conditionElement.trailingComma + ) + addDiagnostic( + unexpected, + NegatedAvailabilityCondition( + availabilityCondition: availability, + negatedAvailabilityKeyword: negatedAvailabilityKeyword + ), + fixIts: [ + FixIt( + message: ReplaceTokensFixIt( + replaceTokens: [prefixOperatorExpr.operator, availability.availabilityKeyword], + replacements: [negatedAvailabilityKeyword] + ), + changes: [ + .replace(oldNode: Syntax(conditionElement), newNode: Syntax(negatedConditionElement)) + ] + ) + ], + handledNodes: [unexpected.id, node.baseName.id] + ) + } else { + addDiagnostic( + unexpected, + AvailabilityConditionInExpression(availabilityCondition: availability), + handledNodes: [unexpected.id, node.baseName.id] + ) + } } } + + // We care more about the first token in the unexpected node before the base name, so favor the module selector's + // unexpected nodes. + if node.moduleSelector == nil, let unexpected = node.unexpectedBeforeModuleSelector { + considerUnexpectedBeforeBaseName(unexpected) + } else if let unexpected = node.unexpectedBetweenModuleSelectorAndBaseName { + considerUnexpectedBeforeBaseName(unexpected) + } } + return .visitChildren } @@ -1237,6 +1316,40 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor { return .visitChildren } + public override func visit(_ node: ImportPathComponentSyntax) -> SyntaxVisitorContinueKind { + if shouldSkip(node) { + return .skipChildren + } + + if let colonColon = node.unexpectedBetweenNameAndTrailingPeriod?.last?.as(TokenSyntax.self), + colonColon.tokenKind == .colonColon, + colonColon.isPresent, + let trailingPeriod = node.trailingPeriod, + trailingPeriod.tokenKind == .period, + trailingPeriod.isMissing + { + addDiagnostic( + colonColon, + .submoduleCannotBeImportedUsingModuleSelector, + fixIts: [ + FixIt( + message: ReplaceTokensFixIt(replaceTokens: [colonColon], replacements: [trailingPeriod]), + changes: [ + .makeMissing(colonColon), + .makePresent(trailingPeriod), + ] + ) + ], + handledNodes: [ + colonColon.id, + trailingPeriod.id, + ] + ) + } + + return .visitChildren + } + public override func visit(_ node: InitializerClauseSyntax) -> SyntaxVisitorContinueKind { if shouldSkip(node) { return .skipChildren diff --git a/Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift b/Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift index f8d7aac2805..9412876697d 100644 --- a/Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift +++ b/Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift @@ -13,11 +13,11 @@ #if compiler(>=6) public import SwiftDiagnostics @_spi(Diagnostics) internal import SwiftParser -@_spi(RawSyntax) public import SwiftSyntax +@_spi(ExperimentalLanguageFeatures) @_spi(RawSyntax) public import SwiftSyntax #else import SwiftDiagnostics @_spi(Diagnostics) import SwiftParser -@_spi(RawSyntax) import SwiftSyntax +@_spi(ExperimentalLanguageFeatures) @_spi(RawSyntax) import SwiftSyntax #endif fileprivate let diagnosticDomain: String = "SwiftParser" @@ -233,6 +233,9 @@ extension DiagnosticMessage where Self == StaticParserError { public static var subscriptsCannotHaveNames: Self { .init("subscripts cannot have a name") } + public static var submoduleCannotBeImportedUsingModuleSelector: Self { + .init("submodule cannot be imported using module selector") + } public static var tooManyClosingPoundDelimiters: Self { .init("too many '#' characters in closing delimiter") } @@ -306,6 +309,63 @@ public struct CannotParseVersionTuple: ParserError { } } +public struct CannotUseModuleSelectorError: ParserError { + public let unexpectedNodes: UnexpectedNodesSyntax + + public var message: String { + var qualifiedSyntaxDescription = "code" + if let parent = unexpectedNodes.parent { + if let parentDeclRef = parent.as(DeclReferenceExprSyntax.self), + parentDeclRef.moduleSelector == nil, + parentDeclRef.unexpectedBeforeModuleSelector == unexpectedNodes + { + // We only insert a module selector here if the `baseName` is some sort of exotic token that can't take a + // module selector. Blame that token. + qualifiedSyntaxDescription = self.exoticNameDescription(for: parentDeclRef.baseName) + } else if let parentTypeName = parent.ancestorOrSelf(mapping: self.parentDescription(for:)) { + qualifiedSyntaxDescription = parentTypeName + // If not first child, and subsequent child has name, add it. + let siblings = parent.children(viewMode: .sourceAccurate) + if siblings.first(where: { $0.totalLength.utf8Length > 0 })?.id != unexpectedNodes.id, + let nextSibling = siblings.suffix(from: siblings.index(of: self.unexpectedNodes)!).dropFirst().first, + let nextSiblingChildName = nextSibling.childNameInParent + { + qualifiedSyntaxDescription += " \(nextSiblingChildName)" + } + } else if let parentTypeName = parent.ancestorOrSelf(mapping: self.parentDescription(for:)) { + qualifiedSyntaxDescription = "code in \(parentTypeName)" + } + } + + return "\(qualifiedSyntaxDescription) cannot be qualified with a module selector" + } + + private func parentDescription(for node: Syntax) -> String? { + if let name = node.nodeTypeNameForDiagnostics(allowBlockNames: false) { + return name + } + + // Special case for otherwise undistinguishable syntax inside an attribute's argument list. + if node.keyPathInParent == \AttributeSyntax.arguments { + return "attribute argument" + } + + return nil + } + + private func exoticNameDescription(for nameToken: TokenSyntax) -> String { + switch nameToken.tokenKind { + case .keyword(let keyword): + return "'\(keyword.defaultText)' keyword" + case .binaryOperator(let text), .dollarIdentifier(let text), .identifier(let text), .postfixOperator(let text), + .prefixOperator(let text): + return "\(nameToken.tokenKind.nameForDiagnostics) '\(text)'" + default: + return nameToken.tokenKind.nameForDiagnostics + } + } +} + public struct DeclarationNotPermittedInContext: ParserError { public var missingDecl: MissingDeclSyntax public var invalidDecl: DeclSyntax @@ -738,6 +798,14 @@ extension FixItMessage where Self == StaticParserFixIt { } } +public struct ExplicitlyInitializeFixIt: ParserFixIt { + public let newVariableName: TokenSyntax + + public var message: String { + "explicitly initialize variable '\(newVariableName.text)'" + } +} + public struct InsertFixIt: ParserFixIt { public let tokenToBeInserted: TokenSyntax diff --git a/Sources/SwiftParserDiagnostics/SyntaxExtensions.swift b/Sources/SwiftParserDiagnostics/SyntaxExtensions.swift index 3dc0aa8e82b..b2653c36076 100644 --- a/Sources/SwiftParserDiagnostics/SyntaxExtensions.swift +++ b/Sources/SwiftParserDiagnostics/SyntaxExtensions.swift @@ -90,6 +90,9 @@ extension SyntaxProtocol { if !allowBlockNames && (syntax.is(CodeBlockSyntax.self) || syntax.is(MemberBlockSyntax.self)) { return nil } + if let relation = syntax.as(PrecedenceGroupRelationSyntax.self) { + return "'\(relation.higherThanOrLowerThanLabel.text)' property of precedencegroup" + } return syntax.kind.nameForDiagnostics } @@ -127,6 +130,14 @@ extension SyntaxProtocol { memberDeclItem.firstToken(viewMode: .all) == self.firstToken(viewMode: .all) { return true + } else if let selfToken = self.as(TokenSyntax.self), + selfToken.isMissing, + selfToken.tokenKind.isIdentifier, + let nextToken = self.nextToken(viewMode: .sourceAccurate), + nextToken.isPresent, + nextToken.tokenKind == .colonColon + { + return true } else { return false } diff --git a/Sources/SwiftParserDiagnostics/generated/ChildNameForDiagnostics.swift b/Sources/SwiftParserDiagnostics/generated/ChildNameForDiagnostics.swift index 4a00dbace1f..f8f6a173d60 100644 --- a/Sources/SwiftParserDiagnostics/generated/ChildNameForDiagnostics.swift +++ b/Sources/SwiftParserDiagnostics/generated/ChildNameForDiagnostics.swift @@ -33,6 +33,8 @@ private func childNameForDiagnostics(_ keyPath: AnyKeyPath) -> String? { return "attributes" case \ActorDeclSyntax.modifiers: return "modifiers" + case \ActorDeclSyntax.name: + return "name" case \ActorDeclSyntax.genericParameterClause: return "generic parameter clause" case \ActorDeclSyntax.inheritanceClause: @@ -45,6 +47,8 @@ private func childNameForDiagnostics(_ keyPath: AnyKeyPath) -> String? { return "attributes" case \AssociatedTypeDeclSyntax.modifiers: return "modifiers" + case \AssociatedTypeDeclSyntax.name: + return "name" case \AssociatedTypeDeclSyntax.inheritanceClause: return "inheritance clause" case \AssociatedTypeDeclSyntax.genericWhereClause: @@ -61,6 +65,8 @@ private func childNameForDiagnostics(_ keyPath: AnyKeyPath) -> String? { return "attributes" case \ClassDeclSyntax.modifiers: return "modifiers" + case \ClassDeclSyntax.name: + return "name" case \ClassDeclSyntax.genericParameterClause: return "generic parameter clause" case \ClassDeclSyntax.inheritanceClause: @@ -109,6 +115,8 @@ private func childNameForDiagnostics(_ keyPath: AnyKeyPath) -> String? { return "modifiers" case \EnumCaseDeclSyntax.elements: return "elements" + case \EnumCaseElementSyntax.name: + return "name" case \EnumCaseElementSyntax.parameterClause: return "associated values" case \EnumCaseParameterClauseSyntax.parameters: @@ -123,6 +131,8 @@ private func childNameForDiagnostics(_ keyPath: AnyKeyPath) -> String? { return "attributes" case \EnumDeclSyntax.modifiers: return "modifiers" + case \EnumDeclSyntax.name: + return "name" case \EnumDeclSyntax.genericParameterClause: return "generic parameter clause" case \EnumDeclSyntax.inheritanceClause: @@ -151,6 +161,8 @@ private func childNameForDiagnostics(_ keyPath: AnyKeyPath) -> String? { return "attributes" case \FunctionDeclSyntax.modifiers: return "modifiers" + case \FunctionDeclSyntax.name: + return "name" case \FunctionDeclSyntax.genericParameterClause: return "generic parameter clause" case \FunctionDeclSyntax.signature: @@ -179,6 +191,8 @@ private func childNameForDiagnostics(_ keyPath: AnyKeyPath) -> String? { return "condition" case \GuardStmtSyntax.body: return "body" + case \IdentifierTypeSyntax.moduleSelector: + return "module selector" case \IfConfigClauseSyntax.condition: return "condition" case \IfExprSyntax.body: @@ -237,6 +251,8 @@ private func childNameForDiagnostics(_ keyPath: AnyKeyPath) -> String? { return "attributes" case \MacroDeclSyntax.modifiers: return "modifiers" + case \MacroDeclSyntax.name: + return "name" case \MacroDeclSyntax.genericParameterClause: return "generic parameter clause" case \MacroDeclSyntax.signature: @@ -255,16 +271,24 @@ private func childNameForDiagnostics(_ keyPath: AnyKeyPath) -> String? { return "name" case \MemberTypeSyntax.baseType: return "base type" + case \MemberTypeSyntax.moduleSelector: + return "module selector" case \MemberTypeSyntax.name: return "name" case \MetatypeTypeSyntax.baseType: return "base type" + case \ModuleSelectorSyntax.moduleName: + return "module name" + case \ModuleSelectorSyntax.colonColon: + return "'::' operator" case \MultipleTrailingClosureElementSyntax.label: return "label" case \ObjCSelectorPieceSyntax.name: return "name" case \OperatorDeclSyntax.fixitySpecifier: return "fixity" + case \OperatorDeclSyntax.name: + return "custom operator" case \OperatorPrecedenceAndTypesSyntax.precedenceGroup: return "precedence group" case \PatternBindingSyntax.typeAnnotation: @@ -283,6 +307,8 @@ private func childNameForDiagnostics(_ keyPath: AnyKeyPath) -> String? { return "attributes" case \PrecedenceGroupDeclSyntax.modifiers: return "modifiers" + case \PrecedenceGroupDeclSyntax.name: + return "name" case \PrecedenceGroupNameSyntax.name: return "name" case \PrimaryAssociatedTypeSyntax.name: @@ -291,6 +317,8 @@ private func childNameForDiagnostics(_ keyPath: AnyKeyPath) -> String? { return "attributes" case \ProtocolDeclSyntax.modifiers: return "modifiers" + case \ProtocolDeclSyntax.name: + return "name" case \ProtocolDeclSyntax.primaryAssociatedTypeClause: return "primary associated type clause" case \ProtocolDeclSyntax.inheritanceClause: @@ -317,6 +345,8 @@ private func childNameForDiagnostics(_ keyPath: AnyKeyPath) -> String? { return "attributes" case \StructDeclSyntax.modifiers: return "modifiers" + case \StructDeclSyntax.name: + return "name" case \StructDeclSyntax.genericParameterClause: return "generic parameter clause" case \StructDeclSyntax.inheritanceClause: @@ -359,6 +389,8 @@ private func childNameForDiagnostics(_ keyPath: AnyKeyPath) -> String? { return "attributes" case \TypeAliasDeclSyntax.modifiers: return "modifiers" + case \TypeAliasDeclSyntax.name: + return "name" case \TypeAliasDeclSyntax.genericParameterClause: return "generic parameter clause" case \TypeAliasDeclSyntax.genericWhereClause: diff --git a/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift b/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift index 52e2023df3e..5fe9debdb99 100644 --- a/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift +++ b/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift @@ -32,6 +32,8 @@ extension SyntaxKind { return "accessor" case .accessorEffectSpecifiers: return "accessor specifiers" + case .accessorParameters: + return "accessor parameter" case .actorDecl: return "actor" case .arrayElement: @@ -140,6 +142,8 @@ extension SyntaxKind { return "'@differentiable' argument" case .differentiableAttributeArguments: return "'@differentiable' arguments" + case .discardAssignmentExpr: + return "wildcard expression" case .discardStmt: return "'discard' statement" case .doExpr: @@ -221,7 +225,7 @@ extension SyntaxKind { case .ifExpr: return "'if' statement" case .implementsAttributeArguments: - return "@_implements arguemnts" + return "@_implements arguments" case .implicitlyUnwrappedOptionalType: return "implicitly unwrapped optional type" case .importDecl: @@ -290,10 +294,14 @@ extension SyntaxKind { return "statement" case .missingType: return "type" + case .moduleSelector: + return "module selector" case .multipleTrailingClosureElement: return "trailing closure" case .namedOpaqueReturnType: return "named opaque return type" + case .nilLiteralExpr: + return "'nil' keyword" case .nonisolatedTypeSpecifier: return "'nonisolated' specifier" case .objCSelectorPieceList: @@ -331,7 +339,7 @@ extension SyntaxKind { case .precedenceGroupAssociativity: return "'associativity' property of precedencegroup" case .precedenceGroupDecl: - return "precedencegroup" + return "precedence group" case .precedenceGroupRelation: return "'relation' property of precedencegroup" case .prefixOperatorExpr: @@ -372,6 +380,8 @@ extension SyntaxKind { return "subscript" case .subscriptDecl: return "subscript" + case .superExpr: + return "'super' keyword" case .suppressedType: return "suppressed type conformance" case .switchCase: diff --git a/Sources/SwiftParserDiagnostics/generated/TokenNameForDiagnostics.swift b/Sources/SwiftParserDiagnostics/generated/TokenNameForDiagnostics.swift index 4d1a90253da..2f7cfd67902 100644 --- a/Sources/SwiftParserDiagnostics/generated/TokenNameForDiagnostics.swift +++ b/Sources/SwiftParserDiagnostics/generated/TokenNameForDiagnostics.swift @@ -34,6 +34,8 @@ extension TokenKind { return "binary operator" case .colon: return ":" + case .colonColon: + return "::" case .comma: return "," case .dollarIdentifier: diff --git a/Sources/SwiftSyntax/MissingNodeInitializers.swift b/Sources/SwiftSyntax/MissingNodeInitializers.swift index 532f53a70ca..7f50affa5b3 100644 --- a/Sources/SwiftSyntax/MissingNodeInitializers.swift +++ b/Sources/SwiftSyntax/MissingNodeInitializers.swift @@ -83,6 +83,7 @@ extension RawMissingDeclSyntax { extension RawMissingExprSyntax { public init(arena: __shared RawSyntaxArena) { self.init( + moduleSelector: nil, placeholder: RawTokenSyntax(missing: .identifier, text: "<#expression#>", arena: arena), arena: arena ) @@ -110,6 +111,7 @@ extension RawMissingStmtSyntax { extension RawMissingTypeSyntax { public init(arena: __shared RawSyntaxArena) { self.init( + moduleSelector: nil, placeholder: RawTokenSyntax(missing: .identifier, text: "<#type#>", arena: arena), arena: arena ) diff --git a/Sources/SwiftSyntax/SwiftSyntaxCompatibility.swift b/Sources/SwiftSyntax/SwiftSyntaxCompatibility.swift index a7333a7838d..3adfb33fbd0 100644 --- a/Sources/SwiftSyntax/SwiftSyntaxCompatibility.swift +++ b/Sources/SwiftSyntax/SwiftSyntaxCompatibility.swift @@ -405,6 +405,21 @@ extension GenericArgumentSyntax { } } +extension FreestandingMacroExpansionSyntax { + // SPI protocol requirements require a default implementation, but this should never be used because there should be + // no conforming types outside of SwiftSyntax. + @_spi(ExperimentalLanguageFeatures) + @available(*, deprecated, message: "concrete type should implement its own moduleSelector property") + public var moduleSelector: ModuleSelectorSyntax? { + get { + return nil + } + set { + fatalError("\(Self.self) should implement its own moduleSelector property") + } + } +} + extension FunctionCallExprSyntax { @_disfavoredOverload @available( @@ -705,6 +720,18 @@ extension KeyPathPropertyComponentSyntax { } } +extension MemberTypeSyntax { + @available(*, deprecated, renamed: "unexpectedBetweenModuleSelectorAndName") + public var unexpectedBeforeName: UnexpectedNodesSyntax? { + get { + return unexpectedBetweenModuleSelectorAndName + } + set(value) { + unexpectedBetweenModuleSelectorAndName = value + } + } +} + extension NamedDeclSyntax { @available(*, deprecated, renamed: "name") public var identifier: TokenSyntax { diff --git a/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift b/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift index 0bcd20aee62..1fa70994605 100644 --- a/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift +++ b/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift @@ -824,8 +824,12 @@ public func childName(_ keyPath: AnyKeyPath) -> String? { return "rightParen" case \DeclNameArgumentsSyntax.unexpectedAfterRightParen: return "unexpectedAfterRightParen" - case \DeclReferenceExprSyntax.unexpectedBeforeBaseName: - return "unexpectedBeforeBaseName" + case \DeclReferenceExprSyntax.unexpectedBeforeModuleSelector: + return "unexpectedBeforeModuleSelector" + case \DeclReferenceExprSyntax.moduleSelector: + return "moduleSelector" + case \DeclReferenceExprSyntax.unexpectedBetweenModuleSelectorAndBaseName: + return "unexpectedBetweenModuleSelectorAndBaseName" case \DeclReferenceExprSyntax.baseName: return "baseName" case \DeclReferenceExprSyntax.unexpectedBetweenBaseNameAndArgumentNames: @@ -1652,8 +1656,12 @@ public func childName(_ keyPath: AnyKeyPath) -> String? { return "identifier" case \IdentifierPatternSyntax.unexpectedAfterIdentifier: return "unexpectedAfterIdentifier" - case \IdentifierTypeSyntax.unexpectedBeforeName: - return "unexpectedBeforeName" + case \IdentifierTypeSyntax.unexpectedBeforeModuleSelector: + return "unexpectedBeforeModuleSelector" + case \IdentifierTypeSyntax.moduleSelector: + return "moduleSelector" + case \IdentifierTypeSyntax.unexpectedBetweenModuleSelectorAndName: + return "unexpectedBetweenModuleSelectorAndName" case \IdentifierTypeSyntax.name: return "name" case \IdentifierTypeSyntax.unexpectedBetweenNameAndGenericArgumentClause: @@ -2138,8 +2146,12 @@ public func childName(_ keyPath: AnyKeyPath) -> String? { return "unexpectedBetweenModifiersAndPound" case \MacroExpansionDeclSyntax.pound: return "pound" - case \MacroExpansionDeclSyntax.unexpectedBetweenPoundAndMacroName: - return "unexpectedBetweenPoundAndMacroName" + case \MacroExpansionDeclSyntax.unexpectedBetweenPoundAndModuleSelector: + return "unexpectedBetweenPoundAndModuleSelector" + case \MacroExpansionDeclSyntax.moduleSelector: + return "moduleSelector" + case \MacroExpansionDeclSyntax.unexpectedBetweenModuleSelectorAndMacroName: + return "unexpectedBetweenModuleSelectorAndMacroName" case \MacroExpansionDeclSyntax.macroName: return "macroName" case \MacroExpansionDeclSyntax.unexpectedBetweenMacroNameAndGenericArgumentClause: @@ -2172,8 +2184,12 @@ public func childName(_ keyPath: AnyKeyPath) -> String? { return "unexpectedBeforePound" case \MacroExpansionExprSyntax.pound: return "pound" - case \MacroExpansionExprSyntax.unexpectedBetweenPoundAndMacroName: - return "unexpectedBetweenPoundAndMacroName" + case \MacroExpansionExprSyntax.unexpectedBetweenPoundAndModuleSelector: + return "unexpectedBetweenPoundAndModuleSelector" + case \MacroExpansionExprSyntax.moduleSelector: + return "moduleSelector" + case \MacroExpansionExprSyntax.unexpectedBetweenModuleSelectorAndMacroName: + return "unexpectedBetweenModuleSelectorAndMacroName" case \MacroExpansionExprSyntax.macroName: return "macroName" case \MacroExpansionExprSyntax.unexpectedBetweenMacroNameAndGenericArgumentClause: @@ -2276,8 +2292,12 @@ public func childName(_ keyPath: AnyKeyPath) -> String? { return "unexpectedBetweenBaseTypeAndPeriod" case \MemberTypeSyntax.period: return "period" - case \MemberTypeSyntax.unexpectedBetweenPeriodAndName: - return "unexpectedBetweenPeriodAndName" + case \MemberTypeSyntax.unexpectedBetweenPeriodAndModuleSelector: + return "unexpectedBetweenPeriodAndModuleSelector" + case \MemberTypeSyntax.moduleSelector: + return "moduleSelector" + case \MemberTypeSyntax.unexpectedBetweenModuleSelectorAndName: + return "unexpectedBetweenModuleSelectorAndName" case \MemberTypeSyntax.name: return "name" case \MemberTypeSyntax.unexpectedBetweenNameAndGenericArgumentClause: @@ -2314,8 +2334,12 @@ public func childName(_ keyPath: AnyKeyPath) -> String? { return "placeholder" case \MissingDeclSyntax.unexpectedAfterPlaceholder: return "unexpectedAfterPlaceholder" - case \MissingExprSyntax.unexpectedBeforePlaceholder: - return "unexpectedBeforePlaceholder" + case \MissingExprSyntax.unexpectedBeforeModuleSelector: + return "unexpectedBeforeModuleSelector" + case \MissingExprSyntax.moduleSelector: + return "moduleSelector" + case \MissingExprSyntax.unexpectedBetweenModuleSelectorAndPlaceholder: + return "unexpectedBetweenModuleSelectorAndPlaceholder" case \MissingExprSyntax.placeholder: return "placeholder" case \MissingExprSyntax.unexpectedAfterPlaceholder: @@ -2338,12 +2362,26 @@ public func childName(_ keyPath: AnyKeyPath) -> String? { return "placeholder" case \MissingSyntax.unexpectedAfterPlaceholder: return "unexpectedAfterPlaceholder" - case \MissingTypeSyntax.unexpectedBeforePlaceholder: - return "unexpectedBeforePlaceholder" + case \MissingTypeSyntax.unexpectedBeforeModuleSelector: + return "unexpectedBeforeModuleSelector" + case \MissingTypeSyntax.moduleSelector: + return "moduleSelector" + case \MissingTypeSyntax.unexpectedBetweenModuleSelectorAndPlaceholder: + return "unexpectedBetweenModuleSelectorAndPlaceholder" case \MissingTypeSyntax.placeholder: return "placeholder" case \MissingTypeSyntax.unexpectedAfterPlaceholder: return "unexpectedAfterPlaceholder" + case \ModuleSelectorSyntax.unexpectedBeforeModuleName: + return "unexpectedBeforeModuleName" + case \ModuleSelectorSyntax.moduleName: + return "moduleName" + case \ModuleSelectorSyntax.unexpectedBetweenModuleNameAndColonColon: + return "unexpectedBetweenModuleNameAndColonColon" + case \ModuleSelectorSyntax.colonColon: + return "colonColon" + case \ModuleSelectorSyntax.unexpectedAfterColonColon: + return "unexpectedAfterColonColon" case \MultipleTrailingClosureElementSyntax.unexpectedBeforeLabel: return "unexpectedBeforeLabel" case \MultipleTrailingClosureElementSyntax.label: diff --git a/Sources/SwiftSyntax/generated/RenamedChildrenCompatibility.swift b/Sources/SwiftSyntax/generated/RenamedChildrenCompatibility.swift index 88518daf105..fe5b522c606 100644 --- a/Sources/SwiftSyntax/generated/RenamedChildrenCompatibility.swift +++ b/Sources/SwiftSyntax/generated/RenamedChildrenCompatibility.swift @@ -1473,13 +1473,12 @@ extension ConsumeExprSyntax { } extension DeclReferenceExprSyntax { - @available(*, deprecated, renamed: "unexpectedBeforeBaseName") - public var unexpectedBeforeIdentifier: UnexpectedNodesSyntax? { + public var unexpectedBeforeBaseName: UnexpectedNodesSyntax? { get { - return unexpectedBeforeBaseName + return unexpectedBeforeModuleSelector } set { - unexpectedBeforeBaseName = newValue + unexpectedBeforeModuleSelector = newValue } } @@ -1523,11 +1522,33 @@ extension DeclReferenceExprSyntax { } } - @available(*, deprecated, renamed: "init(leadingTrivia:_:baseName:_:argumentNames:_:trailingTrivia:)") + public init( + leadingTrivia: Trivia? = nil, + _ unexpectedBeforeBaseName: UnexpectedNodesSyntax? = nil, + baseName: TokenSyntax, + _ unexpectedBetweenBaseNameAndArgumentNames: UnexpectedNodesSyntax? = nil, + argumentNames: DeclNameArgumentsSyntax? = nil, + _ unexpectedAfterArgumentNames: UnexpectedNodesSyntax? = nil, + trailingTrivia: Trivia? = nil + ) { + self.init( + leadingTrivia: leadingTrivia, + unexpectedBeforeBaseName, + moduleSelector: nil, + nil, + baseName: baseName, + unexpectedBetweenBaseNameAndArgumentNames, + argumentNames: argumentNames, + unexpectedAfterArgumentNames, + trailingTrivia: trailingTrivia + ) + } + + @available(*, deprecated, renamed: "init(leadingTrivia:_:moduleSelector:_:baseName:_:argumentNames:_:trailingTrivia:)") @_disfavoredOverload public init( leadingTrivia: Trivia? = nil, - _ unexpectedBeforeIdentifier: UnexpectedNodesSyntax? = nil, + _ unexpectedBeforeBaseName: UnexpectedNodesSyntax? = nil, identifier: TokenSyntax, _ unexpectedBetweenIdentifierAndDeclNameArguments: UnexpectedNodesSyntax? = nil, declNameArguments: DeclNameArgumentsSyntax? = nil, @@ -1536,7 +1557,9 @@ extension DeclReferenceExprSyntax { ) { self.init( leadingTrivia: leadingTrivia, - unexpectedBeforeIdentifier, + unexpectedBeforeBaseName, + moduleSelector: nil, + nil, baseName: identifier, unexpectedBetweenIdentifierAndDeclNameArguments, argumentNames: declNameArguments, @@ -3792,6 +3815,39 @@ extension GenericWhereClauseSyntax { } } +extension IdentifierTypeSyntax { + public var unexpectedBeforeName: UnexpectedNodesSyntax? { + get { + return unexpectedBeforeModuleSelector + } + set { + unexpectedBeforeModuleSelector = newValue + } + } + + public init( + leadingTrivia: Trivia? = nil, + _ unexpectedBeforeName: UnexpectedNodesSyntax? = nil, + name: TokenSyntax, + _ unexpectedBetweenNameAndGenericArgumentClause: UnexpectedNodesSyntax? = nil, + genericArgumentClause: GenericArgumentClauseSyntax? = nil, + _ unexpectedAfterGenericArgumentClause: UnexpectedNodesSyntax? = nil, + trailingTrivia: Trivia? = nil + ) { + self.init( + leadingTrivia: leadingTrivia, + unexpectedBeforeName, + moduleSelector: nil, + nil, + name: name, + unexpectedBetweenNameAndGenericArgumentClause, + genericArgumentClause: genericArgumentClause, + unexpectedAfterGenericArgumentClause, + trailingTrivia: trailingTrivia + ) + } +} + extension ImplementsAttributeArgumentsSyntax { @available(*, deprecated, renamed: "unexpectedBetweenCommaAndDeclName") public var unexpectedBetweenCommaAndDeclname: UnexpectedNodesSyntax? { @@ -4647,6 +4703,15 @@ extension MacroDeclSyntax { } extension MacroExpansionDeclSyntax { + public var unexpectedBetweenPoundAndMacroName: UnexpectedNodesSyntax? { + get { + return unexpectedBetweenPoundAndModuleSelector + } + set { + unexpectedBetweenPoundAndModuleSelector = newValue + } + } + @available(*, deprecated, renamed: "unexpectedBetweenModifiersAndPound") public var unexpectedBetweenModifiersAndPoundToken: UnexpectedNodesSyntax? { get { @@ -4667,13 +4732,13 @@ extension MacroExpansionDeclSyntax { } } - @available(*, deprecated, renamed: "unexpectedBetweenPoundAndMacroName") + @available(*, deprecated, renamed: "unexpectedBetweenPoundAndModuleSelector") public var unexpectedBetweenPoundTokenAndMacro: UnexpectedNodesSyntax? { get { - return unexpectedBetweenPoundAndMacroName + return unexpectedBetweenPoundAndModuleSelector } set { - unexpectedBetweenPoundAndMacroName = newValue + unexpectedBetweenPoundAndModuleSelector = newValue } } @@ -4747,7 +4812,61 @@ extension MacroExpansionDeclSyntax { } } - @available(*, deprecated, renamed: "init(leadingTrivia:_:attributes:_:modifiers:_:pound:_:macroName:_:genericArgumentClause:_:leftParen:_:arguments:_:rightParen:_:trailingClosure:_:additionalTrailingClosures:_:trailingTrivia:)") + public init( + leadingTrivia: Trivia? = nil, + _ unexpectedBeforeAttributes: UnexpectedNodesSyntax? = nil, + attributes: AttributeListSyntax = [], + _ unexpectedBetweenAttributesAndModifiers: UnexpectedNodesSyntax? = nil, + modifiers: DeclModifierListSyntax = [], + _ unexpectedBetweenModifiersAndPound: UnexpectedNodesSyntax? = nil, + pound: TokenSyntax = .poundToken(), + _ unexpectedBetweenPoundAndMacroName: UnexpectedNodesSyntax? = nil, + macroName: TokenSyntax, + _ unexpectedBetweenMacroNameAndGenericArgumentClause: UnexpectedNodesSyntax? = nil, + genericArgumentClause: GenericArgumentClauseSyntax? = nil, + _ unexpectedBetweenGenericArgumentClauseAndLeftParen: UnexpectedNodesSyntax? = nil, + leftParen: TokenSyntax? = nil, + _ unexpectedBetweenLeftParenAndArguments: UnexpectedNodesSyntax? = nil, + arguments: LabeledExprListSyntax, + _ unexpectedBetweenArgumentsAndRightParen: UnexpectedNodesSyntax? = nil, + rightParen: TokenSyntax? = nil, + _ unexpectedBetweenRightParenAndTrailingClosure: UnexpectedNodesSyntax? = nil, + trailingClosure: ClosureExprSyntax? = nil, + _ unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures: UnexpectedNodesSyntax? = nil, + additionalTrailingClosures: MultipleTrailingClosureElementListSyntax = [], + _ unexpectedAfterAdditionalTrailingClosures: UnexpectedNodesSyntax? = nil, + trailingTrivia: Trivia? = nil + ) { + self.init( + leadingTrivia: leadingTrivia, + unexpectedBeforeAttributes, + attributes: attributes, + unexpectedBetweenAttributesAndModifiers, + modifiers: modifiers, + unexpectedBetweenModifiersAndPound, + pound: pound, + unexpectedBetweenPoundAndMacroName, + moduleSelector: nil, + nil, + macroName: macroName, + unexpectedBetweenMacroNameAndGenericArgumentClause, + genericArgumentClause: genericArgumentClause, + unexpectedBetweenGenericArgumentClauseAndLeftParen, + leftParen: leftParen, + unexpectedBetweenLeftParenAndArguments, + arguments: arguments, + unexpectedBetweenArgumentsAndRightParen, + rightParen: rightParen, + unexpectedBetweenRightParenAndTrailingClosure, + trailingClosure: trailingClosure, + unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures, + additionalTrailingClosures: additionalTrailingClosures, + unexpectedAfterAdditionalTrailingClosures, + trailingTrivia: trailingTrivia + ) + } + + @available(*, deprecated, renamed: "init(leadingTrivia:_:attributes:_:modifiers:_:pound:_:moduleSelector:_:macroName:_:genericArgumentClause:_:leftParen:_:arguments:_:rightParen:_:trailingClosure:_:additionalTrailingClosures:_:trailingTrivia:)") @_disfavoredOverload public init( leadingTrivia: Trivia? = nil, @@ -4783,6 +4902,8 @@ extension MacroExpansionDeclSyntax { unexpectedBetweenModifiersAndPoundToken, pound: poundToken, unexpectedBetweenPoundTokenAndMacro, + moduleSelector: nil, + nil, macroName: macro, unexpectedBetweenMacroAndGenericArguments, genericArgumentClause: genericArguments, @@ -4803,6 +4924,15 @@ extension MacroExpansionDeclSyntax { } extension MacroExpansionExprSyntax { + public var unexpectedBetweenPoundAndMacroName: UnexpectedNodesSyntax? { + get { + return unexpectedBetweenPoundAndModuleSelector + } + set { + unexpectedBetweenPoundAndModuleSelector = newValue + } + } + @available(*, deprecated, renamed: "unexpectedBeforePound") public var unexpectedBeforePoundToken: UnexpectedNodesSyntax? { get { @@ -4823,13 +4953,13 @@ extension MacroExpansionExprSyntax { } } - @available(*, deprecated, renamed: "unexpectedBetweenPoundAndMacroName") + @available(*, deprecated, renamed: "unexpectedBetweenPoundAndModuleSelector") public var unexpectedBetweenPoundTokenAndMacro: UnexpectedNodesSyntax? { get { - return unexpectedBetweenPoundAndMacroName + return unexpectedBetweenPoundAndModuleSelector } set { - unexpectedBetweenPoundAndMacroName = newValue + unexpectedBetweenPoundAndModuleSelector = newValue } } @@ -4903,7 +5033,53 @@ extension MacroExpansionExprSyntax { } } - @available(*, deprecated, renamed: "init(leadingTrivia:_:pound:_:macroName:_:genericArgumentClause:_:leftParen:_:arguments:_:rightParen:_:trailingClosure:_:additionalTrailingClosures:_:trailingTrivia:)") + public init( + leadingTrivia: Trivia? = nil, + _ unexpectedBeforePound: UnexpectedNodesSyntax? = nil, + pound: TokenSyntax = .poundToken(), + _ unexpectedBetweenPoundAndMacroName: UnexpectedNodesSyntax? = nil, + macroName: TokenSyntax, + _ unexpectedBetweenMacroNameAndGenericArgumentClause: UnexpectedNodesSyntax? = nil, + genericArgumentClause: GenericArgumentClauseSyntax? = nil, + _ unexpectedBetweenGenericArgumentClauseAndLeftParen: UnexpectedNodesSyntax? = nil, + leftParen: TokenSyntax? = nil, + _ unexpectedBetweenLeftParenAndArguments: UnexpectedNodesSyntax? = nil, + arguments: LabeledExprListSyntax, + _ unexpectedBetweenArgumentsAndRightParen: UnexpectedNodesSyntax? = nil, + rightParen: TokenSyntax? = nil, + _ unexpectedBetweenRightParenAndTrailingClosure: UnexpectedNodesSyntax? = nil, + trailingClosure: ClosureExprSyntax? = nil, + _ unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures: UnexpectedNodesSyntax? = nil, + additionalTrailingClosures: MultipleTrailingClosureElementListSyntax = [], + _ unexpectedAfterAdditionalTrailingClosures: UnexpectedNodesSyntax? = nil, + trailingTrivia: Trivia? = nil + ) { + self.init( + leadingTrivia: leadingTrivia, + unexpectedBeforePound, + pound: pound, + unexpectedBetweenPoundAndMacroName, + moduleSelector: nil, + nil, + macroName: macroName, + unexpectedBetweenMacroNameAndGenericArgumentClause, + genericArgumentClause: genericArgumentClause, + unexpectedBetweenGenericArgumentClauseAndLeftParen, + leftParen: leftParen, + unexpectedBetweenLeftParenAndArguments, + arguments: arguments, + unexpectedBetweenArgumentsAndRightParen, + rightParen: rightParen, + unexpectedBetweenRightParenAndTrailingClosure, + trailingClosure: trailingClosure, + unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures, + additionalTrailingClosures: additionalTrailingClosures, + unexpectedAfterAdditionalTrailingClosures, + trailingTrivia: trailingTrivia + ) + } + + @available(*, deprecated, renamed: "init(leadingTrivia:_:pound:_:moduleSelector:_:macroName:_:genericArgumentClause:_:leftParen:_:arguments:_:rightParen:_:trailingClosure:_:additionalTrailingClosures:_:trailingTrivia:)") @_disfavoredOverload public init( leadingTrivia: Trivia? = nil, @@ -4931,6 +5107,8 @@ extension MacroExpansionExprSyntax { unexpectedBeforePoundToken, pound: poundToken, unexpectedBetweenPoundTokenAndMacro, + moduleSelector: nil, + nil, macroName: macro, unexpectedBetweenMacroAndGenericArguments, genericArgumentClause: genericArguments, @@ -5008,6 +5186,47 @@ extension MemberAccessExprSyntax { } } +extension MemberTypeSyntax { + public var unexpectedBetweenPeriodAndName: UnexpectedNodesSyntax? { + get { + return unexpectedBetweenPeriodAndModuleSelector + } + set { + unexpectedBetweenPeriodAndModuleSelector = newValue + } + } + + public init( + leadingTrivia: Trivia? = nil, + _ unexpectedBeforeBaseType: UnexpectedNodesSyntax? = nil, + baseType: some TypeSyntaxProtocol, + _ unexpectedBetweenBaseTypeAndPeriod: UnexpectedNodesSyntax? = nil, + period: TokenSyntax = .periodToken(), + _ unexpectedBetweenPeriodAndName: UnexpectedNodesSyntax? = nil, + name: TokenSyntax, + _ unexpectedBetweenNameAndGenericArgumentClause: UnexpectedNodesSyntax? = nil, + genericArgumentClause: GenericArgumentClauseSyntax? = nil, + _ unexpectedAfterGenericArgumentClause: UnexpectedNodesSyntax? = nil, + trailingTrivia: Trivia? = nil + ) { + self.init( + leadingTrivia: leadingTrivia, + unexpectedBeforeBaseType, + baseType: baseType, + unexpectedBetweenBaseTypeAndPeriod, + period: period, + unexpectedBetweenPeriodAndName, + moduleSelector: nil, + nil, + name: name, + unexpectedBetweenNameAndGenericArgumentClause, + genericArgumentClause: genericArgumentClause, + unexpectedAfterGenericArgumentClause, + trailingTrivia: trailingTrivia + ) + } +} + extension MetatypeTypeSyntax { @available(*, deprecated, renamed: "unexpectedBetweenPeriodAndMetatypeSpecifier") public var unexpectedBetweenPeriodAndTypeOrProtocol: UnexpectedNodesSyntax? { @@ -5066,6 +5285,64 @@ extension MetatypeTypeSyntax { } } +extension MissingExprSyntax { + public var unexpectedBeforePlaceholder: UnexpectedNodesSyntax? { + get { + return unexpectedBeforeModuleSelector + } + set { + unexpectedBeforeModuleSelector = newValue + } + } + + public init( + leadingTrivia: Trivia? = nil, + _ unexpectedBeforePlaceholder: UnexpectedNodesSyntax? = nil, + placeholder: TokenSyntax, + _ unexpectedAfterPlaceholder: UnexpectedNodesSyntax? = nil, + trailingTrivia: Trivia? = nil + ) { + self.init( + leadingTrivia: leadingTrivia, + unexpectedBeforePlaceholder, + moduleSelector: nil, + nil, + placeholder: placeholder, + unexpectedAfterPlaceholder, + trailingTrivia: trailingTrivia + ) + } +} + +extension MissingTypeSyntax { + public var unexpectedBeforePlaceholder: UnexpectedNodesSyntax? { + get { + return unexpectedBeforeModuleSelector + } + set { + unexpectedBeforeModuleSelector = newValue + } + } + + public init( + leadingTrivia: Trivia? = nil, + _ unexpectedBeforePlaceholder: UnexpectedNodesSyntax? = nil, + placeholder: TokenSyntax, + _ unexpectedAfterPlaceholder: UnexpectedNodesSyntax? = nil, + trailingTrivia: Trivia? = nil + ) { + self.init( + leadingTrivia: leadingTrivia, + unexpectedBeforePlaceholder, + moduleSelector: nil, + nil, + placeholder: placeholder, + unexpectedAfterPlaceholder, + trailingTrivia: trailingTrivia + ) + } +} + extension NamedOpaqueReturnTypeSyntax { @available(*, deprecated, renamed: "unexpectedBeforeGenericParameterClause") public var unexpectedBeforeGenericParameters: UnexpectedNodesSyntax? { diff --git a/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift b/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift index 134ae3fcaf8..b9e02ebdaac 100644 --- a/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift +++ b/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift @@ -1551,6 +1551,16 @@ open class SyntaxAnyVisitor: SyntaxVisitor { visitAnyPost(node._syntaxNode) } + @_spi(ExperimentalLanguageFeatures) + override open func visit(_ node: ModuleSelectorSyntax) -> SyntaxVisitorContinueKind { + return visitAny(node._syntaxNode) + } + + @_spi(ExperimentalLanguageFeatures) + override open func visitPost(_ node: ModuleSelectorSyntax) { + visitAnyPost(node._syntaxNode) + } + override open func visit(_ node: MultipleTrailingClosureElementListSyntax) -> SyntaxVisitorContinueKind { return visitAny(node._syntaxNode) } diff --git a/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift b/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift index 3268316597d..4faaeada696 100644 --- a/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift +++ b/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift @@ -1696,6 +1696,7 @@ extension Syntax { .node(MissingStmtSyntax.self), .node(MissingSyntax.self), .node(MissingTypeSyntax.self), + .node(ModuleSelectorSyntax.self), .node(MultipleTrailingClosureElementListSyntax.self), .node(MultipleTrailingClosureElementSyntax.self), .node(NamedOpaqueReturnTypeSyntax.self), diff --git a/Sources/SwiftSyntax/generated/SyntaxEnum.swift b/Sources/SwiftSyntax/generated/SyntaxEnum.swift index b94aae22e71..bf2a5149ed5 100644 --- a/Sources/SwiftSyntax/generated/SyntaxEnum.swift +++ b/Sources/SwiftSyntax/generated/SyntaxEnum.swift @@ -211,6 +211,8 @@ public enum SyntaxEnum: Sendable { case missingStmt(MissingStmtSyntax) case missing(MissingSyntax) case missingType(MissingTypeSyntax) + @_spi(ExperimentalLanguageFeatures) + case moduleSelector(ModuleSelectorSyntax) case multipleTrailingClosureElementList(MultipleTrailingClosureElementListSyntax) case multipleTrailingClosureElement(MultipleTrailingClosureElementSyntax) case namedOpaqueReturnType(NamedOpaqueReturnTypeSyntax) @@ -695,6 +697,8 @@ extension Syntax { return .missing(MissingSyntax(self)!) case .missingType: return .missingType(MissingTypeSyntax(self)!) + case .moduleSelector: + return .moduleSelector(ModuleSelectorSyntax(self)!) case .multipleTrailingClosureElementList: return .multipleTrailingClosureElementList(MultipleTrailingClosureElementListSyntax(self)!) case .multipleTrailingClosureElement: diff --git a/Sources/SwiftSyntax/generated/SyntaxKind.swift b/Sources/SwiftSyntax/generated/SyntaxKind.swift index dcfaf4e18b0..ce80e735c79 100644 --- a/Sources/SwiftSyntax/generated/SyntaxKind.swift +++ b/Sources/SwiftSyntax/generated/SyntaxKind.swift @@ -211,6 +211,8 @@ public enum SyntaxKind: Sendable { case missingStmt case missing case missingType + @_spi(ExperimentalLanguageFeatures) + case moduleSelector case multipleTrailingClosureElementList case multipleTrailingClosureElement case namedOpaqueReturnType @@ -820,6 +822,8 @@ public enum SyntaxKind: Sendable { return MissingSyntax.self case .missingType: return MissingTypeSyntax.self + case .moduleSelector: + return ModuleSelectorSyntax.self case .multipleTrailingClosureElementList: return MultipleTrailingClosureElementListSyntax.self case .multipleTrailingClosureElement: diff --git a/Sources/SwiftSyntax/generated/SyntaxRewriter.swift b/Sources/SwiftSyntax/generated/SyntaxRewriter.swift index c82f5b54f20..d7525737573 100644 --- a/Sources/SwiftSyntax/generated/SyntaxRewriter.swift +++ b/Sources/SwiftSyntax/generated/SyntaxRewriter.swift @@ -1398,6 +1398,14 @@ open class SyntaxRewriter { return TypeSyntax(MissingTypeSyntax(unsafeCasting: visitChildren(node._syntaxNode))) } + /// Visit a `ModuleSelectorSyntax`. + /// - Parameter node: the node that is being visited + /// - Returns: the rewritten node + @_spi(ExperimentalLanguageFeatures) + open func visit(_ node: ModuleSelectorSyntax) -> ModuleSelectorSyntax { + return ModuleSelectorSyntax(unsafeCasting: visitChildren(node._syntaxNode)) + } + /// Visit a ``MultipleTrailingClosureElementListSyntax``. /// - Parameter node: the node that is being visited /// - Returns: the rewritten node @@ -3102,6 +3110,11 @@ open class SyntaxRewriter { Syntax(visit(MissingTypeSyntax(unsafeCasting: node))) } + @inline(never) + private func visitModuleSelectorSyntaxImpl(_ node: Syntax) -> Syntax { + Syntax(visit(ModuleSelectorSyntax(unsafeCasting: node))) + } + @inline(never) private func visitMultipleTrailingClosureElementListSyntaxImpl(_ node: Syntax) -> Syntax { Syntax(visit(MultipleTrailingClosureElementListSyntax(unsafeCasting: node))) @@ -4028,6 +4041,8 @@ open class SyntaxRewriter { return self.visitMissingSyntaxImpl(_:) case .missingType: return self.visitMissingTypeSyntaxImpl(_:) + case .moduleSelector: + return self.visitModuleSelectorSyntaxImpl(_:) case .multipleTrailingClosureElementList: return self.visitMultipleTrailingClosureElementListSyntaxImpl(_:) case .multipleTrailingClosureElement: @@ -4618,6 +4633,8 @@ open class SyntaxRewriter { return visitMissingSyntaxImpl(node) case .missingType: return visitMissingTypeSyntaxImpl(node) + case .moduleSelector: + return visitModuleSelectorSyntaxImpl(node) case .multipleTrailingClosureElementList: return visitMultipleTrailingClosureElementListSyntaxImpl(node) case .multipleTrailingClosureElement: diff --git a/Sources/SwiftSyntax/generated/SyntaxTraits.swift b/Sources/SwiftSyntax/generated/SyntaxTraits.swift index 368b529b45b..f982fc26147 100644 --- a/Sources/SwiftSyntax/generated/SyntaxTraits.swift +++ b/Sources/SwiftSyntax/generated/SyntaxTraits.swift @@ -205,6 +205,12 @@ public protocol FreestandingMacroExpansionSyntax: SyntaxProtocol { set } + @_spi(ExperimentalLanguageFeatures) + var moduleSelector: ModuleSelectorSyntax? { + get + set + } + /// ### Tokens /// /// For syntax trees generated by the parser, this is guaranteed to be ``. diff --git a/Sources/SwiftSyntax/generated/SyntaxVisitor.swift b/Sources/SwiftSyntax/generated/SyntaxVisitor.swift index 914b87f2692..7574bf8a235 100644 --- a/Sources/SwiftSyntax/generated/SyntaxVisitor.swift +++ b/Sources/SwiftSyntax/generated/SyntaxVisitor.swift @@ -2265,6 +2265,20 @@ open class SyntaxVisitor { open func visitPost(_ node: MissingTypeSyntax) { } + /// Visiting `ModuleSelectorSyntax` specifically. + /// - Parameter node: the node we are visiting. + /// - Returns: how should we continue visiting. + @_spi(ExperimentalLanguageFeatures) + open func visit(_ node: ModuleSelectorSyntax) -> SyntaxVisitorContinueKind { + return .visitChildren + } + + /// The function called after visiting `ModuleSelectorSyntax` and its descendants. + /// - node: the node we just finished visiting. + @_spi(ExperimentalLanguageFeatures) + open func visitPost(_ node: ModuleSelectorSyntax) { + } + /// Visiting ``MultipleTrailingClosureElementListSyntax`` specifically. /// - Parameter node: the node we are visiting. /// - Returns: how should we continue visiting. @@ -5032,6 +5046,14 @@ open class SyntaxVisitor { visitPost(MissingTypeSyntax(unsafeCasting: node)) } + @inline(never) + private func visitModuleSelectorSyntaxImpl(_ node: Syntax) { + if visit(ModuleSelectorSyntax(unsafeCasting: node)) == .visitChildren { + visitChildren(node) + } + visitPost(ModuleSelectorSyntax(unsafeCasting: node)) + } + @inline(never) private func visitMultipleTrailingClosureElementListSyntaxImpl(_ node: Syntax) { if visit(MultipleTrailingClosureElementListSyntax(unsafeCasting: node)) == .visitChildren { @@ -6276,6 +6298,8 @@ open class SyntaxVisitor { return self.visitMissingSyntaxImpl(_:) case .missingType: return self.visitMissingTypeSyntaxImpl(_:) + case .moduleSelector: + return self.visitModuleSelectorSyntaxImpl(_:) case .multipleTrailingClosureElementList: return self.visitMultipleTrailingClosureElementListSyntaxImpl(_:) case .multipleTrailingClosureElement: @@ -6866,6 +6890,8 @@ open class SyntaxVisitor { self.visitMissingSyntaxImpl(node) case .missingType: self.visitMissingTypeSyntaxImpl(node) + case .moduleSelector: + self.visitModuleSelectorSyntaxImpl(node) case .multipleTrailingClosureElementList: self.visitMultipleTrailingClosureElementListSyntaxImpl(node) case .multipleTrailingClosureElement: diff --git a/Sources/SwiftSyntax/generated/TokenKind.swift b/Sources/SwiftSyntax/generated/TokenKind.swift index 10589e1b4e4..ab41c2cd4c7 100644 --- a/Sources/SwiftSyntax/generated/TokenKind.swift +++ b/Sources/SwiftSyntax/generated/TokenKind.swift @@ -21,6 +21,7 @@ public enum TokenKind: Hashable, Sendable { case backtick case binaryOperator(String) case colon + case colonColon case comma case dollarIdentifier(String) case ellipsis @@ -82,6 +83,8 @@ public enum TokenKind: Hashable, Sendable { return text case .colon: return ":" + case .colonColon: + return "::" case .comma: return "," case .dollarIdentifier(let text): @@ -187,6 +190,8 @@ public enum TokenKind: Hashable, Sendable { return "`" case .colon: return ":" + case .colonColon: + return "::" case .comma: return "," case .ellipsis: @@ -275,6 +280,8 @@ public enum TokenKind: Hashable, Sendable { return false case .colon: return true + case .colonColon: + return true case .comma: return true case .dollarIdentifier: @@ -382,6 +389,8 @@ extension TokenKind: Equatable { return lhsText == rhsText case (.colon, .colon): return true + case (.colonColon, .colonColon): + return true case (.comma, .comma): return true case (.dollarIdentifier(let lhsText), .dollarIdentifier(let rhsText)): @@ -489,6 +498,7 @@ public enum RawTokenKind: UInt8, Equatable, Hashable { case backtick case binaryOperator case colon + case colonColon case comma case dollarIdentifier case ellipsis @@ -547,6 +557,8 @@ public enum RawTokenKind: UInt8, Equatable, Hashable { return "`" case .colon: return ":" + case .colonColon: + return "::" case .comma: return "," case .ellipsis: @@ -633,6 +645,8 @@ public enum RawTokenKind: UInt8, Equatable, Hashable { return false case .colon: return true + case .colonColon: + return true case .comma: return true case .dollarIdentifier: @@ -747,6 +761,9 @@ extension TokenKind { case .colon: precondition(text.isEmpty || rawKind.defaultText.map(String.init) == text) return .colon + case .colonColon: + precondition(text.isEmpty || rawKind.defaultText.map(String.init) == text) + return .colonColon case .comma: precondition(text.isEmpty || rawKind.defaultText.map(String.init) == text) return .comma @@ -889,6 +906,8 @@ extension TokenKind { return (.binaryOperator, str) case .colon: return (.colon, nil) + case .colonColon: + return (.colonColon, nil) case .comma: return (.comma, nil) case .dollarIdentifier(let str): diff --git a/Sources/SwiftSyntax/generated/Tokens.swift b/Sources/SwiftSyntax/generated/Tokens.swift index 421aa3ed3d9..30ec618c5a4 100644 --- a/Sources/SwiftSyntax/generated/Tokens.swift +++ b/Sources/SwiftSyntax/generated/Tokens.swift @@ -93,6 +93,19 @@ extension TokenSyntax { ) } + public static func colonColonToken( + leadingTrivia: Trivia = [], + trailingTrivia: Trivia = [], + presence: SourcePresence = .present + ) -> TokenSyntax { + return TokenSyntax( + .colonColon, + leadingTrivia: leadingTrivia, + trailingTrivia: trailingTrivia, + presence: presence + ) + } + public static func commaToken( leadingTrivia: Trivia = [], trailingTrivia: Trivia = [], diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesD.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesD.swift index 79480c99c6b..53e55832a34 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesD.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesD.swift @@ -450,7 +450,9 @@ public struct RawDeclReferenceExprSyntax: RawExprSyntaxNodeProtocol { } public init( - _ unexpectedBeforeBaseName: RawUnexpectedNodesSyntax? = nil, + _ unexpectedBeforeModuleSelector: RawUnexpectedNodesSyntax? = nil, + moduleSelector: RawModuleSelectorSyntax?, + _ unexpectedBetweenModuleSelectorAndBaseName: RawUnexpectedNodesSyntax? = nil, baseName: RawTokenSyntax, _ unexpectedBetweenBaseNameAndArgumentNames: RawUnexpectedNodesSyntax? = nil, argumentNames: RawDeclNameArgumentsSyntax?, @@ -458,35 +460,45 @@ public struct RawDeclReferenceExprSyntax: RawExprSyntaxNodeProtocol { arena: __shared RawSyntaxArena ) { let raw = RawSyntax.makeLayout( - kind: .declReferenceExpr, uninitializedCount: 5, arena: arena) { layout in + kind: .declReferenceExpr, uninitializedCount: 7, arena: arena) { layout in layout.initialize(repeating: nil) - layout[0] = unexpectedBeforeBaseName?.raw - layout[1] = baseName.raw - layout[2] = unexpectedBetweenBaseNameAndArgumentNames?.raw - layout[3] = argumentNames?.raw - layout[4] = unexpectedAfterArgumentNames?.raw + layout[0] = unexpectedBeforeModuleSelector?.raw + layout[1] = moduleSelector?.raw + layout[2] = unexpectedBetweenModuleSelectorAndBaseName?.raw + layout[3] = baseName.raw + layout[4] = unexpectedBetweenBaseNameAndArgumentNames?.raw + layout[5] = argumentNames?.raw + layout[6] = unexpectedAfterArgumentNames?.raw } self.init(unchecked: raw) } - public var unexpectedBeforeBaseName: RawUnexpectedNodesSyntax? { + public var unexpectedBeforeModuleSelector: RawUnexpectedNodesSyntax? { layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:)) } + public var moduleSelector: RawModuleSelectorSyntax? { + layoutView.children[1].map(RawModuleSelectorSyntax.init(raw:)) + } + + public var unexpectedBetweenModuleSelectorAndBaseName: RawUnexpectedNodesSyntax? { + layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) + } + public var baseName: RawTokenSyntax { - layoutView.children[1].map(RawTokenSyntax.init(raw:))! + layoutView.children[3].map(RawTokenSyntax.init(raw:))! } public var unexpectedBetweenBaseNameAndArgumentNames: RawUnexpectedNodesSyntax? { - layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) } public var argumentNames: RawDeclNameArgumentsSyntax? { - layoutView.children[3].map(RawDeclNameArgumentsSyntax.init(raw:)) + layoutView.children[5].map(RawDeclNameArgumentsSyntax.init(raw:)) } public var unexpectedAfterArgumentNames: RawUnexpectedNodesSyntax? { - layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:)) } } diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesGHI.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesGHI.swift index dfe5fc4d0e6..98dd27f0db7 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesGHI.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesGHI.swift @@ -988,7 +988,9 @@ public struct RawIdentifierTypeSyntax: RawTypeSyntaxNodeProtocol { } public init( - _ unexpectedBeforeName: RawUnexpectedNodesSyntax? = nil, + _ unexpectedBeforeModuleSelector: RawUnexpectedNodesSyntax? = nil, + moduleSelector: RawModuleSelectorSyntax?, + _ unexpectedBetweenModuleSelectorAndName: RawUnexpectedNodesSyntax? = nil, name: RawTokenSyntax, _ unexpectedBetweenNameAndGenericArgumentClause: RawUnexpectedNodesSyntax? = nil, genericArgumentClause: RawGenericArgumentClauseSyntax?, @@ -996,35 +998,45 @@ public struct RawIdentifierTypeSyntax: RawTypeSyntaxNodeProtocol { arena: __shared RawSyntaxArena ) { let raw = RawSyntax.makeLayout( - kind: .identifierType, uninitializedCount: 5, arena: arena) { layout in + kind: .identifierType, uninitializedCount: 7, arena: arena) { layout in layout.initialize(repeating: nil) - layout[0] = unexpectedBeforeName?.raw - layout[1] = name.raw - layout[2] = unexpectedBetweenNameAndGenericArgumentClause?.raw - layout[3] = genericArgumentClause?.raw - layout[4] = unexpectedAfterGenericArgumentClause?.raw + layout[0] = unexpectedBeforeModuleSelector?.raw + layout[1] = moduleSelector?.raw + layout[2] = unexpectedBetweenModuleSelectorAndName?.raw + layout[3] = name.raw + layout[4] = unexpectedBetweenNameAndGenericArgumentClause?.raw + layout[5] = genericArgumentClause?.raw + layout[6] = unexpectedAfterGenericArgumentClause?.raw } self.init(unchecked: raw) } - public var unexpectedBeforeName: RawUnexpectedNodesSyntax? { + public var unexpectedBeforeModuleSelector: RawUnexpectedNodesSyntax? { layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:)) } + public var moduleSelector: RawModuleSelectorSyntax? { + layoutView.children[1].map(RawModuleSelectorSyntax.init(raw:)) + } + + public var unexpectedBetweenModuleSelectorAndName: RawUnexpectedNodesSyntax? { + layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) + } + public var name: RawTokenSyntax { - layoutView.children[1].map(RawTokenSyntax.init(raw:))! + layoutView.children[3].map(RawTokenSyntax.init(raw:))! } public var unexpectedBetweenNameAndGenericArgumentClause: RawUnexpectedNodesSyntax? { - layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) } public var genericArgumentClause: RawGenericArgumentClauseSyntax? { - layoutView.children[3].map(RawGenericArgumentClauseSyntax.init(raw:)) + layoutView.children[5].map(RawGenericArgumentClauseSyntax.init(raw:)) } public var unexpectedAfterGenericArgumentClause: RawUnexpectedNodesSyntax? { - layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:)) } } diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesJKLMN.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesJKLMN.swift index 8e6766d2c4f..a44209f348c 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesJKLMN.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesJKLMN.swift @@ -1429,7 +1429,9 @@ public struct RawMacroExpansionDeclSyntax: RawDeclSyntaxNodeProtocol { modifiers: RawDeclModifierListSyntax, _ unexpectedBetweenModifiersAndPound: RawUnexpectedNodesSyntax? = nil, pound: RawTokenSyntax, - _ unexpectedBetweenPoundAndMacroName: RawUnexpectedNodesSyntax? = nil, + _ unexpectedBetweenPoundAndModuleSelector: RawUnexpectedNodesSyntax? = nil, + moduleSelector: RawModuleSelectorSyntax?, + _ unexpectedBetweenModuleSelectorAndMacroName: RawUnexpectedNodesSyntax? = nil, macroName: RawTokenSyntax, _ unexpectedBetweenMacroNameAndGenericArgumentClause: RawUnexpectedNodesSyntax? = nil, genericArgumentClause: RawGenericArgumentClauseSyntax?, @@ -1447,7 +1449,7 @@ public struct RawMacroExpansionDeclSyntax: RawDeclSyntaxNodeProtocol { arena: __shared RawSyntaxArena ) { let raw = RawSyntax.makeLayout( - kind: .macroExpansionDecl, uninitializedCount: 21, arena: arena) { layout in + kind: .macroExpansionDecl, uninitializedCount: 23, arena: arena) { layout in layout.initialize(repeating: nil) layout[0] = unexpectedBeforeAttributes?.raw layout[1] = attributes.raw @@ -1455,21 +1457,23 @@ public struct RawMacroExpansionDeclSyntax: RawDeclSyntaxNodeProtocol { layout[3] = modifiers.raw layout[4] = unexpectedBetweenModifiersAndPound?.raw layout[5] = pound.raw - layout[6] = unexpectedBetweenPoundAndMacroName?.raw - layout[7] = macroName.raw - layout[8] = unexpectedBetweenMacroNameAndGenericArgumentClause?.raw - layout[9] = genericArgumentClause?.raw - layout[10] = unexpectedBetweenGenericArgumentClauseAndLeftParen?.raw - layout[11] = leftParen?.raw - layout[12] = unexpectedBetweenLeftParenAndArguments?.raw - layout[13] = arguments.raw - layout[14] = unexpectedBetweenArgumentsAndRightParen?.raw - layout[15] = rightParen?.raw - layout[16] = unexpectedBetweenRightParenAndTrailingClosure?.raw - layout[17] = trailingClosure?.raw - layout[18] = unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures?.raw - layout[19] = additionalTrailingClosures.raw - layout[20] = unexpectedAfterAdditionalTrailingClosures?.raw + layout[6] = unexpectedBetweenPoundAndModuleSelector?.raw + layout[7] = moduleSelector?.raw + layout[8] = unexpectedBetweenModuleSelectorAndMacroName?.raw + layout[9] = macroName.raw + layout[10] = unexpectedBetweenMacroNameAndGenericArgumentClause?.raw + layout[11] = genericArgumentClause?.raw + layout[12] = unexpectedBetweenGenericArgumentClauseAndLeftParen?.raw + layout[13] = leftParen?.raw + layout[14] = unexpectedBetweenLeftParenAndArguments?.raw + layout[15] = arguments.raw + layout[16] = unexpectedBetweenArgumentsAndRightParen?.raw + layout[17] = rightParen?.raw + layout[18] = unexpectedBetweenRightParenAndTrailingClosure?.raw + layout[19] = trailingClosure?.raw + layout[20] = unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures?.raw + layout[21] = additionalTrailingClosures.raw + layout[22] = unexpectedAfterAdditionalTrailingClosures?.raw } self.init(unchecked: raw) } @@ -1498,64 +1502,72 @@ public struct RawMacroExpansionDeclSyntax: RawDeclSyntaxNodeProtocol { layoutView.children[5].map(RawTokenSyntax.init(raw:))! } - public var unexpectedBetweenPoundAndMacroName: RawUnexpectedNodesSyntax? { + public var unexpectedBetweenPoundAndModuleSelector: RawUnexpectedNodesSyntax? { layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:)) } + public var moduleSelector: RawModuleSelectorSyntax? { + layoutView.children[7].map(RawModuleSelectorSyntax.init(raw:)) + } + + public var unexpectedBetweenModuleSelectorAndMacroName: RawUnexpectedNodesSyntax? { + layoutView.children[8].map(RawUnexpectedNodesSyntax.init(raw:)) + } + public var macroName: RawTokenSyntax { - layoutView.children[7].map(RawTokenSyntax.init(raw:))! + layoutView.children[9].map(RawTokenSyntax.init(raw:))! } public var unexpectedBetweenMacroNameAndGenericArgumentClause: RawUnexpectedNodesSyntax? { - layoutView.children[8].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[10].map(RawUnexpectedNodesSyntax.init(raw:)) } public var genericArgumentClause: RawGenericArgumentClauseSyntax? { - layoutView.children[9].map(RawGenericArgumentClauseSyntax.init(raw:)) + layoutView.children[11].map(RawGenericArgumentClauseSyntax.init(raw:)) } public var unexpectedBetweenGenericArgumentClauseAndLeftParen: RawUnexpectedNodesSyntax? { - layoutView.children[10].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[12].map(RawUnexpectedNodesSyntax.init(raw:)) } public var leftParen: RawTokenSyntax? { - layoutView.children[11].map(RawTokenSyntax.init(raw:)) + layoutView.children[13].map(RawTokenSyntax.init(raw:)) } public var unexpectedBetweenLeftParenAndArguments: RawUnexpectedNodesSyntax? { - layoutView.children[12].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[14].map(RawUnexpectedNodesSyntax.init(raw:)) } public var arguments: RawLabeledExprListSyntax { - layoutView.children[13].map(RawLabeledExprListSyntax.init(raw:))! + layoutView.children[15].map(RawLabeledExprListSyntax.init(raw:))! } public var unexpectedBetweenArgumentsAndRightParen: RawUnexpectedNodesSyntax? { - layoutView.children[14].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[16].map(RawUnexpectedNodesSyntax.init(raw:)) } public var rightParen: RawTokenSyntax? { - layoutView.children[15].map(RawTokenSyntax.init(raw:)) + layoutView.children[17].map(RawTokenSyntax.init(raw:)) } public var unexpectedBetweenRightParenAndTrailingClosure: RawUnexpectedNodesSyntax? { - layoutView.children[16].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[18].map(RawUnexpectedNodesSyntax.init(raw:)) } public var trailingClosure: RawClosureExprSyntax? { - layoutView.children[17].map(RawClosureExprSyntax.init(raw:)) + layoutView.children[19].map(RawClosureExprSyntax.init(raw:)) } public var unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures: RawUnexpectedNodesSyntax? { - layoutView.children[18].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[20].map(RawUnexpectedNodesSyntax.init(raw:)) } public var additionalTrailingClosures: RawMultipleTrailingClosureElementListSyntax { - layoutView.children[19].map(RawMultipleTrailingClosureElementListSyntax.init(raw:))! + layoutView.children[21].map(RawMultipleTrailingClosureElementListSyntax.init(raw:))! } public var unexpectedAfterAdditionalTrailingClosures: RawUnexpectedNodesSyntax? { - layoutView.children[20].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[22].map(RawUnexpectedNodesSyntax.init(raw:)) } } @@ -1591,7 +1603,9 @@ public struct RawMacroExpansionExprSyntax: RawExprSyntaxNodeProtocol { public init( _ unexpectedBeforePound: RawUnexpectedNodesSyntax? = nil, pound: RawTokenSyntax, - _ unexpectedBetweenPoundAndMacroName: RawUnexpectedNodesSyntax? = nil, + _ unexpectedBetweenPoundAndModuleSelector: RawUnexpectedNodesSyntax? = nil, + moduleSelector: RawModuleSelectorSyntax?, + _ unexpectedBetweenModuleSelectorAndMacroName: RawUnexpectedNodesSyntax? = nil, macroName: RawTokenSyntax, _ unexpectedBetweenMacroNameAndGenericArgumentClause: RawUnexpectedNodesSyntax? = nil, genericArgumentClause: RawGenericArgumentClauseSyntax?, @@ -1609,25 +1623,27 @@ public struct RawMacroExpansionExprSyntax: RawExprSyntaxNodeProtocol { arena: __shared RawSyntaxArena ) { let raw = RawSyntax.makeLayout( - kind: .macroExpansionExpr, uninitializedCount: 17, arena: arena) { layout in + kind: .macroExpansionExpr, uninitializedCount: 19, arena: arena) { layout in layout.initialize(repeating: nil) layout[0] = unexpectedBeforePound?.raw layout[1] = pound.raw - layout[2] = unexpectedBetweenPoundAndMacroName?.raw - layout[3] = macroName.raw - layout[4] = unexpectedBetweenMacroNameAndGenericArgumentClause?.raw - layout[5] = genericArgumentClause?.raw - layout[6] = unexpectedBetweenGenericArgumentClauseAndLeftParen?.raw - layout[7] = leftParen?.raw - layout[8] = unexpectedBetweenLeftParenAndArguments?.raw - layout[9] = arguments.raw - layout[10] = unexpectedBetweenArgumentsAndRightParen?.raw - layout[11] = rightParen?.raw - layout[12] = unexpectedBetweenRightParenAndTrailingClosure?.raw - layout[13] = trailingClosure?.raw - layout[14] = unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures?.raw - layout[15] = additionalTrailingClosures.raw - layout[16] = unexpectedAfterAdditionalTrailingClosures?.raw + layout[2] = unexpectedBetweenPoundAndModuleSelector?.raw + layout[3] = moduleSelector?.raw + layout[4] = unexpectedBetweenModuleSelectorAndMacroName?.raw + layout[5] = macroName.raw + layout[6] = unexpectedBetweenMacroNameAndGenericArgumentClause?.raw + layout[7] = genericArgumentClause?.raw + layout[8] = unexpectedBetweenGenericArgumentClauseAndLeftParen?.raw + layout[9] = leftParen?.raw + layout[10] = unexpectedBetweenLeftParenAndArguments?.raw + layout[11] = arguments.raw + layout[12] = unexpectedBetweenArgumentsAndRightParen?.raw + layout[13] = rightParen?.raw + layout[14] = unexpectedBetweenRightParenAndTrailingClosure?.raw + layout[15] = trailingClosure?.raw + layout[16] = unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures?.raw + layout[17] = additionalTrailingClosures.raw + layout[18] = unexpectedAfterAdditionalTrailingClosures?.raw } self.init(unchecked: raw) } @@ -1640,64 +1656,72 @@ public struct RawMacroExpansionExprSyntax: RawExprSyntaxNodeProtocol { layoutView.children[1].map(RawTokenSyntax.init(raw:))! } - public var unexpectedBetweenPoundAndMacroName: RawUnexpectedNodesSyntax? { + public var unexpectedBetweenPoundAndModuleSelector: RawUnexpectedNodesSyntax? { layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) } + public var moduleSelector: RawModuleSelectorSyntax? { + layoutView.children[3].map(RawModuleSelectorSyntax.init(raw:)) + } + + public var unexpectedBetweenModuleSelectorAndMacroName: RawUnexpectedNodesSyntax? { + layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) + } + public var macroName: RawTokenSyntax { - layoutView.children[3].map(RawTokenSyntax.init(raw:))! + layoutView.children[5].map(RawTokenSyntax.init(raw:))! } public var unexpectedBetweenMacroNameAndGenericArgumentClause: RawUnexpectedNodesSyntax? { - layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:)) } public var genericArgumentClause: RawGenericArgumentClauseSyntax? { - layoutView.children[5].map(RawGenericArgumentClauseSyntax.init(raw:)) + layoutView.children[7].map(RawGenericArgumentClauseSyntax.init(raw:)) } public var unexpectedBetweenGenericArgumentClauseAndLeftParen: RawUnexpectedNodesSyntax? { - layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[8].map(RawUnexpectedNodesSyntax.init(raw:)) } public var leftParen: RawTokenSyntax? { - layoutView.children[7].map(RawTokenSyntax.init(raw:)) + layoutView.children[9].map(RawTokenSyntax.init(raw:)) } public var unexpectedBetweenLeftParenAndArguments: RawUnexpectedNodesSyntax? { - layoutView.children[8].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[10].map(RawUnexpectedNodesSyntax.init(raw:)) } public var arguments: RawLabeledExprListSyntax { - layoutView.children[9].map(RawLabeledExprListSyntax.init(raw:))! + layoutView.children[11].map(RawLabeledExprListSyntax.init(raw:))! } public var unexpectedBetweenArgumentsAndRightParen: RawUnexpectedNodesSyntax? { - layoutView.children[10].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[12].map(RawUnexpectedNodesSyntax.init(raw:)) } public var rightParen: RawTokenSyntax? { - layoutView.children[11].map(RawTokenSyntax.init(raw:)) + layoutView.children[13].map(RawTokenSyntax.init(raw:)) } public var unexpectedBetweenRightParenAndTrailingClosure: RawUnexpectedNodesSyntax? { - layoutView.children[12].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[14].map(RawUnexpectedNodesSyntax.init(raw:)) } public var trailingClosure: RawClosureExprSyntax? { - layoutView.children[13].map(RawClosureExprSyntax.init(raw:)) + layoutView.children[15].map(RawClosureExprSyntax.init(raw:)) } public var unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures: RawUnexpectedNodesSyntax? { - layoutView.children[14].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[16].map(RawUnexpectedNodesSyntax.init(raw:)) } public var additionalTrailingClosures: RawMultipleTrailingClosureElementListSyntax { - layoutView.children[15].map(RawMultipleTrailingClosureElementListSyntax.init(raw:))! + layoutView.children[17].map(RawMultipleTrailingClosureElementListSyntax.init(raw:))! } public var unexpectedAfterAdditionalTrailingClosures: RawUnexpectedNodesSyntax? { - layoutView.children[16].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[18].map(RawUnexpectedNodesSyntax.init(raw:)) } } @@ -2184,7 +2208,9 @@ public struct RawMemberTypeSyntax: RawTypeSyntaxNodeProtocol { baseType: some RawTypeSyntaxNodeProtocol, _ unexpectedBetweenBaseTypeAndPeriod: RawUnexpectedNodesSyntax? = nil, period: RawTokenSyntax, - _ unexpectedBetweenPeriodAndName: RawUnexpectedNodesSyntax? = nil, + _ unexpectedBetweenPeriodAndModuleSelector: RawUnexpectedNodesSyntax? = nil, + moduleSelector: RawModuleSelectorSyntax?, + _ unexpectedBetweenModuleSelectorAndName: RawUnexpectedNodesSyntax? = nil, name: RawTokenSyntax, _ unexpectedBetweenNameAndGenericArgumentClause: RawUnexpectedNodesSyntax? = nil, genericArgumentClause: RawGenericArgumentClauseSyntax?, @@ -2192,17 +2218,19 @@ public struct RawMemberTypeSyntax: RawTypeSyntaxNodeProtocol { arena: __shared RawSyntaxArena ) { let raw = RawSyntax.makeLayout( - kind: .memberType, uninitializedCount: 9, arena: arena) { layout in + kind: .memberType, uninitializedCount: 11, arena: arena) { layout in layout.initialize(repeating: nil) layout[0] = unexpectedBeforeBaseType?.raw layout[1] = baseType.raw layout[2] = unexpectedBetweenBaseTypeAndPeriod?.raw layout[3] = period.raw - layout[4] = unexpectedBetweenPeriodAndName?.raw - layout[5] = name.raw - layout[6] = unexpectedBetweenNameAndGenericArgumentClause?.raw - layout[7] = genericArgumentClause?.raw - layout[8] = unexpectedAfterGenericArgumentClause?.raw + layout[4] = unexpectedBetweenPeriodAndModuleSelector?.raw + layout[5] = moduleSelector?.raw + layout[6] = unexpectedBetweenModuleSelectorAndName?.raw + layout[7] = name.raw + layout[8] = unexpectedBetweenNameAndGenericArgumentClause?.raw + layout[9] = genericArgumentClause?.raw + layout[10] = unexpectedAfterGenericArgumentClause?.raw } self.init(unchecked: raw) } @@ -2223,24 +2251,32 @@ public struct RawMemberTypeSyntax: RawTypeSyntaxNodeProtocol { layoutView.children[3].map(RawTokenSyntax.init(raw:))! } - public var unexpectedBetweenPeriodAndName: RawUnexpectedNodesSyntax? { + public var unexpectedBetweenPeriodAndModuleSelector: RawUnexpectedNodesSyntax? { layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) } + public var moduleSelector: RawModuleSelectorSyntax? { + layoutView.children[5].map(RawModuleSelectorSyntax.init(raw:)) + } + + public var unexpectedBetweenModuleSelectorAndName: RawUnexpectedNodesSyntax? { + layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:)) + } + public var name: RawTokenSyntax { - layoutView.children[5].map(RawTokenSyntax.init(raw:))! + layoutView.children[7].map(RawTokenSyntax.init(raw:))! } public var unexpectedBetweenNameAndGenericArgumentClause: RawUnexpectedNodesSyntax? { - layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[8].map(RawUnexpectedNodesSyntax.init(raw:)) } public var genericArgumentClause: RawGenericArgumentClauseSyntax? { - layoutView.children[7].map(RawGenericArgumentClauseSyntax.init(raw:)) + layoutView.children[9].map(RawGenericArgumentClauseSyntax.init(raw:)) } public var unexpectedAfterGenericArgumentClause: RawUnexpectedNodesSyntax? { - layoutView.children[8].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[10].map(RawUnexpectedNodesSyntax.init(raw:)) } } @@ -2438,31 +2474,43 @@ public struct RawMissingExprSyntax: RawExprSyntaxNodeProtocol { } public init( - _ unexpectedBeforePlaceholder: RawUnexpectedNodesSyntax? = nil, + _ unexpectedBeforeModuleSelector: RawUnexpectedNodesSyntax? = nil, + moduleSelector: RawModuleSelectorSyntax?, + _ unexpectedBetweenModuleSelectorAndPlaceholder: RawUnexpectedNodesSyntax? = nil, placeholder: RawTokenSyntax, _ unexpectedAfterPlaceholder: RawUnexpectedNodesSyntax? = nil, arena: __shared RawSyntaxArena ) { let raw = RawSyntax.makeLayout( - kind: .missingExpr, uninitializedCount: 3, arena: arena) { layout in + kind: .missingExpr, uninitializedCount: 5, arena: arena) { layout in layout.initialize(repeating: nil) - layout[0] = unexpectedBeforePlaceholder?.raw - layout[1] = placeholder.raw - layout[2] = unexpectedAfterPlaceholder?.raw + layout[0] = unexpectedBeforeModuleSelector?.raw + layout[1] = moduleSelector?.raw + layout[2] = unexpectedBetweenModuleSelectorAndPlaceholder?.raw + layout[3] = placeholder.raw + layout[4] = unexpectedAfterPlaceholder?.raw } self.init(unchecked: raw) } - public var unexpectedBeforePlaceholder: RawUnexpectedNodesSyntax? { + public var unexpectedBeforeModuleSelector: RawUnexpectedNodesSyntax? { layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:)) } + public var moduleSelector: RawModuleSelectorSyntax? { + layoutView.children[1].map(RawModuleSelectorSyntax.init(raw:)) + } + + public var unexpectedBetweenModuleSelectorAndPlaceholder: RawUnexpectedNodesSyntax? { + layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) + } + public var placeholder: RawTokenSyntax { - layoutView.children[1].map(RawTokenSyntax.init(raw:))! + layoutView.children[3].map(RawTokenSyntax.init(raw:))! } public var unexpectedAfterPlaceholder: RawUnexpectedNodesSyntax? { - layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) } } @@ -2670,32 +2718,115 @@ public struct RawMissingTypeSyntax: RawTypeSyntaxNodeProtocol { } public init( - _ unexpectedBeforePlaceholder: RawUnexpectedNodesSyntax? = nil, + _ unexpectedBeforeModuleSelector: RawUnexpectedNodesSyntax? = nil, + moduleSelector: RawModuleSelectorSyntax?, + _ unexpectedBetweenModuleSelectorAndPlaceholder: RawUnexpectedNodesSyntax? = nil, placeholder: RawTokenSyntax, _ unexpectedAfterPlaceholder: RawUnexpectedNodesSyntax? = nil, arena: __shared RawSyntaxArena ) { let raw = RawSyntax.makeLayout( - kind: .missingType, uninitializedCount: 3, arena: arena) { layout in + kind: .missingType, uninitializedCount: 5, arena: arena) { layout in layout.initialize(repeating: nil) - layout[0] = unexpectedBeforePlaceholder?.raw - layout[1] = placeholder.raw - layout[2] = unexpectedAfterPlaceholder?.raw + layout[0] = unexpectedBeforeModuleSelector?.raw + layout[1] = moduleSelector?.raw + layout[2] = unexpectedBetweenModuleSelectorAndPlaceholder?.raw + layout[3] = placeholder.raw + layout[4] = unexpectedAfterPlaceholder?.raw } self.init(unchecked: raw) } - public var unexpectedBeforePlaceholder: RawUnexpectedNodesSyntax? { + public var unexpectedBeforeModuleSelector: RawUnexpectedNodesSyntax? { layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:)) } + public var moduleSelector: RawModuleSelectorSyntax? { + layoutView.children[1].map(RawModuleSelectorSyntax.init(raw:)) + } + + public var unexpectedBetweenModuleSelectorAndPlaceholder: RawUnexpectedNodesSyntax? { + layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) + } + public var placeholder: RawTokenSyntax { - layoutView.children[1].map(RawTokenSyntax.init(raw:))! + layoutView.children[3].map(RawTokenSyntax.init(raw:))! } public var unexpectedAfterPlaceholder: RawUnexpectedNodesSyntax? { + layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) + } +} + +@_spi(ExperimentalLanguageFeatures) +@_spi(RawSyntax) +public struct RawModuleSelectorSyntax: RawSyntaxNodeProtocol { + @_spi(RawSyntax) + public var layoutView: RawSyntaxLayoutView { + return raw.layoutView! + } + + public static func isKindOf(_ raw: RawSyntax) -> Bool { + return raw.kind == .moduleSelector + } + + public var raw: RawSyntax + + init(raw: RawSyntax) { + precondition(Self.isKindOf(raw)) + self.raw = raw + } + + private init(unchecked raw: RawSyntax) { + self.raw = raw + } + + public init?(_ other: some RawSyntaxNodeProtocol) { + guard Self.isKindOf(other.raw) else { + return nil + } + self.init(unchecked: other.raw) + } + + public init( + _ unexpectedBeforeModuleName: RawUnexpectedNodesSyntax? = nil, + moduleName: RawTokenSyntax, + _ unexpectedBetweenModuleNameAndColonColon: RawUnexpectedNodesSyntax? = nil, + colonColon: RawTokenSyntax, + _ unexpectedAfterColonColon: RawUnexpectedNodesSyntax? = nil, + arena: __shared RawSyntaxArena + ) { + let raw = RawSyntax.makeLayout( + kind: .moduleSelector, uninitializedCount: 5, arena: arena) { layout in + layout.initialize(repeating: nil) + layout[0] = unexpectedBeforeModuleName?.raw + layout[1] = moduleName.raw + layout[2] = unexpectedBetweenModuleNameAndColonColon?.raw + layout[3] = colonColon.raw + layout[4] = unexpectedAfterColonColon?.raw + } + self.init(unchecked: raw) + } + + public var unexpectedBeforeModuleName: RawUnexpectedNodesSyntax? { + layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:)) + } + + public var moduleName: RawTokenSyntax { + layoutView.children[1].map(RawTokenSyntax.init(raw:))! + } + + public var unexpectedBetweenModuleNameAndColonColon: RawUnexpectedNodesSyntax? { layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) } + + public var colonColon: RawTokenSyntax { + layoutView.children[3].map(RawTokenSyntax.init(raw:))! + } + + public var unexpectedAfterColonColon: RawUnexpectedNodesSyntax? { + layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) + } } @_spi(RawSyntax) diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift index 4def2848664..a40b5102829 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift @@ -915,9 +915,11 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self)) } func validateDeclReferenceExprSyntax(kind: SyntaxKind, layout: RawSyntaxBuffer) { - assert(layout.count == 5) + assert(layout.count == 7) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [ + assertNoError(kind, 1, verify(layout[1], as: RawModuleSelectorSyntax?.self)) + assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax.self, tokenChoices: [ .tokenKind(.identifier), .keyword("self"), .keyword("Self"), @@ -928,9 +930,9 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { .tokenKind(.binaryOperator), .tokenKind(.integerLiteral) ])) - assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 3, verify(layout[3], as: RawDeclNameArgumentsSyntax?.self)) assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 5, verify(layout[5], as: RawDeclNameArgumentsSyntax?.self)) + assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self)) } func validateDeferStmtSyntax(kind: SyntaxKind, layout: RawSyntaxBuffer) { assert(layout.count == 5) @@ -1565,17 +1567,19 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) } func validateIdentifierTypeSyntax(kind: SyntaxKind, layout: RawSyntaxBuffer) { - assert(layout.count == 5) + assert(layout.count == 7) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [ + assertNoError(kind, 1, verify(layout[1], as: RawModuleSelectorSyntax?.self)) + assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax.self, tokenChoices: [ .tokenKind(.identifier), .keyword("Self"), .keyword("Any"), .tokenKind(.wildcard) ])) - assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 3, verify(layout[3], as: RawGenericArgumentClauseSyntax?.self)) assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 5, verify(layout[5], as: RawGenericArgumentClauseSyntax?.self)) + assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self)) } func validateIfConfigClauseListSyntax(kind: SyntaxKind, layout: RawSyntaxBuffer) { for (index, element) in layout.enumerated() { @@ -1673,7 +1677,7 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { .tokenKind(.postfixOperator) ])) assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.period)])) + assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.period), .tokenKind(.colonColon)])) assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) } func validateInOutExprSyntax(kind: SyntaxKind, layout: RawSyntaxBuffer) { @@ -1965,7 +1969,7 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { assertNoError(kind, 16, verify(layout[16], as: RawUnexpectedNodesSyntax?.self)) } func validateMacroExpansionDeclSyntax(kind: SyntaxKind, layout: RawSyntaxBuffer) { - assert(layout.count == 21) + assert(layout.count == 23) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) assertNoError(kind, 1, verify(layout[1], as: RawAttributeListSyntax.self)) assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) @@ -1973,40 +1977,44 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) assertNoError(kind, 5, verify(layout[5], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.pound)])) assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 7, verify(layout[7], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.identifier)])) + assertNoError(kind, 7, verify(layout[7], as: RawModuleSelectorSyntax?.self)) assertNoError(kind, 8, verify(layout[8], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 9, verify(layout[9], as: RawGenericArgumentClauseSyntax?.self)) + assertNoError(kind, 9, verify(layout[9], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.identifier)])) assertNoError(kind, 10, verify(layout[10], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 11, verify(layout[11], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.leftParen)])) + assertNoError(kind, 11, verify(layout[11], as: RawGenericArgumentClauseSyntax?.self)) assertNoError(kind, 12, verify(layout[12], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 13, verify(layout[13], as: RawLabeledExprListSyntax.self)) + assertNoError(kind, 13, verify(layout[13], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.leftParen)])) assertNoError(kind, 14, verify(layout[14], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 15, verify(layout[15], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.rightParen)])) + assertNoError(kind, 15, verify(layout[15], as: RawLabeledExprListSyntax.self)) assertNoError(kind, 16, verify(layout[16], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 17, verify(layout[17], as: RawClosureExprSyntax?.self)) + assertNoError(kind, 17, verify(layout[17], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.rightParen)])) assertNoError(kind, 18, verify(layout[18], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 19, verify(layout[19], as: RawMultipleTrailingClosureElementListSyntax.self)) + assertNoError(kind, 19, verify(layout[19], as: RawClosureExprSyntax?.self)) assertNoError(kind, 20, verify(layout[20], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 21, verify(layout[21], as: RawMultipleTrailingClosureElementListSyntax.self)) + assertNoError(kind, 22, verify(layout[22], as: RawUnexpectedNodesSyntax?.self)) } func validateMacroExpansionExprSyntax(kind: SyntaxKind, layout: RawSyntaxBuffer) { - assert(layout.count == 17) + assert(layout.count == 19) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.pound)])) assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.identifier)])) + assertNoError(kind, 3, verify(layout[3], as: RawModuleSelectorSyntax?.self)) assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 5, verify(layout[5], as: RawGenericArgumentClauseSyntax?.self)) + assertNoError(kind, 5, verify(layout[5], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.identifier)])) assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 7, verify(layout[7], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.leftParen)])) + assertNoError(kind, 7, verify(layout[7], as: RawGenericArgumentClauseSyntax?.self)) assertNoError(kind, 8, verify(layout[8], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 9, verify(layout[9], as: RawLabeledExprListSyntax.self)) + assertNoError(kind, 9, verify(layout[9], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.leftParen)])) assertNoError(kind, 10, verify(layout[10], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 11, verify(layout[11], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.rightParen)])) + assertNoError(kind, 11, verify(layout[11], as: RawLabeledExprListSyntax.self)) assertNoError(kind, 12, verify(layout[12], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 13, verify(layout[13], as: RawClosureExprSyntax?.self)) + assertNoError(kind, 13, verify(layout[13], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.rightParen)])) assertNoError(kind, 14, verify(layout[14], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 15, verify(layout[15], as: RawMultipleTrailingClosureElementListSyntax.self)) + assertNoError(kind, 15, verify(layout[15], as: RawClosureExprSyntax?.self)) assertNoError(kind, 16, verify(layout[16], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 17, verify(layout[17], as: RawMultipleTrailingClosureElementListSyntax.self)) + assertNoError(kind, 18, verify(layout[18], as: RawUnexpectedNodesSyntax?.self)) } func validateMatchingPatternConditionSyntax(kind: SyntaxKind, layout: RawSyntaxBuffer) { assert(layout.count == 9) @@ -2062,16 +2070,18 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self)) } func validateMemberTypeSyntax(kind: SyntaxKind, layout: RawSyntaxBuffer) { - assert(layout.count == 9) + assert(layout.count == 11) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) assertNoError(kind, 1, verify(layout[1], as: RawTypeSyntax.self)) assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.period)])) assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 5, verify(layout[5], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.identifier), .keyword("self")])) + assertNoError(kind, 5, verify(layout[5], as: RawModuleSelectorSyntax?.self)) assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 7, verify(layout[7], as: RawGenericArgumentClauseSyntax?.self)) + assertNoError(kind, 7, verify(layout[7], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.identifier), .keyword("self")])) assertNoError(kind, 8, verify(layout[8], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 9, verify(layout[9], as: RawGenericArgumentClauseSyntax?.self)) + assertNoError(kind, 10, verify(layout[10], as: RawUnexpectedNodesSyntax?.self)) } func validateMetatypeTypeSyntax(kind: SyntaxKind, layout: RawSyntaxBuffer) { assert(layout.count == 7) @@ -2094,10 +2104,12 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self)) } func validateMissingExprSyntax(kind: SyntaxKind, layout: RawSyntaxBuffer) { - assert(layout.count == 3) + assert(layout.count == 5) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.identifier)])) + assertNoError(kind, 1, verify(layout[1], as: RawModuleSelectorSyntax?.self)) assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.identifier)])) + assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) } func validateMissingPatternSyntax(kind: SyntaxKind, layout: RawSyntaxBuffer) { assert(layout.count == 3) @@ -2118,10 +2130,20 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) } func validateMissingTypeSyntax(kind: SyntaxKind, layout: RawSyntaxBuffer) { - assert(layout.count == 3) + assert(layout.count == 5) + assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 1, verify(layout[1], as: RawModuleSelectorSyntax?.self)) + assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.identifier)])) + assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) + } + func validateModuleSelectorSyntax(kind: SyntaxKind, layout: RawSyntaxBuffer) { + assert(layout.count == 5) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.identifier)])) assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.colonColon)])) + assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) } func validateMultipleTrailingClosureElementListSyntax(kind: SyntaxKind, layout: RawSyntaxBuffer) { for (index, element) in layout.enumerated() { @@ -3515,6 +3537,8 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { validateMissingSyntax(kind: kind, layout: layout) case .missingType: validateMissingTypeSyntax(kind: kind, layout: layout) + case .moduleSelector: + validateModuleSelectorSyntax(kind: kind, layout: layout) case .multipleTrailingClosureElementList: validateMultipleTrailingClosureElementListSyntax(kind: kind, layout: layout) case .multipleTrailingClosureElement: diff --git a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesD.swift b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesD.swift index 4891b0cdf97..7348868196b 100644 --- a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesD.swift +++ b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesD.swift @@ -628,6 +628,7 @@ public struct DeclNameArgumentsSyntax: SyntaxProtocol, SyntaxHashable, _LeafSynt /// ### Children /// +/// - `moduleSelector`: `ModuleSelectorSyntax`? /// - `baseName`: (`` | `self` | `Self` | `init` | `deinit` | `subscript` | `` | `` | ``) /// - `argumentNames`: ``DeclNameArgumentsSyntax``? /// @@ -656,9 +657,11 @@ public struct DeclReferenceExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _Leaf /// - Parameters: /// - leadingTrivia: Trivia to be prepended to the leading trivia of the node’s first token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. /// - trailingTrivia: Trivia to be appended to the trailing trivia of the node’s last token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. - public init( + @_spi(ExperimentalLanguageFeatures) public init( leadingTrivia: Trivia? = nil, - _ unexpectedBeforeBaseName: UnexpectedNodesSyntax? = nil, + _ unexpectedBeforeModuleSelector: UnexpectedNodesSyntax? = nil, + moduleSelector: ModuleSelectorSyntax? = nil, + _ unexpectedBetweenModuleSelectorAndBaseName: UnexpectedNodesSyntax? = nil, baseName: TokenSyntax, _ unexpectedBetweenBaseNameAndArgumentNames: UnexpectedNodesSyntax? = nil, argumentNames: DeclNameArgumentsSyntax? = nil, @@ -668,14 +671,18 @@ public struct DeclReferenceExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _Leaf // Extend the lifetime of all parameters so their arenas don't get destroyed // before they can be added as children of the new arena. self = withExtendedLifetime((RawSyntaxArena(), ( - unexpectedBeforeBaseName, + unexpectedBeforeModuleSelector, + moduleSelector, + unexpectedBetweenModuleSelectorAndBaseName, baseName, unexpectedBetweenBaseNameAndArgumentNames, argumentNames, unexpectedAfterArgumentNames ))) { (arena, _) in let layout: [RawSyntax?] = [ - unexpectedBeforeBaseName?.raw, + unexpectedBeforeModuleSelector?.raw, + moduleSelector?.raw, + unexpectedBetweenModuleSelectorAndBaseName?.raw, baseName.raw, unexpectedBetweenBaseNameAndArgumentNames?.raw, argumentNames?.raw, @@ -692,7 +699,8 @@ public struct DeclReferenceExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _Leaf } } - public var unexpectedBeforeBaseName: UnexpectedNodesSyntax? { + @_spi(ExperimentalLanguageFeatures) + public var unexpectedBeforeModuleSelector: UnexpectedNodesSyntax? { get { return Syntax(self).child(at: 0)?.cast(UnexpectedNodesSyntax.self) } @@ -701,6 +709,26 @@ public struct DeclReferenceExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _Leaf } } + @_spi(ExperimentalLanguageFeatures) + public var moduleSelector: ModuleSelectorSyntax? { + get { + return Syntax(self).child(at: 1)?.cast(ModuleSelectorSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 1, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(DeclReferenceExprSyntax.self) + } + } + + @_spi(ExperimentalLanguageFeatures) + public var unexpectedBetweenModuleSelectorAndBaseName: UnexpectedNodesSyntax? { + get { + return Syntax(self).child(at: 2)?.cast(UnexpectedNodesSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 2, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(DeclReferenceExprSyntax.self) + } + } + /// ### Tokens /// /// For syntax trees generated by the parser, this is guaranteed to be one of the following kinds: @@ -715,42 +743,44 @@ public struct DeclReferenceExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _Leaf /// - `` public var baseName: TokenSyntax { get { - return Syntax(self).child(at: 1)!.cast(TokenSyntax.self) + return Syntax(self).child(at: 3)!.cast(TokenSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 1, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(DeclReferenceExprSyntax.self) + self = Syntax(self).replacingChild(at: 3, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(DeclReferenceExprSyntax.self) } } public var unexpectedBetweenBaseNameAndArgumentNames: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 2)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 4)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 2, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(DeclReferenceExprSyntax.self) + self = Syntax(self).replacingChild(at: 4, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(DeclReferenceExprSyntax.self) } } public var argumentNames: DeclNameArgumentsSyntax? { get { - return Syntax(self).child(at: 3)?.cast(DeclNameArgumentsSyntax.self) + return Syntax(self).child(at: 5)?.cast(DeclNameArgumentsSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 3, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(DeclReferenceExprSyntax.self) + self = Syntax(self).replacingChild(at: 5, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(DeclReferenceExprSyntax.self) } } public var unexpectedAfterArgumentNames: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 4)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 6)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 4, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(DeclReferenceExprSyntax.self) + self = Syntax(self).replacingChild(at: 6, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(DeclReferenceExprSyntax.self) } } public static let structure: SyntaxNodeStructure = .layout([ - \Self.unexpectedBeforeBaseName, + \Self.unexpectedBeforeModuleSelector, + \Self.moduleSelector, + \Self.unexpectedBetweenModuleSelectorAndBaseName, \Self.baseName, \Self.unexpectedBetweenBaseNameAndArgumentNames, \Self.argumentNames, diff --git a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift index b6eec06d4b0..f69841e3b87 100644 --- a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift +++ b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift @@ -1707,6 +1707,7 @@ public struct IdentifierPatternSyntax: PatternSyntaxProtocol, SyntaxHashable, _L /// ### Children /// +/// - `moduleSelector`: `ModuleSelectorSyntax`? /// - `name`: (`` | `Self` | `Any` | `_`) /// - `genericArgumentClause`: ``GenericArgumentClauseSyntax``? public struct IdentifierTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTypeSyntaxNodeProtocol { @@ -1727,9 +1728,11 @@ public struct IdentifierTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTyp /// - Parameters: /// - leadingTrivia: Trivia to be prepended to the leading trivia of the node’s first token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. /// - trailingTrivia: Trivia to be appended to the trailing trivia of the node’s last token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. - public init( + @_spi(ExperimentalLanguageFeatures) public init( leadingTrivia: Trivia? = nil, - _ unexpectedBeforeName: UnexpectedNodesSyntax? = nil, + _ unexpectedBeforeModuleSelector: UnexpectedNodesSyntax? = nil, + moduleSelector: ModuleSelectorSyntax? = nil, + _ unexpectedBetweenModuleSelectorAndName: UnexpectedNodesSyntax? = nil, name: TokenSyntax, _ unexpectedBetweenNameAndGenericArgumentClause: UnexpectedNodesSyntax? = nil, genericArgumentClause: GenericArgumentClauseSyntax? = nil, @@ -1739,14 +1742,18 @@ public struct IdentifierTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTyp // Extend the lifetime of all parameters so their arenas don't get destroyed // before they can be added as children of the new arena. self = withExtendedLifetime((RawSyntaxArena(), ( - unexpectedBeforeName, + unexpectedBeforeModuleSelector, + moduleSelector, + unexpectedBetweenModuleSelectorAndName, name, unexpectedBetweenNameAndGenericArgumentClause, genericArgumentClause, unexpectedAfterGenericArgumentClause ))) { (arena, _) in let layout: [RawSyntax?] = [ - unexpectedBeforeName?.raw, + unexpectedBeforeModuleSelector?.raw, + moduleSelector?.raw, + unexpectedBetweenModuleSelectorAndName?.raw, name.raw, unexpectedBetweenNameAndGenericArgumentClause?.raw, genericArgumentClause?.raw, @@ -1763,7 +1770,8 @@ public struct IdentifierTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTyp } } - public var unexpectedBeforeName: UnexpectedNodesSyntax? { + @_spi(ExperimentalLanguageFeatures) + public var unexpectedBeforeModuleSelector: UnexpectedNodesSyntax? { get { return Syntax(self).child(at: 0)?.cast(UnexpectedNodesSyntax.self) } @@ -1772,6 +1780,26 @@ public struct IdentifierTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTyp } } + @_spi(ExperimentalLanguageFeatures) + public var moduleSelector: ModuleSelectorSyntax? { + get { + return Syntax(self).child(at: 1)?.cast(ModuleSelectorSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 1, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(IdentifierTypeSyntax.self) + } + } + + @_spi(ExperimentalLanguageFeatures) + public var unexpectedBetweenModuleSelectorAndName: UnexpectedNodesSyntax? { + get { + return Syntax(self).child(at: 2)?.cast(UnexpectedNodesSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 2, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(IdentifierTypeSyntax.self) + } + } + /// ### Tokens /// /// For syntax trees generated by the parser, this is guaranteed to be one of the following kinds: @@ -1781,42 +1809,44 @@ public struct IdentifierTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTyp /// - `_` public var name: TokenSyntax { get { - return Syntax(self).child(at: 1)!.cast(TokenSyntax.self) + return Syntax(self).child(at: 3)!.cast(TokenSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 1, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(IdentifierTypeSyntax.self) + self = Syntax(self).replacingChild(at: 3, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(IdentifierTypeSyntax.self) } } public var unexpectedBetweenNameAndGenericArgumentClause: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 2)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 4)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 2, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(IdentifierTypeSyntax.self) + self = Syntax(self).replacingChild(at: 4, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(IdentifierTypeSyntax.self) } } public var genericArgumentClause: GenericArgumentClauseSyntax? { get { - return Syntax(self).child(at: 3)?.cast(GenericArgumentClauseSyntax.self) + return Syntax(self).child(at: 5)?.cast(GenericArgumentClauseSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 3, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(IdentifierTypeSyntax.self) + self = Syntax(self).replacingChild(at: 5, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(IdentifierTypeSyntax.self) } } public var unexpectedAfterGenericArgumentClause: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 4)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 6)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 4, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(IdentifierTypeSyntax.self) + self = Syntax(self).replacingChild(at: 6, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(IdentifierTypeSyntax.self) } } public static let structure: SyntaxNodeStructure = .layout([ - \Self.unexpectedBeforeName, + \Self.unexpectedBeforeModuleSelector, + \Self.moduleSelector, + \Self.unexpectedBetweenModuleSelectorAndName, \Self.name, \Self.unexpectedBetweenNameAndGenericArgumentClause, \Self.genericArgumentClause, @@ -3208,7 +3238,7 @@ public struct ImportDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _LeafDeclSyn /// ### Children /// /// - `name`: (`` | `` | `` | ``) -/// - `trailingPeriod`: `.`? +/// - `trailingPeriod`: (`.` | `::`)? /// /// ### Contained in /// @@ -3303,7 +3333,9 @@ public struct ImportPathComponentSyntax: SyntaxProtocol, SyntaxHashable, _LeafSy /// ### Tokens /// - /// For syntax trees generated by the parser, this is guaranteed to be `.`. + /// For syntax trees generated by the parser, this is guaranteed to be one of the following kinds: + /// - `.` + /// - `::` public var trailingPeriod: TokenSyntax? { get { return Syntax(self).child(at: 3)?.cast(TokenSyntax.self) diff --git a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesJKLMN.swift b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesJKLMN.swift index 902e11c9a85..8430e9f2639 100644 --- a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesJKLMN.swift +++ b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesJKLMN.swift @@ -2653,6 +2653,7 @@ public struct MacroDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _LeafDeclSynt /// - `attributes`: ``AttributeListSyntax`` /// - `modifiers`: ``DeclModifierListSyntax`` /// - `pound`: `#` +/// - `moduleSelector`: `ModuleSelectorSyntax`? /// - `macroName`: `` /// - `genericArgumentClause`: ``GenericArgumentClauseSyntax``? /// - `leftParen`: `(`? @@ -2679,7 +2680,7 @@ public struct MacroExpansionDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _Lea /// - leadingTrivia: Trivia to be prepended to the leading trivia of the node’s first token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. /// - pound: The `#` sign. /// - trailingTrivia: Trivia to be appended to the trailing trivia of the node’s last token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. - public init( + @_spi(ExperimentalLanguageFeatures) public init( leadingTrivia: Trivia? = nil, _ unexpectedBeforeAttributes: UnexpectedNodesSyntax? = nil, attributes: AttributeListSyntax = [], @@ -2687,7 +2688,9 @@ public struct MacroExpansionDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _Lea modifiers: DeclModifierListSyntax = [], _ unexpectedBetweenModifiersAndPound: UnexpectedNodesSyntax? = nil, pound: TokenSyntax = .poundToken(), - _ unexpectedBetweenPoundAndMacroName: UnexpectedNodesSyntax? = nil, + _ unexpectedBetweenPoundAndModuleSelector: UnexpectedNodesSyntax? = nil, + moduleSelector: ModuleSelectorSyntax? = nil, + _ unexpectedBetweenModuleSelectorAndMacroName: UnexpectedNodesSyntax? = nil, macroName: TokenSyntax, _ unexpectedBetweenMacroNameAndGenericArgumentClause: UnexpectedNodesSyntax? = nil, genericArgumentClause: GenericArgumentClauseSyntax? = nil, @@ -2713,7 +2716,9 @@ public struct MacroExpansionDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _Lea modifiers, unexpectedBetweenModifiersAndPound, pound, - unexpectedBetweenPoundAndMacroName, + unexpectedBetweenPoundAndModuleSelector, + moduleSelector, + unexpectedBetweenModuleSelectorAndMacroName, macroName, unexpectedBetweenMacroNameAndGenericArgumentClause, genericArgumentClause, @@ -2736,7 +2741,9 @@ public struct MacroExpansionDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _Lea modifiers.raw, unexpectedBetweenModifiersAndPound?.raw, pound.raw, - unexpectedBetweenPoundAndMacroName?.raw, + unexpectedBetweenPoundAndModuleSelector?.raw, + moduleSelector?.raw, + unexpectedBetweenModuleSelectorAndMacroName?.raw, macroName.raw, unexpectedBetweenMacroNameAndGenericArgumentClause?.raw, genericArgumentClause?.raw, @@ -2876,7 +2883,8 @@ public struct MacroExpansionDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _Lea } } - public var unexpectedBetweenPoundAndMacroName: UnexpectedNodesSyntax? { + @_spi(ExperimentalLanguageFeatures) + public var unexpectedBetweenPoundAndModuleSelector: UnexpectedNodesSyntax? { get { return Syntax(self).child(at: 6)?.cast(UnexpectedNodesSyntax.self) } @@ -2885,42 +2893,62 @@ public struct MacroExpansionDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _Lea } } + @_spi(ExperimentalLanguageFeatures) + public var moduleSelector: ModuleSelectorSyntax? { + get { + return Syntax(self).child(at: 7)?.cast(ModuleSelectorSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 7, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) + } + } + + @_spi(ExperimentalLanguageFeatures) + public var unexpectedBetweenModuleSelectorAndMacroName: UnexpectedNodesSyntax? { + get { + return Syntax(self).child(at: 8)?.cast(UnexpectedNodesSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 8, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) + } + } + /// ### Tokens /// /// For syntax trees generated by the parser, this is guaranteed to be ``. public var macroName: TokenSyntax { get { - return Syntax(self).child(at: 7)!.cast(TokenSyntax.self) + return Syntax(self).child(at: 9)!.cast(TokenSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 7, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) + self = Syntax(self).replacingChild(at: 9, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) } } public var unexpectedBetweenMacroNameAndGenericArgumentClause: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 8)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 10)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 8, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) + self = Syntax(self).replacingChild(at: 10, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) } } public var genericArgumentClause: GenericArgumentClauseSyntax? { get { - return Syntax(self).child(at: 9)?.cast(GenericArgumentClauseSyntax.self) + return Syntax(self).child(at: 11)?.cast(GenericArgumentClauseSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 9, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) + self = Syntax(self).replacingChild(at: 11, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) } } public var unexpectedBetweenGenericArgumentClauseAndLeftParen: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 10)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 12)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 10, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) + self = Syntax(self).replacingChild(at: 12, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) } } @@ -2929,28 +2957,28 @@ public struct MacroExpansionDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _Lea /// For syntax trees generated by the parser, this is guaranteed to be `(`. public var leftParen: TokenSyntax? { get { - return Syntax(self).child(at: 11)?.cast(TokenSyntax.self) + return Syntax(self).child(at: 13)?.cast(TokenSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 11, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) + self = Syntax(self).replacingChild(at: 13, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) } } public var unexpectedBetweenLeftParenAndArguments: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 12)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 14)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 12, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) + self = Syntax(self).replacingChild(at: 14, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) } } public var arguments: LabeledExprListSyntax { get { - return Syntax(self).child(at: 13)!.cast(LabeledExprListSyntax.self) + return Syntax(self).child(at: 15)!.cast(LabeledExprListSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 13, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) + self = Syntax(self).replacingChild(at: 15, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) } } @@ -2965,7 +2993,7 @@ public struct MacroExpansionDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _Lea public func addArgument(_ element: LabeledExprSyntax) -> MacroExpansionDeclSyntax { var collection: RawSyntax let arena = RawSyntaxArena() - if let col = raw.layoutView!.children[13] { + if let col = raw.layoutView!.children[15] { collection = col.layoutView!.appending(element.raw, arena: arena) } else { collection = RawSyntax.makeLayout(kind: SyntaxKind.labeledExprList, @@ -2973,7 +3001,7 @@ public struct MacroExpansionDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _Lea } return Syntax(self) .replacingChild( - at: 13, + at: 15, with: collection, rawNodeArena: arena, rawAllocationArena: arena @@ -2983,10 +3011,10 @@ public struct MacroExpansionDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _Lea public var unexpectedBetweenArgumentsAndRightParen: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 14)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 16)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 14, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) + self = Syntax(self).replacingChild(at: 16, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) } } @@ -2995,46 +3023,46 @@ public struct MacroExpansionDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _Lea /// For syntax trees generated by the parser, this is guaranteed to be `)`. public var rightParen: TokenSyntax? { get { - return Syntax(self).child(at: 15)?.cast(TokenSyntax.self) + return Syntax(self).child(at: 17)?.cast(TokenSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 15, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) + self = Syntax(self).replacingChild(at: 17, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) } } public var unexpectedBetweenRightParenAndTrailingClosure: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 16)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 18)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 16, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) + self = Syntax(self).replacingChild(at: 18, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) } } public var trailingClosure: ClosureExprSyntax? { get { - return Syntax(self).child(at: 17)?.cast(ClosureExprSyntax.self) + return Syntax(self).child(at: 19)?.cast(ClosureExprSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 17, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) + self = Syntax(self).replacingChild(at: 19, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) } } public var unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 18)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 20)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 18, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) + self = Syntax(self).replacingChild(at: 20, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) } } public var additionalTrailingClosures: MultipleTrailingClosureElementListSyntax { get { - return Syntax(self).child(at: 19)!.cast(MultipleTrailingClosureElementListSyntax.self) + return Syntax(self).child(at: 21)!.cast(MultipleTrailingClosureElementListSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 19, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) + self = Syntax(self).replacingChild(at: 21, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) } } @@ -3049,7 +3077,7 @@ public struct MacroExpansionDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _Lea public func addAdditionalTrailingClosure(_ element: MultipleTrailingClosureElementSyntax) -> MacroExpansionDeclSyntax { var collection: RawSyntax let arena = RawSyntaxArena() - if let col = raw.layoutView!.children[19] { + if let col = raw.layoutView!.children[21] { collection = col.layoutView!.appending(element.raw, arena: arena) } else { collection = RawSyntax.makeLayout(kind: SyntaxKind.multipleTrailingClosureElementList, @@ -3057,7 +3085,7 @@ public struct MacroExpansionDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _Lea } return Syntax(self) .replacingChild( - at: 19, + at: 21, with: collection, rawNodeArena: arena, rawAllocationArena: arena @@ -3067,10 +3095,10 @@ public struct MacroExpansionDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _Lea public var unexpectedAfterAdditionalTrailingClosures: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 20)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 22)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 20, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) + self = Syntax(self).replacingChild(at: 22, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionDeclSyntax.self) } } @@ -3081,7 +3109,9 @@ public struct MacroExpansionDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _Lea \Self.modifiers, \Self.unexpectedBetweenModifiersAndPound, \Self.pound, - \Self.unexpectedBetweenPoundAndMacroName, + \Self.unexpectedBetweenPoundAndModuleSelector, + \Self.moduleSelector, + \Self.unexpectedBetweenModuleSelectorAndMacroName, \Self.macroName, \Self.unexpectedBetweenMacroNameAndGenericArgumentClause, \Self.genericArgumentClause, @@ -3106,6 +3136,7 @@ public struct MacroExpansionDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _Lea /// ### Children /// /// - `pound`: `#` +/// - `moduleSelector`: `ModuleSelectorSyntax`? /// - `macroName`: `` /// - `genericArgumentClause`: ``GenericArgumentClauseSyntax``? /// - `leftParen`: `(`? @@ -3132,11 +3163,13 @@ public struct MacroExpansionExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _Lea /// - leadingTrivia: Trivia to be prepended to the leading trivia of the node’s first token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. /// - pound: The `#` sign. /// - trailingTrivia: Trivia to be appended to the trailing trivia of the node’s last token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. - public init( + @_spi(ExperimentalLanguageFeatures) public init( leadingTrivia: Trivia? = nil, _ unexpectedBeforePound: UnexpectedNodesSyntax? = nil, pound: TokenSyntax = .poundToken(), - _ unexpectedBetweenPoundAndMacroName: UnexpectedNodesSyntax? = nil, + _ unexpectedBetweenPoundAndModuleSelector: UnexpectedNodesSyntax? = nil, + moduleSelector: ModuleSelectorSyntax? = nil, + _ unexpectedBetweenModuleSelectorAndMacroName: UnexpectedNodesSyntax? = nil, macroName: TokenSyntax, _ unexpectedBetweenMacroNameAndGenericArgumentClause: UnexpectedNodesSyntax? = nil, genericArgumentClause: GenericArgumentClauseSyntax? = nil, @@ -3158,7 +3191,9 @@ public struct MacroExpansionExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _Lea self = withExtendedLifetime((RawSyntaxArena(), ( unexpectedBeforePound, pound, - unexpectedBetweenPoundAndMacroName, + unexpectedBetweenPoundAndModuleSelector, + moduleSelector, + unexpectedBetweenModuleSelectorAndMacroName, macroName, unexpectedBetweenMacroNameAndGenericArgumentClause, genericArgumentClause, @@ -3177,7 +3212,9 @@ public struct MacroExpansionExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _Lea let layout: [RawSyntax?] = [ unexpectedBeforePound?.raw, pound.raw, - unexpectedBetweenPoundAndMacroName?.raw, + unexpectedBetweenPoundAndModuleSelector?.raw, + moduleSelector?.raw, + unexpectedBetweenModuleSelectorAndMacroName?.raw, macroName.raw, unexpectedBetweenMacroNameAndGenericArgumentClause?.raw, genericArgumentClause?.raw, @@ -3227,7 +3264,8 @@ public struct MacroExpansionExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _Lea } } - public var unexpectedBetweenPoundAndMacroName: UnexpectedNodesSyntax? { + @_spi(ExperimentalLanguageFeatures) + public var unexpectedBetweenPoundAndModuleSelector: UnexpectedNodesSyntax? { get { return Syntax(self).child(at: 2)?.cast(UnexpectedNodesSyntax.self) } @@ -3236,42 +3274,62 @@ public struct MacroExpansionExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _Lea } } + @_spi(ExperimentalLanguageFeatures) + public var moduleSelector: ModuleSelectorSyntax? { + get { + return Syntax(self).child(at: 3)?.cast(ModuleSelectorSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 3, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) + } + } + + @_spi(ExperimentalLanguageFeatures) + public var unexpectedBetweenModuleSelectorAndMacroName: UnexpectedNodesSyntax? { + get { + return Syntax(self).child(at: 4)?.cast(UnexpectedNodesSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 4, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) + } + } + /// ### Tokens /// /// For syntax trees generated by the parser, this is guaranteed to be ``. public var macroName: TokenSyntax { get { - return Syntax(self).child(at: 3)!.cast(TokenSyntax.self) + return Syntax(self).child(at: 5)!.cast(TokenSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 3, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) + self = Syntax(self).replacingChild(at: 5, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) } } public var unexpectedBetweenMacroNameAndGenericArgumentClause: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 4)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 6)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 4, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) + self = Syntax(self).replacingChild(at: 6, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) } } public var genericArgumentClause: GenericArgumentClauseSyntax? { get { - return Syntax(self).child(at: 5)?.cast(GenericArgumentClauseSyntax.self) + return Syntax(self).child(at: 7)?.cast(GenericArgumentClauseSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 5, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) + self = Syntax(self).replacingChild(at: 7, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) } } public var unexpectedBetweenGenericArgumentClauseAndLeftParen: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 6)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 8)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 6, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) + self = Syntax(self).replacingChild(at: 8, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) } } @@ -3280,28 +3338,28 @@ public struct MacroExpansionExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _Lea /// For syntax trees generated by the parser, this is guaranteed to be `(`. public var leftParen: TokenSyntax? { get { - return Syntax(self).child(at: 7)?.cast(TokenSyntax.self) + return Syntax(self).child(at: 9)?.cast(TokenSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 7, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) + self = Syntax(self).replacingChild(at: 9, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) } } public var unexpectedBetweenLeftParenAndArguments: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 8)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 10)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 8, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) + self = Syntax(self).replacingChild(at: 10, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) } } public var arguments: LabeledExprListSyntax { get { - return Syntax(self).child(at: 9)!.cast(LabeledExprListSyntax.self) + return Syntax(self).child(at: 11)!.cast(LabeledExprListSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 9, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) + self = Syntax(self).replacingChild(at: 11, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) } } @@ -3316,7 +3374,7 @@ public struct MacroExpansionExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _Lea public func addArgument(_ element: LabeledExprSyntax) -> MacroExpansionExprSyntax { var collection: RawSyntax let arena = RawSyntaxArena() - if let col = raw.layoutView!.children[9] { + if let col = raw.layoutView!.children[11] { collection = col.layoutView!.appending(element.raw, arena: arena) } else { collection = RawSyntax.makeLayout(kind: SyntaxKind.labeledExprList, @@ -3324,7 +3382,7 @@ public struct MacroExpansionExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _Lea } return Syntax(self) .replacingChild( - at: 9, + at: 11, with: collection, rawNodeArena: arena, rawAllocationArena: arena @@ -3334,10 +3392,10 @@ public struct MacroExpansionExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _Lea public var unexpectedBetweenArgumentsAndRightParen: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 10)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 12)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 10, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) + self = Syntax(self).replacingChild(at: 12, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) } } @@ -3346,46 +3404,46 @@ public struct MacroExpansionExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _Lea /// For syntax trees generated by the parser, this is guaranteed to be `)`. public var rightParen: TokenSyntax? { get { - return Syntax(self).child(at: 11)?.cast(TokenSyntax.self) + return Syntax(self).child(at: 13)?.cast(TokenSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 11, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) + self = Syntax(self).replacingChild(at: 13, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) } } public var unexpectedBetweenRightParenAndTrailingClosure: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 12)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 14)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 12, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) + self = Syntax(self).replacingChild(at: 14, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) } } public var trailingClosure: ClosureExprSyntax? { get { - return Syntax(self).child(at: 13)?.cast(ClosureExprSyntax.self) + return Syntax(self).child(at: 15)?.cast(ClosureExprSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 13, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) + self = Syntax(self).replacingChild(at: 15, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) } } public var unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 14)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 16)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 14, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) + self = Syntax(self).replacingChild(at: 16, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) } } public var additionalTrailingClosures: MultipleTrailingClosureElementListSyntax { get { - return Syntax(self).child(at: 15)!.cast(MultipleTrailingClosureElementListSyntax.self) + return Syntax(self).child(at: 17)!.cast(MultipleTrailingClosureElementListSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 15, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) + self = Syntax(self).replacingChild(at: 17, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) } } @@ -3400,7 +3458,7 @@ public struct MacroExpansionExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _Lea public func addAdditionalTrailingClosure(_ element: MultipleTrailingClosureElementSyntax) -> MacroExpansionExprSyntax { var collection: RawSyntax let arena = RawSyntaxArena() - if let col = raw.layoutView!.children[15] { + if let col = raw.layoutView!.children[17] { collection = col.layoutView!.appending(element.raw, arena: arena) } else { collection = RawSyntax.makeLayout(kind: SyntaxKind.multipleTrailingClosureElementList, @@ -3408,7 +3466,7 @@ public struct MacroExpansionExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _Lea } return Syntax(self) .replacingChild( - at: 15, + at: 17, with: collection, rawNodeArena: arena, rawAllocationArena: arena @@ -3418,17 +3476,19 @@ public struct MacroExpansionExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _Lea public var unexpectedAfterAdditionalTrailingClosures: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 16)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 18)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 16, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) + self = Syntax(self).replacingChild(at: 18, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MacroExpansionExprSyntax.self) } } public static let structure: SyntaxNodeStructure = .layout([ \Self.unexpectedBeforePound, \Self.pound, - \Self.unexpectedBetweenPoundAndMacroName, + \Self.unexpectedBetweenPoundAndModuleSelector, + \Self.moduleSelector, + \Self.unexpectedBetweenModuleSelectorAndMacroName, \Self.macroName, \Self.unexpectedBetweenMacroNameAndGenericArgumentClause, \Self.genericArgumentClause, @@ -4208,6 +4268,7 @@ public struct MemberBlockSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxNode /// /// - `baseType`: ``TypeSyntax`` /// - `period`: `.` +/// - `moduleSelector`: `ModuleSelectorSyntax`? /// - `name`: (`` | `self`) /// - `genericArgumentClause`: ``GenericArgumentClauseSyntax``? public struct MemberTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTypeSyntaxNodeProtocol { @@ -4228,13 +4289,15 @@ public struct MemberTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTypeSyn /// - Parameters: /// - leadingTrivia: Trivia to be prepended to the leading trivia of the node’s first token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. /// - trailingTrivia: Trivia to be appended to the trailing trivia of the node’s last token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. - public init( + @_spi(ExperimentalLanguageFeatures) public init( leadingTrivia: Trivia? = nil, _ unexpectedBeforeBaseType: UnexpectedNodesSyntax? = nil, baseType: some TypeSyntaxProtocol, _ unexpectedBetweenBaseTypeAndPeriod: UnexpectedNodesSyntax? = nil, period: TokenSyntax = .periodToken(), - _ unexpectedBetweenPeriodAndName: UnexpectedNodesSyntax? = nil, + _ unexpectedBetweenPeriodAndModuleSelector: UnexpectedNodesSyntax? = nil, + moduleSelector: ModuleSelectorSyntax? = nil, + _ unexpectedBetweenModuleSelectorAndName: UnexpectedNodesSyntax? = nil, name: TokenSyntax, _ unexpectedBetweenNameAndGenericArgumentClause: UnexpectedNodesSyntax? = nil, genericArgumentClause: GenericArgumentClauseSyntax? = nil, @@ -4248,7 +4311,9 @@ public struct MemberTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTypeSyn baseType, unexpectedBetweenBaseTypeAndPeriod, period, - unexpectedBetweenPeriodAndName, + unexpectedBetweenPeriodAndModuleSelector, + moduleSelector, + unexpectedBetweenModuleSelectorAndName, name, unexpectedBetweenNameAndGenericArgumentClause, genericArgumentClause, @@ -4259,7 +4324,9 @@ public struct MemberTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTypeSyn baseType.raw, unexpectedBetweenBaseTypeAndPeriod?.raw, period.raw, - unexpectedBetweenPeriodAndName?.raw, + unexpectedBetweenPeriodAndModuleSelector?.raw, + moduleSelector?.raw, + unexpectedBetweenModuleSelectorAndName?.raw, name.raw, unexpectedBetweenNameAndGenericArgumentClause?.raw, genericArgumentClause?.raw, @@ -4315,7 +4382,8 @@ public struct MemberTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTypeSyn } } - public var unexpectedBetweenPeriodAndName: UnexpectedNodesSyntax? { + @_spi(ExperimentalLanguageFeatures) + public var unexpectedBetweenPeriodAndModuleSelector: UnexpectedNodesSyntax? { get { return Syntax(self).child(at: 4)?.cast(UnexpectedNodesSyntax.self) } @@ -4324,6 +4392,26 @@ public struct MemberTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTypeSyn } } + @_spi(ExperimentalLanguageFeatures) + public var moduleSelector: ModuleSelectorSyntax? { + get { + return Syntax(self).child(at: 5)?.cast(ModuleSelectorSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 5, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MemberTypeSyntax.self) + } + } + + @_spi(ExperimentalLanguageFeatures) + public var unexpectedBetweenModuleSelectorAndName: UnexpectedNodesSyntax? { + get { + return Syntax(self).child(at: 6)?.cast(UnexpectedNodesSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 6, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MemberTypeSyntax.self) + } + } + /// ### Tokens /// /// For syntax trees generated by the parser, this is guaranteed to be one of the following kinds: @@ -4331,37 +4419,37 @@ public struct MemberTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTypeSyn /// - `self` public var name: TokenSyntax { get { - return Syntax(self).child(at: 5)!.cast(TokenSyntax.self) + return Syntax(self).child(at: 7)!.cast(TokenSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 5, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MemberTypeSyntax.self) + self = Syntax(self).replacingChild(at: 7, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MemberTypeSyntax.self) } } public var unexpectedBetweenNameAndGenericArgumentClause: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 6)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 8)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 6, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MemberTypeSyntax.self) + self = Syntax(self).replacingChild(at: 8, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MemberTypeSyntax.self) } } public var genericArgumentClause: GenericArgumentClauseSyntax? { get { - return Syntax(self).child(at: 7)?.cast(GenericArgumentClauseSyntax.self) + return Syntax(self).child(at: 9)?.cast(GenericArgumentClauseSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 7, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MemberTypeSyntax.self) + self = Syntax(self).replacingChild(at: 9, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MemberTypeSyntax.self) } } public var unexpectedAfterGenericArgumentClause: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 8)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 10)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 8, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MemberTypeSyntax.self) + self = Syntax(self).replacingChild(at: 10, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MemberTypeSyntax.self) } } @@ -4370,7 +4458,9 @@ public struct MemberTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTypeSyn \Self.baseType, \Self.unexpectedBetweenBaseTypeAndPeriod, \Self.period, - \Self.unexpectedBetweenPeriodAndName, + \Self.unexpectedBetweenPeriodAndModuleSelector, + \Self.moduleSelector, + \Self.unexpectedBetweenModuleSelectorAndName, \Self.name, \Self.unexpectedBetweenNameAndGenericArgumentClause, \Self.genericArgumentClause, @@ -4746,6 +4836,7 @@ public struct MissingDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _LeafDeclSy /// /// ### Children /// +/// - `moduleSelector`: `ModuleSelectorSyntax`? /// - `placeholder`: `` public struct MissingExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _LeafExprSyntaxNodeProtocol { public let _syntaxNode: Syntax @@ -4764,19 +4855,34 @@ public struct MissingExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _LeafExprSy /// - Parameters: /// - leadingTrivia: Trivia to be prepended to the leading trivia of the node’s first token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. + /// - moduleSelector: A module selector. Some expressions can be prefixed with module selectors, so if one is parsed before an invalid expression, it will be inserted here. /// - placeholder: A placeholder, i.e. `<#expression#>`, that can be inserted into the source code to represent the missing expression. /// - trailingTrivia: Trivia to be appended to the trailing trivia of the node’s last token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. - public init( + @_spi(ExperimentalLanguageFeatures) public init( leadingTrivia: Trivia? = nil, - _ unexpectedBeforePlaceholder: UnexpectedNodesSyntax? = nil, + _ unexpectedBeforeModuleSelector: UnexpectedNodesSyntax? = nil, + moduleSelector: ModuleSelectorSyntax? = nil, + _ unexpectedBetweenModuleSelectorAndPlaceholder: UnexpectedNodesSyntax? = nil, placeholder: TokenSyntax, _ unexpectedAfterPlaceholder: UnexpectedNodesSyntax? = nil, trailingTrivia: Trivia? = nil ) { // Extend the lifetime of all parameters so their arenas don't get destroyed // before they can be added as children of the new arena. - self = withExtendedLifetime((RawSyntaxArena(), (unexpectedBeforePlaceholder, placeholder, unexpectedAfterPlaceholder))) { (arena, _) in - let layout: [RawSyntax?] = [unexpectedBeforePlaceholder?.raw, placeholder.raw, unexpectedAfterPlaceholder?.raw] + self = withExtendedLifetime((RawSyntaxArena(), ( + unexpectedBeforeModuleSelector, + moduleSelector, + unexpectedBetweenModuleSelectorAndPlaceholder, + placeholder, + unexpectedAfterPlaceholder + ))) { (arena, _) in + let layout: [RawSyntax?] = [ + unexpectedBeforeModuleSelector?.raw, + moduleSelector?.raw, + unexpectedBetweenModuleSelectorAndPlaceholder?.raw, + placeholder.raw, + unexpectedAfterPlaceholder?.raw + ] let raw = RawSyntax.makeLayout( kind: SyntaxKind.missingExpr, from: layout, @@ -4788,7 +4894,8 @@ public struct MissingExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _LeafExprSy } } - public var unexpectedBeforePlaceholder: UnexpectedNodesSyntax? { + @_spi(ExperimentalLanguageFeatures) + public var unexpectedBeforeModuleSelector: UnexpectedNodesSyntax? { get { return Syntax(self).child(at: 0)?.cast(UnexpectedNodesSyntax.self) } @@ -4797,6 +4904,27 @@ public struct MissingExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _LeafExprSy } } + /// A module selector. Some expressions can be prefixed with module selectors, so if one is parsed before an invalid expression, it will be inserted here. + @_spi(ExperimentalLanguageFeatures) + public var moduleSelector: ModuleSelectorSyntax? { + get { + return Syntax(self).child(at: 1)?.cast(ModuleSelectorSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 1, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MissingExprSyntax.self) + } + } + + @_spi(ExperimentalLanguageFeatures) + public var unexpectedBetweenModuleSelectorAndPlaceholder: UnexpectedNodesSyntax? { + get { + return Syntax(self).child(at: 2)?.cast(UnexpectedNodesSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 2, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MissingExprSyntax.self) + } + } + /// A placeholder, i.e. `<#expression#>`, that can be inserted into the source code to represent the missing expression. /// /// This token should always have `presence = .missing`. @@ -4806,23 +4934,29 @@ public struct MissingExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _LeafExprSy /// For syntax trees generated by the parser, this is guaranteed to be ``. public var placeholder: TokenSyntax { get { - return Syntax(self).child(at: 1)!.cast(TokenSyntax.self) + return Syntax(self).child(at: 3)!.cast(TokenSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 1, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MissingExprSyntax.self) + self = Syntax(self).replacingChild(at: 3, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MissingExprSyntax.self) } } public var unexpectedAfterPlaceholder: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 2)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 4)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 2, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MissingExprSyntax.self) + self = Syntax(self).replacingChild(at: 4, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MissingExprSyntax.self) } } - public static let structure: SyntaxNodeStructure = .layout([\Self.unexpectedBeforePlaceholder, \Self.placeholder, \Self.unexpectedAfterPlaceholder]) + public static let structure: SyntaxNodeStructure = .layout([ + \Self.unexpectedBeforeModuleSelector, + \Self.moduleSelector, + \Self.unexpectedBetweenModuleSelectorAndPlaceholder, + \Self.placeholder, + \Self.unexpectedAfterPlaceholder + ]) } // MARK: - MissingPatternSyntax @@ -5086,6 +5220,7 @@ public struct MissingSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxNodeProt /// /// ### Children /// +/// - `moduleSelector`: `ModuleSelectorSyntax`? /// - `placeholder`: `` public struct MissingTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTypeSyntaxNodeProtocol { public let _syntaxNode: Syntax @@ -5104,19 +5239,34 @@ public struct MissingTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTypeSy /// - Parameters: /// - leadingTrivia: Trivia to be prepended to the leading trivia of the node’s first token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. + /// - moduleSelector: A module selector. Some types can be prefixed with module selectors, so if one is parsed before an invalid type, it will be inserted here. /// - placeholder: A placeholder, i.e. `<#type#>`, that can be inserted into the source code to represent the missing type. /// - trailingTrivia: Trivia to be appended to the trailing trivia of the node’s last token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. - public init( + @_spi(ExperimentalLanguageFeatures) public init( leadingTrivia: Trivia? = nil, - _ unexpectedBeforePlaceholder: UnexpectedNodesSyntax? = nil, + _ unexpectedBeforeModuleSelector: UnexpectedNodesSyntax? = nil, + moduleSelector: ModuleSelectorSyntax? = nil, + _ unexpectedBetweenModuleSelectorAndPlaceholder: UnexpectedNodesSyntax? = nil, placeholder: TokenSyntax, _ unexpectedAfterPlaceholder: UnexpectedNodesSyntax? = nil, trailingTrivia: Trivia? = nil ) { // Extend the lifetime of all parameters so their arenas don't get destroyed // before they can be added as children of the new arena. - self = withExtendedLifetime((RawSyntaxArena(), (unexpectedBeforePlaceholder, placeholder, unexpectedAfterPlaceholder))) { (arena, _) in - let layout: [RawSyntax?] = [unexpectedBeforePlaceholder?.raw, placeholder.raw, unexpectedAfterPlaceholder?.raw] + self = withExtendedLifetime((RawSyntaxArena(), ( + unexpectedBeforeModuleSelector, + moduleSelector, + unexpectedBetweenModuleSelectorAndPlaceholder, + placeholder, + unexpectedAfterPlaceholder + ))) { (arena, _) in + let layout: [RawSyntax?] = [ + unexpectedBeforeModuleSelector?.raw, + moduleSelector?.raw, + unexpectedBetweenModuleSelectorAndPlaceholder?.raw, + placeholder.raw, + unexpectedAfterPlaceholder?.raw + ] let raw = RawSyntax.makeLayout( kind: SyntaxKind.missingType, from: layout, @@ -5128,7 +5278,8 @@ public struct MissingTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTypeSy } } - public var unexpectedBeforePlaceholder: UnexpectedNodesSyntax? { + @_spi(ExperimentalLanguageFeatures) + public var unexpectedBeforeModuleSelector: UnexpectedNodesSyntax? { get { return Syntax(self).child(at: 0)?.cast(UnexpectedNodesSyntax.self) } @@ -5137,6 +5288,27 @@ public struct MissingTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTypeSy } } + /// A module selector. Some types can be prefixed with module selectors, so if one is parsed before an invalid type, it will be inserted here. + @_spi(ExperimentalLanguageFeatures) + public var moduleSelector: ModuleSelectorSyntax? { + get { + return Syntax(self).child(at: 1)?.cast(ModuleSelectorSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 1, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MissingTypeSyntax.self) + } + } + + @_spi(ExperimentalLanguageFeatures) + public var unexpectedBetweenModuleSelectorAndPlaceholder: UnexpectedNodesSyntax? { + get { + return Syntax(self).child(at: 2)?.cast(UnexpectedNodesSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 2, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MissingTypeSyntax.self) + } + } + /// A placeholder, i.e. `<#type#>`, that can be inserted into the source code to represent the missing type. /// /// This token should always have `presence = .missing`. @@ -5146,23 +5318,162 @@ public struct MissingTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTypeSy /// For syntax trees generated by the parser, this is guaranteed to be ``. public var placeholder: TokenSyntax { get { - return Syntax(self).child(at: 1)!.cast(TokenSyntax.self) + return Syntax(self).child(at: 3)!.cast(TokenSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 1, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MissingTypeSyntax.self) + self = Syntax(self).replacingChild(at: 3, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MissingTypeSyntax.self) } } public var unexpectedAfterPlaceholder: UnexpectedNodesSyntax? { + get { + return Syntax(self).child(at: 4)?.cast(UnexpectedNodesSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 4, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MissingTypeSyntax.self) + } + } + + public static let structure: SyntaxNodeStructure = .layout([ + \Self.unexpectedBeforeModuleSelector, + \Self.moduleSelector, + \Self.unexpectedBetweenModuleSelectorAndPlaceholder, + \Self.placeholder, + \Self.unexpectedAfterPlaceholder + ]) +} + +// MARK: - ModuleSelectorSyntax + +/// - Note: Requires experimental feature `moduleSelector`. +/// +/// ### Children +/// +/// - `moduleName`: `` +/// - `colonColon`: `::` +/// +/// ### Contained in +/// +/// - ``DeclReferenceExprSyntax``.``DeclReferenceExprSyntax/moduleSelector`` +/// - ``IdentifierTypeSyntax``.``IdentifierTypeSyntax/moduleSelector`` +/// - ``MacroExpansionDeclSyntax``.``MacroExpansionDeclSyntax/moduleSelector`` +/// - ``MacroExpansionExprSyntax``.``MacroExpansionExprSyntax/moduleSelector`` +/// - ``MemberTypeSyntax``.``MemberTypeSyntax/moduleSelector`` +/// - ``MissingExprSyntax``.``MissingExprSyntax/moduleSelector`` +/// - ``MissingTypeSyntax``.``MissingTypeSyntax/moduleSelector`` +@_spi(ExperimentalLanguageFeatures) +public struct ModuleSelectorSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxNodeProtocol { + public let _syntaxNode: Syntax + + public init?(_ node: __shared some SyntaxProtocol) { + guard node.raw.kind == .moduleSelector else { + return nil + } + self._syntaxNode = node._syntaxNode + } + + @_transparent + init(unsafeCasting node: Syntax) { + self._syntaxNode = node + } + + /// - Parameters: + /// - leadingTrivia: Trivia to be prepended to the leading trivia of the node’s first token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. + /// - trailingTrivia: Trivia to be appended to the trailing trivia of the node’s last token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored. + public init( + leadingTrivia: Trivia? = nil, + _ unexpectedBeforeModuleName: UnexpectedNodesSyntax? = nil, + moduleName: TokenSyntax, + _ unexpectedBetweenModuleNameAndColonColon: UnexpectedNodesSyntax? = nil, + colonColon: TokenSyntax = .colonColonToken(), + _ unexpectedAfterColonColon: UnexpectedNodesSyntax? = nil, + trailingTrivia: Trivia? = nil + ) { + // Extend the lifetime of all parameters so their arenas don't get destroyed + // before they can be added as children of the new arena. + self = withExtendedLifetime((RawSyntaxArena(), ( + unexpectedBeforeModuleName, + moduleName, + unexpectedBetweenModuleNameAndColonColon, + colonColon, + unexpectedAfterColonColon + ))) { (arena, _) in + let layout: [RawSyntax?] = [ + unexpectedBeforeModuleName?.raw, + moduleName.raw, + unexpectedBetweenModuleNameAndColonColon?.raw, + colonColon.raw, + unexpectedAfterColonColon?.raw + ] + let raw = RawSyntax.makeLayout( + kind: SyntaxKind.moduleSelector, + from: layout, + arena: arena, + leadingTrivia: leadingTrivia, + trailingTrivia: trailingTrivia + ) + return Syntax.forRoot(raw, rawNodeArena: arena).cast(Self.self) + } + } + + public var unexpectedBeforeModuleName: UnexpectedNodesSyntax? { + get { + return Syntax(self).child(at: 0)?.cast(UnexpectedNodesSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 0, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(ModuleSelectorSyntax.self) + } + } + + /// ### Tokens + /// + /// For syntax trees generated by the parser, this is guaranteed to be ``. + public var moduleName: TokenSyntax { + get { + return Syntax(self).child(at: 1)!.cast(TokenSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 1, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(ModuleSelectorSyntax.self) + } + } + + public var unexpectedBetweenModuleNameAndColonColon: UnexpectedNodesSyntax? { get { return Syntax(self).child(at: 2)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 2, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(MissingTypeSyntax.self) + self = Syntax(self).replacingChild(at: 2, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(ModuleSelectorSyntax.self) } } - public static let structure: SyntaxNodeStructure = .layout([\Self.unexpectedBeforePlaceholder, \Self.placeholder, \Self.unexpectedAfterPlaceholder]) + /// ### Tokens + /// + /// For syntax trees generated by the parser, this is guaranteed to be `::`. + public var colonColon: TokenSyntax { + get { + return Syntax(self).child(at: 3)!.cast(TokenSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 3, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(ModuleSelectorSyntax.self) + } + } + + public var unexpectedAfterColonColon: UnexpectedNodesSyntax? { + get { + return Syntax(self).child(at: 4)?.cast(UnexpectedNodesSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 4, with: Syntax(value), rawAllocationArena: RawSyntaxArena()).cast(ModuleSelectorSyntax.self) + } + } + + public static let structure: SyntaxNodeStructure = .layout([ + \Self.unexpectedBeforeModuleName, + \Self.moduleName, + \Self.unexpectedBetweenModuleNameAndColonColon, + \Self.colonColon, + \Self.unexpectedAfterColonColon + ]) } // MARK: - MultipleTrailingClosureElementSyntax diff --git a/Sources/SwiftSyntaxBuilder/generated/BuildableNodes.swift b/Sources/SwiftSyntaxBuilder/generated/BuildableNodes.swift index 398e1b56af9..5469a229908 100644 --- a/Sources/SwiftSyntaxBuilder/generated/BuildableNodes.swift +++ b/Sources/SwiftSyntaxBuilder/generated/BuildableNodes.swift @@ -1043,7 +1043,7 @@ extension KeyPathSubscriptComponentSyntax { extension MacroExpansionDeclSyntax { /// A convenience initializer that allows initializing syntax collections using result builders - public init( + @_spi(ExperimentalLanguageFeatures) public init( leadingTrivia: Trivia? = nil, unexpectedBeforeAttributes: UnexpectedNodesSyntax? = nil, attributes: AttributeListSyntax = [], @@ -1051,7 +1051,9 @@ extension MacroExpansionDeclSyntax { modifiers: DeclModifierListSyntax = [], unexpectedBetweenModifiersAndPound: UnexpectedNodesSyntax? = nil, pound: TokenSyntax = .poundToken(), - unexpectedBetweenPoundAndMacroName: UnexpectedNodesSyntax? = nil, + unexpectedBetweenPoundAndModuleSelector: UnexpectedNodesSyntax? = nil, + moduleSelector: ModuleSelectorSyntax? = nil, + unexpectedBetweenModuleSelectorAndMacroName: UnexpectedNodesSyntax? = nil, macroName: TokenSyntax, unexpectedBetweenMacroNameAndGenericArgumentClause: UnexpectedNodesSyntax? = nil, genericArgumentClause: GenericArgumentClauseSyntax? = nil, @@ -1076,7 +1078,9 @@ extension MacroExpansionDeclSyntax { modifiers: modifiers, unexpectedBetweenModifiersAndPound, pound: pound, - unexpectedBetweenPoundAndMacroName, + unexpectedBetweenPoundAndModuleSelector, + moduleSelector: moduleSelector, + unexpectedBetweenModuleSelectorAndMacroName, macroName: macroName, unexpectedBetweenMacroNameAndGenericArgumentClause, genericArgumentClause: genericArgumentClause, @@ -1098,11 +1102,13 @@ extension MacroExpansionDeclSyntax { extension MacroExpansionExprSyntax { /// A convenience initializer that allows initializing syntax collections using result builders - public init( + @_spi(ExperimentalLanguageFeatures) public init( leadingTrivia: Trivia? = nil, unexpectedBeforePound: UnexpectedNodesSyntax? = nil, pound: TokenSyntax = .poundToken(), - unexpectedBetweenPoundAndMacroName: UnexpectedNodesSyntax? = nil, + unexpectedBetweenPoundAndModuleSelector: UnexpectedNodesSyntax? = nil, + moduleSelector: ModuleSelectorSyntax? = nil, + unexpectedBetweenModuleSelectorAndMacroName: UnexpectedNodesSyntax? = nil, macroName: TokenSyntax, unexpectedBetweenMacroNameAndGenericArgumentClause: UnexpectedNodesSyntax? = nil, genericArgumentClause: GenericArgumentClauseSyntax? = nil, @@ -1123,7 +1129,9 @@ extension MacroExpansionExprSyntax { leadingTrivia: leadingTrivia, unexpectedBeforePound, pound: pound, - unexpectedBetweenPoundAndMacroName, + unexpectedBetweenPoundAndModuleSelector, + moduleSelector: moduleSelector, + unexpectedBetweenModuleSelectorAndMacroName, macroName: macroName, unexpectedBetweenMacroNameAndGenericArgumentClause, genericArgumentClause: genericArgumentClause, diff --git a/Sources/SwiftSyntaxBuilder/generated/RenamedChildrenBuilderCompatibility.swift b/Sources/SwiftSyntaxBuilder/generated/RenamedChildrenBuilderCompatibility.swift index 6629c0a42de..a60a0524b6f 100644 --- a/Sources/SwiftSyntaxBuilder/generated/RenamedChildrenBuilderCompatibility.swift +++ b/Sources/SwiftSyntaxBuilder/generated/RenamedChildrenBuilderCompatibility.swift @@ -599,7 +599,62 @@ extension KeyPathSubscriptComponentSyntax { } extension MacroExpansionDeclSyntax { - @available(*, deprecated, message: "Use an initializer with pound, macroName, genericArgumentClause, arguments argument(s).") + /// A convenience initializer that allows initializing syntax collections using result builders + public init( + leadingTrivia: Trivia? = nil, + unexpectedBeforeAttributes: UnexpectedNodesSyntax? = nil, + attributes: AttributeListSyntax = [], + unexpectedBetweenAttributesAndModifiers: UnexpectedNodesSyntax? = nil, + modifiers: DeclModifierListSyntax = [], + unexpectedBetweenModifiersAndPound: UnexpectedNodesSyntax? = nil, + pound: TokenSyntax = .poundToken(), + unexpectedBetweenPoundAndMacroName: UnexpectedNodesSyntax? = nil, + macroName: TokenSyntax, + unexpectedBetweenMacroNameAndGenericArgumentClause: UnexpectedNodesSyntax? = nil, + genericArgumentClause: GenericArgumentClauseSyntax? = nil, + unexpectedBetweenGenericArgumentClauseAndLeftParen: UnexpectedNodesSyntax? = nil, + leftParen: TokenSyntax? = nil, + unexpectedBetweenLeftParenAndArguments: UnexpectedNodesSyntax? = nil, + unexpectedBetweenArgumentsAndRightParen: UnexpectedNodesSyntax? = nil, + rightParen: TokenSyntax? = nil, + unexpectedBetweenRightParenAndTrailingClosure: UnexpectedNodesSyntax? = nil, + trailingClosure: ClosureExprSyntax? = nil, + unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures: UnexpectedNodesSyntax? = nil, + additionalTrailingClosures: MultipleTrailingClosureElementListSyntax = [], + unexpectedAfterAdditionalTrailingClosures: UnexpectedNodesSyntax? = nil, + @LabeledExprListBuilder argumentsBuilder: () throws -> LabeledExprListSyntax, + trailingTrivia: Trivia? = nil + ) rethrows { + try self.init( + leadingTrivia: leadingTrivia, + unexpectedBeforeAttributes, + attributes: attributes, + unexpectedBetweenAttributesAndModifiers, + modifiers: modifiers, + unexpectedBetweenModifiersAndPound, + pound: pound, + unexpectedBetweenPoundAndMacroName, + macroName: macroName, + unexpectedBetweenMacroNameAndGenericArgumentClause, + genericArgumentClause: genericArgumentClause, + unexpectedBetweenGenericArgumentClauseAndLeftParen, + leftParen: leftParen, + unexpectedBetweenLeftParenAndArguments, + arguments: argumentsBuilder(), + unexpectedBetweenArgumentsAndRightParen, + rightParen: rightParen, + unexpectedBetweenRightParenAndTrailingClosure, + trailingClosure: trailingClosure, + unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures, + additionalTrailingClosures: additionalTrailingClosures, + unexpectedAfterAdditionalTrailingClosures, + trailingTrivia: trailingTrivia + ) + } +} + +extension MacroExpansionDeclSyntax { + @available(*, deprecated, message: "Use an initializer with pound, moduleSelector, macroName, genericArgumentClause, arguments argument(s).") @_disfavoredOverload /// A convenience initializer that allows initializing syntax collections using result builders public init( @@ -656,7 +711,54 @@ extension MacroExpansionDeclSyntax { } extension MacroExpansionExprSyntax { - @available(*, deprecated, message: "Use an initializer with pound, macroName, genericArgumentClause, arguments argument(s).") + /// A convenience initializer that allows initializing syntax collections using result builders + public init( + leadingTrivia: Trivia? = nil, + unexpectedBeforePound: UnexpectedNodesSyntax? = nil, + pound: TokenSyntax = .poundToken(), + unexpectedBetweenPoundAndMacroName: UnexpectedNodesSyntax? = nil, + macroName: TokenSyntax, + unexpectedBetweenMacroNameAndGenericArgumentClause: UnexpectedNodesSyntax? = nil, + genericArgumentClause: GenericArgumentClauseSyntax? = nil, + unexpectedBetweenGenericArgumentClauseAndLeftParen: UnexpectedNodesSyntax? = nil, + leftParen: TokenSyntax? = nil, + unexpectedBetweenLeftParenAndArguments: UnexpectedNodesSyntax? = nil, + unexpectedBetweenArgumentsAndRightParen: UnexpectedNodesSyntax? = nil, + rightParen: TokenSyntax? = nil, + unexpectedBetweenRightParenAndTrailingClosure: UnexpectedNodesSyntax? = nil, + trailingClosure: ClosureExprSyntax? = nil, + unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures: UnexpectedNodesSyntax? = nil, + additionalTrailingClosures: MultipleTrailingClosureElementListSyntax = [], + unexpectedAfterAdditionalTrailingClosures: UnexpectedNodesSyntax? = nil, + @LabeledExprListBuilder argumentsBuilder: () throws -> LabeledExprListSyntax, + trailingTrivia: Trivia? = nil + ) rethrows { + try self.init( + leadingTrivia: leadingTrivia, + unexpectedBeforePound, + pound: pound, + unexpectedBetweenPoundAndMacroName, + macroName: macroName, + unexpectedBetweenMacroNameAndGenericArgumentClause, + genericArgumentClause: genericArgumentClause, + unexpectedBetweenGenericArgumentClauseAndLeftParen, + leftParen: leftParen, + unexpectedBetweenLeftParenAndArguments, + arguments: argumentsBuilder(), + unexpectedBetweenArgumentsAndRightParen, + rightParen: rightParen, + unexpectedBetweenRightParenAndTrailingClosure, + trailingClosure: trailingClosure, + unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures, + additionalTrailingClosures: additionalTrailingClosures, + unexpectedAfterAdditionalTrailingClosures, + trailingTrivia: trailingTrivia + ) + } +} + +extension MacroExpansionExprSyntax { + @available(*, deprecated, message: "Use an initializer with pound, moduleSelector, macroName, genericArgumentClause, arguments argument(s).") @_disfavoredOverload /// A convenience initializer that allows initializing syntax collections using result builders public init( diff --git a/Tests/SwiftBasicFormatTest/BasicFormatTests.swift b/Tests/SwiftBasicFormatTest/BasicFormatTests.swift index 801c5e5e7ff..43ad18f3cd6 100644 --- a/Tests/SwiftBasicFormatTest/BasicFormatTests.swift +++ b/Tests/SwiftBasicFormatTest/BasicFormatTests.swift @@ -12,7 +12,7 @@ import SwiftBasicFormat import SwiftParser -import SwiftSyntax +@_spi(ExperimentalLanguageFeatures) import SwiftSyntax @_spi(Testing) import SwiftSyntaxBuilder import XCTest import _SwiftSyntaxTestSupport @@ -695,4 +695,17 @@ final class BasicFormatTest: XCTestCase { expected: "let x: (Int) -> Void" ) } + + func testColonColon() { + assertFormatted( + tree: DeclReferenceExprSyntax( + moduleSelector: ModuleSelectorSyntax( + moduleName: .identifier("Swift"), + colonColon: .colonColonToken() + ), + baseName: TokenSyntax.identifier("print") + ), + expected: "Swift::print" + ) + } } diff --git a/Tests/SwiftParserTest/Assertions.swift b/Tests/SwiftParserTest/Assertions.swift index cb537012a3c..da6f7008056 100644 --- a/Tests/SwiftParserTest/Assertions.swift +++ b/Tests/SwiftParserTest/Assertions.swift @@ -190,6 +190,7 @@ private func assertTokens( func assertLexemes( _ markedSource: String, lexemes expectedLexemes: [LexemeSpec], + experimentalFeatures: Parser.ExperimentalFeatures = [], file: StaticString = #filePath, line: UInt = #line ) { @@ -206,7 +207,12 @@ func assertLexemes( lookaheadTracker.initialize(to: LookaheadTracker()) source.withUTF8 { buf in var lexemes = [Lexer.Lexeme]() - for token in Lexer.tokenize(buf, from: 0, lookaheadTracker: lookaheadTracker) { + for token in Lexer.tokenize( + buf, + from: 0, + lookaheadTracker: lookaheadTracker, + experimentalFeatures: experimentalFeatures + ) { lexemes.append(token) if token.rawTokenKind == .endOfFile { diff --git a/Tests/SwiftParserTest/AttributeTests.swift b/Tests/SwiftParserTest/AttributeTests.swift index 695df2b4735..d26b8be41c5 100644 --- a/Tests/SwiftParserTest/AttributeTests.swift +++ b/Tests/SwiftParserTest/AttributeTests.swift @@ -188,11 +188,50 @@ final class AttributeTests: ParserTestCase { @objc(zeroArg) class A { } - @objc(:::::) + @objc(:::x::) func f(_: Int, _: Int, _: Int, _: Int, _: Int) { } """ ) + // Same as above, but with module selectors, which introduce a token for adjacent colons. + assertParse( + """ + @objc(zeroArg) + class A { } + + @objc(:::x::) + func f(_: Int, _: Int, _: Int, _: Int, _: Int) { } + """, + experimentalFeatures: [.moduleSelector] + ) + + // Found through mutation testing. + assertParse( + """ + @objc<1️⃣::2️⃣:x::) + func f(_: Int, _: Int, _: Int, _: Int, _: Int) { } + """, + diagnostics: [ + DiagnosticSpec( + message: "expected module name in module selector", + fixIts: ["insert module name"] + ), + DiagnosticSpec( + message: "expected type and '>' to end generic argument clause", + fixIts: ["insert type and '>'"] + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "unexpected code ':x::)' in function" + ), + ], + fixedSource: """ + @objc<<#identifier#>::<#type#>>:x::) + func f(_: Int, _: Int, _: Int, _: Int, _: Int) { } + """, + experimentalFeatures: [.moduleSelector] + ) + assertParse( """ @objc(_:) @@ -852,8 +891,8 @@ final class AttributeTests: ParserTestCase { ), DiagnosticSpec( locationMarker: "2️⃣", - message: "expected identifier in class", - fixIts: ["insert identifier"] + message: "expected name in class", + fixIts: ["insert name"] ), DiagnosticSpec( locationMarker: "2️⃣", diff --git a/Tests/SwiftParserTest/DeclarationTests.swift b/Tests/SwiftParserTest/DeclarationTests.swift index 6a7bac74f68..eed055523cf 100644 --- a/Tests/SwiftParserTest/DeclarationTests.swift +++ b/Tests/SwiftParserTest/DeclarationTests.swift @@ -331,8 +331,8 @@ final class DeclarationTests: ParserTestCase { ), DiagnosticSpec( locationMarker: "2️⃣", - message: "expected identifier in enum case", - fixIts: ["insert identifier"] + message: "expected name in enum case", + fixIts: ["insert name"] ), DiagnosticSpec( locationMarker: "2️⃣", @@ -1274,11 +1274,11 @@ final class DeclarationTests: ParserTestCase { diagnostics: [ DiagnosticSpec( locationMarker: "1️⃣", - message: "identifier can only start with a letter or underscore, not a number" + message: "name can only start with a letter or underscore, not a number" ), DiagnosticSpec( locationMarker: "2️⃣", - message: "identifier can only start with a letter or underscore, not a number" + message: "name can only start with a letter or underscore, not a number" ), ] ) @@ -1534,8 +1534,8 @@ final class DeclarationTests: ParserTestCase { ), DiagnosticSpec( locationMarker: "3️⃣", - message: "expected identifier in struct", - fixIts: ["insert identifier"] + message: "expected name in struct", + fixIts: ["insert name"] ), DiagnosticSpec( locationMarker: "4️⃣", @@ -1847,7 +1847,7 @@ final class DeclarationTests: ParserTestCase { assertParse( "associatedtype 1️⃣5s", diagnostics: [ - DiagnosticSpec(message: "identifier can only start with a letter or underscore, not a number") + DiagnosticSpec(message: "name can only start with a letter or underscore, not a number") ] ) } @@ -1979,8 +1979,8 @@ final class DeclarationTests: ParserTestCase { "func 1️⃣{}", diagnostics: [ DiagnosticSpec( - message: "expected identifier and function signature in function", - fixIts: ["insert identifier and function signature"] + message: "expected name and function signature in function", + fixIts: ["insert name and function signature"] ) ], fixedSource: """ @@ -2351,7 +2351,7 @@ final class DeclarationTests: ParserTestCase { assertParse( "protocol 1️⃣{}", diagnostics: [ - DiagnosticSpec(message: "expected identifier in protocol", fixIts: ["insert identifier"]) + DiagnosticSpec(message: "expected name in protocol", fixIts: ["insert name"]) ], fixedSource: """ protocol <#identifier#> {} @@ -2360,7 +2360,7 @@ final class DeclarationTests: ParserTestCase { assertParse( "class 1️⃣{}", diagnostics: [ - DiagnosticSpec(message: "expected identifier in class", fixIts: ["insert identifier"]) + DiagnosticSpec(message: "expected name in class", fixIts: ["insert name"]) ], fixedSource: """ class <#identifier#> {} @@ -2369,7 +2369,7 @@ final class DeclarationTests: ParserTestCase { assertParse( "struct 1️⃣{}", diagnostics: [ - DiagnosticSpec(message: "expected identifier in struct", fixIts: ["insert identifier"]) + DiagnosticSpec(message: "expected name in struct", fixIts: ["insert name"]) ], fixedSource: """ struct <#identifier#> {} @@ -2378,7 +2378,7 @@ final class DeclarationTests: ParserTestCase { assertParse( "enum 1️⃣{}", diagnostics: [ - DiagnosticSpec(message: "expected identifier in enum", fixIts: ["insert identifier"]) + DiagnosticSpec(message: "expected name in enum", fixIts: ["insert name"]) ], fixedSource: """ enum <#identifier#> {} @@ -2501,7 +2501,7 @@ final class DeclarationTests: ParserTestCase { assertParse( "protocol1️⃣<2️⃣:3️⃣", diagnostics: [ - DiagnosticSpec(locationMarker: "1️⃣", message: "expected identifier in protocol", fixIts: ["insert identifier"]), + DiagnosticSpec(locationMarker: "1️⃣", message: "expected name in protocol", fixIts: ["insert name"]), DiagnosticSpec( locationMarker: "2️⃣", message: "expected name and '>' to end primary associated type clause", diff --git a/Tests/SwiftParserTest/LexerTests.swift b/Tests/SwiftParserTest/LexerTests.swift index 910d61c4510..b894431d7ee 100644 --- a/Tests/SwiftParserTest/LexerTests.swift +++ b/Tests/SwiftParserTest/LexerTests.swift @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -@_spi(RawSyntax) @_spi(Testing) import SwiftParser -@_spi(RawSyntax) import SwiftSyntax +@_spi(RawSyntax) @_spi(Testing) @_spi(ExperimentalLanguageFeatures) import SwiftParser +@_spi(RawSyntax) @_spi(ExperimentalLanguageFeatures) import SwiftSyntax import XCTest fileprivate func lex(_ sourceBytes: [UInt8], body: ([Lexer.Lexeme]) throws -> Void) rethrows { @@ -22,7 +22,7 @@ fileprivate func lex(_ sourceBytes: [UInt8], body: ([Lexer.Lexeme]) throws -> Vo lookaheadTracker.initialize(to: LookaheadTracker()) try sourceBytes.withUnsafeBufferPointer { (buf) in var lexemes = [Lexer.Lexeme]() - for token in Lexer.tokenize(buf, from: 0, lookaheadTracker: lookaheadTracker) { + for token in Lexer.tokenize(buf, from: 0, lookaheadTracker: lookaheadTracker, experimentalFeatures: []) { lexemes.append(token) if token.rawTokenKind == .endOfFile { @@ -579,6 +579,17 @@ class LexerTests: ParserTestCase { LexemeSpec(.binaryOperator, text: "^", trailing: "/*/", diagnostic: "unterminated '/*' comment") ] ) + assertLexemes( + "(Foo::/)", + lexemes: [ + LexemeSpec(.leftParen, text: "("), + LexemeSpec(.identifier, text: "Foo"), + LexemeSpec(.colonColon, text: "::"), + LexemeSpec(.binaryOperator, text: "/"), + LexemeSpec(.rightParen, text: ")"), + ], + experimentalFeatures: [.moduleSelector] + ) } func testUnexpectedLexing() { @@ -834,6 +845,70 @@ class LexerTests: ParserTestCase { ) } + func testTwoColons() { + assertLexemes( + "Foo::bar", + lexemes: [ + LexemeSpec(.identifier, text: "Foo"), + LexemeSpec(.colonColon, text: "::"), + LexemeSpec(.identifier, text: "bar"), + ], + experimentalFeatures: [.moduleSelector] + ) + + assertLexemes( + "Foo ::bar", + lexemes: [ + LexemeSpec(.identifier, text: "Foo", trailing: " "), + LexemeSpec(.colonColon, text: "::"), + LexemeSpec(.identifier, text: "bar"), + ], + experimentalFeatures: [.moduleSelector] + ) + + assertLexemes( + "Foo:: bar", + lexemes: [ + LexemeSpec(.identifier, text: "Foo"), + LexemeSpec(.colonColon, text: "::", trailing: " "), + LexemeSpec(.identifier, text: "bar"), + ], + experimentalFeatures: [.moduleSelector] + ) + + assertLexemes( + "Foo :: bar", + lexemes: [ + LexemeSpec(.identifier, text: "Foo", trailing: " "), + LexemeSpec(.colonColon, text: "::", trailing: " "), + LexemeSpec(.identifier, text: "bar"), + ], + experimentalFeatures: [.moduleSelector] + ) + + assertLexemes( + "Foo: :bar", + lexemes: [ + LexemeSpec(.identifier, text: "Foo"), + LexemeSpec(.colon, text: ":", trailing: " "), + LexemeSpec(.colon, text: ":"), + LexemeSpec(.identifier, text: "bar"), + ], + experimentalFeatures: [.moduleSelector] + ) + + // Only produce the new token when the experimental feature is enabled. + assertLexemes( + "Foo::bar", + lexemes: [ + LexemeSpec(.identifier, text: "Foo"), + LexemeSpec(.colon, text: ":"), + LexemeSpec(.colon, text: ":"), + LexemeSpec(.identifier, text: "bar"), + ] + ) + } + func testEditorPlaceholders() { assertLexemes( "!1️⃣<#b1#> && !2️⃣<#b2#>", diff --git a/Tests/SwiftParserTest/translated/DeprecatedWhereTests.swift b/Tests/SwiftParserTest/translated/DeprecatedWhereTests.swift index 3921e4805ed..778d3229049 100644 --- a/Tests/SwiftParserTest/translated/DeprecatedWhereTests.swift +++ b/Tests/SwiftParserTest/translated/DeprecatedWhereTests.swift @@ -179,8 +179,8 @@ final class DeprecatedWhereTests: ParserTestCase { ), DiagnosticSpec( locationMarker: "3️⃣", - message: "expected identifier in protocol", - fixIts: ["insert identifier"] + message: "expected name in protocol", + fixIts: ["insert name"] ), DiagnosticSpec( locationMarker: "4️⃣", @@ -217,8 +217,8 @@ final class DeprecatedWhereTests: ParserTestCase { ), DiagnosticSpec( locationMarker: "3️⃣", - message: "expected identifier in protocol", - fixIts: ["insert identifier"] + message: "expected name in protocol", + fixIts: ["insert name"] ), DiagnosticSpec( locationMarker: "4️⃣", diff --git a/Tests/SwiftParserTest/translated/EnumTests.swift b/Tests/SwiftParserTest/translated/EnumTests.swift index 946169ae67c..db290cbcc9d 100644 --- a/Tests/SwiftParserTest/translated/EnumTests.swift +++ b/Tests/SwiftParserTest/translated/EnumTests.swift @@ -252,7 +252,7 @@ final class EnumTests: ParserTestCase { diagnostics: [ DiagnosticSpec( locationMarker: "1️⃣", - message: "identifier can only start with a letter or underscore, not a number" + message: "name can only start with a letter or underscore, not a number" ), DiagnosticSpec(locationMarker: "2️⃣", message: "unexpected code ':' in enum"), ] @@ -281,7 +281,7 @@ final class EnumTests: ParserTestCase { } """, diagnostics: [ - DiagnosticSpec(locationMarker: "1️⃣", message: "expected identifier in enum case", fixIts: ["insert identifier"]), + DiagnosticSpec(locationMarker: "1️⃣", message: "expected name in enum case", fixIts: ["insert name"]), DiagnosticSpec( locationMarker: "2️⃣", message: "expected ':' and type in parameter", @@ -341,7 +341,8 @@ final class EnumTests: ParserTestCase { } """, diagnostics: [ - DiagnosticSpec(message: "expected identifier in enum case", fixIts: ["insert identifier"]) + // FIXME: Getting "enum case in enum case" because of change to EnumCaseElementSyntax's diagnostic name + DiagnosticSpec(message: "expected name in enum case", fixIts: ["insert name"]) ], fixedSource: """ enum rdar14678675 { @@ -361,7 +362,7 @@ final class EnumTests: ParserTestCase { } """, diagnostics: [ - DiagnosticSpec(message: "expected identifier in enum case", fixIts: ["insert identifier"]), + DiagnosticSpec(message: "expected name in enum case", fixIts: ["insert name"]), DiagnosticSpec(message: "unexpected code ':' in enum"), ], fixedSource: """ @@ -449,7 +450,7 @@ final class EnumTests: ParserTestCase { diagnostics: [ DiagnosticSpec(locationMarker: "1️⃣", message: "'_' cannot be used as an identifier here"), DiagnosticSpec(locationMarker: "2️⃣", message: "'_' cannot be used as an identifier here"), - DiagnosticSpec(locationMarker: "3️⃣", message: "expected identifier in enum case", fixIts: ["insert identifier"]), + DiagnosticSpec(locationMarker: "3️⃣", message: "expected name in enum case", fixIts: ["insert name"]), ], fixedSource: """ enum Recovery6 { @@ -1356,7 +1357,7 @@ final class EnumTests: ParserTestCase { } """, diagnostics: [ - DiagnosticSpec(message: "expected identifier in enum case", fixIts: ["insert identifier"]) + DiagnosticSpec(message: "expected name in enum case", fixIts: ["insert name"]) ], fixedSource: """ enum E_53662_Newline { @@ -1378,7 +1379,7 @@ final class EnumTests: ParserTestCase { } """, diagnostics: [ - DiagnosticSpec(message: "expected identifier in enum case", fixIts: ["insert identifier"]) + DiagnosticSpec(message: "expected name in enum case", fixIts: ["insert name"]) ], fixedSource: """ enum E_53662_Newline2 { @@ -1424,8 +1425,8 @@ final class EnumTests: ParserTestCase { } """#, diagnostics: [ - DiagnosticSpec(locationMarker: "1️⃣", message: "expected identifier in enum case", fixIts: ["insert identifier"]), - DiagnosticSpec(locationMarker: "2️⃣", message: "expected identifier in enum case", fixIts: ["insert identifier"]), + DiagnosticSpec(locationMarker: "1️⃣", message: "expected name in enum case", fixIts: ["insert name"]), + DiagnosticSpec(locationMarker: "2️⃣", message: "expected name in enum case", fixIts: ["insert name"]), ], fixedSource: #""" enum CasesWithMissingElement: Int { diff --git a/Tests/SwiftParserTest/translated/ModuleSelectorTests.swift b/Tests/SwiftParserTest/translated/ModuleSelectorTests.swift new file mode 100644 index 00000000000..2310505ad26 --- /dev/null +++ b/Tests/SwiftParserTest/translated/ModuleSelectorTests.swift @@ -0,0 +1,2450 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +// This test file has been translated from swift/test/NameLookup/module_selector.swift + +@_spi(ExperimentalLanguageFeatures) import SwiftParser +@_spi(ExperimentalLanguageFeatures) import SwiftSyntax +import XCTest + +final class ModuleSelectorTests: ParserTestCase { + override var experimentalFeatures: Parser.ExperimentalFeatures { + [.moduleSelector] + } + + func testModuleSelectorImports() { + assertParse( + """ + import struct ModuleSelectorTestingKit::A + """, + substructure: ImportDeclSyntax( + importKindSpecifier: .keyword(.struct), + path: [ + ImportPathComponentSyntax( + name: .identifier("ModuleSelectorTestingKit"), + trailingPeriod: .colonColonToken() + ), + ImportPathComponentSyntax( + name: .identifier("A") + ), + ] + ) + ) + + assertParse( + """ + import ctypes1️⃣::bits + """, + diagnostics: [ + DiagnosticSpec( + message: "submodule cannot be imported using module selector", + fixIts: ["replace '::' with '.'"] + ) + ], + fixedSource: """ + import ctypes.bits + """ + ) + } + + func testModuleSelectorCorrectCode() { + assertParse( + """ + extension ModuleSelectorTestingKit::A {} + """, + substructure: ExtensionDeclSyntax( + extendedType: makeType(moduleSelector: "ModuleSelectorTestingKit", name: "A"), + memberBlock: MemberBlockSyntax {} + ) + ) + + assertParse( + """ + extension A: @retroactive Swift::Equatable {} + """, + substructure: ExtensionDeclSyntax( + extendedType: IdentifierTypeSyntax(name: .identifier("A")), + inheritanceClause: InheritanceClauseSyntax( + inheritedTypes: [ + InheritedTypeSyntax( + type: AttributedTypeSyntax( + specifiers: [], + attributes: [ + .attribute( + AttributeSyntax( + attributeName: makeType(name: "retroactive"), + arguments: nil + ) + ) + ], + baseType: makeType(moduleSelector: "Swift", name: "Equatable") + ) + ) + ] + ), + memberBlock: MemberBlockSyntax {} + ) + ) + + assertParse( + """ + @_implements(Swift::Equatable, ==(_:_:)) + public static func equals(_: ModuleSelectorTestingKit::A, _: ModuleSelectorTestingKit::A) -> Swift::Bool { + Swift::fatalError() + } + """, + substructure: FunctionDeclSyntax( + attributes: [ + .attribute( + AttributeSyntax( + attributeName: makeType(name: "_implements"), + leftParen: .leftParenToken(), + arguments: .implementsArguments( + ImplementsAttributeArgumentsSyntax( + type: makeType(moduleSelector: "Swift", name: "Equatable"), + declName: makeDeclRef( + baseName: .binaryOperator("=="), + argumentLabels: [nil, nil] + ) + ) + ), + rightParen: .rightParenToken() + ) + ) + ], + modifiers: [ + DeclModifierSyntax(name: .keyword(.public)), + DeclModifierSyntax(name: .keyword(.static)), + ], + name: .identifier("equals"), + signature: FunctionSignatureSyntax( + parameterClause: FunctionParameterClauseSyntax { + FunctionParameterSyntax( + firstName: .wildcardToken(), + type: makeType(moduleSelector: "ModuleSelectorTestingKit", name: "A") + ) + FunctionParameterSyntax( + firstName: .wildcardToken(), + type: makeType(moduleSelector: "ModuleSelectorTestingKit", name: "A") + ) + }, + returnClause: ReturnClauseSyntax( + type: makeType(moduleSelector: "Swift", name: "Bool") + ) + ), + body: CodeBlockSyntax { + makeCall( + callee: ExprSyntax(makeDeclRef(moduleSelector: "Swift", baseName: "fatalError")), + arguments: [:] + ) + } + ) + ) + + // FIXME: Add tests with autodiff @_differentiable(jvp:vjp:) and + // @_derivative(of:) + + assertParse( + """ + @_dynamicReplacement(for: ModuleSelectorTestingKit::negate()) + mutating func myNegate() {} + """, + substructure: FunctionDeclSyntax( + attributes: [ + .attribute( + AttributeSyntax( + attributeName: makeType(name: "_dynamicReplacement"), + leftParen: .leftParenToken(), + arguments: .dynamicReplacementArguments( + DynamicReplacementAttributeArgumentsSyntax( + declName: makeDeclRef( + moduleSelector: "ModuleSelectorTestingKit", + baseName: "negate", + argumentLabels: [] + ) + ) + ), + rightParen: .rightParenToken() + ) + ) + ], + modifiers: [ + DeclModifierSyntax(name: .keyword(.mutating)) + ], + name: .identifier("myNegate"), + signature: FunctionSignatureSyntax( + parameterClause: FunctionParameterClauseSyntax {} + ), + body: CodeBlockSyntax { + } + ) + ) + + // FIXME: Can we test @convention(witness_method:)? + + assertParse( + """ + let fn: (Swift::Int, Swift::Int) -> Swift::Int = (Swift::+) + """, + substructure: VariableDeclSyntax(bindingSpecifier: .keyword(.let)) { + PatternBindingSyntax( + pattern: IdentifierPatternSyntax(identifier: "fn"), + typeAnnotation: TypeAnnotationSyntax( + type: FunctionTypeSyntax( + parameters: TupleTypeElementListSyntax { + TupleTypeElementSyntax(type: makeType(moduleSelector: "Swift", name: "Int")) + TupleTypeElementSyntax(type: makeType(moduleSelector: "Swift", name: "Int")) + }, + returnClause: ReturnClauseSyntax( + type: makeType(moduleSelector: "Swift", name: "Int") + ) + ) + ), + initializer: InitializerClauseSyntax( + value: TupleExprSyntax { + LabeledExprSyntax(expression: makeDeclRef(moduleSelector: "Swift", baseName: .binaryOperator("+"))) + } + ) + ) + } + ) + + assertParse( + """ + let magnitude: Int.Swift::Magnitude = main::magnitude + """, + substructure: VariableDeclSyntax(bindingSpecifier: .keyword(.let)) { + PatternBindingSyntax( + pattern: IdentifierPatternSyntax(identifier: "magnitude"), + typeAnnotation: TypeAnnotationSyntax( + type: makeMember( + of: makeType(name: "Int"), + moduleSelector: "Swift", + name: "Magnitude" + ) + ), + initializer: InitializerClauseSyntax( + value: makeDeclRef(moduleSelector: "main", baseName: "magnitude") + ) + ) + } + ) + + assertParse( + """ + if Swift::Bool.Swift::random() { + } + """, + substructure: IfExprSyntax( + conditions: ConditionElementListSyntax { + ConditionElementSyntax( + condition: .expression( + ExprSyntax( + makeCall( + callee: MemberAccessExprSyntax( + base: makeDeclRef(moduleSelector: "Swift", baseName: "Bool"), + declName: makeDeclRef(moduleSelector: "Swift", baseName: "random") + ), + arguments: [:] + ) + ) + ) + ) + } + ) {} + ) + + assertParse( + """ + self.ModuleSelectorTestingKit::negate() + """, + substructure: makeCall( + callee: MemberAccessExprSyntax( + base: makeDeclRef(baseName: .keyword(.self)), + declName: makeDeclRef(moduleSelector: "ModuleSelectorTestingKit", baseName: "negate") + ), + arguments: [:] + ) + ) + + assertParse( + """ + self = ModuleSelectorTestingKit::A(value: .Swift::min) + """, + substructure: SequenceExprSyntax { + makeDeclRef(baseName: .keyword(.self)) + AssignmentExprSyntax() + makeCall( + callee: makeDeclRef(moduleSelector: "ModuleSelectorTestingKit", baseName: "A"), + arguments: [ + "value": ExprSyntax( + MemberAccessExprSyntax( + declName: makeDeclRef(moduleSelector: "Swift", baseName: "min") + ) + ) + ] + ) + } + ) + + assertParse( + """ + self = A.ModuleSelectorTestingKit::init(value: .min) + """, + substructure: SequenceExprSyntax { + makeDeclRef(baseName: .keyword(.self)) + AssignmentExprSyntax() + makeCall( + callee: MemberAccessExprSyntax( + base: makeDeclRef(baseName: "A"), + declName: makeDeclRef(moduleSelector: "ModuleSelectorTestingKit", baseName: .keyword(.`init`)) + ), + arguments: [ + "value": ExprSyntax( + MemberAccessExprSyntax( + declName: makeDeclRef(baseName: "min") + ) + ) + ] + ) + } + ) + + assertParse( + """ + self.main::myNegate() + """, + substructure: makeCall( + callee: MemberAccessExprSyntax( + base: makeDeclRef(baseName: .keyword(.self)), + declName: makeDeclRef(moduleSelector: "main", baseName: "myNegate") + ), + arguments: [:] + ) + ) + } + + func testModuleSelectorIncorrectAttrNames() { + // An attribute with a module selector *must* be a custom attribute and should be parsed as such. + assertParse( + """ + @2️⃣main::available(macOS 1️⃣10.15, *) var use1: String { "foo" } + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "unexpected code '10.15, *' in attribute" + ) + ] + ) + + assertParse( + """ + @main::available var use2 + """, + substructure: AttributeSyntax( + attributeName: makeType(moduleSelector: "main", name: "available") + ) + ) + + assertParse( + """ + @main::available(foo: bar) var use3 + """, + substructure: AttributeSyntax( + attributeName: makeType(moduleSelector: "main", name: "available"), + leftParen: .leftParenToken(), + arguments: .argumentList( + [ + LabeledExprSyntax( + label: "foo", + colon: .colonToken(), + expression: makeDeclRef(baseName: "bar") + ) + ] + ), + rightParen: .rightParenToken() + ) + ) + + assertParse( + """ + func builderUser2(@main::MyBuilder fn: () -> Void) {} + """, + substructure: FunctionParameterSyntax( + attributes: [ + .attribute( + AttributeSyntax( + attributeName: makeType(moduleSelector: "main", name: "MyBuilder") + ) + ) + ], + firstName: "fn", + type: TypeSyntax("() -> Void") + ) + ) + } + + func testModuleSelectorWhitespace() { + assertParse( + """ + _ = Swift::print + """, + substructure: makeDeclRef(moduleSelector: "Swift", baseName: "print") + ) + assertParse( + """ + _ = Swift:: print + """, + substructure: makeDeclRef(moduleSelector: "Swift", baseName: "print") + ) + assertParse( + """ + _ = Swift ::print + """, + substructure: makeDeclRef(moduleSelector: "Swift", baseName: "print") + ) + assertParse( + """ + _ = Swift :: print + """, + substructure: makeDeclRef(moduleSelector: "Swift", baseName: "print") + ) + assertParse( + """ + _ = Swift:: + print + """, + substructure: makeDeclRef(moduleSelector: "Swift", baseName: "print") + ) + assertParse( + """ + _ = Swift + ::print + """, + substructure: makeDeclRef(moduleSelector: "Swift", baseName: "print") + ) + assertParse( + """ + _ = Swift :: + print + """, + substructure: makeDeclRef(moduleSelector: "Swift", baseName: "print") + ) + assertParse( + """ + _ = Swift + :: print + """, + substructure: makeDeclRef(moduleSelector: "Swift", baseName: "print") + ) + assertParse( + """ + _ = Swift + :: + print + """, + substructure: makeDeclRef(moduleSelector: "Swift", baseName: "print") + ) + } + + func testModuleSelectorIncorrectFuncSignature() { + assertParse( + """ + func 1️⃣main::decl1() {} + """, + diagnostics: [ + DiagnosticSpec( + message: "function name cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ) + ], + fixedSource: """ + func decl1() {} + """ + ) + assertParse( + """ + func decl1( + 1️⃣main::p1: Swift::A + ) {} + """, + diagnostics: [ + DiagnosticSpec( + message: "parameter cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ) + ], + fixedSource: """ + func decl1( + p1: Swift::A + ) {} + """ + ) + + // Round-tripping failures: + assertParse( + """ + func decl1( + 1️⃣main::p1: 2️⃣::A + ) {} + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "parameter cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "expected module name in module selector", + fixIts: ["insert module name"] + ), + ], + fixedSource: """ + func decl1( + p1: <#identifier#>::A + ) {} + """ + ) + assertParse( + """ + func decl1( + 1️⃣main::p12️⃣3️⃣< ::A + ) {} + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "parameter cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "expected ':' in parameter", + fixIts: ["insert ':'"] + ), + DiagnosticSpec( + locationMarker: "3️⃣", + message: "'<' is not a valid identifier" + ), + + ], + fixedSource: """ + func decl1( + p1: < ::A + ) {} + """ + ) + assertParse( + """ + func decl1( + 1️⃣main::p12️⃣3️⃣> ::A + ) {} + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "parameter cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "expected ':' in parameter", + fixIts: ["insert ':'"] + ), + DiagnosticSpec( + locationMarker: "3️⃣", + message: "'>' is not a valid identifier" + ), + + ], + fixedSource: """ + func decl1( + p1: > ::A + ) {} + """ + ) + assertParse( + """ + func decl1( + 1️⃣main::p1: Swift::2️⃣ + ) {} + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "parameter cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ), + // Don't diagnose 'Swift::' module selector; it may be part of the missing type. + DiagnosticSpec( + locationMarker: "2️⃣", + message: "expected type in parameter", + fixIts: ["insert type"] + ), + ], + fixedSource: """ + func decl1( + p1: Swift::<#type#> + ) {} + """ + ) + + assertParse( + """ + func decl1( + 1️⃣main::label p2: 2️⃣Swift::inout A + ) {} + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "parameter cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "type specifier cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ), + ], + fixedSource: """ + func decl1( + label p2: inout A + ) {} + """ + ) + assertParse( + """ + func decl1( + label 1️⃣main::p3: @Swift::escaping () -> A + ) {} + """, + diagnostics: [ + DiagnosticSpec( + message: "parameter internal name cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ) + ], + fixedSource: """ + func decl1( + label p3: @Swift::escaping () -> A + ) {} + """ + ) + } + + func testModuleSelectorIncorrectBindingDecls() { + assertParse( + """ + let 1️⃣main::decl1a = "a" + """, + diagnostics: [ + DiagnosticSpec( + message: "pattern cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ) + ], + fixedSource: """ + let decl1a = "a" + """ + ) + assertParse( + """ + var 1️⃣main::decl1b = "b" + """, + diagnostics: [ + DiagnosticSpec( + message: "pattern cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ) + ], + fixedSource: """ + var decl1b = "b" + """ + ) + assertParse( + """ + let (1️⃣main::decl1c, 2️⃣Swift::decl1d) = ("c", "d") + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "pattern cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "pattern cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ), + ], + fixedSource: """ + let (decl1c, decl1d) = ("c", "d") + """ + ) + assertParse( + """ + if let (1️⃣main::decl1e, 2️⃣Swift::decl1f) = Optional(("e", "f")) {} + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "pattern cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "pattern cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ), + ], + fixedSource: """ + if let (decl1e, decl1f) = Optional(("e", "f")) {} + """ + ) + assertParse( + """ + guard let (1️⃣main::decl1g, 2️⃣Swift::decl1h) = Optional(("g", "h")) else { return } + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "pattern cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "pattern cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ), + ], + fixedSource: """ + guard let (decl1g, decl1h) = Optional(("g", "h")) else { return } + """ + ) + assertParse( + """ + switch Optional(main::decl1g) { + case Optional.some(let 1️⃣Swift::decl1i): + break + case .none: + break + } + """, + diagnostics: [ + DiagnosticSpec( + message: "pattern cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: """ + switch Optional(main::decl1g) { + case Optional.some(let decl1i): + break + case .none: + break + } + """ + ) + assertParse( + """ + switch Optional(main::decl1g) { + case let Optional.some(1️⃣Swift::decl1j): + break + case .none: + break + } + """, + diagnostics: [ + DiagnosticSpec( + message: "pattern cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: """ + switch Optional(main::decl1g) { + case let Optional.some(decl1j): + break + case .none: + break + } + """ + ) + assertParse( + """ + switch Optional(main::decl1g) { + case let 1️⃣Swift::decl1k?: + break + case .none: + break + } + """, + diagnostics: [ + DiagnosticSpec( + message: "pattern cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: """ + switch Optional(main::decl1g) { + case let decl1k?: + break + case .none: + break + } + """ + ) + assertParse( + """ + for 1️⃣main::decl1l in "lll" {} + """, + diagnostics: [ + DiagnosticSpec( + message: "pattern cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ) + ], + fixedSource: """ + for decl1l in "lll" {} + """ + ) + } + + func testModuleSelectorIncorrectClosureDecls() { + assertParse( + """ + "lll".forEach { [ /*before*/ 1️⃣Swift::magnitude /*after*/ ] + 2️⃣main::elem in print(elem) + } + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "closure capture cannot be qualified with a module selector", + fixIts: ["explicitly initialize variable 'magnitude'", "remove 'Swift::'"] + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "closure parameter cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ), + ], + fixedSource: """ + "lll".forEach { [ /*before*/ magnitude = Swift::magnitude /*after*/ ] + elem in print(elem) + } + """ + ) + assertParse( + """ + "lll".forEach { (1️⃣main::elem) in print(elem) } + """, + diagnostics: [ + DiagnosticSpec( + message: "parameter cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ) + ], + fixedSource: """ + "lll".forEach { (elem) in print(elem) } + """ + ) + assertParse( + """ + "lll".forEach { (1️⃣main::elem) -> Void in print(elem) } + """, + diagnostics: [ + DiagnosticSpec( + message: "parameter cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ) + ], + fixedSource: """ + "lll".forEach { (elem) -> Void in print(elem) } + """ + ) + assertParse( + """ + "lll".forEach { (1️⃣main::elem: Character) -> Void in print(elem) } + """, + diagnostics: [ + DiagnosticSpec( + message: "parameter cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ) + ], + fixedSource: """ + "lll".forEach { (elem: Character) -> Void in print(elem) } + """ + ) + } + + func testModuleSelectorIncorrectTypeDecls() { + assertParse( + """ + enum 1️⃣main::decl2 { + case 2️⃣Swift::decl2a + } + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "enum name cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "enum case cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ), + ], + fixedSource: """ + enum decl2 { + case decl2a + } + """ + ) + assertParse( + """ + struct 1️⃣main::decl3 {} + """, + diagnostics: [ + DiagnosticSpec( + message: "struct name cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ) + ], + fixedSource: """ + struct decl3 {} + """ + ) + assertParse( + """ + class 1️⃣main::decl4<2️⃣Swift::T> {} + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "class name cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "generic parameter cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ), + ], + fixedSource: """ + class decl4 {} + """ + ) + assertParse( + """ + typealias 1️⃣main::decl5 = Swift::Bool + """, + diagnostics: [ + DiagnosticSpec( + message: "typealias declaration name cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ) + ], + fixedSource: """ + typealias decl5 = Swift::Bool + """ + ) + assertParse( + """ + protocol 1️⃣main::decl6 { + associatedtype 2️⃣Swift::decl6a + } + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "protocol name cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "associatedtype declaration name cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ), + ], + fixedSource: """ + protocol decl6 { + associatedtype decl6a + } + """ + ) + } + + func testModuleSelectorIncorrectGlobalVarDecls() { + assertParse( + """ + let 1️⃣main::decl7 = 7 + """, + diagnostics: [ + DiagnosticSpec( + message: "pattern cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ) + ], + fixedSource: """ + let decl7 = 7 + """ + ) + assertParse( + """ + var 1️⃣main::decl8 = 8 { + willSet(2️⃣Swift::newValue) {} + didSet(3️⃣Foo::oldValue) {} + } + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "pattern cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "accessor parameter name cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ), + DiagnosticSpec( + locationMarker: "3️⃣", + message: "accessor parameter name cannot be qualified with a module selector", + fixIts: ["remove 'Foo::'"] + ), + ], + fixedSource: """ + var decl8 = 8 { + willSet(newValue) {} + didSet(oldValue) {} + } + """ + ) + } + + func testModuleSelectorIncorrectNestedDecls() { + assertParse( + """ + struct Parent { + func 1️⃣main::decl1() {} + } + """, + diagnostics: [ + DiagnosticSpec( + message: "function name cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ) + ], + fixedSource: """ + struct Parent { + func decl1() {} + } + """ + ) + assertParse( + """ + struct Parent { + enum 1️⃣main::decl2 { + case 2️⃣Swift::decl2a + } + } + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "enum name cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "enum case cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ), + ], + fixedSource: """ + struct Parent { + enum decl2 { + case decl2a + } + } + """ + ) + assertParse( + """ + struct Parent { + struct 1️⃣main::decl3 {} + } + """, + diagnostics: [ + DiagnosticSpec( + message: "struct name cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ) + ], + fixedSource: """ + struct Parent { + struct decl3 {} + } + """ + ) + assertParse( + """ + struct Parent { + class 1️⃣main::decl4 {} + } + """, + diagnostics: [ + DiagnosticSpec( + message: "class name cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ) + ], + fixedSource: """ + struct Parent { + class decl4 {} + } + """ + ) + assertParse( + """ + struct Parent { + typealias 1️⃣main::decl5 = Swift::Bool + } + """, + diagnostics: [ + DiagnosticSpec( + message: "typealias declaration name cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ) + ], + fixedSource: """ + struct Parent { + typealias decl5 = Swift::Bool + } + """ + ) + } + + func testModuleSelectorMacroDecls() { + assertParse( + """ + struct CreatesDeclExpectation { + #main::myMacro() + } + """, + substructure: MacroExpansionDeclSyntax( + moduleSelector: ModuleSelectorSyntax(moduleName: "main"), + macroName: "myMacro", + leftParen: .leftParenToken(), + arguments: [], + rightParen: .rightParenToken() + ) + ) + } + + func testModuleSelectorIncorrectRuntimeBaseAttr() { + // Should be diagnosed in ASTGen: + assertParse( + """ + @_swift_native_objc_runtime_base(1️⃣main::BaseClass) + class C1 {} + """, + substructure: AttributeSyntax( + attributeName: makeType(name: "_swift_native_objc_runtime_base"), + leftParen: .leftParenToken(), + arguments: .argumentList( + [ + LabeledExprSyntax(expression: makeDeclRef(moduleSelector: "main", baseName: "BaseClass")) + ] + ), + rightParen: .rightParenToken() + ) + ) + } + + func testModuleSelectorOperatorDecls() { + assertParse( + """ + infix operator <<<<< : 1️⃣Swift::AdditionPrecedence + """, + diagnostics: [ + DiagnosticSpec( + message: "operator declaration precedence group cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: """ + infix operator <<<<< : AdditionPrecedence + """ + ) + assertParse( + """ + precedencegroup 1️⃣main::PG1 { + higherThan: 2️⃣Swift::AdditionPrecedence + } + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "precedence group name cannot be qualified with a module selector", + fixIts: ["remove 'main::'"] + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "'higherThan' property of precedencegroup cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ), + ], + fixedSource: """ + precedencegroup PG1 { + higherThan: AdditionPrecedence + } + """ + ) + } + + func testModuleSelectorIllFormedModuleNames() { + assertParse( + """ + var a: 1️⃣::Int + """, + diagnostics: [ + DiagnosticSpec( + message: "expected module name in module selector", + fixIts: ["insert module name"] + ) + ], + fixedSource: """ + var a: <#identifier#>::Int + """ + ) + assertParse( + """ + var b: (1️⃣::Int) + """, + diagnostics: [ + DiagnosticSpec( + message: "expected module name in module selector", + fixIts: ["insert module name"] + ) + ], + fixedSource: """ + var b: (<#identifier#>::Int) + """ + ) + assertParse( + """ + var c: 1️⃣*::Int + """, + diagnostics: [ + DiagnosticSpec(message: "'*' is not a valid identifier") + ] + ) + assertParse( + """ + var d: 1️⃣_::Int + """, + diagnostics: [ + DiagnosticSpec(message: "'_' cannot be used as an identifier here") + ] + ) + assertParse( + """ + var e: 1️⃣Self::Int + """, + diagnostics: [ + DiagnosticSpec( + message: "keyword 'Self' cannot be used as an identifier here", + fixIts: ["if this name is unavoidable, use backticks to escape it"] + ) + ], + fixedSource: """ + var e: `Self`::Int + """ + ) + assertParse( + """ + var f: 1️⃣self::Int + """, + diagnostics: [ + DiagnosticSpec( + message: "keyword 'self' cannot be used as an identifier here", + fixIts: ["if this name is unavoidable, use backticks to escape it"] + ) + ], + fixedSource: """ + var f: `self`::Int + """ + ) + assertParse( + """ + var g: 1️⃣inout::Int + """, + diagnostics: [ + DiagnosticSpec( + message: "keyword 'inout' cannot be used as an identifier here", + fixIts: ["if this name is unavoidable, use backticks to escape it"] + ) + ], + fixedSource: """ + var g: `inout`::Int + """ + ) + assertParse( + """ + var h: 1️⃣Any::Int + """, + diagnostics: [ + DiagnosticSpec( + message: "keyword 'Any' cannot be used as an identifier here", + fixIts: ["if this name is unavoidable, use backticks to escape it"] + ) + ], + fixedSource: """ + var h: `Any`::Int + """ + ) + assertParse( + """ + var aArray: [1️⃣::Int] + """, + diagnostics: [ + DiagnosticSpec( + message: "expected module name in module selector", + fixIts: ["insert module name"] + ) + ], + fixedSource: """ + var aArray: [<#identifier#>::Int] + """ + ) + assertParse( + """ + var bArray: [(1️⃣::Int)] + """, + diagnostics: [ + DiagnosticSpec( + message: "expected module name in module selector", + fixIts: ["insert module name"] + ) + ], + fixedSource: """ + var bArray: [(<#identifier#>::Int)] + """ + ) + assertParse( + """ + var cArray: [1️⃣*::Int] + """, + diagnostics: [ + DiagnosticSpec(message: "'*' is not a valid identifier") + ] + ) + assertParse( + """ + var dArray: [1️⃣_::Int] + """, + diagnostics: [ + DiagnosticSpec(message: "'_' cannot be used as an identifier here") + ] + ) + assertParse( + """ + var eArray: [1️⃣Self::Int] + """, + diagnostics: [ + DiagnosticSpec( + message: "keyword 'Self' cannot be used as an identifier here", + fixIts: ["if this name is unavoidable, use backticks to escape it"] + ) + ], + fixedSource: """ + var eArray: [`Self`::Int] + """ + ) + assertParse( + """ + var fArray: [1️⃣self::Int] + """, + diagnostics: [ + DiagnosticSpec( + message: "keyword 'self' cannot be used as an identifier here", + fixIts: ["if this name is unavoidable, use backticks to escape it"] + ) + ], + fixedSource: """ + var fArray: [`self`::Int] + """ + ) + assertParse( + """ + var gArray: [1️⃣inout::Int] + """, + diagnostics: [ + DiagnosticSpec( + message: "keyword 'inout' cannot be used as an identifier here", + fixIts: ["if this name is unavoidable, use backticks to escape it"] + ) + ], + fixedSource: """ + var gArray: [`inout`::Int] + """ + ) + assertParse( + """ + var hArray: [1️⃣Any::Int] + """, + diagnostics: [ + DiagnosticSpec( + message: "keyword 'Any' cannot be used as an identifier here", + fixIts: ["if this name is unavoidable, use backticks to escape it"] + ) + ], + fixedSource: """ + var hArray: [`Any`::Int] + """ + ) + assertParse( + """ + var aIndex: String.1️⃣::Index + """, + diagnostics: [ + DiagnosticSpec( + message: "expected module name in module selector", + fixIts: ["insert module name"] + ) + ], + fixedSource: """ + var aIndex: String.<#identifier#>::Index + """ + ) + // FIXME: This gets interpreted as a single `.*` operator; may not be ideal. + assertParse( + """ + var cIndex: String1️⃣.*::Index + """, + diagnostics: [ + DiagnosticSpec( + message: "expected '=' in variable", + fixIts: ["insert '='"] + ), + DiagnosticSpec(message: "'.*' is not a valid identifier"), + ], + fixedSource: """ + var cIndex: String = .*::Index + """ + ) + assertParse( + """ + var dIndex: String.1️⃣_::Index + """, + diagnostics: [ + DiagnosticSpec(message: "'_' cannot be used as an identifier here") + ] + ) + assertParse( + """ + var eIndex: String.1️⃣Self::Index + """, + diagnostics: [ + DiagnosticSpec( + message: "keyword 'Self' cannot be used as an identifier here", + fixIts: ["if this name is unavoidable, use backticks to escape it"] + ) + ], + fixedSource: """ + var eIndex: String.`Self`::Index + """ + ) + assertParse( + """ + var fIndex: String.1️⃣self::Index + """, + diagnostics: [ + DiagnosticSpec( + message: "keyword 'self' cannot be used as an identifier here", + fixIts: ["if this name is unavoidable, use backticks to escape it"] + ) + ], + fixedSource: """ + var fIndex: String.`self`::Index + """ + ) + assertParse( + """ + var gIndex: String.1️⃣inout::Index + """, + diagnostics: [ + DiagnosticSpec( + message: "keyword 'inout' cannot be used as an identifier here", + fixIts: ["if this name is unavoidable, use backticks to escape it"] + ) + ], + fixedSource: """ + var gIndex: String.`inout`::Index + """ + ) + assertParse( + """ + var hIndex: String.1️⃣Any::Index + """, + diagnostics: [ + DiagnosticSpec( + message: "keyword 'Any' cannot be used as an identifier here", + fixIts: ["if this name is unavoidable, use backticks to escape it"] + ) + ], + fixedSource: """ + var hIndex: String.`Any`::Index + """ + ) + assertParse( + """ + func inExpr() { + 1️⃣::print() + } + """, + diagnostics: [ + DiagnosticSpec( + message: "expected module name in module selector", + fixIts: ["insert module name"] + ) + ], + fixedSource: """ + func inExpr() { + <#identifier#>::print() + } + """ + ) + assertParse( + """ + func inExpr() { + (1️⃣::print()) + } + """, + diagnostics: [ + DiagnosticSpec( + message: "expected module name in module selector", + fixIts: ["insert module name"] + ) + ], + fixedSource: """ + func inExpr() { + (<#identifier#>::print()) + } + """ + ) + assertParse( + """ + func inExpr() { + 1️⃣*::print() + } + """, + diagnostics: [ + DiagnosticSpec(message: "'*' is not a valid identifier") + ] + ) + assertParse( + """ + func inExpr() { + 1️⃣_::print() + } + """, + diagnostics: [ + DiagnosticSpec(message: "'_' cannot be used as an identifier here") + ] + ) + assertParse( + """ + func inExpr() { + 1️⃣Self::print() + } + """, + diagnostics: [ + DiagnosticSpec( + message: "keyword 'Self' cannot be used as an identifier here", + fixIts: ["if this name is unavoidable, use backticks to escape it"] + ) + ], + fixedSource: """ + func inExpr() { + `Self`::print() + } + """ + ) + assertParse( + """ + func inExpr() { + 1️⃣self::print() + } + """, + diagnostics: [ + DiagnosticSpec( + message: "keyword 'self' cannot be used as an identifier here", + fixIts: ["if this name is unavoidable, use backticks to escape it"] + ) + ], + fixedSource: """ + func inExpr() { + `self`::print() + } + """ + ) + assertParse( + """ + func inExpr() { + 1️⃣inout::print() + } + """, + diagnostics: [ + DiagnosticSpec( + message: "keyword 'inout' cannot be used as an identifier here", + fixIts: ["if this name is unavoidable, use backticks to escape it"] + ) + ], + fixedSource: """ + func inExpr() { + `inout`::print() + } + """ + ) + assertParse( + """ + func inExpr() { + 1️⃣Any::print() + } + """, + diagnostics: [ + DiagnosticSpec( + message: "keyword 'Any' cannot be used as an identifier here", + fixIts: ["if this name is unavoidable, use backticks to escape it"] + ) + ], + fixedSource: """ + func inExpr() { + `Any`::print() + } + """ + ) + assertParse( + """ + func inExpr() { + _ = 1.1️⃣::magnitude + } + """, + diagnostics: [ + DiagnosticSpec( + message: "expected module name in module selector", + fixIts: ["insert module name"] + ) + ], + fixedSource: """ + func inExpr() { + _ = 1.<#identifier#>::magnitude + } + """ + ) + assertParse( + """ + func inExpr() { + _ = (1.1️⃣::magnitude) + } + """, + diagnostics: [ + DiagnosticSpec( + message: "expected module name in module selector", + fixIts: ["insert module name"] + ) + ], + fixedSource: """ + func inExpr() { + _ = (1.<#identifier#>::magnitude) + } + """ + ) + // FIXME: This gets interpreted as a single `.*` operator; may not be ideal. + assertParse( + """ + func inExpr() { + _ = 1.*1️⃣::magnitude + } + """, + diagnostics: [ + DiagnosticSpec( + message: "consecutive statements on a line must be separated by newline or ';'", + fixIts: ["insert newline", "insert ';'"] + ), + DiagnosticSpec( + message: "expected module name in module selector", + fixIts: ["insert module name"] + ), + ], + fixedSource: """ + func inExpr() { + _ = 1.* + <#identifier#>::magnitude + } + """ + ) + assertParse( + """ + func inExpr() { + _ = 1.1️⃣_::magnitude + } + """, + diagnostics: [ + DiagnosticSpec(message: "'_' cannot be used as an identifier here") + ] + ) + assertParse( + """ + func inExpr() { + _ = 1.1️⃣Self::magnitude + } + """, + diagnostics: [ + DiagnosticSpec( + message: "keyword 'Self' cannot be used as an identifier here", + fixIts: ["if this name is unavoidable, use backticks to escape it"] + ) + ], + fixedSource: """ + func inExpr() { + _ = 1.`Self`::magnitude + } + """ + ) + assertParse( + """ + func inExpr() { + _ = 1.1️⃣self::magnitude + } + """, + diagnostics: [ + DiagnosticSpec( + message: "keyword 'self' cannot be used as an identifier here", + fixIts: ["if this name is unavoidable, use backticks to escape it"] + ) + ], + fixedSource: """ + func inExpr() { + _ = 1.`self`::magnitude + } + """ + ) + assertParse( + """ + func inExpr() { + _ = 1.1️⃣inout::magnitude + } + """, + diagnostics: [ + DiagnosticSpec( + message: "keyword 'inout' cannot be used as an identifier here", + fixIts: ["if this name is unavoidable, use backticks to escape it"] + ) + ], + fixedSource: """ + func inExpr() { + _ = 1.`inout`::magnitude + } + """ + ) + assertParse( + """ + func inExpr() { + _ = 1.1️⃣Any::magnitude + } + """, + diagnostics: [ + DiagnosticSpec( + message: "keyword 'Any' cannot be used as an identifier here", + fixIts: ["if this name is unavoidable, use backticks to escape it"] + ) + ], + fixedSource: """ + func inExpr() { + _ = 1.`Any`::magnitude + } + """ + ) + } + + func testModuleSelectorAttrs() { + // Should be diagnosed in ASTGen + assertParse( + """ + @_spi(main::Private) + // expected-error@-1 {{SPI group cannot be qualified with a module selector}} expected-note@-1 {{remove module selector from this name}} {{7-13=}} + public struct BadImplementsAttr: CustomStringConvertible {} + """, + substructure: AttributeSyntax( + attributeName: makeType(name: "_spi"), + leftParen: .leftParenToken(), + arguments: .argumentList( + [ + LabeledExprSyntax(expression: makeDeclRef(moduleSelector: "main", baseName: "Private")) + ] + ), + rightParen: .rightParenToken() + ) + ) + assertParse( + """ + @_implements(main::CustomStringConvertible, 1️⃣Swift::description) + public var stringValue: String { fatalError() } + """, + diagnostics: [ + DiagnosticSpec( + message: "@_implements arguments declaration name cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: """ + @_implements(main::CustomStringConvertible, description) + public var stringValue: String { fatalError() } + """ + ) + assertParse( + """ + @_specialize(target: main::fn(), spi: 1️⃣Swift::Private, where T == Swift::Int) + public func fn() -> T { fatalError() } + """, + diagnostics: [ + DiagnosticSpec( + message: "attribute argument value cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: """ + @_specialize(target: main::fn(), spi: Private, where T == Swift::Int) + public func fn() -> T { fatalError() } + """ + ) + assertParse( + """ + func fn(_: @isolated(1️⃣Swift::any) () -> Void) {} + """, + diagnostics: [ + DiagnosticSpec( + message: "attribute argument cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: """ + func fn(_: @isolated(any) () -> Void) {} + """ + ) + assertParse( + """ + @_documentation(metadata: 1️⃣Swift::GroupName) + func fn() {} + """, + diagnostics: [ + DiagnosticSpec( + message: "@_documentation argument cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: """ + @_documentation(metadata: GroupName) + func fn() {} + """ + ) + assertParse( + """ + @derivative(of: Swift::Foo.Swift::Bar.Swift::baz(), wrt: quux) + func fn() {} + """, + substructure: AttributeSyntax( + attributeName: makeType(name: "derivative"), + leftParen: .leftParenToken(), + arguments: .derivativeRegistrationArguments( + DerivativeAttributeArgumentsSyntax( + originalDeclName: MemberAccessExprSyntax( + base: TypeExprSyntax( + type: makeMember( + of: makeType(moduleSelector: "Swift", name: "Foo"), + moduleSelector: "Swift", + name: "Bar" + ) + ), + declName: makeDeclRef(moduleSelector: "Swift", baseName: "baz", argumentLabels: []) + ), + comma: .commaToken(), + arguments: DifferentiabilityWithRespectToArgumentSyntax( + arguments: .argument( + DifferentiabilityArgumentSyntax(argument: "quux") + ) + ) + ) + ), + rightParen: .rightParenToken() + ) + ) + } + + func testModuleSelectorExpr() { + assertParse( + "let x = 1️⃣Swift::do { 1 }", + diagnostics: [ + DiagnosticSpec( + message: "'do' block cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "let x = do { 1 }", + experimentalFeatures: [.moduleSelector, .doExpressions] + ) + assertParse( + "let x = 1️⃣Swift::if y { 1 } else { 0 }", + diagnostics: [ + DiagnosticSpec( + message: "'if' statement cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "let x = if y { 1 } else { 0 }" + ) + assertParse( + """ + let x = 1️⃣Swift::switch y { + case true: 1 + case false: 0 + } + """, + diagnostics: [ + DiagnosticSpec( + message: "'switch' statement cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: """ + let x = switch y { + case true: 1 + case false: 0 + } + """ + ) + assertParse( + "fn(1️⃣Swift::&x)", + diagnostics: [ + DiagnosticSpec( + message: "inout expression cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "fn(&x)" + ) + assertParse( + #"_ = 1️⃣Swift::\main::Foo.BarKit::bar"#, + diagnostics: [ + DiagnosticSpec( + message: "key path cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: #"_ = \main::Foo.BarKit::bar"# + ) + assertParse( + #"_ = \main::Foo.BarKit::bar"#, + substructure: KeyPathExprSyntax( + root: makeType(moduleSelector: "main", name: "Foo"), + components: [ + KeyPathComponentSyntax( + period: .periodToken(), + component: .property( + KeyPathPropertyComponentSyntax( + declName: makeDeclRef(moduleSelector: "BarKit", baseName: "bar") + ) + ) + ) + ] + ) + ) + assertParse( + "_ = 1️⃣Swift::-x", + diagnostics: [ + DiagnosticSpec( + message: "operator cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "_ = -x" + ) + assertParse( + "_ = 1️⃣Swift::1", + diagnostics: [ + DiagnosticSpec( + message: "integer literal cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "_ = 1" + ) + assertParse( + "_ = 1️⃣Swift::1.0", + diagnostics: [ + DiagnosticSpec( + message: "floating literal cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "_ = 1.0" + ) + assertParse( + #"_ = 1️⃣Swift::@"fnord""#, + diagnostics: [ + DiagnosticSpec(message: "unexpected code 'Swift::@' before string literal") + ] + ) + assertParse( + #"_ = 1️⃣Swift::"fnord""#, + diagnostics: [ + DiagnosticSpec( + message: "string literal cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: #"_ = "fnord""# + ) + assertParse( + "_ = 1️⃣Swift::/fnord/", + diagnostics: [ + DiagnosticSpec( + message: "regex literal cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "_ = /fnord/" + ) + assertParse( + "_ = 1️⃣Swift::nil", + diagnostics: [ + DiagnosticSpec( + message: "'nil' keyword cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "_ = nil" + ) + assertParse( + "_ = 1️⃣Swift::true", + diagnostics: [ + DiagnosticSpec( + message: "bool literal cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "_ = true" + ) + assertParse( + "_ = Swift::identifier", + substructure: makeDeclRef(moduleSelector: "Swift", baseName: "identifier") + ) + assertParse( + "_ = Swift::self", + substructure: makeDeclRef(moduleSelector: "Swift", baseName: .keyword(.self)) + ) + assertParse( + "_ = Swift::init", + substructure: makeDeclRef(moduleSelector: "Swift", baseName: .keyword(.`init`)) + ) + assertParse( + "@attached(extension, names: 1️⃣Swift::deinit) macro m()", + substructure: makeDeclRef(moduleSelector: "Swift", baseName: .keyword(.`deinit`)), + substructureAfterMarker: "1️⃣" + ) + assertParse( + "@attached(extension, names: 1️⃣Swift::subscript) macro m()", + substructure: makeDeclRef(moduleSelector: "Swift", baseName: .keyword(.subscript)), + substructureAfterMarker: "1️⃣" + ) + assertParse( + "_ = Swift::Self", + substructure: makeDeclRef(moduleSelector: "Swift", baseName: .keyword(.`Self`)) + ) + assertParse( + "_ = Swift::Any", + substructure: makeType(moduleSelector: "Swift", name: .keyword(.Any)) + ) + assertParse( + "_ = Swift::$0", + substructure: makeDeclRef(moduleSelector: "Swift", baseName: .dollarIdentifier("$0")) + ) + assertParse( + "_ = Swift::$foo", + substructure: makeDeclRef(moduleSelector: "Swift", baseName: .identifier("$foo")) + ) + assertParse( + "_ = 1️⃣Swift::_", + diagnostics: [ + DiagnosticSpec( + message: "wildcard expression cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "_ = _" + ) + assertParse( + "1️⃣Swift::_ = 1", + diagnostics: [ + DiagnosticSpec( + message: "wildcard expression cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "_ = 1" + ) + assertParse( + "_ = 1️⃣Swift::#foo", + diagnostics: [ + DiagnosticSpec( + message: "macro expansion cannot be qualified with a module selector", + // FIXME: should fix-it exchange module selector and `#`? + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "_ = #foo" + ) + assertParse( + "_ = #Swift::foo", + substructure: MacroExpansionExprSyntax( + moduleSelector: ModuleSelectorSyntax(moduleName: "Swift"), + macroName: "foo", + arguments: [] + ) + ) + assertParse( + "_ = 1️⃣Swift::{ 1 }", + diagnostics: [ + DiagnosticSpec( + message: "closure cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "_ = { 1 }" + ) + assertParse( + "_ = 1️⃣Swift::.random()", + diagnostics: [ + DiagnosticSpec( + message: "member access cannot be qualified with a module selector", + // FIXME: should fix-it exchange module selector and `.`? + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "_ = .random()" + ) + assertParse( + "_ = 1️⃣Swift::.main::random()", + diagnostics: [ + DiagnosticSpec( + message: "member access cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "_ = .main::random()" + ) + assertParse( + "_ = .main::random()", + substructure: MemberAccessExprSyntax( + declName: makeDeclRef(moduleSelector: "main", baseName: "random") + ) + ) + assertParse( + "_ = 1️⃣Swift::super.foo()", + diagnostics: [ + DiagnosticSpec( + message: "'super' keyword cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "_ = super.foo()" + ) + assertParse( + "_ = 1️⃣Swift::(a, b)", + diagnostics: [ + DiagnosticSpec( + message: "tuple cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "_ = (a, b)" + ) + assertParse( + "_ = 1️⃣Swift::[a, b]", + diagnostics: [ + DiagnosticSpec( + message: "array cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "_ = [a, b]" + ) + assertParse( + "_ = Swift::1️⃣", + diagnostics: [ + // Don't diagnose the module selector itself--there are expressions where it might be valid + DiagnosticSpec( + message: "expected expression", + fixIts: ["insert expression"] + ) + ], + fixedSource: "_ = Swift::<#expression#>" + ) + + assertParse( + "_ = x.Swift::y", + substructure: MemberAccessExprSyntax( + base: makeDeclRef(baseName: "x"), + declName: makeDeclRef(moduleSelector: "Swift", baseName: "y") + ) + ) + assertParse( + "_ = x.1️⃣Swift::1", + diagnostics: [ + DiagnosticSpec( + message: "integer literal cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "_ = x.1" + ) + assertParse( + "_ = x.1️⃣Swift::self", + diagnostics: [ + // FIXME: improve location wording + DiagnosticSpec( + message: "'self' keyword cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "_ = x.self" + ) + assertParse( + "_ = x.Swift::Self.self", + // FIXME: inconsistent with type syntax + substructure: MemberAccessExprSyntax( + base: MemberAccessExprSyntax( + base: makeDeclRef(baseName: "x"), + declName: makeDeclRef(moduleSelector: "Swift", baseName: .keyword(.`Self`)) + ), + declName: makeDeclRef(baseName: .keyword(.`self`)) + ) + ) + assertParse( + "_ = x.Swift::Type.self", + // FIXME: inconsistent with type syntax + substructure: MemberAccessExprSyntax( + base: MemberAccessExprSyntax( + base: makeDeclRef(baseName: "x"), + declName: makeDeclRef(moduleSelector: "Swift", baseName: "Type") + ), + declName: makeDeclRef(baseName: .keyword(.`self`)) + ) + ) + assertParse( + "_ = x.Swift::Protocol.self", + // FIXME: inconsistent with type syntax + substructure: MemberAccessExprSyntax( + base: MemberAccessExprSyntax( + base: makeDeclRef(baseName: "x"), + declName: makeDeclRef(moduleSelector: "Swift", baseName: "Protocol") + ), + declName: makeDeclRef(baseName: .keyword(.`self`)) + ) + ) + assertParse( + "_ = myArray.reduce(0, 1️⃣Swift::+)", + substructure: makeDeclRef(moduleSelector: "Swift", baseName: .binaryOperator("+")), + substructureAfterMarker: "1️⃣" + ) + } + + func testModuleSelectorStmt() { + assertParse( + "if 1️⃣Swift::#available(macOS 15, *) {}", + diagnostics: [ + DiagnosticSpec( + message: "availability condition cannot be qualified with a module selector", + // FIXME: Exchange module selector and `#`? + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "if #available(macOS 15, *) {}" + ) + assertParse( + "if let 1️⃣Swift::optional {}", + diagnostics: [ + DiagnosticSpec( + message: "pattern cannot be qualified with a module selector", + fixIts: ["explicitly initialize variable 'optional'", "remove 'Swift::'"] + ) + ], + fixedSource: "if let optional = Swift::optional {}" + ) + } + + func testModuleSelectorType() { + assertParse( + "func fn(_: Swift::Self) {}", + substructure: makeType(moduleSelector: "Swift", name: .keyword(.`Self`)) + ) + assertParse( + "func fn(_: Swift::Any) {}", + substructure: makeType(moduleSelector: "Swift", name: .keyword(.Any)) + ) + assertParse( + "func fn(_: Swift::Foo) {}", + substructure: makeType(moduleSelector: "Swift", name: "Foo") + ) + assertParse( + "func fn(_: 1️⃣Swift::(Int, String)) {}", + diagnostics: [ + DiagnosticSpec( + message: "tuple type cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "func fn(_: (Int, String)) {}" + ) + assertParse( + "func fn(_: 1️⃣Swift::[Int]) {}", + diagnostics: [ + DiagnosticSpec( + message: "array type cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "func fn(_: [Int]) {}" + ) + assertParse( + "func fn(_: Swift::_) {}", + substructure: makeType(moduleSelector: "Swift", name: .wildcardToken()) + ) + assertParse( + "func fn(_: Swift::1️⃣) {}", + diagnostics: [ + // Don't diagnose the module selector--it may be a partly-written type + DiagnosticSpec( + message: "expected type in parameter", + fixIts: ["insert type"] + ) + ], + fixedSource: "func fn(_: Swift::<#type#>) {}" + ) + assertParse( + "func fn(_: Foo.1️⃣Swift::Type) {}", + diagnostics: [ + DiagnosticSpec( + message: "metatype cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "func fn(_: Foo.Type) {}" + ) + assertParse( + "func fn(_: Foo.1️⃣Swift::Protocol) {}", + diagnostics: [ + DiagnosticSpec( + message: "metatype cannot be qualified with a module selector", + fixIts: ["remove 'Swift::'"] + ) + ], + fixedSource: "func fn(_: Foo.Protocol) {}" + ) + assertParse( + "func fn(_: Foo.Swift::Bar) {}", + substructure: makeMember( + of: makeType(name: "Foo"), + moduleSelector: "Swift", + name: "Bar" + ) + ) + + // Bizarre, but will be diagnosed semantically anyway + assertParse( + "func fn(_: Foo.Swift::self) {}", + substructure: makeMember( + of: makeType(name: "Foo"), + moduleSelector: "Swift", + name: .keyword(.`self`) + ) + ) + } +} + +// MARK: - Syntax tree construction helpers + +private func makeType(moduleSelector: TokenSyntax? = nil, name: TokenSyntax) -> IdentifierTypeSyntax { + return IdentifierTypeSyntax( + moduleSelector: moduleSelector.map { ModuleSelectorSyntax(moduleName: $0) }, + name: name + ) +} + +private func makeDeclRef( + moduleSelector: TokenSyntax? = nil, + baseName: TokenSyntax, + argumentLabels: [TokenSyntax?]? = nil +) -> DeclReferenceExprSyntax { + return DeclReferenceExprSyntax( + moduleSelector: moduleSelector.map { ModuleSelectorSyntax(moduleName: $0) }, + baseName: baseName, + argumentNames: argumentLabels.map { argumentLabels in + DeclNameArgumentsSyntax( + arguments: DeclNameArgumentListSyntax( + argumentLabels.map { DeclNameArgumentSyntax(name: $0 ?? .wildcardToken()) } + ) + ) + } + ) +} + +private func makeMember( + of base: some TypeSyntaxProtocol, + moduleSelector: TokenSyntax? = nil, + name: TokenSyntax +) -> MemberTypeSyntax { + return MemberTypeSyntax( + baseType: base, + moduleSelector: moduleSelector.map { ModuleSelectorSyntax(moduleName: $0) }, + name: name + ) +} + +private func makeCall( + callee: some ExprSyntaxProtocol, + arguments: KeyValuePairs +) -> FunctionCallExprSyntax { + return FunctionCallExprSyntax( + calledExpression: callee, + leftParen: .leftParenToken(), + arguments: LabeledExprListSyntax( + arguments.map { labelAndExpr in + LabeledExprSyntax( + label: labelAndExpr.0, + colon: labelAndExpr.0 == nil ? nil : .colonToken(), + expression: labelAndExpr.1 + ) + } + ), + rightParen: .rightParenToken() + ) +} diff --git a/Tests/SwiftParserTest/translated/NumberIdentifierErrorsTests.swift b/Tests/SwiftParserTest/translated/NumberIdentifierErrorsTests.swift index c9806a481d0..1f6f10177b6 100644 --- a/Tests/SwiftParserTest/translated/NumberIdentifierErrorsTests.swift +++ b/Tests/SwiftParserTest/translated/NumberIdentifierErrorsTests.swift @@ -31,7 +31,7 @@ final class NumberIdentifierErrorsTests: ParserTestCase { func 1️⃣1() {} """, diagnostics: [ - DiagnosticSpec(message: "identifier can only start with a letter or underscore, not a number") + DiagnosticSpec(message: "name can only start with a letter or underscore, not a number") ] ) } @@ -42,7 +42,7 @@ final class NumberIdentifierErrorsTests: ParserTestCase { func 1️⃣2.0() {} """, diagnostics: [ - DiagnosticSpec(message: "identifier can only start with a letter or underscore, not a number") + DiagnosticSpec(message: "name can only start with a letter or underscore, not a number") ] ) } @@ -53,7 +53,7 @@ final class NumberIdentifierErrorsTests: ParserTestCase { func 1️⃣3func() {} """, diagnostics: [ - DiagnosticSpec(message: "identifier can only start with a letter or underscore, not a number") + DiagnosticSpec(message: "name can only start with a letter or underscore, not a number") ] ) } @@ -68,11 +68,11 @@ final class NumberIdentifierErrorsTests: ParserTestCase { diagnostics: [ DiagnosticSpec( locationMarker: "1️⃣", - message: "identifier can only start with a letter or underscore, not a number" + message: "name can only start with a letter or underscore, not a number" ), DiagnosticSpec( locationMarker: "2️⃣", - message: "identifier can only start with a letter or underscore, not a number" + message: "name can only start with a letter or underscore, not a number" ), ] ) @@ -88,11 +88,11 @@ final class NumberIdentifierErrorsTests: ParserTestCase { diagnostics: [ DiagnosticSpec( locationMarker: "1️⃣", - message: "identifier can only start with a letter or underscore, not a number" + message: "name can only start with a letter or underscore, not a number" ), DiagnosticSpec( locationMarker: "2️⃣", - message: "identifier can only start with a letter or underscore, not a number" + message: "name can only start with a letter or underscore, not a number" ), ] ) @@ -108,11 +108,11 @@ final class NumberIdentifierErrorsTests: ParserTestCase { diagnostics: [ DiagnosticSpec( locationMarker: "1️⃣", - message: "identifier can only start with a letter or underscore, not a number" + message: "name can only start with a letter or underscore, not a number" ), DiagnosticSpec( locationMarker: "2️⃣", - message: "identifier can only start with a letter or underscore, not a number" + message: "name can only start with a letter or underscore, not a number" ), ] ) @@ -124,7 +124,7 @@ final class NumberIdentifierErrorsTests: ParserTestCase { typealias 1️⃣10 = Int """, diagnostics: [ - DiagnosticSpec(message: "identifier can only start with a letter or underscore, not a number") + DiagnosticSpec(message: "name can only start with a letter or underscore, not a number") ] ) } @@ -135,7 +135,7 @@ final class NumberIdentifierErrorsTests: ParserTestCase { typealias 1️⃣11.0 = Int """, diagnostics: [ - DiagnosticSpec(message: "identifier can only start with a letter or underscore, not a number") + DiagnosticSpec(message: "name can only start with a letter or underscore, not a number") ] ) } @@ -146,7 +146,7 @@ final class NumberIdentifierErrorsTests: ParserTestCase { typealias 1️⃣12typealias = Int """, diagnostics: [ - DiagnosticSpec(message: "identifier can only start with a letter or underscore, not a number") + DiagnosticSpec(message: "name can only start with a letter or underscore, not a number") ] ) } @@ -157,7 +157,7 @@ final class NumberIdentifierErrorsTests: ParserTestCase { struct 1️⃣13 {} """, diagnostics: [ - DiagnosticSpec(message: "identifier can only start with a letter or underscore, not a number") + DiagnosticSpec(message: "name can only start with a letter or underscore, not a number") ] ) } @@ -168,7 +168,7 @@ final class NumberIdentifierErrorsTests: ParserTestCase { struct 1️⃣14.0 {} """, diagnostics: [ - DiagnosticSpec(message: "identifier can only start with a letter or underscore, not a number") + DiagnosticSpec(message: "name can only start with a letter or underscore, not a number") ] ) } @@ -179,7 +179,7 @@ final class NumberIdentifierErrorsTests: ParserTestCase { struct 1️⃣15struct {} """, diagnostics: [ - DiagnosticSpec(message: "identifier can only start with a letter or underscore, not a number") + DiagnosticSpec(message: "name can only start with a letter or underscore, not a number") ] ) } @@ -190,7 +190,7 @@ final class NumberIdentifierErrorsTests: ParserTestCase { enum 1️⃣16 {} """, diagnostics: [ - DiagnosticSpec(message: "identifier can only start with a letter or underscore, not a number") + DiagnosticSpec(message: "name can only start with a letter or underscore, not a number") ] ) } @@ -201,7 +201,7 @@ final class NumberIdentifierErrorsTests: ParserTestCase { enum 1️⃣17.0 {} """, diagnostics: [ - DiagnosticSpec(message: "identifier can only start with a letter or underscore, not a number") + DiagnosticSpec(message: "name can only start with a letter or underscore, not a number") ] ) } @@ -212,7 +212,7 @@ final class NumberIdentifierErrorsTests: ParserTestCase { enum 1️⃣18enum {} """, diagnostics: [ - DiagnosticSpec(message: "identifier can only start with a letter or underscore, not a number") + DiagnosticSpec(message: "name can only start with a letter or underscore, not a number") ] ) } @@ -227,11 +227,11 @@ final class NumberIdentifierErrorsTests: ParserTestCase { diagnostics: [ DiagnosticSpec( locationMarker: "1️⃣", - message: "identifier can only start with a letter or underscore, not a number" + message: "name can only start with a letter or underscore, not a number" ), DiagnosticSpec( locationMarker: "2️⃣", - message: "identifier can only start with a letter or underscore, not a number" + message: "name can only start with a letter or underscore, not a number" ), ] ) @@ -247,11 +247,11 @@ final class NumberIdentifierErrorsTests: ParserTestCase { diagnostics: [ DiagnosticSpec( locationMarker: "1️⃣", - message: "identifier can only start with a letter or underscore, not a number" + message: "name can only start with a letter or underscore, not a number" ), DiagnosticSpec( locationMarker: "2️⃣", - message: "identifier can only start with a letter or underscore, not a number" + message: "name can only start with a letter or underscore, not a number" ), ] ) @@ -267,11 +267,11 @@ final class NumberIdentifierErrorsTests: ParserTestCase { diagnostics: [ DiagnosticSpec( locationMarker: "1️⃣", - message: "identifier can only start with a letter or underscore, not a number" + message: "name can only start with a letter or underscore, not a number" ), DiagnosticSpec( locationMarker: "2️⃣", - message: "identifier can only start with a letter or underscore, not a number" + message: "name can only start with a letter or underscore, not a number" ), ] ) diff --git a/Tests/SwiftParserTest/translated/OperatorDeclTests.swift b/Tests/SwiftParserTest/translated/OperatorDeclTests.swift index a8e79ba960f..1d8d798a637 100644 --- a/Tests/SwiftParserTest/translated/OperatorDeclTests.swift +++ b/Tests/SwiftParserTest/translated/OperatorDeclTests.swift @@ -199,7 +199,7 @@ final class OperatorDeclTests: ParserTestCase { prefix operator1️⃣ """, diagnostics: [ - DiagnosticSpec(message: "expected binary operator in operator declaration", fixIts: ["insert binary operator"]) + DiagnosticSpec(message: "expected custom operator in operator declaration", fixIts: ["insert custom operator"]) ], fixedSource: """ prefix operator <#binary operator#> @@ -411,7 +411,7 @@ final class OperatorDeclTests: ParserTestCase { } """, diagnostics: [ - DiagnosticSpec(message: "expected identifier in precedencegroup", fixIts: ["insert identifier"]) + DiagnosticSpec(message: "expected name in precedence group", fixIts: ["insert name"]) ], fixedSource: """ precedencegroup <#identifier#> { @@ -447,7 +447,7 @@ final class OperatorDeclTests: ParserTestCase { } """, diagnostics: [ - DiagnosticSpec(message: "unexpected code 'precedence 123' in precedencegroup") + DiagnosticSpec(message: "unexpected code 'precedence 123' in precedence group") ] ) } @@ -486,7 +486,7 @@ final class OperatorDeclTests: ParserTestCase { } """, diagnostics: [ - DiagnosticSpec(message: "expected name in 'relation' property of precedencegroup", fixIts: ["insert name"]) + DiagnosticSpec(message: "expected name in 'higherThan' property of precedencegroup", fixIts: ["insert name"]) ], fixedSource: """ precedencegroup E { diff --git a/Tests/SwiftParserTest/translated/SwitchTests.swift b/Tests/SwiftParserTest/translated/SwitchTests.swift index 1e9a2778236..9b9f36f7ab1 100644 --- a/Tests/SwiftParserTest/translated/SwitchTests.swift +++ b/Tests/SwiftParserTest/translated/SwitchTests.swift @@ -40,8 +40,8 @@ final class SwitchTests: ParserTestCase { ), DiagnosticSpec( locationMarker: "2️⃣", - message: "expected identifier and function signature in function", - fixIts: ["insert identifier and function signature"] + message: "expected name and function signature in function", + fixIts: ["insert name and function signature"] ), ], fixedSource: """