8000 Simplify AbsolutePosition offset calculation and support columns · swiftlang/swift-syntax@d259fcc · GitHub
[go: up one dir, main page]

Skip to content

Commit d259fcc

Browse files
Harlan Haskinsallevato
Harlan Haskins
authored andcommitted
Simplify AbsolutePosition offset calculation and support columns
1 parent b4295c5 commit d259fcc

File tree

3 files changed

+37
-126
lines changed

3 files changed

+37
-126
lines changed

Sources/SwiftSyntax/Diagnostic.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ public struct SourceLocation: Codable {
3030
public let file: String
3131

3232
public init(file: String, position: AbsolutePosition) {
33-
assert(position is UTF8Position, "must be utf8 position")
3433
self.init(line: position.line, column: position.column,
3534
offset: position.byteOffset, file: file)
3635
}
@@ -88,7 +87,7 @@ public enum FixIt: Codable {
8887
let string = try container.decode(String.self, forKey: .string)
8988
let loc = try container.decode(SourceLocation.self, forKey: .location)
9089
self = .insert(loc, string)
91-
case "replace":
90+
case "replace":
9291
let string = try container.decode(String.self, forKey: .string)
9392
let range = try container.decode(SourceRange.self, forKey: .range)
9493
self = .replace(range, string)
@@ -202,7 +201,7 @@ public struct Diagnostic: Codable {
202201
/// An array of possible FixIts to apply to this diagnostic.
203202
public let fixIts: [FixIt]
204203

205-
/// A diagnostic builder that
204+
/// A diagnostic builder that
206205
public struct Builder {
207206
/// An in-flight array of notes.
208207
internal var notes = [Note]()
@@ -225,7 +224,7 @@ public struct Diagnostic: Codable {
225224
/// - fixIts: Any FixIts that should be attached to this note.
226225
public mutating func note(_ message: Message,
227226
location: SourceLocation? = nil,
228-
highlights: [SourceRange] = [],
227+
highlights: [SourceRange] = [],
229228
fixIts: [FixIt] = []) {
230229
self.notes.append(Note(message: message, location: location,
231230
highlights: highlights, fixIts: fixIts))
@@ -252,7 +251,7 @@ public struct Diagnostic: Codable {
252251

253252
/// Adds a FixIt to replace the contents of the source file corresponding
254253
/// to the provided SourceRange with the provided text.
255-
public mutating
254+
public mutating
256255
func fixItReplace(_ sourceRange: SourceRange, with text: String) {
257256
fixIts.append(.replace(sourceRange, text))
258257
}

Sources/SwiftSyntax/SyntaxData.swift

Lines changed: 32 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ final class SyntaxData: Equatable {
6565
}
6666

6767
var position: AbsolutePosition {
68-
return positionCache.value { return calculatePosition(UTF8Position()) }
68+
return positionCache.value { return calculatePosition(AbsolutePosition()) }
6969
}
7070

71-
var positionAfterSkippingLeadingTrivia: AbsolutePosition {
71+
var positionBeforeLeadingTrivia: AbsolutePosition {
7272
let result = position.copy()
7373
_ = raw.accumulateLeadingTrivia(result)
7474
return result
@@ -261,78 +261,57 @@ final class SyntaxData: Equatable {
261261

262262
/// An absolute position in a source file as text - the absolute byteOffset from
263263
/// the start, line, and column.
264-
public class AbsolutePosition {
264+
public final class AbsolutePosition {
265265
public fileprivate(set) var byteOffset: Int
266266
public fileprivate(set) var line: Int
267267
public fileprivate(set) var column: Int
268+
public let encoding: Encoding
268269

269-
required public init(line: Int = 1, column: Int = 1, byteOffset: Int = 0) {
270+
public enum Encoding {
271+
case utf8
272+
case utf16
273+
}
274+
275+
public init(line: Int = 1, column: Int = 1, byteOffset: Int = 0,
276+
encoding: Encoding = .utf8) {
270277
self.line = line
271278
self.column = column
272279
self.byteOffset = byteOffset
280+
self.encoding = encoding
273281
}
274282

275-
internal func add(text: String) {
276-
preconditionFailure("this function must be overridden")
277-
}
278-
279-
internal func copy() -> Self {
280-
return type(of: self).init(line: line, column: column, byteOffset: byteOffset)
281-
}
282-
}
283-
284-
extension AbsolutePosition {
285-
286-
/// Add some number of columns to the position.
287283
internal func add(columns: Int) {
288-
column += columns
289-
byteOffset += columns
284+
self.column += columns
290285
}
291286

292-
/// Add some number of newlines to the position, resetting the column.
293-
/// Size is byte size of newline char.
294-
/// '\n' and '\r' are 1, '\r\n' is 2.
295287
internal func add(lines: Int, size: Int) {
296-
line += lines
297-
column = 1
298-
byteOffset += lines * size
288+
self.line += lines * size
289+
self.column = 1
299290
}
300291

301292
/// Use some text as a reference for adding to the absolute position,
302293
/// taking note of newlines, etc.
303-
fileprivate func add<C: BidirectionalCollection>(text chars: C)
304-
where C.Element: UnsignedInteger {
305-
let cr: C.Element = 13
306-
let nl: C.Element = 10
307-
var idx = chars.startIndex
308-
while idx != chars.endIndex {
309-
let c = chars[idx]
310-
idx = chars.index(after: idx)
311-
switch c {
312-
case cr:
313-
if chars[idx] == nl {
314-
add(lines: 1, size: 2)
315-
idx = chars.index(after: idx)
316-
} else {
317-
add(lines: 1, size: 1)
318-
}
319-
case nl:
320-
add(lines: 1, size: 1)
294+
internal func add(text: String) {
295+
for char in text {
296+
switch char {
297+
case "\n", "\r\n":
298+
line += 1
299+
column = 1
321300
default:
322-
add(columns: 1)
301+
column += 1
323302
}
324-
}
325-
}
326-
}
327303

328-
class UTF8Position: AbsolutePosition {
329-
internal override func add(text: String) {
330-
add(text: text.utf8)
304+
switch encoding {
305+
case .utf8:
306+
byteOffset += String(char).utf8.count
307+
case .utf16:
308+
byteOffset += String(char).utf16.count * 2
309+
}
310+
}
331311
}
332-
}
333312

334-
class UTF16Position: AbsolutePosition {
335-
internal override func add(text: String) {
336-
add(text: text.utf16)
313+
internal func copy() -> Self {
314+
return type(of: self).init(line: line, column: column,
315+
byteOffset: byteOffset)
337316
}
338317
}

Sources/SwiftSyntax/Trivia.swift.gyb

Lines changed: 1 addition & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -99,59 +99,6 @@ extension TriviaPiece: TextOutputStreamable {
9999
case let .${trivia.lower_name}(text):
100100
target.write(text)
101101
% end
102-
% end
103-
}
104-
}
105-
106-
/// Computes the information from this trivia to inform the source locations
107-
/// of the associated tokens.
108-
/// Specifically, walks through the trivia and keeps track of every newline
109-
/// to give a number of how many newlines and UTF8 characters appear in the
110-
/// trivia, along with the UTF8 offset of the last column.
111-
func characterSizes() -> (lines: Int, lastColumn: Int, utf8Length: Int) {
112-
func calculateTextSizes(_ text: String) ->
113-
(lines: Int, lastColumn: Int, utf8Length: Int) {
114-
var lines = 0
115-
var col = 0
116-
var total = 0
117-
var prevChar: UInt8? = nil
118-
// TODO: CR + LF should be regarded as one newline
119-
for char in text.utf8 {
120 F987 -
total += 1
121-
switch char {
122-
case 0x0a:
123-
if prevChar == 0x0d {
124-
/* ASCII CR LF */
125-
assert(col == 0)
126-
} else {
127-
/* ASCII newline */
128-
col = 0
129-
lines += 1
130-
}
131-
/* ASCII carriage-return */
132-
case 0x0d:
133-
col = 0
134-
lines += 1
135-
136-
default:
137-
col += 1
138-
}
139-
prevChar = char
140-
}
141-
return (lines: lines, lastColumn: col, utf8Length: total)
142-
}
143-
switch self {
144-
% for trivia in TRIVIAS:
145-
% if trivia.is_new_line:
146-
case let .${trivia.lower_name}s(n):
147-
return (lines: n, lastColumn: 0, utf8Length: n * ${trivia.characters_len()})
148-
% elif trivia.is_collection():
149-
case let .${trivia.lower_name}s(n):
150-
return (lines: 0, lastColumn: n, utf8Length: n * ${trivia.characters_len()})
151-
% else:
152-
case let .${trivia.lower_name}(text):
153-
return calculateTextSizes(text)
154-
% end
155102
% end
156103
}
157104
}
@@ -209,20 +156,6 @@ public struct Trivia: Codable {
209156
}
210157
% end
211158
% end
212-
213-
/// Computes the total sizes and offsets of all pieces in this Trivia.
214-
func characterSizes() -> (lines: Int, lastColumn: Int, utf8Length: Int) {
215-
var lines = 0
216-
var lastColumn = 0
217-
var length = 0
218-
for piece in pieces {
219-
let (ln, col, len) = piece.characterSizes()
220-
lines += ln
221-
lastColumn = col
222-
length += len
223-
}
224-
return (lines: lines, lastColumn: lastColumn, utf8Length: length)
225-
}
226159
}
227160

228161
/// Conformance for Trivia to the Collection protocol.
@@ -245,7 +178,7 @@ extension Trivia: Collection {
245178

246179
/// Get the byteSize of this trivia
247180
public var byteSize: Int {
248-
let pos = UTF8Position()
181+
let pos = AbsolutePosition()
249182
for piece in pieces {
250183
piece.accumulateAbsolutePosition(pos)
251184
}

0 commit comments

Comments
 (0)
0