Skip to content

Format the swift-syntax repository using swift-format #1113

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
Dec 15, 2022
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
18 changes: 18 additions & 0 deletions .swift-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"version": 1,
"lineLength": 1000,
"indentation": {
"spaces": 2
},
"lineBreakBeforeEachArgument": true,
"indentConditionalCompilationBlocks": false,
"rules": {
"AlwaysUseLowerCamelCase": false,
"AmbiguousTrailingClosureOverload": false,
"DontRepeatTypeInStaticProperties": false,
"NoBlockComments": false,
"Spacing": false,
"UseLetInEveryBoundCaseVariable": false,
"UseSynthesizedInitializer": false
}
}
8 changes: 8 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ Alternatively you can also build it from the command line using `build-script.py
swift-syntax/build-script.py build --toolchain /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-<recent date>.xctoolchain/usr
```

## Formatting

SwiftSyntax is being formatted using [swift-format](http://github.com/apple/swift-format) to ensure a consistent style.

To format your changes run `format.py` at the root of this repository. If you have a `swift-format` executable ready, you can pass it to `format.py`. If you do not, `format.py` will build its own copy of `swift-format` in /tmp/swift-format.

CI will ensure that all hand-written source code is correctly formatted. Generated source code is not formatted to make it easier to spot changes when re-running code generation.

## Testing

Because of SwiftSyntax’s integration with the Swift compiler project, testing certain parts of the project is a little bit more involved than others.
Expand Down
71 changes: 46 additions & 25 deletions Sources/IDEUtils/SyntaxClassifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ fileprivate extension SyntaxProtocol {
var curData = Syntax(self)
repeat {
guard let parent = curData.parent else { break }
contextualClassif = SyntaxClassification.classify(parentKind: parent.raw.kind,
indexInParent: curData.indexInParent, childKind: raw.kind)
contextualClassif = SyntaxClassification.classify(
parentKind: parent.raw.kind,
indexInParent: curData.indexInParent,
childKind: raw.kind
)
curData = parent
} while contextualClassif == nil
return contextualClassif
Expand All @@ -33,19 +36,21 @@ extension TokenSyntax {
let relativeOffset = leadingTriviaLength.utf8Length
let absoluteOffset = position.utf8Offset + relativeOffset
return TokenKindAndText(kind: rawTokenKind, text: tokenView.rawText).classify(
offset: absoluteOffset, contextualClassification: contextualClassification)
offset: absoluteOffset,
contextualClassification: contextualClassification
)
}
}

