Skip to content

Split SyntaxNodes.swift.gyb into multiple files #165

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
Nov 5, 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
64 changes: 64 additions & 0 deletions Sources/SwiftSyntax/Misc.swift.gyb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
%{
# -*- mode: Swift -*-
from gyb_syntax_support import *
from gyb_syntax_support.Traits import TRAITS
NODE_MAP = create_node_map()
# Ignore the following admonition it applies to the resulting .swift file only
}%
//// Automatically Generated From SyntaxNodes.swift.gyb.
//// Do Not Edit Directly!
//===---------- Misc.swift - Miscelaneous SwiftSyntax definitions ---------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import _InternalSwiftSyntaxParser

extension SyntaxNode {
public var isUnknown: Bool { return raw.kind.isUnknown }
public var asUnknown: UnknownSyntax? {
guard isUnknown else { return nil }
return UnknownSyntax(asSyntaxData)
}
% for node in SYNTAX_NODES:
% if not node.is_base():

public var is${node.syntax_kind}: Bool { return raw.kind == .${node.swift_syntax_kind} }
public var as${node.syntax_kind}: ${node.name}? {
guard is${node.syntax_kind} else { return nil }
return ${node.name}(asSyntaxData)
}
% end
% end
}

public extension Syntax {
/// Retrieve the concretely typed node that this Syntax node wraps.
/// This property is exposed for testing purposes only.
var _asConcreteType: Any {
switch self.asSyntaxEnum {
case .token(let node):
return node
case .unknown(let node):
return node
% for node in SYNTAX_NODES:
case .${node.swift_syntax_kind}(let node):
return node
% end
}
}
}

extension SyntaxParser {
static func verifyNodeDeclarationHash() -> Bool {
return String(cString: swiftparse_syntax_structure_versioning_identifier()!) ==
"${calculate_node_hash()}"
}
}
208 changes: 62 additions & 146 deletions Sources/SwiftSyntax/Syntax.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,36 @@ public struct Syntax: SyntaxProtocol {
}
}

/// Provide common functionality for specialized syntax nodes. Extend this
// Casting functions to specialized syntax nodes.
extension Syntax {
public func `is`<S: SyntaxProtocol>(_ syntaxType: S.Type) -> Bool {
return self.as(syntaxType) != nil
}

public func `as`<S: SyntaxProtocol>(_ syntaxType: S.Type) -> S? {
return S.init(self)
}
}

extension Syntax: CustomReflectable {
/// Reconstructs the real syntax type for this type from the node's kind and
/// provides a mirror that reflects this type.
public var customMirror: Mirror {
return Mirror(reflecting: self._asConcreteType)
}
}

