Skip to content

Remove SyntaxProtocol.index in favor of index(of:) methods in SyntaxCollection and SyntaxChildren #1919

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

Merged
merged 1 commit into from
Jul 23, 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
6 changes: 4 additions & 2 deletions Sources/SwiftParser/IncrementalParseTransition.swift
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,10 @@ fileprivate struct SyntaxCursor {
var node = self.node
while let parent = node.parent {
let children = parent.children(viewMode: viewMode)
if children.index(after: node.index) != children.endIndex {
return children[children.index(after: node.index)]
if let nodeIndex = children.index(of: node),
children.index(after: nodeIndex) != children.endIndex
{
return children[children.index(after: nodeIndex)]
}
node = parent
}
Expand Down
9 changes: 5 additions & 4 deletions Sources/SwiftParserDiagnostics/MissingNodesError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,8 @@ public struct MissingNodesError: ParserError {
if let missingExpr,
let exprList = missingExpr.parent?.as(ExprListSyntax.self),
exprList.parent?.is(SequenceExprSyntax.self) ?? false,
let previousSiblingIndex = exprList.index(missingExpr.index, offsetBy: -1, limitedBy: exprList.startIndex)
let missingExprIndex = exprList.index(of: missingExpr),
let previousSiblingIndex = exprList.index(missingExprIndex, offsetBy: -1, limitedBy: exprList.startIndex)
{
let previousSibling = exprList[previousSiblingIndex]
if let previousSiblingName = previousSibling.nodeTypeNameForDiagnostics(allowBlockNames: false) {
Expand Down Expand Up @@ -359,17 +360,17 @@ extension ParseDiagnosticsGenerator {
/// Ancestors that don't contain any tokens are not very interesting to merge diagnostics (because there can't be any missing tokens we can merge them with).
/// Find the first ancestor that contains any tokens.
var ancestorWithMoreTokens = node.parent
var index = node.index
var index = ancestorWithMoreTokens?.children(viewMode: .all).index(of: node)
let nodeTokens = Array(node.tokens(viewMode: .all))
while let unwrappedParent = ancestorWithMoreTokens, Array(unwrappedParent.tokens(viewMode: .all)) == nodeTokens {
ancestorWithMoreTokens = unwrappedParent.parent
index = unwrappedParent.index
index = ancestorWithMoreTokens?.children(viewMode: .all).index(of: unwrappedParent)
}

// 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)]
if let parentWithTokens = ancestorWithMoreTokens {
if let parentWithTokens = ancestorWithMoreTokens, let index {
let siblings = parentWithTokens.children(viewMode: .all)
let siblingsAfter = siblings[siblings.index(after: index)...]
for sibling in siblingsAfter {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1818,7 +1818,8 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
}
if node.colon.isMissing {
if let siblings = node.parent?.children(viewMode: .all),
let nextSibling = siblings[siblings.index(after: node.index)...].first,
let nodeIndex = siblings.index(of: node),
let nextSibling = siblings[siblings.index(after: nodeIndex)...].first,
nextSibling.is(MissingExprSyntax.self)
{
addDiagnostic(
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftSyntax/CommonAncestor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public func findCommonAncestorOrSelf(_ lhs: Syntax, _ rhs: Syntax) -> Syntax? {
if lhs == rhs {
return lhs
}
if let lhsIndex = lhs?.index.data?.indexInTree, let rhsIndex = rhs?.index.data?.indexInTree {
if let lhsIndex = lhs?.indexInParent.data?.indexInTree, let rhsIndex = rhs?.indexInParent.data?.indexInTree {
if lhsIndex < rhsIndex {
rhs = rhs?.parent
} else {
Expand Down
12 changes: 9 additions & 3 deletions Sources/SwiftSyntax/Syntax.swift
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,13 @@ public extension SyntaxProtocol {
}

/// The index of this node in a ``SyntaxChildren`` collection.
@available(*, deprecated, message: "Use index(of:) on the collection that contains this node")
var index: SyntaxChildrenIndex {
return indexInParent
}

/// The index of this node in a ``SyntaxChildren`` collection.
internal var indexInParent: SyntaxChildrenIndex {
return SyntaxChildrenIndex(self.data.absoluteInfo)
}

Expand Down Expand Up @@ -319,8 +325,8 @@ public extension SyntaxProtocol {
let siblings = NonNilRawSyntaxChildren(parent, viewMode: viewMode)
// `self` could be a missing node at index 0 and `viewMode` be `.sourceAccurate`.
// In that case `siblings` skips over the missing `self` node and has a `startIndex > 0`.
if self.index >= siblings.startIndex {
for absoluteRaw in siblings[..<self.index].reversed() {
if self.indexInParent >= siblings.startIndex {
for absoluteRaw in siblings[..<self.indexInParent].reversed() {
let child = Syntax(SyntaxData(absoluteRaw, parent: parent))
if let token = child.lastToken(viewMode: viewMode) {
return token
Expand All @@ -342,7 +348,7 @@ public extension SyntaxProtocol {
return nil
}
let siblings = NonNilRawSyntaxChildren(parent, viewMode: viewMode)
let nextSiblingIndex = siblings.index(after: self.index)
let nextSiblingIndex = siblings.index(after: self.indexInParent)
for absoluteRaw in siblings[nextSiblingIndex...] {
let child = Syntax(SyntaxData(absoluteRaw, parent: parent))
if let token = child.firstToken(viewMode: viewMode) {
Expand Down
21 changes: 21 additions & 0 deletions Sources/SwiftSyntax/SyntaxChildren.swift
Original file line number Diff line number Diff line change
Expand Up @@ -455,4 +455,25 @@ public struct SyntaxChildren: BidirectionalCollection {
self.rawChildren = NonNilRawSyntaxChildren(node, viewMode: viewMode)
self.parent = node
}

/// Return the index of `node` within this collection.
///
/// If `node` is not part of this collection, returns `nil`.
public func index(of node: some SyntaxProtocol) -> SyntaxChildrenIndex? {
return index(of: Syntax(node))
}

/// Return the index of `node` within this collection.
///
/// If `node` is not part of this collection, returns `nil`.
///
/// - Note: This method is functionally equivalent to the one that takes
/// ``SyntaxProtocol``. It is provided because otherwise `Collection.index(of:)`
/// is chosen, which is marked as deprecated and renamed to `firstIndex(of:)`.
public func index(of node: Syntax) -> SyntaxChildrenIndex? {
guard node.parent == parent else {
return nil
}
return node.indexInParent
}
}
26 changes: 25 additions & 1 deletion Sources/SwiftSyntax/SyntaxCollection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,30 @@ extension SyntaxCollection {
return Syntax(newData).cast(Self.self)
}

/// Return the index of `node` within this collection.
///
/// If `node` is not part of this collection, returns `nil`.
public func index(of node: some SyntaxProtocol) -> SyntaxChildrenIndex? {
guard let node = node as? Element else {
return nil
}
return index(of: node)
}

/// Return the index of `node` within this collection.
///
/// If `node` is not part of this collection, returns `nil`.
///
/// - Note: This method is functionally equivalent to the one that takes
/// ``SyntaxProtocol``. It is provided because otherwise `Collection.index(of:)`
/// is chosen, which is marked as deprecated and renamed to `firstIndex(of:)`.
public func index(of node: Element) -> SyntaxChildrenIndex? {
guard node.parent == Syntax(self) else {
return nil
}
return node.indexInParent
}

/// Creates a new collection by appending the provided syntax element
/// to the children.
///
Expand Down Expand Up @@ -232,7 +256,7 @@ extension SyntaxCollection {
/// Make sure the index is a valid index for replacing
precondition(
(newLayout.startIndex..<newLayout.endIndex).contains(indexToReplace),
"replacing node at invalid index \(index)"
"replacing node at invalid index \(indexInParent)"
)
newLayout[indexToReplace] = newValue.raw
self = replacingLayout(newLayout)
Expand Down