Skip to content

Commit 77051cd

Browse files
committed
Deprecate placeholder nodes
1 parent e695b37 commit 77051cd

File tree

21 files changed

+72
-36
lines changed

21 files changed

+72
-36
lines changed

CodeGeneration/Package.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ let package = Package(
2121
// checkout of swift-syntax that is unaffected by the newly generated files.
2222
// Be sure to revert the change before committing your changes.
2323
//
24-
// .package(url: "https://github.com/apple/swift-syntax", branch: "main")
25-
.package(path: "..")
24+
.package(url: "https://github.com/apple/swift-syntax", branch: "main")
25+
// .package(path: "..")
2626
],
2727
targets: [
2828
.executableTarget(

CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@ public let DECL_NODES: [Node] = [
551551
Node(
552552
kind: .editorPlaceholderDecl,
553553
base: .decl,
554+
isDeprecated: true,
554555
nameForDiagnostics: "editor placeholder",
555556
documentation: """
556557
An editor placeholder, e.g. `<#declaration#>` that is used in a position that expects a declaration.

CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,7 @@ public let EXPR_NODES: [Node] = [
791791
Node(
792792
kind: .editorPlaceholderExpr,
793793
base: .expr,
794+
isDeprecated: true,
794795
nameForDiagnostics: "editor placeholder",
795796
children: [
796797
Child(

CodeGeneration/Sources/SyntaxSupport/Node.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ public class Node {
5757
/// function that should be invoked to create this node.
5858
public let parserFunction: TokenSyntax?
5959

60+
/// If `true`, if the node is deprecated and should not be used anymore.
61+
public let isDeprecated: Bool
62+
6063
/// If `true`, this is for an experimental language feature, and any public
6164
/// API generated should be SPI.
6265
public var isExperimental: Bool { experimentalFeature != nil }
@@ -95,7 +98,7 @@ public class Node {
9598

9699
/// Retrieve the attributes that should be printed on any API for the
97100
/// generated node. If `forRaw` is true, this is for the raw syntax node.
98-
public func apiAttributes(forRaw: Bool = false) -> AttributeListSyntax {
101+
public func apiAttributes(forRaw: Bool = false, ignoreAvailableAttribute: Bool = false) -> AttributeListSyntax {
99102
let attrList = AttributeListSyntax {
100103
if isExperimental {
101104
// SPI for enum cases currently requires Swift 5.8 to work correctly.
@@ -106,10 +109,16 @@ public class Node {
106109
"""
107110
experimentalSPI.with(\.trailingTrivia, .newline)
108111
}
112+
109113
if forRaw {
110114
"@_spi(RawSyntax)"
111115
}
116+
117+
if isDeprecated, !ignoreAvailableAttribute {
118+
#"@available(*, deprecated, message: "Will be removed in a future version.")"#
119+
}
112120
}
121+
113122
return attrList.with(\.trailingTrivia, attrList.isEmpty ? [] : .newline)
114123
}
115124

@@ -128,6 +137,7 @@ public class Node {
128137
kind: SyntaxNodeKind,
129138
base: SyntaxNodeKind,
130139
experimentalFeature: ExperimentalFeature? = nil,
140+
isDeprecated: Bool = false,
131141
nameForDiagnostics: String?,
132142
documentation: String? = nil,
133143
parserFunction: TokenSyntax? = nil,
@@ -140,6 +150,7 @@ public class Node {
140150
self.kind = kind
141151
self.base = base
142152
self.experimentalFeature = experimentalFeature
153+
self.isDeprecated = isDeprecated
143154
self.nameForDiagnostics = nameForDiagnostics
144155
self.documentation = SwiftSyntax.Trivia.docCommentTrivia(from: documentation)
145156
self.parserFunction = parserFunction
@@ -272,6 +283,7 @@ public class Node {
272283
kind: SyntaxNodeKind,
273284
base: SyntaxNodeKind,
274285
experimentalFeature: ExperimentalFeature? = nil,
286+
isDeprecated: Bool = false,
275287
nameForDiagnostics: String?,
276288
documentation: String? = nil,
277289
parserFunction: TokenSyntax? = nil,
@@ -281,6 +293,7 @@ public class Node {
281293
precondition(base == .syntaxCollection)
282294
self.base = base
283295
self.experimentalFeature = experimentalFeature
296+
self.isDeprecated = isDeprecated
284297
self.nameForDiagnostics = nameForDiagnostics
285298
self.documentation = SwiftSyntax.Trivia.docCommentTrivia(from: documentation)
286299
self.parserFunction = parserFunction

CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/SyntaxKindFile.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ let syntaxKindFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
2626
for node in NON_BASE_SYNTAX_NODES {
2727
DeclSyntax(
2828
"""
29-
\(node.apiAttributes())\
29+
\(node.apiAttributes(ignoreAvailableAttribute: true))\
3030
case \(node.varOrCaseName)
3131
"""
3232
)

Sources/SwiftParser/Declarations.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,9 @@ extension Parser {
275275
}
276276

277277
if self.currentToken.isEditorPlaceholder {
278-
let placeholder = self.consumeAnyToken()
278+
let placeholder = self.parseAnyIdentifier()
279279
return RawDeclSyntax(
280-
RawEditorPlaceholderDeclSyntax(
280+
RawMissingDeclSyntax(
281281
attributes: attrs.attributes,
282282
modifiers: attrs.modifiers,
283283
placeholder: placeholder,

Sources/SwiftParser/Expressions.swift

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,14 +1241,6 @@ extension Parser {
12411241
mutating func parseIdentifierExpression() -> RawExprSyntax {
12421242
let declName = self.parseDeclReferenceExpr(.compoundNames)
12431243
guard self.withLookahead({ $0.canParseAsGenericArgumentList() }) else {
1244-
if declName.baseName.tokenText.isEditorPlaceholder && declName.argumentNames == nil {
1245-
return RawExprSyntax(
1246-
RawEditorPlaceholderExprSyntax(
1247-
placeholder: declName.baseName,
1248-
arena: self.arena
1249-
)
1250-
)
1251-
}
12521244
return RawExprSyntax(declName)
12531245
}
12541246

Sources/SwiftParserDiagnostics/MissingNodesError.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,17 @@ extension ParseDiagnosticsGenerator {
381381

382382
// Walk all upcoming sibling to see if they are also missing to handle them in this diagnostic.
383383
// If this is the case, handle all of them in this diagnostic.
384-
var missingNodes = [Syntax(node)]
384+
var missingNodes: [Syntax] = [Syntax(node)]
385+
386+
// If the node is an `MissingDeclSyntax` and the placeholder is an editor placeholder
387+
// we should not add a diagnostic that it's missing.
388+
if let missing = missingNodes.first?.as(MissingDeclSyntax.self),
389+
missing.placeholder.isEditorPlaceholder,
390+
!missing.placeholder.isMissing
391+
{
392+
missingNodes = []
393+
}
394+
385395
if let parentWithTokens = ancestorWithMoreTokens, let index {
386396
let siblings = parentWithTokens.children(viewMode: .all)
387397
let siblingsAfter = siblings[siblings.index(after: index)...]
@@ -403,6 +413,10 @@ extension ParseDiagnosticsGenerator {
403413
}
404414
}
405415

416+
if missingNodes.isEmpty {
417+
return .visitChildren
418+
}
419+
406420
let changes = missingNodes.map { node in
407421
if let missing = node.asProtocol(MissingNodeSyntax.self) {
408422
// For missing nodes, only make the placeholder present. Don’t make any

Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
678678
if shouldSkip(node) {
679679
return .skipChildren
680680
}
681-
if node.statements.only?.item.is(EditorPlaceholderExprSyntax.self) == true {
681+
if let item = node.statements.only?.item.as(DeclReferenceExprSyntax.self), item.baseName.isEditorPlaceholder {
682682
// Only emit a single diagnostic about the editor placeholder and none for the missing '{' and '}'.
683683
addDiagnostic(node, .editorPlaceholderInSourceFile, handledNodes: [node.id])
684684
return .skipChildren

Sources/SwiftRefactor/ExpandEditorPlaceholder.swift

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ public struct ExpandEditorPlaceholder: EditRefactoringProvider {
135135
/// Expansion on `closure1` and `normalArg` is the same as `ExpandEditorPlaceholder`.
136136
public struct ExpandEditorPlaceholders: EditRefactoringProvider {
137137
public static func textRefactor(syntax token: TokenSyntax, in context: Void) -> [SourceEdit] {
138-
guard let placeholder = token.parent?.as(EditorPlaceholderExprSyntax.self),
138+
guard let placeholder = token.parent?.as(DeclReferenceExprSyntax.self),
139139
let arg = placeholder.parent?.as(LabeledExprSyntax.self),
140140
let argList = arg.parent?.as(LabeledExprListSyntax.self),
141141
let call = argList.parent?.as(FunctionCallExprSyntax.self)
@@ -190,8 +190,8 @@ extension FunctionTypeSyntax {
190190
placeholder = ExpandEditorPlaceholder.wrapInTypePlaceholder(ret, type: ret)
191191
}
192192

193-
let statementPlaceholder = EditorPlaceholderExprSyntax(
194-
placeholder: .identifier(placeholder)
193+
let statementPlaceholder = DeclReferenceExprSyntax(
194+
baseName: .identifier(placeholder)
195195
)
196196
let closureStatement = CodeBlockItemSyntax(
197197
item: .expr(ExprSyntax(statementPlaceholder))
@@ -234,8 +234,9 @@ extension FunctionCallExprSyntax {
234234
var includedArg = false
235235
var argsToExpand = 0
236236
for arg in arguments.reversed() {
237-
guard let expr = arg.expression.as(EditorPlaceholderExprSyntax.self),
238-
let data = EditorPlaceholderData(token: expr.placeholder),
237+
guard let expr = arg.expression.as(DeclReferenceExprSyntax.self),
238+
expr.baseName.isEditorPlaceholder,
239+
let data = EditorPlaceholderData(token: expr.baseName),
239240
case let .typed(_, type) = data,
240241
type.is(FunctionTypeSyntax.self)
241242
else {
@@ -253,7 +254,7 @@ extension FunctionCallExprSyntax {
253254

254255
var expandedArgs = [LabeledExprSyntax]()
255256
for arg in arguments.suffix(argsToExpand) {
256-
let edits = ExpandEditorPlaceholder.textRefactor(syntax: arg.expression.cast(EditorPlaceholderExprSyntax.self).placeholder)
257+
let edits = ExpandEditorPlaceholder.textRefactor(syntax: arg.expression.cast(DeclReferenceExprSyntax.self).baseName)
257258
guard edits.count == 1, let edit = edits.first, !edit.replacement.isEmpty else {
258259
return nil
259260
}

0 commit comments

Comments
 (0)