Skip to content

Enhancements to classification mechanism #109

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 3 commits into from
Mar 10, 2019
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
67 changes: 67 additions & 0 deletions Sources/SwiftSyntax/Syntax.swift
Original file line number Diff line number Diff line change
Expand Up @@ -251,20 +251,55 @@ extension _SyntaxBase {
}

/// Sequence of `SyntaxClassifiedRange`s for this syntax node.
///
/// The provided classified ranges are consecutive and cover the full source
/// text of the node. The ranges may also span multiple tokens, if multiple
/// consecutive tokens would have the same classification then a single classified
/// range is provided for all of them.
var classifications: SyntaxClassifications {
let fullRange = ByteSourceRange(offset: 0, length: byteSize)
return SyntaxClassifications(self, in: fullRange)
}

/// Sequence of `SyntaxClassifiedRange`s contained in this syntax node within
/// a relative range.
///
/// The provided classified ranges may extend beyond the provided `range`.
/// Active classifications (non-`none`) will extend the range to include the
/// full classified range (e.g. from the beginning of the comment block), while
/// `none` classified ranges will extend to the beginning or end of the token
/// that the `range` touches.
/// It is guaranteed that no classified range will be provided that doesn't
/// intersect the provided `range`.
///
/// - Parameters:
/// - in: The relative byte range to pull `SyntaxClassifiedRange`s from.
/// - Returns: Sequence of `SyntaxClassifiedRange`s.
func classifications(in range: ByteSourceRange) -> SyntaxClassifications {
return SyntaxClassifications(self, in: range)
}

/// The `SyntaxClassifiedRange` for a relative byte offset.
/// - Parameters:
/// - at: The relative to the node byte offset.
/// - Returns: The `SyntaxClassifiedRange` for the offset or nil if the source text
/// at the given offset is unclassified.
func classification(at offset: Int) -> SyntaxClassifiedRange? {
let classifications = SyntaxClassifications(self, in: ByteSourceRange(offset: offset, length: 1))
var iterator = classifications.makeIterator()
return iterator.next()
}

/// The `SyntaxClassifiedRange` for an absolute position.
/// - Parameters:
/// - at: The absolute position.
/// - Returns: The `SyntaxClassifiedRange` for the position or nil if the source text
/// at the given position is unclassified.
func classification(at position: AbsolutePosition) -> SyntaxClassifiedRange? {
let relativeOffset = position.utf8Offset - self.position.utf8Offset
return self.classification(at: relativeOffset)
}

/// Returns a value representing the unique identity of the node.
var uniqueIdentifier: SyntaxIdentifier {
return data.nodeId
Expand Down Expand Up @@ -483,19 +518,51 @@ extension Syntax {
}

/// Sequence of `SyntaxClassifiedRange`s for this syntax node.
///
/// The provided classification ranges are consecutive and cover the full source
/// text of the node. The ranges may also span multiple tokens, if multiple
/// consecutive tokens would have the same classification then a single classified
/// range is provided for all of them.
public var classifications: SyntaxClassifications {
return base.classifications
}

/// Sequence of `SyntaxClassifiedRange`s contained in this syntax node within
/// a relative range.
///
/// The provided classified ranges may extend beyond the provided `range`.
/// Active classifications (non-`none`) will extend the range to include the
/// full classified range (e.g. from the beginning of the comment block), while
/// `none` classified ranges will extend to the beginning or end of the token
/// that the `range` touches.
/// It is guaranteed that no classified range will be provided that doesn't
/// intersect the provided `range`.
///
/// - Parameters:
/// - in: The relative byte range to pull `SyntaxClassifiedRange`s from.
/// - Returns: Sequence of `SyntaxClassifiedRange`s.
public func classifications(in range: ByteSourceRange) -> SyntaxClassifications {
return base.classifications(in: range)
}

/// The `SyntaxClassifiedRange` for a relative byte offset.
/// - Parameters:
/// - at: The relative to the node byte offset.
/// - Returns: The `SyntaxClassifiedRange` for the offset or nil if the source text
/// at the given offset is unclassified.
public func classification(at offset: Int) -> SyntaxClassifiedRange? {
return base.classification(at: offset)
}

/// The `SyntaxClassifiedRange` for an absolute position.
/// - Parameters:
/// - at: The absolute position.
/// - Returns: The `SyntaxClassifiedRange` for the position or nil if the source text
/// at the given position is unclassified.
public func classification(at position: AbsolutePosition) -> SyntaxClassifiedRange? {
return base.classification(at: position)
}

/// Returns a value representing the unique identity of the node.
public var uniqueIdentifier: SyntaxIdentifier {
return base.uniqueIdentifier
Expand Down
10 changes: 5 additions & 5 deletions Sources/SwiftSyntax/SyntaxClassification.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ extension SyntaxClassification {
/// - Returns: A pair of classification and whether it is "forced", or nil if
/// no classification is attached.
internal static func classify(
parentKind: SyntaxKind, indexInParent: UInt32, childKind: SyntaxKind
parentKind: SyntaxKind, indexInParent: Int, childKind: SyntaxKind
) -> (SyntaxClassification, Bool)? {
// Separate checks for token nodes (most common checks) versus checks for layout nodes.
if childKind == .token {
Expand Down Expand Up @@ -83,18 +83,18 @@ extension SyntaxClassification {
}

extension RawTokenKind {
internal var classification: SyntaxClassification? {
internal var classification: SyntaxClassification {
switch (self) {
% for token in SYNTAX_TOKENS:
case .${token.swift_kind()}:
% if token.classification and token.classification.name != 'None':
% if token.classification:
return .${token.classification.swift_name}
% else:
return nil
return .none
% end
% end
case .eof:
return nil
return .none
}
}
}
Loading