diff --git a/CHANGES.md b/CHANGES.md
index 9cd37d0f5e..9a544f449e 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -15,6 +15,7 @@ Core Grammars:
- enh(delphi) add support for character strings with non-decimal numerics [Jonah Jeleniewski][]
- fix(javascript) incorrect function name highlighting [CY Fung][]
- fix(1c) fix escaped symbols "+-;():=,[]" literals [Vitaly Barilko][]
+- fix(swift) correctly highlight generics and conformances in type definitions [Bradley Mackey][]
New Grammars:
diff --git a/src/languages/swift.js b/src/languages/swift.js
index d68503ea6c..95fbb05d70 100644
--- a/src/languages/swift.js
+++ b/src/languages/swift.js
@@ -457,6 +457,37 @@ export default function(hljs) {
end: /}/
};
+ const TYPE_DECLARATION = {
+ begin: [
+ /(struct|protocol|class|extension|enum|actor)/,
+ /\s+/,
+ Swift.identifier,
+ /\s*/,
+ ],
+ beginScope: {
+ 1: "keyword",
+ 3: "title.class"
+ },
+ keywords: KEYWORDS,
+ contains: [
+ GENERIC_PARAMETERS,
+ ...KEYWORD_MODES,
+ {
+ begin: /:/,
+ end: /\{/,
+ keywords: KEYWORDS,
+ contains: [
+ {
+ scope: "title.class.inherited",
+ match: Swift.typeIdentifier,
+ },
+ ...KEYWORD_MODES,
+ ],
+ relevance: 0,
+ },
+ ]
+ };
+
// Add supported submodes to string interpolation.
for (const variant of STRING.variants) {
const interpolation = variant.contains.find(mode => mode.label === "interpol");
@@ -490,19 +521,7 @@ export default function(hljs) {
...COMMENTS,
FUNCTION_OR_MACRO,
INIT_SUBSCRIPT,
- {
- beginKeywords: 'struct protocol class extension enum actor',
- end: '\\{',
- excludeEnd: true,
- keywords: KEYWORDS,
- contains: [
- hljs.inherit(hljs.TITLE_MODE, {
- className: "title.class",
- begin: /[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/
- }),
- ...KEYWORD_MODES
- ]
- },
+ TYPE_DECLARATION,
OPERATOR_DECLARATION,
PRECEDENCEGROUP,
{
diff --git a/test/markup/swift/functions.expect.txt b/test/markup/swift/functions.expect.txt
index c533960ebd..2398aaef43 100644
--- a/test/markup/swift/functions.expect.txt
+++ b/test/markup/swift/functions.expect.txt
@@ -23,7 +23,7 @@
subscript<X: A>(_ p: @attribute inout (x: Int, var: Int) = (0, 0)) { }
-protocol Comparable: Equatable {
+protocol Comparable: Equatable {
static func < (lhs: Self, rhs: Self) -> Bool
static func <= (lhs: Self, rhs: Self) -> Bool
diff --git a/test/markup/swift/ownership.expect.txt b/test/markup/swift/ownership.expect.txt
index af5aae9d16..d04b63c1fe 100644
--- a/test/markup/swift/ownership.expect.txt
+++ b/test/markup/swift/ownership.expect.txt
@@ -5,9 +5,9 @@ doStuffUniquely(with: consume x)
_ = copy x
doStuff(with: copy x)
-struct MoveOnly: ~Copyable {}
+struct MoveOnly: ~Copyable {}
-struct B: P {
+struct B: P {
func foo(x: borrowing Foo, y: consuming Foo)
}
func foo(_: borrowing Foo)
@@ -20,4 +20,4 @@ doStuff(with: copy x)
consuming func foo()
borrowing func foo()
mutating func foo()
-}
\ No newline at end of file
+}
diff --git a/test/markup/swift/swiftui.expect.txt b/test/markup/swift/swiftui.expect.txt
index ba23fe24b6..ce514f88fc 100644
--- a/test/markup/swift/swiftui.expect.txt
+++ b/test/markup/swift/swiftui.expect.txt
@@ -1,5 +1,5 @@
@main
-struct MyApp: App {
+struct MyApp: App {
var body: some Scene {
WindowGroup {
#if os(iOS)
diff --git a/test/markup/swift/type-definition.expect.txt b/test/markup/swift/type-definition.expect.txt
index 1d39754e22..08e5a79ac8 100644
--- a/test/markup/swift/type-definition.expect.txt
+++ b/test/markup/swift/type-definition.expect.txt
@@ -1,6 +1,61 @@
class TestClass {}
+class TestClass: Superclass {}
+class TestClass: Superclass, Conform1, Conform2 {}
+class TestClass<T> {}
+class TestClass<T, U> {}
+class TestClass<repeat each T> {}
+class TestClass<T> where T: Equatable {}
+class TestClass<T>: Superclass where T: Equatable {}
+
+class
+MoreThanOneLine
+{}
+
+class
+MoreThanOneLineInherit
+:
+Superclass
+{}
+
+class
+MoreThanOneLineInherit
+:
+Superclass1,
+Superclass2
+{}
+
+class
+MoreThanOneLineInherit:
+Superclass
+{}
+
+final class
+MoreThanOneLineGeneric<T>
+where
+T: Param
+{}
+
+class Outer {
+ class Inner<T> {}
+ class InnerInherit: Superclass {}
+}
+
struct TestStruct {}
+struct TestStruct: Conform {}
+struct TestStruct<T, U> {}
+
enum TestEnum {}
+enum TestEnum: Conform {}
+enum TestEnum<T, U> {}
+
actor TestActor {}
+actor TestActor: Conform {}
+actor TestActor<T, U> {}
+
extension TestExtension {}
+extension TestExtension: Conform {}
+extension TestExtension<T, U> {}
+
protocol TestProtocol {}
+protocol TestProtocol: Conform {}
+protocol TestProtocol<T, U> {}
diff --git a/test/markup/swift/type-definition.txt b/test/markup/swift/type-definition.txt
index 6469569a80..ef3edb11aa 100644
--- a/test/markup/swift/type-definition.txt
+++ b/test/markup/swift/type-definition.txt
@@ -1,6 +1,61 @@
class TestClass {}
+class TestClass: Superclass {}
+class TestClass: Superclass, Conform1, Conform2 {}
+class TestClass {}
+class TestClass {}
+class TestClass {}
+class TestClass where T: Equatable {}
+class TestClass: Superclass where T: Equatable {}
+
+class
+MoreThanOneLine
+{}
+
+class
+MoreThanOneLineInherit
+:
+Superclass
+{}
+
+class
+MoreThanOneLineInherit
+:
+Superclass1,
+Superclass2
+{}
+
+class
+MoreThanOneLineInherit:
+Superclass
+{}
+
+final class
+MoreThanOneLineGeneric
+where
+T: Param
+{}
+
+class Outer {
+ class Inner {}
+ class InnerInherit: Superclass {}
+}
+
struct TestStruct {}
+struct TestStruct: Conform {}
+struct TestStruct {}
+
enum TestEnum {}
+enum TestEnum: Conform {}
+enum TestEnum {}
+
actor TestActor {}
+actor TestActor: Conform {}
+actor TestActor {}
+
extension TestExtension {}
+extension TestExtension: Conform {}
+extension TestExtension {}
+
protocol TestProtocol {}
+protocol TestProtocol: Conform {}
+protocol TestProtocol {}