Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate placeholder nodes #2237

Merged
merged 1 commit into from
Nov 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,8 @@ public let DECL_NODES: [Node] = [
nameForDiagnostics: "editor placeholder",
documentation: """
An editor placeholder, e.g. `<#declaration#>` that is used in a position that expects a declaration.

- Warning: This ``EditorPlaceholderDeclSyntax`` node is not generated by the parser anymore. Placeholders are represented by a ``MissingDeclSyntax``.
""",
traits: [
"WithAttributes",
Expand Down
3 changes: 3 additions & 0 deletions CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,9 @@ public let EXPR_NODES: [Node] = [
kind: .editorPlaceholderExpr,
base: .expr,
nameForDiagnostics: "editor placeholder",
documentation: """
- Warning: This ``EditorPlaceholderExprSyntax`` node is not generated by the parser anymore. Placeholders are represented by a ``DeclReferenceExprSyntax``.
""",
children: [
Child(
name: "placeholder",
Expand Down
4 changes: 4 additions & 0 deletions Release Notes/511.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
- Issue: https://github.com/apple/swift-syntax/issues/2267
- Pull request: https://github.com/apple/swift-syntax/pull/2272

- `EditorPlaceholderDeclSyntax` and `EditorPlaceholderExprSyntax`:
- Description: `EditorPlaceholderDeclSyntax` and `EditorPlaceholderExprSyntax` are now deprecated and placeholders are instead parsed as identifiers within a `MissingDeclSyntax` or `DeclReferenceExprSyntax`.
- Pull request: https://github.com/apple/swift-syntax/pull/2237

## API-Incompatible Changes

- Effect specifiers:
Expand Down
4 changes: 2 additions & 2 deletions Sources/SwiftParser/Declarations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,9 @@ extension Parser {
}

if self.currentToken.isEditorPlaceholder {
let placeholder = self.consumeAnyToken()
let placeholder = self.parseAnyIdentifier()
return RawDeclSyntax(
RawEditorPlaceholderDeclSyntax(
RawMissingDeclSyntax(
attributes: attrs.attributes,
modifiers: attrs.modifiers,
placeholder: placeholder,
Expand Down
8 changes: 0 additions & 8 deletions Sources/SwiftParser/Expressions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1241,14 +1241,6 @@ extension Parser {
mutating func parseIdentifierExpression() -> RawExprSyntax {
let declName = self.parseDeclReferenceExpr(.compoundNames)
guard self.withLookahead({ $0.canParseAsGenericArgumentList() }) else {
if declName.baseName.tokenText.isEditorPlaceholder && declName.argumentNames == nil {
return RawExprSyntax(
RawEditorPlaceholderExprSyntax(
placeholder: declName.baseName,
arena: self.arena
)
)
}
return RawExprSyntax(declName)
}

Expand Down
13 changes: 12 additions & 1 deletion Sources/SwiftParserDiagnostics/MissingNodesError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,18 @@ extension ParseDiagnosticsGenerator {

// Walk all upcoming sibling to see if they are also missing to handle them in this diagnostic.
// If this is the case, handle all of them in this diagnostic.
var missingNodes = [Syntax(node)]
var missingNodes: [Syntax] = [Syntax(node)]

// If the node is an `MissingDeclSyntax` and the placeholder is an editor placeholder
// we should not add a diagnostic that it's missing.
kimdv marked this conversation as resolved.
Show resolved Hide resolved
// Instead, we should emit a diagnostic about the fact that there is an editor placeholder in the source file.
if let missing = missingNodes.first?.as(MissingDeclSyntax.self),
missing.placeholder.isEditorPlaceholder,
!missing.placeholder.isMissing
{
return .visitChildren
}

if let parentWithTokens = ancestorWithMoreTokens, let index {
let siblings = parentWithTokens.children(viewMode: .all)
let siblingsAfter = siblings[siblings.index(after: index)...]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
if shouldSkip(node) {
return .skipChildren
}
if node.statements.only?.item.is(EditorPlaceholderExprSyntax.self) == true {
if let item = node.statements.only?.item.as(DeclReferenceExprSyntax.self), item.baseName.isEditorPlaceholder {
// Only emit a single diagnostic about the editor placeholder and none for the missing '{' and '}'.
addDiagnostic(node, .editorPlaceholderInSourceFile, handledNodes: [node.id])
return .skipChildren
Expand Down
14 changes: 8 additions & 6 deletions Sources/SwiftRefactor/ExpandEditorPlaceholder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ public struct ExpandEditorPlaceholder: EditRefactoringProvider {
/// Expansion on `closure1` and `normalArg` is the same as `ExpandEditorPlaceholder`.
public struct ExpandEditorPlaceholders: EditRefactoringProvider {
public static func textRefactor(syntax token: TokenSyntax, in context: Void) -> [SourceEdit] {
guard let placeholder = token.parent?.as(EditorPlaceholderExprSyntax.self),
guard let placeholder = token.parent?.as(DeclReferenceExprSyntax.self),
kimdv marked this conversation as resolved.
Show resolved Hide resolved
placeholder.baseName.isEditorPlaceholder,
let arg = placeholder.parent?.as(LabeledExprSyntax.self),
let argList = arg.parent?.as(LabeledExprListSyntax.self),
let call = argList.parent?.as(FunctionCallExprSyntax.self)
Expand Down Expand Up @@ -190,8 +191,8 @@ extension FunctionTypeSyntax {
placeholder = ExpandEditorPlaceholder.wrapInTypePlaceholder(ret, type: ret)
}

let statementPlaceholder = EditorPlaceholderExprSyntax(
placeholder: .identifier(placeholder)
let statementPlaceholder = DeclReferenceExprSyntax(
baseName: .identifier(placeholder)
)
let closureStatement = CodeBlockItemSyntax(
item: .expr(ExprSyntax(statementPlaceholder))
Expand Down Expand Up @@ -234,8 +235,9 @@ extension FunctionCallExprSyntax {
var includedArg = false
var argsToExpand = 0
for arg in arguments.reversed() {
guard let expr = arg.expression.as(EditorPlaceholderExprSyntax.self),
let data = EditorPlaceholderData(token: expr.placeholder),
guard let expr = arg.expression.as(DeclReferenceExprSyntax.self),
expr.baseName.isEditorPlaceholder,
let data = EditorPlaceholderData(token: expr.baseName),
case let .typed(_, type) = data,
type.is(FunctionTypeSyntax.self)
else {
Expand All @@ -253,7 +255,7 @@ extension FunctionCallExprSyntax {

var expandedArgs = [LabeledExprSyntax]()
for arg in arguments.suffix(argsToExpand) {
let edits = ExpandEditorPlaceholder.textRefactor(syntax: arg.expression.cast(EditorPlaceholderExprSyntax.self).placeholder)
let edits = ExpandEditorPlaceholder.textRefactor(syntax: arg.expression.cast(DeclReferenceExprSyntax.self).baseName)
guard edits.count == 1, let edit = edits.first, !edit.replacement.isEmpty else {
return nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
// MARK: - EditorPlaceholderDeclSyntax

/// An editor placeholder, e.g. `<#declaration#>` that is used in a position that expects a declaration.
///
/// - Warning: This ``EditorPlaceholderDeclSyntax`` node is not generated by the parser anymore. Placeholders are represented by a ``MissingDeclSyntax``.
///
/// ### Children
///
Expand Down Expand Up @@ -220,6 +222,8 @@ public struct EditorPlaceholderDeclSyntax: DeclSyntaxProtocol, SyntaxHashable, _

// MARK: - EditorPlaceholderExprSyntax

/// - Warning: This ``EditorPlaceholderExprSyntax`` node is not generated by the parser anymore. Placeholders are represented by a ``DeclReferenceExprSyntax``.
///
/// ### Children
///
/// - `placeholder`: `<identifier>`
Expand Down
10 changes: 5 additions & 5 deletions Tests/SwiftParserTest/DeclarationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2313,7 +2313,7 @@ final class DeclarationTests: ParserTestCase {
1️⃣<#code#>
}
""",
substructure: MemberBlockItemSyntax(decl: EditorPlaceholderDeclSyntax(placeholder: .identifier("<#code#>"))),
substructure: MemberBlockItemSyntax(decl: MissingDeclSyntax(placeholder: .identifier("<#code#>"))),
diagnostics: [
DiagnosticSpec(message: "editor placeholder in source file")
]
Expand Down Expand Up @@ -2847,8 +2847,8 @@ final class DeclarationTests: ParserTestCase {
CodeBlockItemSyntax(
item: .expr(
ExprSyntax(
EditorPlaceholderExprSyntax(
placeholder: .identifier("<#function body#>")
DeclReferenceExprSyntax(
baseName: .identifier("<#function body#>")
)
)
)
Expand Down Expand Up @@ -2892,8 +2892,8 @@ final class DeclarationTests: ParserTestCase {
CodeBlockItemSyntax(
item: .expr(
ExprSyntax(
EditorPlaceholderExprSyntax(
placeholder: .identifier("<#function body#>")
DeclReferenceExprSyntax(
baseName: .identifier("<#function body#>")
)
)
)
Expand Down
4 changes: 2 additions & 2 deletions Tests/SwiftParserTest/PatternTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,8 @@ final class PatternTests: ParserTestCase {
identifier: .identifier("<#name#>")
),
initializer: InitializerClauseSyntax(
value: EditorPlaceholderExprSyntax(
placeholder: .identifier("<#value#>")
value: DeclReferenceExprSyntax(
baseName: .identifier("<#value#>")
)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ final class TrailingClosuresTests: ParserTestCase {
leftBrace: .leftBraceToken(presence: .missing),
statements: CodeBlockItemListSyntax([
CodeBlockItemSyntax(
item: .init(EditorPlaceholderExprSyntax(placeholder: .identifier("<#T##() -> Void#>")))
item: .init(DeclReferenceExprSyntax(baseName: .identifier("<#T##() -> Void#>")))
)
]),
rightBrace: .rightBraceToken(presence: .missing)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ fileprivate func assertRefactorPlaceholder(
} else {
var parser = Parser(placeholder)
let expr = ExprSyntax.parse(from: &parser)
token = try XCTUnwrap(expr.as(EditorPlaceholderExprSyntax.self)?.placeholder, file: file, line: line)
token = try XCTUnwrap(expr.as(DeclReferenceExprSyntax.self)?.baseName, file: file, line: line)
}

try assertRefactor(token, context: (), provider: ExpandEditorPlaceholder.self, expected: [SourceEdit.replace(token, with: expected)], file: file, line: line)
Expand Down
4 changes: 2 additions & 2 deletions Tests/SwiftRefactorTest/ExpandEditorPlaceholdersTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ fileprivate func assertRefactorPlaceholderCall(
var parser = Parser(expr)
let call = try XCTUnwrap(ExprSyntax.parse(from: &parser).as(FunctionCallExprSyntax.self), file: file, line: line)
let arg = call.arguments[call.arguments.index(at: placeholder)]
let token: TokenSyntax = try XCTUnwrap(arg.expression.as(EditorPlaceholderExprSyntax.self), file: file, line: line).placeholder
let token: TokenSyntax = try XCTUnwrap(arg.expression.as(DeclReferenceExprSyntax.self), file: file, line: line).baseName

try assertRefactor(token, context: (), provider: ExpandEditorPlaceholders.self, expected: [SourceEdit.replace(call, with: expected)], file: file, line: line)
}
Expand All @@ -127,7 +127,7 @@ fileprivate func assertRefactorPlaceholderToken(
var parser = Parser(expr)
let call = try XCTUnwrap(ExprSyntax.parse(from: &parser).as(FunctionCallExprSyntax.self), file: file, line: line)
let arg = call.arguments[call.arguments.index(at: placeholder)]
let token: TokenSyntax = try XCTUnwrap(arg.expression.as(EditorPlaceholderExprSyntax.self), file: file, line: line).placeholder
let token: TokenSyntax = try XCTUnwrap(arg.expression.as(DeclReferenceExprSyntax.self), file: file, line: line).baseName

try assertRefactor(token, context: (), provider: ExpandEditorPlaceholders.self, expected: [SourceEdit.replace(token, with: expected)], file: file, line: line)
}