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..5e1b4f0a0b9 100644 --- a/CodeGeneration/Sources/SyntaxSupport/CommonNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/CommonNodes.swift @@ -330,6 +330,25 @@ public let COMMON_NODES: [Node] = [ ] ), + 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" + ), + ] + ), + Node( kind: .pattern, base: .syntax, 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..4c5a1061d4d 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 ), ], @@ -1554,6 +1554,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)]) 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..47f3d57817d 100644 --- a/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift @@ -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)]) 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..772ce471083 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, @@ -788,6 +818,7 @@ extension Parser { let (unexpectedBeforeIsolationKind, isolationKind) = self.expectIdentifier(allowKeywordsAsIdentifier: true) let isolationKindElement = RawLabeledExprSyntax( + moduleSelector: nil, unexpectedBeforeIsolationKind, identifier: isolationKind, arena: self.arena @@ -918,6 +949,7 @@ extension Parser { 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 diff --git a/Sources/SwiftParser/Declarations.swift b/Sources/SwiftParser/Declarations.swift index 6ffffd81438..d2271bfcd4e 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 @@ -429,7 +431,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 +447,25 @@ 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) + 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( name: name, + unexpectedBeforeTrailingPeriod, trailingPeriod: keepGoing, arena: self.arena ) @@ -604,6 +615,7 @@ extension Parser { unexpectedBeforeInherited = RawUnexpectedNodesSyntax([classKeyword], arena: self.arena) inherited = RawTypeSyntax( RawIdentifierTypeSyntax( + moduleSelector: nil, name: missingToken(.identifier, text: "AnyObject"), genericArgumentClause: nil, arena: self.arena @@ -2188,11 +2200,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 +2256,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..299493acea5 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() @@ -652,6 +658,7 @@ extension Parser { if skipMemberName { let missingIdentifier = missingToken(.identifier) let declName = RawDeclReferenceExprSyntax( + moduleSelector: nil, baseName: missingIdentifier, argumentNames: nil, arena: self.arena @@ -661,9 +668,10 @@ extension Parser { // Parse the name portion. let declName: RawDeclReferenceExprSyntax - if let indexOrSelf = self.consume(if: .integerLiteral, .keyword(.self)) { + if !self.isAtModuleSelector(), let indexOrSelf = self.consume(if: .integerLiteral, .keyword(.self)) { // Handle "x.42" - a tuple index. declName = RawDeclReferenceExprSyntax( + moduleSelector: nil, baseName: indexOrSelf, argumentNames: nil, arena: self.arena @@ -1199,6 +1207,10 @@ extension Parser { pattern: PatternContext, flavor: ExprFlavor ) -> RawExprSyntax { + if self.isAtModuleSelector() && (!pattern.admitsBinding || !self.lookahead().isInBindingPatternPosition()) { + return self.parseIdentifierExpression(flavor: flavor) + } + switch self.at(anyIn: PrimaryExpressionStart.self) { case (.integerLiteral, let handle)?: let literal = self.eat(handle) @@ -1246,11 +1258,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 +1288,7 @@ extension Parser { let poundAvailable = self.parsePoundAvailableConditionElement() return RawExprSyntax( RawDeclReferenceExprSyntax( + moduleSelector: nil, RawUnexpectedNodesSyntax([poundAvailable], arena: self.arena), baseName: missingToken(.identifier), argumentNames: nil, @@ -1382,6 +1395,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 +1443,7 @@ extension Parser { return RawMacroExpansionExprSyntax( unexpectedBeforePound, pound: pound, + moduleSelector: moduleSelector, unexpectedBeforeMacroName, macroName: macroName, genericArgumentClause: generics, @@ -1743,6 +1758,7 @@ extension Parser { mutating func parseAnonymousClosureArgument() -> RawDeclReferenceExprSyntax { let (unexpectedBeforeBaseName, baseName) = self.expect(.dollarIdentifier) return RawDeclReferenceExprSyntax( + moduleSelector: nil, unexpectedBeforeBaseName, baseName: baseName, argumentNames: nil, @@ -1964,6 +1980,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. /// @@ -2015,7 +2039,7 @@ 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) { + if self.atBinaryOperatorArgument() { expr = RawExprSyntax(self.parseDeclReferenceExpr(.operators)) } else { expr = self.parseExpression(flavor: flavor, pattern: pattern) @@ -2395,8 +2419,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, 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..b0456e97edf 100644 --- a/Sources/SwiftParser/Names.swift +++ b/Sources/SwiftParser/Names.swift @@ -11,9 +11,9 @@ //===----------------------------------------------------------------------===// #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 { @@ -45,6 +45,151 @@ extension Parser { } } +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) { + switch lexeme.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) + } + + /// 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() -> ( + moduleNameOrUnexpected: Token, colonColonToken: Token, extra: [Token] + )? { + 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) + } +} + +extension Parser { + /// Parses one or more module selectors, if present. + mutating func parseModuleSelector() -> RawModuleSelectorSyntax? { + guard let (moduleNameOrUnexpected, colonColon, extra) = consumeModuleSelectorTokens() else { + return nil + } + + let leadingUnexpected: [RawSyntax] + let moduleName: RawTokenSyntax + let trailingUnexpected: [RawSyntax] + + if moduleNameOrUnexpected.tokenKind == .identifier { + leadingUnexpected = [] + moduleName = moduleNameOrUnexpected + } else { + leadingUnexpected = [RawSyntax(moduleNameOrUnexpected)] + moduleName = RawTokenSyntax.init(missing: .identifier, arena: arena) + } + + trailingUnexpected = extra.map { RawSyntax($0) } + + return RawModuleSelectorSyntax( + RawUnexpectedNodesSyntax(leadingUnexpected, arena: arena), + moduleName: moduleName, + colonColon: colonColon, + RawUnexpectedNodesSyntax(trailingUnexpected, arena: arena), + arena: arena + ) + } +} + extension Parser { struct DeclNameOptions: OptionSet { var rawValue: UInt8 @@ -68,6 +213,9 @@ extension Parser { } mutating func parseDeclReferenceExpr(_ flags: DeclNameOptions = []) -> RawDeclReferenceExprSyntax { + // Consume a module selector if present. + let moduleSelector = self.parseModuleSelector() + // Consume the base name. let base: RawTokenSyntax if let identOrSelf = self.consume(if: .identifier, .keyword(.self), .keyword(.Self)) @@ -89,6 +237,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 @@ -187,41 +336,31 @@ extension Parser { } mutating func parseQualifiedTypeIdentifier() -> RawTypeSyntax { - if self.at(.keyword(.Any)) { - return RawTypeSyntax(self.parseAnyType()) - } - let (unexpectedBeforeName, name) = self.expect(anyIn: IdentifierTypeSyntax.NameOptions.self, default: .identifier) - let generics: RawGenericArgumentClauseSyntax? - if self.at(prefix: "<") { - generics = self.parseGenericArguments() - } else { - generics = nil + let identifierType = self.parseTypeIdentifier() + var result = RawTypeSyntax(identifierType) + + // 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 +377,7 @@ extension Parser { RawMemberTypeSyntax( baseType: result, period: keepGoing!, + moduleSelector: memberModuleSelector, unexpectedBeforeName, name: name, genericArgumentClause: generics, @@ -245,14 +385,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 } diff --git a/Sources/SwiftParser/Parameters.swift b/Sources/SwiftParser/Parameters.swift index 1a40901237b..e6ec75d36bb 100644 --- a/Sources/SwiftParser/Parameters.swift +++ b/Sources/SwiftParser/Parameters.swift @@ -131,6 +131,7 @@ extension Parser { // Synthesize the secondName parameter as a type node. type = RawTypeSyntax( RawIdentifierTypeSyntax( + moduleSelector: nil, name: secondName, genericArgumentClause: nil, arena: self.arena diff --git a/Sources/SwiftParser/Parser.swift b/Sources/SwiftParser/Parser.swift index 6d6e8b37cb3..9ecd400b263 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) @@ -641,6 +645,25 @@ 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. + @inline(__always) + mutating func expect( + prefix: SyntaxText, + as tokenKind: RawTokenKind + ) -> (unexpected: RawUnexpectedNodesSyntax?, token: RawTokenSyntax) { + let spec = TokenSpec(tokenKind) + return expectImpl( + 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. diff --git a/Sources/SwiftParser/Patterns.swift b/Sources/SwiftParser/Patterns.swift index b58d68e51b0..37e5c390ecf 100644 --- a/Sources/SwiftParser/Patterns.swift +++ b/Sources/SwiftParser/Patterns.swift @@ -272,7 +272,10 @@ 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 diff --git a/Sources/SwiftParser/Statements.swift b/Sources/SwiftParser/Statements.swift index b6834a69af5..619794f19e7 100644 --- a/Sources/SwiftParser/Statements.swift +++ b/Sources/SwiftParser/Statements.swift @@ -969,6 +969,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/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..816a9fbd247 100644 --- a/Sources/SwiftParser/Types.swift +++ b/Sources/SwiftParser/Types.swift @@ -194,6 +194,26 @@ extension Parser { mutating func parseSimpleType( 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 { enum TypeBaseStart: TokenSpecSet { case `Self` @@ -227,27 +247,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 { + switch self.isAtModuleSelector() ? .identifier : 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 +258,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,13 +272,16 @@ 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)) { + } + + if !self.isAtModuleSelector() && (self.at(.keyword(.Type)) || self.at(.keyword(.Protocol))) { let metatypeSpecifier = self.consume(if: .keyword(.Type)) ?? self.consume(if: .keyword(.Protocol))! base = RawTypeSyntax( RawMetatypeTypeSyntax( @@ -287,6 +293,7 @@ extension Parser { ) ) } else { + let memberModuleSelector = self.parseModuleSelector() let name: RawTokenSyntax if let handle = self.at(anyIn: MemberTypeSyntax.NameOptions.self)?.handle { name = self.eat(handle) @@ -306,6 +313,7 @@ extension Parser { baseType: base, unexpectedPeriod, period: period, + moduleSelector: memberModuleSelector, name: name, genericArgumentClause: generics, arena: self.arena @@ -332,8 +340,6 @@ extension Parser { break } - base = wrapInTilde(base) - return base } @@ -362,9 +368,11 @@ extension Parser { } /// Parse a type identifier. - mutating func parseTypeIdentifier() -> RawTypeSyntax { - if self.at(.keyword(.Any)) { - return RawTypeSyntax(self.parseAnyType()) + mutating func parseTypeIdentifier() -> RawIdentifierTypeSyntax { + let moduleSelector = self.parseModuleSelector() + + if moduleSelector == nil && self.at(.keyword(.Any)) { + return self.parseAnyType() } let (unexpectedBeforeName, name) = self.expect(anyIn: IdentifierTypeSyntax.NameOptions.self, default: .identifier) @@ -375,13 +383,12 @@ extension Parser { generics = nil } - return RawTypeSyntax( - RawIdentifierTypeSyntax( - unexpectedBeforeName, - name: name, - genericArgumentClause: generics, - arena: self.arena - ) + return RawIdentifierTypeSyntax( + moduleSelector: moduleSelector, + unexpectedBeforeName, + name: name, + genericArgumentClause: generics, + arena: self.arena ) } @@ -389,6 +396,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 +408,7 @@ extension Parser { mutating func parsePlaceholderType() -> RawIdentifierTypeSyntax { let (unexpectedBeforeName, name) = self.expect(.wildcard) return RawIdentifierTypeSyntax( + moduleSelector: nil, unexpectedBeforeName, name: name, genericArgumentClause: nil, @@ -535,7 +544,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 @@ -994,6 +1008,8 @@ extension Parser.Lookahead { } mutating func canParseTypeIdentifier(allowKeyword: Bool = false) -> Bool { + _ = self.consumeModuleSelectorTokens() + if self.at(.keyword(.Any)) { self.consumeAnyToken() return true @@ -1305,7 +1321,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 +1352,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 +1369,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..f8489922cfa 100644 --- a/Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift +++ b/Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift @@ -1085,53 +1085,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 +1249,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..1c6b779f513 100644 --- a/Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift +++ b/Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift @@ -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") } diff --git a/Sources/SwiftParserDiagnostics/SyntaxExtensions.swift b/Sources/SwiftParserDiagnostics/SyntaxExtensions.swift index 3dc0aa8e82b..d044e030de5 100644 --- a/Sources/SwiftParserDiagnostics/SyntaxExtensions.swift +++ b/Sources/SwiftParserDiagnostics/SyntaxExtensions.swift @@ -127,6 +127,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..f047dc2cc51 100644 --- a/Sources/SwiftParserDiagnostics/generated/ChildNameForDiagnostics.swift +++ b/Sources/SwiftParserDiagnostics/generated/ChildNameForDiagnostics.swift @@ -179,6 +179,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: @@ -255,10 +257,16 @@ 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: diff --git a/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift b/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift index 52e2023df3e..7fe6aeb6c0e 100644 --- a/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift +++ b/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift @@ -221,7 +221,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,6 +290,8 @@ extension SyntaxKind { return "statement" case .missingType: return "type" + case .moduleSelector: + return "module selector" case .multipleTrailingClosureElement: return "trailing closure" case .namedOpaqueReturnType: 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/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..7f199475e8b 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: @@ -2344,6 +2364,16 @@ public func childName(_ keyPath: AnyKeyPath) -> String? { 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..ef893e1f9bc 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? { 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..14aff2265cb 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:)) } } @@ -2698,6 +2734,77 @@ public struct RawMissingTypeSyntax: RawTypeSyntaxNodeProtocol { } } +@_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) public struct RawMultipleTrailingClosureElementListSyntax: RawSyntaxNodeProtocol { @_spi(RawSyntax) diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift index 4def2848664..a768f46192f 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) @@ -2123,6 +2133,14 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.identifier)])) assertNoError(kind, 2, verify(layout[2], 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() { assertNoError(kind, index, verify(element, as: RawMultipleTrailingClosureElementSyntax.self)) @@ -3515,6 +3533,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..956844943fc 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, @@ -5165,6 +5255,137 @@ public struct MissingTypeSyntax: TypeSyntaxProtocol, SyntaxHashable, _LeafTypeSy public static let structure: SyntaxNodeStructure = .layout([\Self.unexpectedBeforePlaceholder, \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`` +@_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(ModuleSelectorSyntax.self) + } + } + + /// ### 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 /// ### Children 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..9901ff75f93 100644 --- a/Tests/SwiftParserTest/AttributeTests.swift +++ b/Tests/SwiftParserTest/AttributeTests.swift @@ -188,11 +188,23 @@ 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] + ) + assertParse( """ @objc(_:) 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/ModuleSelectorTests.swift b/Tests/SwiftParserTest/translated/ModuleSelectorTests.swift new file mode 100644 index 00000000000..43ad2484796 --- /dev/null +++ b/Tests/SwiftParserTest/translated/ModuleSelectorTests.swift @@ -0,0 +1,2174 @@ +//===----------------------------------------------------------------------===// +// +// 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 main1️⃣::decl1() {} + """, + diagnostics: [ + DiagnosticSpec(message: "unexpected code '::decl1' before parameter clause") + ] + ) + assertParse( + """ + func decl1( + main1️⃣::p1: Swift::A + ) {} + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "unexpected code '::p1' in parameter" + ) + ] + ) + + // Round-tripping failures: + assertParse( + """ + func decl1( + main1️⃣::p1: 2️⃣::A + ) {} + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "unexpected code '::p1' in parameter" + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "expected module name in module selector", + fixIts: ["insert module name"] + ), + ], + fixedSource: """ + func decl1( + main::p1: <#identifier#>::A + ) {} + """ + ) + assertParse( + """ + func decl1( + main1️⃣::p1: Swift::2️⃣ + ) {} + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "unexpected code '::p1' in parameter" + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "expected identifier in type", + fixIts: ["insert identifier"] + ), + ], + fixedSource: """ + func decl1( + main::p1: Swift::<#identifier#> + ) {} + """ + ) + + assertParse( + """ + func decl13️⃣( + main1️⃣::label p2: Swift::2️⃣inout A + 4️⃣) {} + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "unexpected code '::label p2' in parameter" + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "expected identifier in type", + fixIts: ["insert identifier"] + ), + // This recovers poorly becuase `inout` is treated as a decl keyword for recovery. Sucks for this test case, + // but it seems to be needed by others. + DiagnosticSpec( + locationMarker: "2️⃣", + message: "expected ')' to end parameter clause", + notes: [ + NoteSpec(locationMarker: "3️⃣", message: "to match this opening '('") + ], + fixIts: ["insert ')'"] + ), + DiagnosticSpec( + locationMarker: "4️⃣", + message: "extraneous code ') {}' at top level" + ), + ], + fixedSource: """ + func decl1( + main::label p2: Swift::<#identifier#>)inout A + ) {} + """ + ) + assertParse( + """ + func decl1( + label main1️⃣::p3: @Swift::escaping () -> A + ) {} + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "unexpected code '::p3' in parameter" + ) + ] + ) + } + + func testModuleSelectorIncorrectBindingDecls() { + assertParse( + """ + let main1️⃣::decl1a = "a" + """, + diagnostics: [ + DiagnosticSpec( + message: "expected '=' in variable", + fixIts: ["insert '='"] + ), + DiagnosticSpec( + message: "expected module name in module selector", + fixIts: ["insert module name"] + ), + ], + fixedSource: """ + let main = <#identifier#>::decl1a = "a" + """ + ) + + // Found by mutation testing: + assertParse( + """ + let let1️⃣::decl1a = "a" + """, + diagnostics: [ + DiagnosticSpec( + message: "expected pattern in value binding pattern", + fixIts: ["insert pattern"] + ), + DiagnosticSpec( + message: "expected '=' in variable", + fixIts: ["insert '='"] + ), + DiagnosticSpec( + message: "expected module name in module selector", + fixIts: ["insert module name"] + ), + ], + fixedSource: """ + let let<#pattern#> = <#identifier#>::decl1a = "a" + """ + ) + + assertParse( + """ + var main1️⃣::decl1b = "b" + """, + diagnostics: [ + DiagnosticSpec( + message: "expected '=' in variable", + fixIts: ["insert '='"] + ), + DiagnosticSpec( + message: "expected module name in module selector", + fixIts: ["insert module name"] + ), + ], + fixedSource: """ + var main = <#identifier#>::decl1b = "b" + """ + ) + assertParse( + """ + let (main1️⃣::decl1c, Swift::decl1d) = ("c", "d") + """, + diagnostics: [ + DiagnosticSpec( + message: "unexpected code '::decl1c, Swift::decl1d' in tuple pattern" + ) + ] + ) + assertParse( + """ + if let (main1️⃣::decl1e, Swift::decl1f) = Optional(("e", "f")) {} + """, + diagnostics: [ + DiagnosticSpec( + message: "unexpected code '::decl1e, Swift::decl1f' in tuple" + ) + ] + ) + assertParse( + """ + guard let (main1️⃣::decl1g, Swift::decl1h) = Optional(("g", "h")) else { return } + """, + diagnostics: [ + DiagnosticSpec( + message: "unexpected code '::decl1g, Swift::decl1h' in tuple" + ) + ] + ) + assertParse( + """ + switch Optional(main::decl1g) { + case Optional.some(let Swift1️⃣::decl1i): + break + case .none: + break + } + """, + diagnostics: [ + // FIXME: Function call??? + DiagnosticSpec( + message: "unexpected code '::decl1i' in function call" + ) + ] + ) + assertParse( + """ + switch Optional(main::decl1g) { + case let Optional.some(Swift1️⃣::decl1j): + break + case .none: + break + } + """, + diagnostics: [ + DiagnosticSpec( + message: "unexpected code '::decl1j' in function call" + ) + ] + ) + assertParse( + """ + switch Optional(main::decl1g) { + case let Swift1️⃣::decl1k?: + break + case .none: + break + } + """, + diagnostics: [ + DiagnosticSpec( + message: "unexpected code '::decl1k?' in switch case" + ) + ] + ) + assertParse( + """ + for main1️⃣::decl1l in "lll" {} + """, + diagnostics: [ + DiagnosticSpec( + message: "unexpected code '::decl1l' in 'for' statement" + ) + ] + ) + } + + func testModuleSelectorIncorrectClosureDecls() { + assertParse( + // This gets radically misinterpreted as two statements followed by some invalid code. + """ + "lll".forEach { [2️⃣Swift::magnitude] + main::elem 1️⃣in print(elem) + } + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "unexpected code 'in print(elem)' in closure" + ) + ] + ) + assertParse( + """ + "lll".forEach { (main1️⃣::elem) in print(elem) } + """, + diagnostics: [ + DiagnosticSpec( + message: "unexpected code '::elem' in parameter clause" + ) + ] + ) + assertParse( + """ + "lll".forEach { (main1️⃣::elem) -> Void in print(elem) } + """, + diagnostics: [ + DiagnosticSpec( + message: "unexpected code '::elem' in parameter clause" + ) + ] + ) + assertParse( + """ + "lll".forEach { (main1️⃣::elem: Character) -> Void in print(elem) } + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "unexpected code '::elem: Character' in parameter clause" + ) + ] + ) + } + + func testModuleSelectorIncorrectTypeDecls() { + assertParse( + """ + enum main1️⃣::decl2 { + case Swift2️⃣::decl2a + } + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "unexpected code '::decl2' in enum" + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "unexpected code '::decl2a' in enum" + ), + ] + ) + assertParse( + """ + struct main1️⃣::decl3 {} + """, + diagnostics: [ + DiagnosticSpec(message: "unexpected code '::decl3' in struct") + ] + ) + assertParse( + """ + class main1️⃣::decl4 {} + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "unexpected code '::decl4' in class" + ) + ] + ) + assertParse( + """ + typealias main1️⃣::decl5 = Swift::Bool + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "unexpected code '::decl5' in typealias declaration" + ) + ] + ) + assertParse( + """ + protocol main1️⃣::decl6 { + associatedtype Swift2️⃣::decl6a + } + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "unexpected code '::decl6' in protocol" + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "unexpected code '::decl6a' in protocol" + ), + ] + ) + } + + func testModuleSelectorIncorrectGlobalVarDecls() { + assertParse( + """ + let main1️⃣::decl7 = 7 + """, + diagnostics: [ + DiagnosticSpec( + message: "expected '=' in variable", + fixIts: ["insert '='"] + ), + DiagnosticSpec( + message: "expected module name in module selector", + fixIts: ["insert module name"] + ), + ], + fixedSource: """ + let main = <#identifier#>::decl7 = 7 + """ + ) + assertParse( + """ + var main1️⃣::decl8 = 8 { + willSet(Swift2️⃣::newValue) {} + didSet(Foo3️⃣::oldValue) {} + } + """, + diagnostics: [ + DiagnosticSpec( + message: "expected '=' in variable", + fixIts: ["insert '='"] + ), + DiagnosticSpec( + message: "expected module name in module selector", + fixIts: ["insert module name"] + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "unexpected code '::newValue' in accessor" + ), + DiagnosticSpec( + locationMarker: "3️⃣", + message: "unexpected code '::oldValue' in accessor" + ), + ], + fixedSource: """ + var main = <#identifier#>::decl8 = 8 { + willSet(Swift::newValue) {} + didSet(Foo::oldValue) {} + } + """ + ) + } + + func testModuleSelectorIncorrectNestedDecls() { + assertParse( + """ + struct Parent { + func main1️⃣::decl1() {} + } + """, + diagnostics: [ + DiagnosticSpec(message: "unexpected code '::decl1' before parameter clause") + ] + ) + assertParse( + """ + struct Parent { + enum main1️⃣::decl2 { + case Swift2️⃣::decl2a + } + } + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "unexpected code '::decl2' in enum" + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "unexpected code '::decl2a' in enum" + ), + ] + ) + assertParse( + """ + struct Parent { + struct main1️⃣::decl3 {} + } + """, + diagnostics: [ + DiagnosticSpec(message: "unexpected code '::decl3' in struct") + ] + ) + assertParse( + """ + struct Parent { + class main1️⃣::decl4 {} + } + """, + diagnostics: [ + DiagnosticSpec(message: "unexpected code '::decl4' in class") + ] + ) + assertParse( + """ + struct Parent { + typealias main1️⃣::decl5 = Swift::Bool + } + """, + diagnostics: [ + DiagnosticSpec( + message: "unexpected code '::decl5' in typealias declaration" + ) + ] + ) + } + + 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 <<<<< : Swift1️⃣::AdditionPrecedence + """, + 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: """ + infix operator <<<<< : Swift + <#identifier#>::AdditionPrecedence + """ + ) + assertParse( + """ + precedencegroup main1️⃣::PG1 { + higherThan: Swift2️⃣::AdditionPrecedence + } + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "unexpected code '::PG1' in precedencegroup" + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "unexpected code '::AdditionPrecedence' in precedencegroup" + ), + ] + ) + } + + 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() { + inout1️⃣::print() + } + """, + diagnostics: [ + DiagnosticSpec(message: "expected pattern in variable", fixIts: ["insert pattern"]), + DiagnosticSpec(message: "expected '=' in variable", fixIts: ["insert '='"]), + DiagnosticSpec(message: "expected module name in module selector", fixIts: ["insert module name"]), + ], + fixedSource: """ + func inExpr() { + inout<#pattern#> = <#identifier#>::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() { + // 'main::Private' should be diagnosed in ASTGen + assertParse( + """ + @_spi(main::Private) + public struct BadImplementsAttr: CustomStringConvertible {} + """, + substructure: AttributeSyntax( + attributeName: makeType(name: "_spi"), + leftParen: .leftParenToken(), + arguments: .argumentList( + [ + LabeledExprSyntax(expression: makeDeclRef(moduleSelector: "main", baseName: "Private")) + ] + ), + rightParen: .rightParenToken() + ) + ) + // 'Swift::description' should be diagnosed in ASTGen + assertParse( + """ + @_implements(main::CustomStringConvertible, Swift::description) + public var stringValue: String { fatalError() } + """, + substructure: AttributeSyntax( + attributeName: makeType(name: "_implements"), + leftParen: .leftParenToken(), + arguments: .implementsArguments( + ImplementsAttributeArgumentsSyntax( + type: makeType(moduleSelector: "main", name: "CustomStringConvertible"), + declName: makeDeclRef(moduleSelector: "Swift", baseName: "description") + ) + ), + rightParen: .rightParenToken() + ) + ) + assertParse( + """ + @_specialize(target: main::fn(), spi: Swift1️⃣::Private, where T == Swift::Int) + public func fn() -> T { fatalError() } + """, + diagnostics: [ + DiagnosticSpec(message: "unexpected code '::Private, where T == Swift::Int' in attribute") + ] + ) + assertParse( + """ + func fn(_: @isolated(Swift1️⃣::any) () -> Void) {} + """, + diagnostics: [ + DiagnosticSpec(message: "unexpected code '::any' in attribute") + ] + ) + assertParse( + """ + @_documentation(metadata: Swift1️⃣::GroupName) + func fn() {} + """, + diagnostics: [ + DiagnosticSpec(message: "unexpected code '::GroupName' in attribute") + ] + ) + 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 = Swift::1️⃣do { 1 }", + diagnostics: [ + DiagnosticSpec( + message: "expected identifier in variable", + fixIts: ["insert identifier"] + ) + ], + fixedSource: "let x = Swift::<#identifier#>do { 1 }", + experimentalFeatures: [.moduleSelector, .doExpressions] + ) + assertParse( + "let x = Swift::1️⃣if y { 1 } else { 0 }", + diagnostics: [ + DiagnosticSpec( + message: "expected identifier in variable", + fixIts: ["insert identifier"] + ) + ], + fixedSource: "let x = Swift::<#identifier#>if y { 1 } else { 0 }" + ) + assertParse( + """ + let x = Swift::1️⃣switch y { + case true: 1 + case false: 0 + } + """, + diagnostics: [ + DiagnosticSpec( + message: "expected identifier in variable", + fixIts: ["insert identifier"] + ) + ], + fixedSource: """ + let x = Swift::<#identifier#>switch y { + case true: 1 + case false: 0 + } + """ + ) + assertParse( + "fn(Swift::1️⃣&x)", + diagnostics: [ + DiagnosticSpec( + message: "expected identifier in function call", + fixIts: ["insert identifier"] + ), + DiagnosticSpec(message: "unexpected code '&x' in function call"), + ], + fixedSource: "fn(Swift::<#identifier#>&x)" + ) + assertParse( + #"_ = Swift::1️⃣\main::Foo.BarKit::bar"#, + diagnostics: [ + DiagnosticSpec(message: "expected identifier", fixIts: ["insert identifier"]) + ], + fixedSource: #"_ = Swift::<#identifier#>\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( + "_ = Swift::1️⃣-x", + diagnostics: [ + DiagnosticSpec(message: "expected identifier", fixIts: ["insert identifier"]) + ], + fixedSource: "_ = Swift::<#identifier#>-x" + ) + assertParse( + "_ = Swift::1️⃣1", + diagnostics: [ + DiagnosticSpec(message: "expected identifier", fixIts: ["insert identifier"]) + ], + fixedSource: "_ = Swift::<#identifier#>1" + ) + assertParse( + "_ = Swift::1️⃣1.0", + diagnostics: [ + DiagnosticSpec(message: "expected identifier", fixIts: ["insert identifier"]) + ], + fixedSource: "_ = Swift::<#identifier#>1.0" + ) + assertParse( + #"_ = Swift::1️⃣@"fnord""#, + diagnostics: [ + DiagnosticSpec(message: "expected identifier", fixIts: ["insert identifier"]), + DiagnosticSpec(message: #"extraneous code '@"fnord"' at top level"#), + ], + fixedSource: #"_ = Swift::<#identifier#>@"fnord""# + ) + assertParse( + #"_ = Swift::1️⃣"fnord""#, + diagnostics: [ + DiagnosticSpec(message: "expected identifier", fixIts: ["insert identifier"]) + ], + fixedSource: #"_ = Swift::<#identifier#>"fnord""# + ) + assertParse( + "_ = Swift::1️⃣/fnord/", + diagnostics: [ + DiagnosticSpec(message: "expected identifier", fixIts: ["insert identifier"]) + ], + fixedSource: "_ = Swift::<#identifier#>/fnord/" + ) + assertParse( + "_ = Swift::1️⃣nil", + diagnostics: [ + DiagnosticSpec(message: "expected identifier", fixIts: ["insert identifier"]) + ], + fixedSource: "_ = Swift::<#identifier#>nil" + ) + assertParse( + "_ = Swift::1️⃣true", + diagnostics: [ + DiagnosticSpec(message: "expected identifier", fixIts: ["insert identifier"]) + ], + fixedSource: "_ = Swift::<#identifier#>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::1️⃣Any", + diagnostics: [ + DiagnosticSpec(message: "expected identifier", fixIts: ["insert identifier"]) + ], + fixedSource: "_ = Swift::<#identifier#>Any" + ) + assertParse( + "_ = Swift::1️⃣$0", + diagnostics: [ + DiagnosticSpec(message: "expected identifier", fixIts: ["insert identifier"]) + ], + fixedSource: "_ = Swift::<#identifier#>$0" + ) + assertParse( + "_ = Swift::$foo", + substructure: makeDeclRef(moduleSelector: "Swift", baseName: .identifier("$foo")) + ) + assertParse( + "_ = Swift::1️⃣_", + diagnostics: [ + DiagnosticSpec(message: "expected identifier", fixIts: ["insert identifier"]) + ], + fixedSource: "_ = Swift::<#identifier#>_" + ) + assertParse( + "Swift::1️⃣_ = 1", + diagnostics: [ + DiagnosticSpec(message: "expected identifier", fixIts: ["insert identifier"]) + ], + fixedSource: "Swift::<#identifier#>_ = 1" + ) + assertParse( + "_ = Swift::1️⃣#foo", + diagnostics: [ + DiagnosticSpec(message: "expected identifier", fixIts: ["insert identifier"]) + ], + fixedSource: "_ = Swift::<#identifier#>#foo" + ) + assertParse( + "_ = #Swift::foo", + substructure: MacroExpansionExprSyntax( + moduleSelector: ModuleSelectorSyntax(moduleName: "Swift"), + macroName: "foo", + arguments: [] + ) + ) + assertParse( + "_ = Swift::1️⃣{ 1 }", + diagnostics: [ + DiagnosticSpec(message: "expected identifier in function call", fixIts: ["insert identifier"]) + ], + fixedSource: "_ = Swift::<#identifier#> { 1 }" + ) + assertParse( + "_ = Swift::1️⃣.random()", + diagnostics: [ + DiagnosticSpec(message: "expected identifier in member access", fixIts: ["insert identifier"]) + ], + fixedSource: "_ = Swift::<#identifier#>.random()" + ) + assertParse( + "_ = Swift::1️⃣.main::random()", + diagnostics: [ + DiagnosticSpec(message: "expected identifier in member access", fixIts: ["insert identifier"]) + ], + fixedSource: "_ = Swift::<#identifier#>.main::random()" + ) + assertParse( + "_ = .main::random()", + substructure: MemberAccessExprSyntax( + declName: makeDeclRef(moduleSelector: "main", baseName: "random") + ) + ) + assertParse( + "_ = Swift::1️⃣super.foo()", + diagnostics: [ + DiagnosticSpec(message: "expected identifier", fixIts: ["insert identifier"]) + ], + fixedSource: "_ = Swift::<#identifier#>super.foo()" + ) + assertParse( + "_ = Swift::1️⃣(a, b)", + diagnostics: [ + DiagnosticSpec(message: "expected identifier in function call", fixIts: ["insert identifier"]) + ], + fixedSource: "_ = Swift::<#identifier#>(a, b)" + ) + assertParse( + "_ = Swift::1️⃣[a, b]", + diagnostics: [ + DiagnosticSpec(message: "expected identifier in subscript", fixIts: ["insert identifier"]) + ], + fixedSource: "_ = Swift::<#identifier#>[a, b]" + ) + assertParse( + "_ = Swift::1️⃣", + diagnostics: [ + DiagnosticSpec(message: "expected identifier", fixIts: ["insert identifier"]) + ], + fixedSource: "_ = Swift::<#identifier#>" + ) + + assertParse( + "_ = x.Swift::y", + substructure: MemberAccessExprSyntax( + base: makeDeclRef(baseName: "x"), + declName: makeDeclRef(moduleSelector: "Swift", baseName: "y") + ) + ) + assertParse( + "_ = x.Swift::1️⃣1", + diagnostics: [ + DiagnosticSpec(message: "expected identifier in member access", fixIts: ["insert identifier"]) + ], + fixedSource: "_ = x.Swift::<#identifier#>1" + ) + // Diagnose in ASTGen? + assertParse( + "_ = x.Swift::1️⃣self", + substructure: MemberAccessExprSyntax( + base: makeDeclRef(baseName: "x"), + declName: makeDeclRef( + moduleSelector: "Swift", + baseName: .keyword(.`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 Swift::1️⃣#available(macOS 15, *) {}", + diagnostics: [ + DiagnosticSpec(message: "expected identifier in 'if' statement", fixIts: ["insert identifier"]), + DiagnosticSpec(message: "unexpected code '#available(macOS 15, *)' in 'if' statement"), + ], + fixedSource: "if Swift::<#identifier#> #available(macOS 15, *) {}" + ) + } + + 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(_: Swift::1️⃣(Int, String)) {}", + diagnostics: [ + DiagnosticSpec(message: "expected identifier in type", fixIts: ["insert identifier"]), + DiagnosticSpec(message: "unexpected code '(Int, String)' in parameter clause"), + ], + fixedSource: "func fn(_: Swift::<#identifier#>(Int, String)) {}" + ) + assertParse( + "func fn(_: Swift::1️⃣[Int]) {}", + diagnostics: [ + DiagnosticSpec(message: "expected identifier in type", fixIts: ["insert identifier"]), + DiagnosticSpec(message: "unexpected code '[Int]' in parameter clause"), + ], + fixedSource: "func fn(_: Swift::<#identifier#>[Int]) {}" + ) + assertParse( + "func fn(_: Swift::_) {}", + substructure: makeType(moduleSelector: "Swift", name: .wildcardToken()) + ) + assertParse( + "func fn(_: Swift::1️⃣) {}", + diagnostics: [ + DiagnosticSpec(message: "expected identifier in type", fixIts: ["insert identifier"]) + ], + fixedSource: "func fn(_: Swift::<#identifier#>) {}" + ) + // TODO: Add equivalent test case for legacy parser + assertParse( + "func fn(_: Foo.1️⃣Swift::Type) {}", + substructure: makeMember( + of: makeType(name: "Foo"), + moduleSelector: "Swift", + name: "Type" + ) + ) + // TODO: Add equivalent test case for legacy parser + assertParse( + "func fn(_: Foo.1️⃣Swift::Protocol) {}", + substructure: makeMember( + of: makeType(name: "Foo"), + moduleSelector: "Swift", + name: "Protocol" + ) + ) + assertParse( + "func fn(_: Foo.Swift::Bar) {}", + substructure: makeMember( + of: makeType(name: "Foo"), + moduleSelector: "Swift", + name: "Bar" + ) + ) + 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() + ) +}