/// Provide common functionality for specialized syntax nodes. Extend this
/// protocol to provide common functionality for all syntax nodes.
/// DO NOT CONFORM TO THIS PROTOCOL YOURSELF!
public protocol SyntaxProtocol: CustomStringConvertible,
public protocol SyntaxProtocol: CustomStringConvertible,
CustomDebugStringConvertible, TextOutputStreamable, Hashable {

/// Retrieve the generic syntax node that is represented by this node.
/// Do not retrieve this property directly. Use `Syntax(self)` instead.
var _syntaxNode: Syntax { get }

/// Converts the given `Syntax` node to this type. Returns `nil` if the
/// Converts the given `Syntax` node to this type. Returns `nil` if the
/// conversion is not possible.
init?(_ syntaxNode: Syntax)
}
Expand Down Expand Up @@ -238,14 +257,24 @@ public extension SyntaxProtocol {
/// the first token syntax contained by this node. Without such token, this
/// property will return nil.
var leadingTrivia: Trivia? {
return raw.formLeadingTrivia()
get {
return raw.formLeadingTrivia()
}
set {
self = withLeadingTrivia(newValue ?? [])
}
}

/// The trailing trivia of this syntax node. Trailing trivia is attached to
/// the last token syntax contained by this node. Without such token, this
/// property will return nil.
var trailingTrivia: Trivia? {
return raw.formTrailingTrivia()
get {
return raw.formTrailingTrivia()
}
set {
self = withTrailingTrivia(newValue ?? [])
}
}

/// The length this node's leading trivia takes up spelled out in source.
Expand All @@ -258,6 +287,33 @@ public extension SyntaxProtocol {
return raw.trailingTriviaLength
}

/// Returns a new syntax node with its leading trivia replaced
/// by the provided trivia.
func withLeadingTrivia(_ leadingTrivia: Trivia) -> Self {
return Self(Syntax(data.withLeadingTrivia(leadingTrivia)))!
}

/// Returns a new syntax node with its trailing trivia replaced
/// by the provided trivia.
func withTrailingTrivia(_ trailingTrivia: Trivia) -> Self {
return Self(Syntax(data.withTrailingTrivia(trailingTrivia)))!
}

/// Returns a new `${node.name}` with its leading trivia removed.
func withoutLeadingTrivia() -> Self {
return withLeadingTrivia([])
}

/// Returns a new `${node.name}` with its trailing trivia removed.
func withoutTrailingTrivia() -> Self {
return withTrailingTrivia([])
}

/// Returns a new `${node.name}` with all trivia removed.
func withoutTrivia() -> Self {
return withoutLeadingTrivia().withoutTrailingTrivia()
}

/// The length of this node including all of its trivia.
var totalLength: SourceLength {
return raw.totalLength
Expand Down Expand Up @@ -369,146 +425,6 @@ public extension SyntaxProtocol {
}
}


/// MARK: - Nodes

/// A Syntax node representing a single token.
public struct TokenSyntax: SyntaxProtocol {
public let _syntaxNode: Syntax

/// Converts the given `Syntax` node to a `TokenSyntax` if possible. Returns
/// `nil` if the conversion is not possible.
public init?(_ syntax: Syntax) {
guard syntax.raw.kind == .token else { return nil }
self._syntaxNode = syntax
}

/// Creates a Syntax node from the given `SyntaxData`. This assumes
/// that the `SyntaxData` is of the correct kind. If it is not, the behaviour
/// is undefined.
internal init(_ data: SyntaxData) {
assert(data.raw.kind == .token)
self._syntaxNode = Syntax(data)
}

public var presence: SourcePresence {
return raw.presence
}

/// The text of the token as written in the source code.
public var text: String {
return tokenKind.text
}

/// Returns a new TokenSyntax with its kind replaced
/// by the provided token kind.
public func withKind(_ tokenKind: TokenKind) -> TokenSyntax {
guard raw.kind == .token else {
fatalError("TokenSyntax must have token as its raw")
}
let newRaw = RawSyntax.createAndCalcLength(kind: tokenKind,
leadingTrivia: raw.formLeadingTrivia()!, trailingTrivia: raw.formTrailingTrivia()!,
presence: raw.presence)
let newData = data.replacingSelf(newRaw)
return TokenSyntax(newData)
}

/// Returns a new TokenSyntax with its leading trivia replaced
/// by the provided trivia.
public func withLeadingTrivia(_ leadingTrivia: Trivia) -> TokenSyntax {
guard raw.kind == .token else {
fatalError("TokenSyntax must have token as its raw")
}
return TokenSyntax(data.withLeadingTrivia(leadingTrivia))
}

/// Returns a new TokenSyntax with its trailing trivia replaced
/// by the provided trivia.
public func withTrailingTrivia(_ trailingTrivia: Trivia) -> TokenSyntax {
guard raw.kind == .token else {
fatalError("TokenSyntax must have token as its raw")
}
return TokenSyntax(data.withTrailingTrivia(trailingTrivia))
}

/// Returns a new TokenSyntax with its leading trivia removed.
public func withoutLeadingTrivia() -> TokenSyntax {
return withLeadingTrivia([])
}

/// Returns a new TokenSyntax with its trailing trivia removed.
public func withoutTrailingTrivia() -> TokenSyntax {
return withTrailingTrivia([])
}

/// Returns a new TokenSyntax with all trivia removed.
public func withoutTrivia() -> TokenSyntax {
return withoutLeadingTrivia().withoutTrailingTrivia()
}

/// The leading trivia (spaces, newlines, etc.) associated with this token.
public var leadingTrivia: Trivia {
get {
return raw.formTokenLeadingTrivia()!
}
set {
self = withLeadingTrivia(newValue)
}
}

/// The trailing trivia (spaces, newlines, etc.) associated with this token.
public var trailingTrivia: Trivia {
get {
return raw.formTokenTrailingTrivia()!
}
set {
self = withTrailingTrivia(newValue)
}
}

/// The kind of token this node represents.
public var tokenKind: TokenKind {
get {
return raw.formTokenKind()!
}
set {
self = withKind(newValue)
}
}

/// The length this node takes up spelled out in the source, excluding its
/// leading or trailing trivia.
public var contentLength: SourceLength {
return raw.tokenContentLength
}

/// The length this node's leading trivia takes up spelled out in source.
public var leadingTriviaLength: SourceLength {
return raw.tokenLeadingTriviaLength
}

/// The length this node's trailing trivia takes up spelled out in source.
public var trailingTriviaLength: SourceLength {
return raw.tokenTrailingTriviaLength
}

/// The length of this node including all of its trivia.
public var totalLength: SourceLength {
return raw.totalLength
}
}

extension TokenSyntax: CustomReflectable {
public var customMirror: Mirror {
return Mirror(self, children: [
"text": text,
"leadingTrivia": leadingTrivia,
"trailingTrivia": trailingTrivia,
"tokenKind": tokenKind,
])
}
}

/// Sequence of tokens that are part of the provided Syntax node.
public struct TokenSequence: Sequence {
public struct Iterator: IteratorProtocol {
Expand Down Expand Up @@ -621,7 +537,7 @@ public struct SyntaxNode {
/// Converts this node to a `SyntaxData` object.
///
/// This operation results in wrapping all of the node's parents into
/// `SyntaxData` objects. There's a cost associated with it that should be
/// `SyntaxData` objects. There's a cost associated with it that should be
/// taken into account before used inside performance critical code.
internal var asSyntaxData: SyntaxData {
return SyntaxData(absoluteRaw, parent: parent?.asSyntax)
Expand Down
Loading