extension RawTriviaPiece {
func classify(offset: Int) -> SyntaxClassifiedRange {
let range = ByteSourceRange(offset: offset, length: byteLength)
switch self {
case .lineComment: return .init(kind: .lineComment, range: range)
case .blockComment: return .init(kind: .blockComment, range: range)
case .docLineComment: return .init(kind: .docLineComment, range: range)
case .docBlockComment: return .init(kind: .docBlockComment, range: range)
default: return .init(kind: .none, range: range)
case .lineComment: return .init(kind: .lineComment, range: range)
case .blockComment: return .init(kind: .blockComment, range: range)
case .docLineComment: return .init(kind: .docLineComment, range: range)
case .docBlockComment: return .init(kind: .docBlockComment, range: range)
default: return .init(kind: .none, range: range)
}
}
}
Expand All @@ -55,7 +60,8 @@ fileprivate struct TokenKindAndText {
let text: SyntaxText

func classify(
offset: Int, contextualClassification: (SyntaxClassification, Bool)?
offset: Int,
contextualClassification: (SyntaxClassification, Bool)?
) -> SyntaxClassifiedRange {
let range = ByteSourceRange(offset: offset, length: text.count)

Expand All @@ -73,8 +79,9 @@ fileprivate struct TokenKindAndText {
return .stringLiteral
}
if kind == .identifier,
text.hasPrefix("<#"),
text.hasSuffix("#>") {
text.hasPrefix("<#"),
text.hasSuffix("#>")
{
return .editorPlaceholder
}
return kind.classification
Expand Down Expand Up @@ -114,17 +121,21 @@ private struct ClassificationVisitor {
init(node: Syntax, relativeClassificationRange: ByteSourceRange) {
let range = ByteSourceRange(
offset: node.position.utf8Offset + relativeClassificationRange.offset,
length: relativeClassificationRange.length)
length: relativeClassificationRange.length
)
self.targetRange = range
self.classifications = []

// `withExtendedLifetime` to make sure `SyntaxArena` for the node alive
// during the visit.
withExtendedLifetime(node) {
_ = self.visit(Descriptor(
node: node.raw,
byteOffset: node.position.utf8Offset,
contextualClassification: node.contextualClassification))
_ = self.visit(
Descriptor(
node: node.raw,
byteOffset: node.position.utf8Offset,
contextualClassification: node.contextualClassification
)
)
}
}

Expand All @@ -135,15 +146,19 @@ private struct ClassificationVisitor {

// Merge consecutive classified ranges of the same kind.
if let last = classifications.last,
last.kind == range.kind,
last.endOffset == range.offset {
last.kind == range.kind,
last.endOffset == range.offset
{
classifications[classifications.count - 1].range = ByteSourceRange(
offset: last.offset, length: last.length + range.length)
offset: last.offset,
length: last.length + range.length
)
return
}

guard range.offset <= targetRange.endOffset,
range.endOffset >= targetRange.offset else {
range.endOffset >= targetRange.offset
else {
return
}
classifications.append(range)
Expand Down Expand Up @@ -186,11 +201,17 @@ private struct ClassificationVisitor {
for case (let index, let child?) in children.enumerated() {

let classficiation = SyntaxClassification.classify(
parentKind: descriptor.node.kind, indexInParent: index, childKind: child.kind)
let result = visit(.init(
node: child,
byteOffset: byteOffset,
contextualClassification: classficiation ?? descriptor.contextualClassification))
parentKind: descriptor.node.kind,
indexInParent: index,
childKind: child.kind
)
let result = visit(
.init(
node: child,
byteOffset: byteOffset,
contextualClassification: classficiation ?? descriptor.contextualClassification
)
)
if result == .break {
return .break
}
Expand Down
16 changes: 11 additions & 5 deletions Sources/SwiftCompilerSupport/ConsistencyCheck.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,17 @@ extension Syntax {
@_cdecl("swift_parser_consistencyCheck")
@_spi(SwiftCompiler)
public func _parserConsistencyCheck(
bufferPtr: UnsafePointer<UInt8>, bufferLength: Int,
filename: UnsafePointer<UInt8>, flags: CUnsignedInt,
bufferPtr: UnsafePointer<UInt8>,
bufferLength: Int,
filename: UnsafePointer<UInt8>,
flags: CUnsignedInt,
hookCtx: OpaquePointer,
diagnosticHook: @convention(c) (Int, UnsafePointer<Int8>, OpaquePointer) -> Void
) -> CInt {
let buffer = UnsafeBufferPointer<UInt8>(
start: bufferPtr, count: bufferLength)
start: bufferPtr,
count: bufferLength
)
var parser = Parser(buffer)
return withExtendedLifetime(parser) { () -> CInt in
// Parse the source file
Expand All @@ -57,7 +61,8 @@ public func _parserConsistencyCheck(
if flags & 0x01 != 0 {
if sourceFile.syntaxTextBytes != [UInt8](buffer) {
print(
"\(String(cString: filename)): error: file failed to round-trip")
"\(String(cString: filename)): error: file failed to round-trip"
)
return 1
}
}
Expand All @@ -67,7 +72,8 @@ public func _parserConsistencyCheck(
var anyDiags = false

let diags = ParseDiagnosticsGenerator.diagnostics(
for: sourceFile)
for: sourceFile
)
for diag in diags {
// Skip over diagnostics within #if, because we don't know whether
// we are in an active region or not.
Expand Down
1 change: 0 additions & 1 deletion Sources/SwiftDiagnostics/Diagnostic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,3 @@ public struct Diagnostic: CustomDebugStringConvertible {
return "\(location): \(message)"
}
}

44 changes: 23 additions & 21 deletions Sources/SwiftDiagnostics/DiagnosticsFormatter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,30 @@
import SwiftSyntax

public struct DiagnosticsFormatter {

/// A wrapper struct for a source line and its diagnostics
private struct AnnotatedSourceLine {
var diagnostics: [Diagnostic]
var sourceString: String
}

/// Number of lines which should be printed before and after the diagnostic message
static let contextSize = 2

/// Print given diagnostics for a given syntax tree on the command line
public static func annotatedSource<SyntaxType: SyntaxProtocol>(tree: SyntaxType, diags: [Diagnostic]) -> String {
let slc = SourceLocationConverter(file: "", tree: tree)

// First, we need to put each line and its diagnostics together
var annotatedSourceLines = [AnnotatedSourceLine]()

for (sourceLineIndex, sourceLine) in slc.sourceLines.enumerated() {
let diagsForLine = diags.filter { diag in
return diag.location(converter: slc).line == (sourceLineIndex + 1)
}
annotatedSourceLines.append(AnnotatedSourceLine(diagnostics: diagsForLine, sourceString: sourceLine))
}

// Only lines with diagnostic messages should be printed, but including some context
let rangesToPrint = annotatedSourceLines.enumerated().compactMap { (lineIndex, sourceLine) -> Range<Int>? in
let lineNumber = lineIndex + 1
Expand All @@ -45,50 +45,52 @@ public struct DiagnosticsFormatter {
}
return nil
}

var annotatedSource = ""

/// Keep track if a line missing char should be printed
var hasLineBeenSkipped = false

let maxNumberOfDigits = String(annotatedSourceLines.count).count

for (lineIndex, annotatedLine) in annotatedSourceLines.enumerated() {
let lineNumber = lineIndex + 1
guard rangesToPrint.contains(where: { range in
range.contains(lineNumber)
}) else {
guard
rangesToPrint.contains(where: { range in
range.contains(lineNumber)
})
else {
hasLineBeenSkipped = true
continue
}

// line numbers should be right aligned
let lineNumberString = String(lineNumber)
let leadingSpaces = String(repeating: " ", count: maxNumberOfDigits - lineNumberString.count)
let linePrefix = "\(leadingSpaces)\(lineNumberString) │ "

// If necessary, print a line that indicates that there was lines skipped in the source code
if hasLineBeenSkipped && !annotatedSource.isEmpty {
let lineMissingInfoLine = String(repeating: " ", count: maxNumberOfDigits) + " ┆"
annotatedSource.append("\(lineMissingInfoLine)\n")
}
hasLineBeenSkipped = false

// print the source line
annotatedSource.append("\(linePrefix)\(annotatedLine.sourceString)")

// If the line did not end with \n (e.g. the last line), append it manually
if annotatedSource.last != "\n" {
annotatedSource.append("\n")
}

let columnsWithDiagnostics = Set(annotatedLine.diagnostics.map { $0.location(converter: slc).column ?? 0 })
let diagsPerColumn = Dictionary(grouping: annotatedLine.diagnostics) { diag in
diag.location(converter: slc).column ?? 0
}.sorted { lhs, rhs in
lhs.key > rhs.key
}

for (column, diags) in diagsPerColumn {
// compute the string that is shown before each message
var preMessage = String(repeating: " ", count: maxNumberOfDigits) + " ∣"
Expand All @@ -99,12 +101,12 @@ public struct DiagnosticsFormatter {
preMessage.append(" ")
}
}

for diag in diags.dropLast(1) {
annotatedSource.append("\(preMessage)├─ \(diag.message)\n")
}
annotatedSource.append("\(preMessage)╰─ \(diags.last!.message)\n")

}
}
return annotatedSource
Expand Down
2 changes: 0 additions & 2 deletions Sources/SwiftDiagnostics/FixIt.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ public protocol FixItMessage {
var fixItID: MessageID { get }
}


/// A Fix-It that can be applied to resolve a diagnostic.
public struct FixIt {
public struct Changes: ExpressibleByArrayLiteral {
Expand Down Expand Up @@ -63,4 +62,3 @@ public struct FixIt {
self.changes = changes
}
}

1 change: 0 additions & 1 deletion Sources/SwiftDiagnostics/Message.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
//
//===----------------------------------------------------------------------===//


/// An identifier that identifies a diagnostic message's type.
/// Fundamentally different diagnostics should have a different `diagnosticID`
/// so that clients may filter/prioritise/highlight/... certain diagnostics.
Expand Down
1 change: 0 additions & 1 deletion Sources/SwiftDiagnostics/Note.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,3 @@ public struct Note: CustomDebugStringConvertible {
}
}
}

3 changes: 2 additions & 1 deletion Sources/SwiftOperators/Operator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ public struct Operator {
public let syntax: OperatorDeclSyntax?

public init(
kind: OperatorKind, name: OperatorName,
kind: OperatorKind,
name: OperatorName,
precedenceGroup: PrecedenceGroupName? = nil,
syntax: OperatorDeclSyntax? = nil
) {
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftOperators/OperatorError+Diagnostics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import SwiftDiagnostics
import SwiftParser
import SwiftSyntax

extension OperatorError : DiagnosticMessage {
extension OperatorError: DiagnosticMessage {
public var severity: DiagnosticSeverity {
.error
}
Expand Down
8 changes: 5 additions & 3 deletions Sources/SwiftOperators/OperatorError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ public enum OperatorError: Error {

/// No associativity relationship between operators.
case incomparableOperators(
leftOperator: ExprSyntax, leftPrecedenceGroup: PrecedenceGroupName,
rightOperator: ExprSyntax, rightPrecedenceGroup: PrecedenceGroupName
leftOperator: ExprSyntax,
leftPrecedenceGroup: PrecedenceGroupName,
rightOperator: ExprSyntax,
rightPrecedenceGroup: PrecedenceGroupName
)
}

Expand All @@ -42,4 +44,4 @@ public enum OperatorError: Error {
/// may separately record/drop the error and return without throwing (in
/// which case the operator-precedence parser will recover).
public typealias OperatorErrorHandler =
(OperatorError) throws -> Void
(OperatorError) throws -> Void
Loading