Skip to content

Commit ae1ed93

Browse files
authored
Merge pull request #1197 from liveview-native/client-side-source-meta
Include original source in client-side error messages
2 parents 4bdbfcf + 56b43ee commit ae1ed93

File tree

4 files changed

+74
-50
lines changed

4 files changed

+74
-50
lines changed

Sources/LiveViewNative/Stylesheets/StylesheetParser.swift

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ struct StylesheetParser<M: ViewModifier & ParseableModifierValue>: Parser {
99
let context: ParseableModifierContext
1010

1111
func parse(_ input: inout Substring.UTF8View) throws -> Dictionary<String, Array<M>> {
12-
let fullStylesheet = input
1312
try "%{".utf8.parse(&input)
1413
// early exit
1514
if (try? "}".utf8.parse(&input)) != nil {
@@ -24,7 +23,7 @@ struct StylesheetParser<M: ViewModifier & ParseableModifierValue>: Parser {
2423
try Whitespace().parse(&input)
2524
do {
2625
classes[name] = try ListLiteral {
27-
RecoverableModifier(className: name, fullStylesheet: String(fullStylesheet), context: context)
26+
RecoverableModifier(className: name, context: context)
2827
}
2928
.parse(&input)
3029
.compactMap({ $0 })
@@ -35,10 +34,6 @@ struct StylesheetParser<M: ViewModifier & ParseableModifierValue>: Parser {
3534
Stylesheet parsing failed for class `\(name)`:
3635
3736
\(error)
38-
39-
in stylesheet:
40-
41-
\(String(fullStylesheet) ?? "")
4237
"""
4338
)
4439
// consume the rest
@@ -59,7 +54,6 @@ struct StylesheetParser<M: ViewModifier & ParseableModifierValue>: Parser {
5954

6055
struct RecoverableModifier: Parser {
6156
let className: String
62-
let fullStylesheet: String?
6357
let context: ParseableModifierContext
6458

6559
func parse(_ input: inout Substring.UTF8View) throws -> M? {
@@ -75,10 +69,6 @@ struct StylesheetParser<M: ViewModifier & ParseableModifierValue>: Parser {
7569
Stylesheet parsing failed for modifier `\(modifierName)` in class `\(className)`:
7670
7771
\(modifierError)
78-
79-
in stylesheet:
80-
81-
\(fullStylesheet ?? "")
8272
"""
8373
)
8474
return nil
@@ -129,6 +119,15 @@ struct StylesheetParser<M: ViewModifier & ParseableModifierValue>: Parser {
129119
AnyArgument(context: context)
130120
}
131121
.map({ _ in () })
122+
// keyword list
123+
ListLiteral {
124+
Identifier()
125+
Whitespace()
126+
":".utf8
127+
Whitespace()
128+
AnyArgument(context: context)
129+
}
130+
.map({ _ in () })
132131
}
133132
}
134133
}

Sources/LiveViewNativeStylesheet/ModifierParseError.swift

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,17 @@ public struct ModifierParseError: Error, CustomDebugStringConvertible {
2424
var localizedDescription: String {
2525
switch self {
2626
case .unknownModifier(let name):
27-
"Unknown modifier '\(name)'"
27+
return "Unknown modifier `\(name)`"
2828
case .missingRequiredArgument(let name):
29-
"Missing required argument '\(name)'"
29+
return "Missing required argument `\(name)`"
3030
case .noMatchingClause(let name, let clauses):
31-
"No matching clause found for modifier '\(name)'. Expected one of \(clauses.map({ "`\(name)(\($0.joined(separator: ":"))\($0.count > 0 ? ":" : ""))`" }).joined(separator: ", "))"
31+
if clauses.count == 1,
32+
let clause = clauses.first
33+
{
34+
return "No matching clause found for modifier `\(name)`. Expected `\(name)(\(clause.joined(separator: ":"))\(clause.count > 0 ? ":" : ""))`"
35+
} else {
36+
return "No matching clause found for modifier `\(name)`. Expected one of \(clauses.map({ "`\(name)(\($0.joined(separator: ":"))\($0.count > 0 ? ":" : ""))`" }).joined(separator: ", "))"
37+
}
3238
}
3339
}
3440
}
@@ -38,8 +44,13 @@ public struct ModifierParseError: Error, CustomDebugStringConvertible {
3844
}
3945

4046
public var localizedDescription: String {
41-
"""
42-
\(metadata.file):\(metadata.module):\(metadata.line): \(error.localizedDescription)
47+
let indentation = String(repeating: " ", count: String(metadata.line).count)
48+
return """
49+
\(indentation) |
50+
\(metadata.line) | \(metadata.source)
51+
\(indentation) | ^ \(error.localizedDescription)
52+
53+
in \(metadata.module) (\(metadata.file):\(metadata.line))
4354
"""
4455
}
4556
}

Sources/LiveViewNativeStylesheet/Parsing/External/Metadata.swift

Lines changed: 47 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,42 +4,56 @@ public struct Metadata {
44
public let file: String
55
public let line: Int
66
public let module: String
7+
public let source: String
78

89
public static func parser() -> some Parser<Substring.UTF8View, Self> {
9-
Parse { (file, line, module) in
10-
Self(file: file, line: line, module: module)
11-
} with: {
12-
"[".utf8
13-
14-
Whitespace()
15-
"file:".utf8
16-
Whitespace()
17-
StringLiteral()
18-
Whitespace()
19-
",".utf8
20-
Whitespace()
21-
22-
Whitespace()
23-
"line:".utf8
24-
Whitespace()
25-
Parsers.IntParser<Substring.UTF8View, Int>()
26-
Whitespace()
27-
",".utf8
28-
Whitespace()
29-
30-
Whitespace()
31-
"module:".utf8
32-
Whitespace()
33-
Many {
34-
Identifier()
35-
} separator: {
36-
".".utf8
10+
OneOf {
11+
Parse { (file, line, module, source) in
12+
Self(file: file, line: line, module: module, source: source)
13+
} with: {
14+
"[".utf8
15+
16+
Whitespace()
17+
"file:".utf8
18+
Whitespace()
19+
StringLiteral()
20+
Whitespace()
21+
",".utf8
22+
23+
Whitespace()
24+
25+
"line:".utf8
26+
Whitespace()
27+
Parsers.IntParser<Substring.UTF8View, Int>()
28+
Whitespace()
29+
",".utf8
30+
31+
Whitespace()
32+
33+
"module:".utf8
34+
Whitespace()
35+
Many {
36+
Identifier()
37+
} separator: {
38+
".".utf8
39+
}
40+
.map({ $0.joined(separator: ".") })
41+
Whitespace()
42+
",".utf8
43+
44+
Whitespace()
45+
46+
"source:".utf8
47+
Whitespace()
48+
StringLiteral()
49+
50+
Whitespace()
51+
52+
"]".utf8
53+
}
54+
"[]".utf8.map {
55+
Self.init(file: "", line: 0, module: "", source: "")
3756
}
38-
.map({ $0.joined(separator: ".") })
39-
40-
Whitespace()
41-
42-
"]".utf8
4357
}
4458
}
4559
}

Sources/LiveViewNativeStylesheet/Parsing/External/ParseableModifier.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public struct StandardExpressionParser<Output: ParseableExpressionProtocol>: Par
5151
}
5252

5353
public class ParseableModifierContext {
54-
public var metadata: Metadata = .init(file: "", line: 0, module: "unknown")
54+
public var metadata: Metadata = .init(file: "", line: 0, module: "unknown", source: "<unknown>")
5555

5656
public init() {}
5757
}

0 commit comments

Comments
 (0)