Skip to content

Commit 487bc84

Browse files
committed
Range -> SourceLocation
1 parent 533a3b2 commit 487bc84

17 files changed

Lines changed: 216 additions & 158 deletions

Sources/Compiler/Diagnostic.swift

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
public struct Diagnostic: Error {
99
public let message: String
10-
public let range: Range<String.Index>
10+
public let range: SourceLocation
1111
public let suggestion: Suggestion?
1212

1313
public enum Suggestion: Sendable {
@@ -17,7 +17,7 @@ public struct Diagnostic: Error {
1717

1818
public init(
1919
_ message: String,
20-
at range: Range<String.Index>,
20+
at range: SourceLocation,
2121
suggestion: Suggestion? = nil
2222
) {
2323
self.message = message
@@ -28,7 +28,7 @@ public struct Diagnostic: Error {
2828
init(
2929
expected: TypeNameSyntax,
3030
got actual: TypeNameSyntax,
31-
at range: Range<String.Index>
31+
at range: SourceLocation
3232
) {
3333
self.message = "Incorrect type, expected '\(expected.name)' got '\(actual.name)'"
3434
self.range = range
@@ -45,7 +45,7 @@ extension Diagnostic {
4545
static func incorrectType(
4646
_ actual: TypeNameSyntax,
4747
expected: TypeNameSyntax,
48-
at range: Range<String.Index>
48+
at range: SourceLocation
4949
) -> Diagnostic {
5050
Diagnostic(
5151
"Incorrect type, expected '\(expected.name)' got '\(actual.name)'",
@@ -56,7 +56,7 @@ extension Diagnostic {
5656

5757
static func expectedNumber(
5858
_ actual: TypeNameSyntax,
59-
at range: Range<String.Index>
59+
at range: SourceLocation
6060
) -> Diagnostic {
6161
Diagnostic(
6262
"Incorrect type, expected number got '\(actual.name)'",
@@ -66,7 +66,7 @@ extension Diagnostic {
6666

6767
static func ambiguous(
6868
_ identifier: Substring,
69-
at range: Range<String.Index>
69+
at range: SourceLocation
7070
) -> Diagnostic {
7171
Diagnostic(
7272
"'\(identifier)' is ambigious in the current context",
@@ -95,7 +95,7 @@ extension Diagnostic {
9595
)
9696
}
9797

98-
static func nameRequired(at range: Range<Substring.Index>) -> Diagnostic {
98+
static func nameRequired(at range: SourceLocation) -> Diagnostic {
9999
return Diagnostic(
100100
"Name required, add via 'AS'",
101101
at: range,
@@ -106,7 +106,7 @@ extension Diagnostic {
106106
static func unexpectedToken(
107107
of kind: Token.Kind,
108108
expected: Token.Kind? = nil,
109-
at range: Range<Substring.Index>
109+
at range: SourceLocation
110110
) -> Diagnostic {
111111
if let expected {
112112
return Diagnostic("Unexpected token \(kind), expected '\(expected)'", at: range)
@@ -122,7 +122,7 @@ extension Diagnostic {
122122
static func unexpectedToken(
123123
of kind: Token.Kind,
124124
expectedAnyOf expected: Token.Kind...,
125-
at range: Range<Substring.Index>
125+
at range: SourceLocation
126126
) -> Diagnostic {
127127
var expectedMessage = ""
128128
for (index, kind) in expected.enumerated() {
@@ -140,22 +140,22 @@ extension Diagnostic {
140140

141141
static func illegalStatement(
142142
in context: String,
143-
at range: Range<Substring.Index>
143+
at range: SourceLocation
144144
) -> Diagnostic {
145145
return Diagnostic("Statement is not allowed in \(context)", at: range)
146146
}
147147

148148
static func alreadyHasPrimaryKey(
149149
_ table: Substring,
150-
at range: Range<Substring.Index>
150+
at range: SourceLocation
151151
) -> Diagnostic {
152152
return Diagnostic("Table '\(table)' already has a primary key", at: range)
153153
}
154154

155155
static func unableToUnify(
156156
_ t1: Type,
157157
with t2: Type,
158-
at range: Range<Substring.Index>
158+
at range: SourceLocation
159159
) -> Diagnostic {
160160
return Diagnostic("Unable to unify types '\(t1)' and '\(t2)'", at: range)
161161
}

Sources/Compiler/DiagnosticReporter.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public struct StdoutDiagnosticReporter: DiagnosticReporter {
1313
public init() {}
1414

1515
public func report(diagnostic: Diagnostic, source: String, fileName: String) {
16-
let source = source[diagnostic.range]
16+
let source = source[diagnostic.range.range]
1717

1818
print("""
1919
\(source)

Sources/Compiler/Diagnostics.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public struct Diagnostics {
4040

4141
public mutating func trying<Output>(
4242
_ action: () throws -> Output,
43-
at range: Range<Substring.Index>
43+
at range: SourceLocation
4444
) -> Output? {
4545
do {
4646
return try action()

Sources/Compiler/Gen/Rewriter.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct Rewriter {
2525
mutating func removeNonSql<S: StmtSyntax>(_ stmt: S, in source: String) -> String {
2626
let rangesToRemove = stmt.accept(visitor: &self)
2727

28-
guard !rangesToRemove.isEmpty else { return "\(source[stmt.range]);" }
28+
guard !rangesToRemove.isEmpty else { return "\(source[stmt.range.range]);" }
2929

3030
var final = ""
3131
var start = stmt.range.lowerBound
@@ -61,13 +61,13 @@ struct Rewriter {
6161
let rowRanges: [(Range<Substring.Index>, Parameter<String>)] = parameters
6262
.compactMap { param -> [(Range<Substring.Index>, Parameter<String>)]? in
6363
guard case .row = param.type else { return nil }
64-
return param.ranges.map { ($0, param) }
64+
return param.ranges.map { ($0.range, param) }
6565
}
6666
.flatMap(\.self)
6767
.sorted { $0.0.lowerBound < $1.0.lowerBound }
6868

6969
guard !rowRanges.isEmpty else {
70-
return [.text(source[stmt.range])]
70+
return [.text(source[stmt.range.range])]
7171
}
7272

7373
guard rangesToRemove.isEmpty else {
@@ -109,15 +109,15 @@ extension Rewriter: StmtSyntaxVisitor {
109109
func visit(_ stmt: borrowing CreateTableStmtSyntax) -> [Range<Substring.Index>] {
110110
switch stmt.kind {
111111
case .columns(let columns):
112-
return columns.values.compactMap { $0.type.alias?.range }
112+
return columns.values.compactMap { $0.type.alias?.range.range }
113113
case .select:
114114
return []
115115
}
116116
}
117117

118118
func visit(_ stmt: borrowing AlterTableStmtSyntax) -> [Range<Substring.Index>] {
119119
return switch stmt.kind {
120-
case .addColumn(let c): c.type.alias.map { [$0.range] } ?? []
120+
case .addColumn(let c): c.type.alias.map { [$0.range.range] } ?? []
121121
default: []
122122
}
123123
}
@@ -152,9 +152,9 @@ extension Rewriter: StmtSyntaxVisitor {
152152
func visit(_ stmt: borrowing CreateVirtualTableStmtSyntax) -> [Range<Substring.Index>] {
153153
return stmt.arguments.flatMap { argument -> [Range<Substring.Index>] in
154154
guard case let .fts5Column(_, typeName, notNull, _) = argument else { return [] }
155-
if let typeName, let notNull { return [typeName.range, notNull] }
156-
if let typeName { return [typeName.range] }
157-
if let notNull { return [notNull] }
155+
if let typeName, let notNull { return [typeName.range.range, notNull.range] }
156+
if let typeName { return [typeName.range.range] }
157+
if let notNull { return [notNull.range] }
158158
return []
159159
}
160160
}

Sources/Compiler/Parse/Lexer.swift

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,12 @@ struct Lexer {
3939
}
4040

4141
private var eof: Token {
42-
return Token(kind: .eof, range: source.endIndex..<source.endIndex)
42+
return Token(
43+
kind: .eof,
44+
range: SourceLocation(
45+
range: source.endIndex..<source.endIndex
46+
)
47+
)
4348
}
4449

4550
mutating func next() -> Token {
@@ -82,9 +87,9 @@ struct Lexer {
8287
advance()
8388
if self.current == ">" {
8489
advance()
85-
return Token(kind: .doubleArrow, range: currentIndex..<peekIndex)
90+
return Token(kind: .doubleArrow, range: location(from: currentIndex, to: peekIndex))
8691
} else {
87-
return Token(kind: .arrow, range: currentIndex..<peekIndex)
92+
return Token(kind: .arrow, range: location(from: currentIndex, to: peekIndex))
8893
}
8994
case ("*", _): return consumeSingle(of: .star)
9095
case ("=", _): return consumeSingle(of: .equal)
@@ -109,7 +114,7 @@ struct Lexer {
109114
case ("~", _): return consumeSingle(of: .tilde)
110115
case ("'", _): return parseString()
111116
default:
112-
diagnostics.add(.init("Unexpected character: '\(current)'", at: currentIndex..<peekIndex))
117+
diagnostics.add(.init("Unexpected character: '\(current)'", at: location(from: currentIndex, to: peekIndex)))
113118
advance()
114119
return next()
115120
}
@@ -130,8 +135,8 @@ struct Lexer {
130135
advance()
131136
}
132137

133-
let range = start..<currentIndex
134-
return Token(kind: Token.Kind(word: source[range]), range: range)
138+
let location = location(from: start, to: currentIndex)
139+
return Token(kind: Token.Kind(word: source[location.range]), range: location)
135140
}
136141

137142
private mutating func parseNumber() -> Token {
@@ -152,16 +157,16 @@ struct Lexer {
152157
return scientificNotation(mantissa: start..<currentIndex)
153158
}
154159

155-
let range = start..<currentIndex
156-
let string = source[range]
160+
let location = location(from: start, to: currentIndex)
161+
let string = source[location.range]
157162

158163
let kind: Token.Kind = if hasSeenDecimal {
159-
.double(double(from: string, at: range))
164+
.double(double(from: string, at: location.range))
160165
} else {
161-
.int(integer(from: string, at: range))
166+
.int(integer(from: string, at: location.range))
162167
}
163168

164-
return Token(kind: kind, range: range)
169+
return Token(kind: kind, range: location)
165170
}
166171

167172
private mutating func scientificNotation(
@@ -209,7 +214,10 @@ struct Lexer {
209214
let exponentUnsigned = double(from: source[exponentRange], at: exponentRange)
210215
let exponent = isExpoinentPositive ? exponentUnsigned : -exponentUnsigned
211216
let value = mantissa * pow(10, exponent)
212-
return Token(kind: .double(value), range: mantissaRange.lowerBound..<exponentRange.upperBound)
217+
return Token(
218+
kind: .double(value),
219+
range: location(from: mantissaRange.lowerBound, to: exponentRange.upperBound)
220+
)
213221
}
214222

215223
private mutating func consumeDigits() {
@@ -231,13 +239,14 @@ struct Lexer {
231239
}
232240

233241
let numberRange = numberStart..<currentIndex
242+
let location = location(from: tokenStart, to: currentIndex)
234243

235244
guard let value = Int(source[numberRange], radix: 16) else {
236-
diagnostics.add(.init("Invalid hex number", at: tokenStart..<currentIndex))
237-
return Token(kind: .hex(0), range: tokenStart..<currentIndex)
245+
diagnostics.add(.init("Invalid hex number", at: location))
246+
return Token(kind: .hex(0), range: location)
238247
}
239248

240-
return Token(kind: .hex(value), range: tokenStart..<currentIndex)
249+
return Token(kind: .hex(value), range: location)
241250
}
242251

243252
private mutating func parseString() -> Token {
@@ -254,10 +263,10 @@ struct Lexer {
254263
if current == "'" {
255264
advance()
256265
} else {
257-
diagnostics.add(.init("Unterminated string", at: start..<currentIndex))
266+
diagnostics.add(.init("Unterminated string", at: location(from: start, to: currentIndex)))
258267
}
259268

260-
return Token(kind: .string(source[stringRange]), range: tokenStart..<currentIndex)
269+
return Token(kind: .string(source[stringRange]), range: location(from: tokenStart, to: currentIndex))
261270
}
262271

263272
private mutating func skipWhitespace() {
@@ -269,22 +278,22 @@ struct Lexer {
269278
private mutating func consumeSingle(of kind: Token.Kind) -> Token {
270279
let start = currentIndex
271280
advance()
272-
return Token(kind: kind, range: start..<currentIndex)
281+
return Token(kind: kind, range: location(from: start, to: currentIndex))
273282
}
274283

275284
private mutating func consumeDouble(of kind: Token.Kind) -> Token {
276285
let start = currentIndex
277286
advance()
278287
advance()
279-
return Token(kind: kind, range: start..<currentIndex)
288+
return Token(kind: kind, range: location(from: start, to: currentIndex))
280289
}
281290

282291
private mutating func integer<S: StringProtocol>(
283292
from source: S,
284293
at range: Range<String.Index>
285294
) -> Int {
286295
guard let int = Int(source.replacingOccurrences(of: "_", with: "")) else {
287-
diagnostics.add(.init("Invalid integer '\(source)'", at: range))
296+
diagnostics.add(.init("Invalid integer '\(source)'", at: SourceLocation(range: range)))
288297
return 0
289298
}
290299

@@ -296,7 +305,7 @@ struct Lexer {
296305
at range: Range<String.Index>
297306
) -> Double {
298307
guard let double = Double(source.replacingOccurrences(of: "_", with: "")) else {
299-
diagnostics.add(.init("Invalid double '\(source)'", at: range))
308+
diagnostics.add(.init("Invalid double '\(source)'", at: SourceLocation(range: range)))
300309
return 0
301310
}
302311

@@ -311,4 +320,11 @@ struct Lexer {
311320
advance()
312321
}
313322
}
323+
324+
private func location(
325+
from lowerBound: Substring.Index,
326+
to upperBound: Substring.Index
327+
) -> SourceLocation {
328+
return SourceLocation(range: lowerBound ..< upperBound)
329+
}
314330
}

Sources/Compiler/Parse/ParserState.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,16 @@ struct ParserState {
2222
self.peek2 = self.lexer.next()
2323
}
2424

25-
var range: Range<String.Index> {
25+
var range: SourceLocation {
2626
return current.range
2727
}
2828

29-
func range(from range: borrowing Range<String.Index>) -> Range<String.Index> {
30-
return range.lowerBound..<current.range.lowerBound
29+
func range(from range: borrowing SourceLocation) -> SourceLocation {
30+
return range.upTo(current.range)
3131
}
3232

33-
func range(from token: borrowing Token) -> Range<String.Index> {
34-
return token.range.lowerBound..<current.range.lowerBound
33+
func range(from token: borrowing Token) -> SourceLocation {
34+
return token.range.upTo(current.range)
3535
}
3636

3737
func skippingOne() -> ParserState {

0 commit comments

Comments
 (0)