Skip to content

Commit ec73053

Browse files
authored
Merge pull request #687 from TTOzzi/fix-BeginDocumentationCommentWithOneLineSummary
Ignore sentence terminators inside quotes when applying the 'BeginDocumentationCommentWithOneLineSummary' option.
2 parents 4e8ad38 + c0a3702 commit ec73053

File tree

2 files changed

+57
-6
lines changed

2 files changed

+57
-6
lines changed

Sources/SwiftFormat/Rules/BeginDocumentationCommentWithOneLineSummary.swift

+27-6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import Foundation
14+
#if os(macOS)
15+
import NaturalLanguage
16+
#endif
1417
import SwiftSyntax
1518

1619
/// All documentation comments must begin with a one-line summary of the declaration.
@@ -125,13 +128,31 @@ public final class BeginDocumentationCommentWithOneLineSummary: SyntaxLintRule {
125128
}
126129

127130
var sentences = [String]()
131+
var tags = [NLTag]()
128132
var tokenRanges = [Range<String.Index>]()
129-
let tags = text.linguisticTags(
133+
134+
let tagger = NLTagger(tagSchemes: [.lexicalClass])
135+
tagger.string = text
136+
tagger.enumerateTags(
130137
in: text.startIndex..<text.endIndex,
131-
scheme: NSLinguisticTagScheme.lexicalClass.rawValue,
132-
tokenRanges: &tokenRanges)
138+
unit: .word,
139+
scheme: .lexicalClass
140+
) { tag, range in
141+
if let tag {
142+
tags.append(tag)
143+
tokenRanges.append(range)
144+
}
145+
return true
146+
}
147+
148+
var isInsideQuotes = false
133149
let sentenceTerminatorIndices = tags.enumerated().filter {
134-
$0.element == "SentenceTerminator"
150+
if $0.element == NLTag.openQuote {
151+
isInsideQuotes = true
152+
} else if $0.element == NLTag.closeQuote {
153+
isInsideQuotes = false
154+
}
155+
return !isInsideQuotes && $0.element == NLTag.sentenceTerminator
135156
}.map {
136157
tokenRanges[$0.offset].lowerBound
137158
}
@@ -152,8 +173,8 @@ public final class BeginDocumentationCommentWithOneLineSummary: SyntaxLintRule {
152173
/// Returns the best approximation of sentences in the given text using string splitting around
153174
/// periods that are followed by spaces.
154175
///
155-
/// This method is a fallback for platforms (like Linux, currently) where `String` does not
156-
/// support `NSLinguisticTagger` and its related APIs. It will fail to catch certain kinds of
176+
/// This method is a fallback for platforms (like Linux, currently) that does not
177+
/// support `NaturalLanguage` and its related APIs. It will fail to catch certain kinds of
157178
/// sentences (such as those containing abbreviations that are followed by a period, like "Dr.")
158179
/// that the more advanced API can handle.
159180
private func nonLinguisticSentenceApproximations(in text: String) -> (

Tests/SwiftFormatTests/Rules/BeginDocumentationCommentWithOneLineSummaryTests.swift

+30
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,34 @@ final class BeginDocumentationCommentWithOneLineSummaryTests: LintOrFormatRuleTe
139139
)
140140
#endif
141141
}
142+
143+
func testSentenceTerminationInsideQuotes() {
144+
assertLint(
145+
BeginDocumentationCommentWithOneLineSummary.self,
146+
"""
147+
/// Creates an instance with the same raw value as `x` failing iff `x.kind != Subject.kind`.
148+
struct TestBackTick {}
149+
150+
/// A set of `Diagnostic` that can answer the question ‘was there an error?’ in O(1).
151+
struct TestSingleSmartQuotes {}
152+
153+
/// A set of `Diagnostic` that can answer the question 'was there an error?' in O(1).
154+
struct TestSingleStraightQuotes {}
155+
156+
/// A set of `Diagnostic` that can answer the question “was there an error?” in O(1).
157+
struct TestDoubleSmartQuotes {}
158+
159+
/// A set of `Diagnostic` that can answer the question "was there an error?" in O(1).
160+
struct TestDoubleStraightQuotes {}
161+
162+
/// A set of `Diagnostic` that can answer the question “was there
163+
/// an error?” in O(1).
164+
struct TestTwoLinesDoubleSmartQuotes {}
165+
166+
/// A set of `Diagnostic` that can answer the question "was there
167+
/// an error?" in O(1).
168+
struct TestTwoLinesDoubleStraightQuotes {}
169+
"""
170+
)
171+
}
142172
}

0 commit comments

Comments
 (0)