Skip to content

Diagnose incorrect indentation in multi-line string literals #1255

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Jan 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CodeGeneration/Sources/SyntaxSupport/Trivia.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ public class Trivia {
public let isComment: Bool

public var lowerName: String { lowercaseFirstWord(name: name) }

public var enumCaseName: String {
if self.isCollection {
if lowerName == "backslash" {
return "backslashes"
} else {
return "\(lowerName)s"
}
} else {
return lowerName
}
}

public var charactersLen: Int { characters.count }

Expand Down
28 changes: 28 additions & 0 deletions CodeGeneration/Sources/SyntaxSupport/gyb_generated/Trivia.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ public class Trivia {
public let isComment: Bool

public var lowerName: String { lowercaseFirstWord(name: name) }

public var enumCaseName: String {
if self.isCollection {
if lowerName == "backslash" {
return "backslashes"
} else {
return "\(lowerName)s"
}
} else {
return lowerName
}
}

public var charactersLen: Int { characters.count }

Expand Down Expand Up @@ -122,6 +134,22 @@ public let TRIVIAS: [Trivia] = [
Trivia(name: "DocBlockComment",
comment: #"A documentation block comment, starting with '/**' and ending with '*/'."#,
isComment: true),
Trivia(name: "Backslash",
comment: #"A backslash that is at the end of a line in a multi-line string literal to escape the newline."#,
characters: [
Character("\\")
],
swiftCharacters: [
Character("\\")
]),
Trivia(name: "Pound",
comment: #"A '#' that is at the end of a line in a multi-line string literal to escape the newline."#,
characters: [
Character("#")
],
swiftCharacters: [
Character("#")
]),
Trivia(name: "UnexpectedText",
comment: #"Any skipped unexpected text."#),
Trivia(name: "Shebang",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ let triviaFile = SourceFileSyntax(leadingTrivia: .docLineComment(generateCopyrig
if trivia.isCollection {
EnumCaseDeclSyntax("""
/// \(raw: trivia.comment)
case \(raw: trivia.lowerName)s(Int)
case \(raw: trivia.enumCaseName)(Int)
""")

} else {
EnumCaseDeclSyntax("""
/// \(raw: trivia.comment)
case \(raw: trivia.lowerName)(String)
case \(raw: trivia.enumCaseName)(String)
""")
}
}
Expand All @@ -67,11 +67,11 @@ let triviaFile = SourceFileSyntax(leadingTrivia: .docLineComment(generateCopyrig
for trivia in TRIVIAS {
if trivia.isCollection {
let joined = trivia.characters.map { "\($0)" }.joined()
SwitchCaseSyntax("case let .\(raw: trivia.lowerName)s(count):") {
SwitchCaseSyntax("case let .\(raw: trivia.enumCaseName)(count):") {
FunctionCallExprSyntax("printRepeated(\(literal: joined), count: count)")
}
} else {
SwitchCaseSyntax("case let .\(raw: trivia.lowerName)(text):") {
SwitchCaseSyntax("case let .\(raw: trivia.enumCaseName)(text):") {
FunctionCallExprSyntax("target.write(text)")
}
}
Expand All @@ -89,12 +89,12 @@ let triviaFile = SourceFileSyntax(leadingTrivia: .docLineComment(generateCopyrig
SwitchStmtSyntax(expression: ExprSyntax("self")) {
for trivia in TRIVIAS {
if trivia.isCollection {
SwitchCaseSyntax("case .\(raw: trivia.lowerName)s(let data):") {
ReturnStmtSyntax(#"return "\#(raw: trivia.lowerName)s(\(data))""#)
SwitchCaseSyntax("case .\(raw: trivia.enumCaseName)(let data):") {
ReturnStmtSyntax(#"return "\#(raw: trivia.enumCaseName)(\(data))""#)
}
} else {
SwitchCaseSyntax("case .\(raw: trivia.lowerName)(let name):") {
ReturnStmtSyntax(#"return "\#(raw: trivia.lowerName)(\(name.debugDescription))""#)
SwitchCaseSyntax("case .\(raw: trivia.enumCaseName)(let name):") {
ReturnStmtSyntax(#"return "\#(raw: trivia.enumCaseName)(\(name.debugDescription))""#)
}
}
}
Expand Down Expand Up @@ -127,8 +127,8 @@ let triviaFile = SourceFileSyntax(leadingTrivia: .docLineComment(generateCopyrig

InitializerDeclSyntax("""
/// Creates Trivia with the provided underlying pieces.
public init(pieces: [TriviaPiece]) {
self.pieces = pieces
public init<S: Sequence>(pieces: S) where S.Element == TriviaPiece {
self.pieces = Array(pieces)
}
""")

Expand Down Expand Up @@ -173,24 +173,24 @@ let triviaFile = SourceFileSyntax(leadingTrivia: .docLineComment(generateCopyrig
let joined = trivia.characters.map { "\($0)" }.joined()
FunctionDeclSyntax("""
/// Returns a piece of trivia for some number of \(literal: joined) characters.
public static func \(raw: trivia.lowerName)s(_ count: Int) -> Trivia {
return [.\(raw: trivia.lowerName)s(count)]
public static func \(raw: trivia.enumCaseName)(_ count: Int) -> Trivia {
return [.\(raw: trivia.enumCaseName)(count)]
}
""")

VariableDeclSyntax("""
/// Gets a piece of trivia for \(literal: joined) characters.
public static var \(raw: trivia.lowerName): Trivia {
return .\(raw: trivia.lowerName)s(1)
return .\(raw: trivia.enumCaseName)(1)
}
""")


} else {
FunctionDeclSyntax("""
/// Returns a piece of trivia for \(raw: trivia.name).
public static func \(raw: trivia.lowerName)(_ text: String) -> Trivia {
return [.\(raw: trivia.lowerName)(text)]
public static func \(raw: trivia.enumCaseName)(_ text: String) -> Trivia {
return [.\(raw: trivia.enumCaseName)(text)]
}
""")
}
Expand Down Expand Up @@ -288,15 +288,15 @@ let triviaFile = SourceFileSyntax(leadingTrivia: .docLineComment(generateCopyrig
SwitchStmtSyntax(expression: ExprSyntax("self")) {
for trivia in TRIVIAS {
if trivia.isCollection {
SwitchCaseSyntax("case let .\(raw: trivia.lowerName)s(count):") {
SwitchCaseSyntax("case let .\(raw: trivia.enumCaseName)(count):") {
if trivia.charactersLen != 1 {
ReturnStmtSyntax("return SourceLength(utf8Length: count * \(raw: trivia.charactersLen))")
} else {
ReturnStmtSyntax("return SourceLength(utf8Length: count)")
}
}
} else {
SwitchCaseSyntax("case let .\(raw: trivia.lowerName)(text):") {
SwitchCaseSyntax("case let .\(raw: trivia.enumCaseName)(text):") {
ReturnStmtSyntax("return SourceLength(of: text)")
}
}
Expand All @@ -315,10 +315,10 @@ let triviaFile = SourceFileSyntax(leadingTrivia: .docLineComment(generateCopyrig
""") {
for trivia in TRIVIAS {
if trivia.isCollection {
EnumCaseDeclSyntax(" case \(raw: trivia.lowerName)s(Int)")
EnumCaseDeclSyntax(" case \(raw: trivia.enumCaseName)(Int)")

} else {
EnumCaseDeclSyntax("case \(raw: trivia.lowerName)(SyntaxText)")
EnumCaseDeclSyntax("case \(raw: trivia.enumCaseName)(SyntaxText)")
}
}

Expand All @@ -328,12 +328,12 @@ let triviaFile = SourceFileSyntax(leadingTrivia: .docLineComment(generateCopyrig
SwitchStmtSyntax(expression: ExprSyntax("piece")) {
for trivia in TRIVIAS {
if trivia.isCollection {
SwitchCaseSyntax("case let .\(raw: trivia.lowerName)s(count):") {
ReturnStmtSyntax("return .\(raw: trivia.lowerName)s(count)")
SwitchCaseSyntax("case let .\(raw: trivia.enumCaseName)(count):") {
ReturnStmtSyntax("return .\(raw: trivia.enumCaseName)(count)")
}
} else {
SwitchCaseSyntax("case let .\(raw: trivia.lowerName)(text):") {
ReturnStmtSyntax("return .\(raw: trivia.lowerName)(arena.intern(text))")
SwitchCaseSyntax("case let .\(raw: trivia.enumCaseName)(text):") {
ReturnStmtSyntax("return .\(raw: trivia.enumCaseName)(arena.intern(text))")
}
}
}
Expand Down Expand Up @@ -362,12 +362,12 @@ let triviaFile = SourceFileSyntax(leadingTrivia: .docLineComment(generateCopyrig
SwitchStmtSyntax(expression: ExprSyntax("raw")) {
for trivia in TRIVIAS {
if trivia.isCollection {
SwitchCaseSyntax("case let .\(raw: trivia.lowerName)s(count):") {
ExprSyntax("self = .\(raw: trivia.lowerName)s(count)")
SwitchCaseSyntax("case let .\(raw: trivia.enumCaseName)(count):") {
ExprSyntax("self = .\(raw: trivia.enumCaseName)(count)")
}
} else {
SwitchCaseSyntax("case let .\(raw: trivia.lowerName)(text):") {
ExprSyntax("self = .\(raw: trivia.lowerName)(String(syntaxText: text))")
SwitchCaseSyntax("case let .\(raw: trivia.enumCaseName)(text):") {
ExprSyntax("self = .\(raw: trivia.enumCaseName)(String(syntaxText: text))")
}
}
}
Expand All @@ -383,15 +383,15 @@ let triviaFile = SourceFileSyntax(leadingTrivia: .docLineComment(generateCopyrig
SwitchStmtSyntax(expression: ExprSyntax("self")) {
for trivia in TRIVIAS {
if trivia.isCollection {
SwitchCaseSyntax("case let .\(raw: trivia.lowerName)s(count):") {
SwitchCaseSyntax("case let .\(raw: trivia.enumCaseName)(count):") {
if trivia.charactersLen != 1 {
ReturnStmtSyntax("return count * \(raw: trivia.charactersLen)")
} else {
ReturnStmtSyntax("return count")
}
}
} else {
SwitchCaseSyntax("case let .\(raw: trivia.lowerName)(text):") {
SwitchCaseSyntax("case let .\(raw: trivia.enumCaseName)(text):") {
ReturnStmtSyntax("return text.count")
}
}
Expand All @@ -405,11 +405,11 @@ let triviaFile = SourceFileSyntax(leadingTrivia: .docLineComment(generateCopyrig
SwitchStmtSyntax(expression: ExprSyntax("self")) {
for trivia in TRIVIAS {
if trivia.isCollection {
SwitchCaseSyntax("case .\(raw: trivia.lowerName)s(_):") {
SwitchCaseSyntax("case .\(raw: trivia.enumCaseName)(_):") {
ReturnStmtSyntax("return nil")
}
} else {
SwitchCaseSyntax("case .\(raw: trivia.lowerName)(let text):") {
SwitchCaseSyntax("case .\(raw: trivia.enumCaseName)(let text):") {
ReturnStmtSyntax("return text")
}
}
Expand Down
Loading