Skip to content

Make SyntaxKind internal #80

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
Feb 12, 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
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//===------ IncrementalEditTransition.swift - Edit Transition State -------===//
//===------ IncrementalParseTransition.swift - Parse Transition State -----===//
//
// This source file is part of the Swift.org open source project
//
Expand All @@ -10,7 +10,7 @@
//
//===----------------------------------------------------------------------===//

/// Accepts the re-used `Syntax` nodes that `IncrementalEditTransition`
/// Accepts the re-used `Syntax` nodes that `IncrementalParseTransition`
/// determined they should be re-used for a parse invocation.
///
/// The client can use this information to potentially avoid unnecessary work
Expand Down Expand Up @@ -42,10 +42,10 @@ public final class IncrementalParseReusedNodeCollector:
}

/// Keeps track of a previously parsed syntax tree and the source edits that
/// occurred since it was created and provides the `IncrementalParseLookup`
/// implementation to allow the parser to skip regions of the new source that
/// can be associated with valid `Syntax` nodes from the previous tree.
public final class IncrementalEditTransition: IncrementalParseLookup {
/// occurred since it was created and provides a mechanism for the parser to
/// skip regions of an incrementally updated source that was already parsed
/// during a previous parse invocation.
public final class IncrementalParseTransition {
// The implementation is based on `SyntaxParsingCache` from the swift
// repository.

Expand All @@ -65,7 +65,7 @@ public final class IncrementalEditTransition: IncrementalParseLookup {
public init(previousTree: SourceFileSyntax,
edits: [SourceEdit],
reusedNodeDelegate: IncrementalParseReusedNodeDelegate? = nil) {
assert(IncrementalEditTransition.isEditArrayValid(edits))
assert(IncrementalParseTransition.isEditArrayValid(edits))
self.previousTree = previousTree
self.edits = edits
self.reusedDelegate = reusedNodeDelegate
Expand All @@ -88,7 +88,19 @@ public final class IncrementalEditTransition: IncrementalParseLookup {
return true
}

public func lookUp(_ newOffset: Int, kind: SyntaxKind) -> Syntax? {
/// Does a lookup to see if the current source `offset` should be associated
/// with a known `Syntax` node and its region skipped during parsing.
///
/// The implementation is responsible for checking whether an incremental edit
/// has invalidated the previous `Syntax` node.
///
/// - Parameters:
/// - offset: The byte offset of the source string that is currently parsed.
/// - kind: The `SyntaxKind` that the parser expects at this position.
/// - Returns: A `Syntax` node from the previous parse invocation,
/// representing the contents of this region, if it is still valid
/// to re-use. `nil` otherwise.
func lookUp(_ newOffset: Int, kind: SyntaxKind) -> _SyntaxBase? {
guard let prevOffset = translateToPreEditOffset(newOffset) else {
return nil
}
Expand Down Expand Up @@ -117,7 +129,7 @@ public final class IncrementalEditTransition: IncrementalParseLookup {
}
let childEnd = childOffset + child.byteSize
if childOffset <= prevOffset && prevOffset < childEnd {
return lookUpFrom(child.base, nodeOffset: childOffset,
return lookUpFrom(child, nodeOffset: childOffset,
prevOffset: prevOffset, kind: kind)
}
// The next child starts where the previous child ended
Expand Down
40 changes: 8 additions & 32 deletions Sources/SwiftSyntax/SyntaxKind.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,12 @@
//
//===----------------------------------------------------------------------===//

import Foundation

/// Enumerates the known kinds of Syntax represented in the Syntax tree.
public enum SyntaxKind: String {
case token = "Token"
case unknown = "Unknown"
internal enum SyntaxKind: CSyntaxKind {
case token = 0
case unknown = 1
% for node in SYNTAX_NODES:
case ${node.swift_syntax_kind} = "${node.syntax_kind}"
case ${node.swift_syntax_kind} = ${SYNTAX_NODE_SERIALIZATION_CODES[node.syntax_kind]}
% end

% for name, nodes in grouped_nodes.items():
Expand Down Expand Up @@ -56,11 +54,11 @@ public enum SyntaxKind: String {
default: return false
}
}
}

public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let kind = try container.decode(String.self)
self = SyntaxKind(rawValue: kind) ?? .unknown
extension SyntaxKind {
static func fromRawValue(_ rawValue: CSyntaxKind) -> SyntaxKind {
return SyntaxKind(rawValue: rawValue)!
}
}

Expand All @@ -83,25 +81,3 @@ internal func makeSyntax(_ data: SyntaxData) -> _SyntaxBase {
% end
}
}


extension SyntaxKind {
static func fromRawValue(_ rawValue: CSyntaxKind) -> SyntaxKind {
// Explicitly spell out all SyntaxKinds to keep the serialized value stable
// even if its members get reordered or members get removed
switch rawValue {
case 0:
return .token
case 1:
return .unknown
% for name, nodes in grouped_nodes.items():
% for node in nodes:
case ${SYNTAX_NODE_SERIALIZATION_CODES[node.syntax_kind]}:
return .${node.swift_syntax_kind}
% end
% end
default:
return .unknown
}
}
}
33 changes: 7 additions & 26 deletions Sources/SwiftSyntax/SyntaxParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,26 +49,8 @@ public enum ParserError: Error, CustomStringConvertible {
}
}

/// Provides a mechanism for the parser to skip regions of an incrementally
/// updated source that were already parsed during a previous parse invocation.
public protocol IncrementalParseLookup {
/// Does a lookup to see if the current source `offset` should be associated
/// with a known `Syntax` node and its region skipped during parsing.
///
/// The implementation is responsible for checking whether an incremental edit
/// has invalidated the previous `Syntax` node.
///
/// - Parameters:
/// - offset: The byte offset of the source string that is currently parsed.
/// - kind: The `SyntaxKind` that the parser expects at this position.
/// - Returns: A `Syntax` node from the previous parse invocation,
/// representing the contents of this region, if it is still valid
/// to re-use. `nil` otherwise.
func lookUp(_ offset: Int, kind: SyntaxKind) -> Syntax?
}

/// Namespace for functions to parse swift source and retrieve a syntax tree.
public struct SyntaxParser {
public enum SyntaxParser {

/// True if the parser library is compatible with the SwiftSyntax client;
/// false otherwise.
Expand All @@ -78,13 +60,13 @@ public struct SyntaxParser {
///
/// - Parameters:
/// - source: The source string to parse.
/// - parseLookup: Optional mechanism for incremental re-parsing.
/// - parseTransition: Optional mechanism for incremental re-parsing.
/// - Returns: A top-level Syntax node representing the contents of the tree,
/// if the parse was successful.
/// - Throws: `ParserError`
public static func parse(
source: String,
parseLookup: IncrementalParseLookup? = nil
parseTransition: IncrementalParseTransition? = nil
) throws -> SourceFileSyntax {
guard nodeHashVerifyResult else {
throw ParserError.parserCompatibilityCheckFailed
Expand All @@ -95,7 +77,7 @@ public struct SyntaxParser {
var utf8Source = source
utf8Source.makeNativeUTF8IfNeeded()

let rawSyntax = parseRaw(utf8Source, parseLookup: parseLookup)
let rawSyntax = parseRaw(utf8Source, parseTransition)

guard let file = makeSyntax(.forRoot(rawSyntax)) as? SourceFileSyntax else {
throw ParserError.invalidSyntaxData
Expand All @@ -122,7 +104,7 @@ public struct SyntaxParser {

private static func parseRaw(
_ source: String,
parseLookup: IncrementalParseLookup?
_ parseTransition: IncrementalParseTransition?
) -> RawSyntax {
assert(source.isNativeUTF8)
let c_parser = swiftparse_parser_create()
Expand All @@ -139,12 +121,11 @@ public struct SyntaxParser {
}
swiftparse_parser_set_node_handler(c_parser, nodeHandler);

if let parseLookup = parseLookup {
if let parseTransition = parseTransition {
let nodeLookup = {
(offset: Int, kind: CSyntaxKind) -> CParseLookupResult in
guard let foundNode =
parseLookup.lookUp(offset,
kind: SyntaxKind.fromRawValue(kind)) else {
parseTransition.lookUp(offset, kind: .fromRawValue(kind)) else {
return CParseLookupResult(length: 0, node: nil)
}
let lengthToSkip = foundNode.byteSize
Expand Down
4 changes: 2 additions & 2 deletions Sources/lit-test-helper/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -272,12 +272,12 @@ func performParseIncremental(args: CommandLineArguments) throws {
let preEditTree = try SyntaxParser.parse(preEditURL)
let edits = try parseIncrementalEditArguments(args: args)
let regionCollector = IncrementalParseReusedNodeCollector()
let editTransition = IncrementalEditTransition(previousTree: preEditTree,
let editTransition = IncrementalParseTransition(previousTree: preEditTree,
edits: edits, reusedNodeDelegate: regionCollector)

let postEditText = try String(contentsOf: postEditURL)
let postEditTree =
try SyntaxParser.parse(source: postEditText, parseLookup: editTransition)
try SyntaxParser.parse(source: postEditText, parseTransition: editTransition)

let postTreeDump = postEditTree.description

Expand Down
4 changes: 2 additions & 2 deletions Tests/SwiftSyntaxTest/IncrementalParsingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ public class IncrementalParsingTestCase: XCTestCase {

var tree = try! SyntaxParser.parse(source: original)
let sourceEdit = SourceEdit(range: ByteSourceRange(offset: step.1.0, length: step.1.1), replacementLength: step.1.2.utf8.count)
let lookup = IncrementalEditTransition(previousTree: tree, edits: [sourceEdit])
tree = try! SyntaxParser.parse(source: step.0, parseLookup: lookup)
let lookup = IncrementalParseTransition(previousTree: tree, edits: [sourceEdit])
tree = try! SyntaxParser.parse(source: step.0, parseTransition: lookup)
XCTAssertEqual("\(tree)", step.0)
}
}