diff --git a/.gitignore b/.gitignore index cb8ec35a..1879e0df 100644 --- a/.gitignore +++ b/.gitignore @@ -305,3 +305,4 @@ Pods/ .swiftpm/ test/integration/generated/**/**/xcuserdata/ **/Package.resolved +Podfile.lock diff --git a/AutorestSwift.xcodeproj/project.pbxproj b/AutorestSwift.xcodeproj/project.pbxproj index 1c63e815..3c050858 100644 --- a/AutorestSwift.xcodeproj/project.pbxproj +++ b/AutorestSwift.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 0A10427F25D483C4008E472E /* ReservedKeywords.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A10427E25D483C4008E472E /* ReservedKeywords.swift */; }; 0A22B0DC24D3671D00EC018E /* ClientMethodOptionsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A22B0C224D3301100EC018E /* ClientMethodOptionsViewModel.swift */; }; 0A22B0DD24D3671D00EC018E /* EnumerationChoiceViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A22B0AC24D2198D00EC018E /* EnumerationChoiceViewModel.swift */; }; 0A22B0DE24D3671D00EC018E /* EnumerationFileViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A22B05B24CA4CA400EC018E /* EnumerationFileViewModel.swift */; }; @@ -331,6 +332,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 0A10427E25D483C4008E472E /* ReservedKeywords.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReservedKeywords.swift; sourceTree = ""; }; 0A22B02C24C88EB000EC018E /* Podfile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Podfile; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 0A22B03424C8964000EC018E /* LanguageShortcut.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LanguageShortcut.swift; sourceTree = ""; }; 0A22B03524C8964000EC018E /* FileDestination.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileDestination.swift; sourceTree = ""; }; @@ -713,6 +715,7 @@ 0A22B07924CB721900EC018E /* String+Extensions.swift */, 0A22B07A24CB721900EC018E /* Encodable+Extensions.swift */, 0A22B07B24CB721900EC018E /* URL+Extensions.swift */, + 0A10427E25D483C4008E472E /* ReservedKeywords.swift */, ); path = Utils; sourceTree = ""; @@ -1333,6 +1336,7 @@ 0AA2BA3024F57A5B00CEA1D6 /* ParameterType.swift in Sources */, 0A22B11724D3671E00EC018E /* Protocol.swift in Sources */, 0A22B11824D3671E00EC018E /* Request.swift in Sources */, + 0A10427F25D483C4008E472E /* ReservedKeywords.swift in Sources */, 0A22B11924D3671E00EC018E /* Response.swift in Sources */, 0AA2BA1F24EC958600CEA1D6 /* Model.swift in Sources */, 0A22B11A24D3671E00EC018E /* Schema.swift in Sources */, diff --git a/Podfile.lock b/Podfile.lock deleted file mode 100644 index 1f8a3a26..00000000 --- a/Podfile.lock +++ /dev/null @@ -1,76 +0,0 @@ -PODS: - - CNIOAtomics (2.20.2) - - CNIODarwin (2.20.2) - - CNIOLinux (2.20.2) - - CNIOSHA1 (2.20.2) - - PathKit (0.9.2) - - Stencil (0.13.1): - - PathKit (~> 0.9.0) - - SwiftFormat/CLI (0.44.17) - - SwiftLint (0.39.2) - - SwiftNIO (2.20.2): - - CNIOAtomics (= 2.20.2) - - CNIODarwin (= 2.20.2) - - CNIOLinux (= 2.20.2) - - CNIOSHA1 (= 2.20.2) - - SwiftNIOConcurrencyHelpers (= 2.20.2) - - SwiftNIOConcurrencyHelpers (2.20.2): - - CNIOAtomics (= 2.20.2) - - SwiftNIOFoundationCompat (2.20.2): - - SwiftNIO (= 2.20.2) - - Yams (4.0.0) - -DEPENDENCIES: - - Stencil (from `https://github.com/stencilproject/Stencil.git`, branch `trim_whitespace`) - - SwiftFormat/CLI - - SwiftLint - - SwiftNIO - - SwiftNIOFoundationCompat - - Yams (from `https://github.com/tjprescott/Yams.git`, branch `CircularReferences`) - -SPEC REPOS: - trunk: - - CNIOAtomics - - CNIODarwin - - CNIOLinux - - CNIOSHA1 - - PathKit - - SwiftFormat - - SwiftLint - - SwiftNIO - - SwiftNIOConcurrencyHelpers - - SwiftNIOFoundationCompat - -EXTERNAL SOURCES: - Stencil: - :branch: trim_whitespace - :git: https://github.com/stencilproject/Stencil.git - Yams: - :branch: CircularReferences - :git: https://github.com/tjprescott/Yams.git - -CHECKOUT OPTIONS: - Stencil: - :commit: 8e327cf073ba3b8bf2d1b88f9ad2158b67567063 - :git: https://github.com/stencilproject/Stencil.git - Yams: - :commit: 9baf4735fbe4fa45050e0e8b0e03420f2f323f2d - :git: https://github.com/tjprescott/Yams.git - -SPEC CHECKSUMS: - CNIOAtomics: 7daf6423d00650104436c5f8a2a341679104ae83 - CNIODarwin: 65509d8e6a65a3f3f7bf5b09455cbabd535f48f3 - CNIOLinux: 380e2601f1f32f8f32a78437c5f4f5a688205e2b - CNIOSHA1: 5cc4fc5054beeb21c8e0017ad6bf559ce8095c10 - PathKit: 273f59a38e3218eb95abd9f6a61730a8bcfd2f06 - Stencil: ba3fc96199e0be13ba95c490d042532d784260dc - SwiftFormat: 3b5caa6389b2b9adbc00e133b3ccc8c6e687a6a4 - SwiftLint: 22ccbbe3b8008684be5955693bab135e0ed6a447 - SwiftNIO: a3c1b37da3e97ce44b3cfafc61c05fe0cac540b8 - SwiftNIOConcurrencyHelpers: cd7afc3d1f1ceaf55bbd030e7d1a469d3024db92 - SwiftNIOFoundationCompat: 573f44d5b24f7ead54b6b111264c0a420fc6eccf - Yams: 9d49b85824751ee13d31e9ec6617c4dfb9a8c3cd - -PODFILE CHECKSUM: b9d02b9d727aa8afdca85686ae509a2235ce05c6 - -COCOAPODS: 1.9.3 diff --git a/src/AutorestSwift/Code Generator/LanguageShortcut.swift b/src/AutorestSwift/Code Generator/LanguageShortcut.swift index 94fdd7dc..000c49fe 100644 --- a/src/AutorestSwift/Code Generator/LanguageShortcut.swift +++ b/src/AutorestSwift/Code Generator/LanguageShortcut.swift @@ -43,7 +43,12 @@ protocol LanguageShortcut { extension LanguageShortcut { var name: String { get { - return language.swift.name.trimmingCharacters(in: .whitespacesAndNewlines) + let name = language.swift.name.trimmingCharacters(in: .whitespacesAndNewlines) + // apply backticks to reserved keywords + if name.isReservedKeyword { + return "`\(name)`" + } + return name } set { language.swift.name = newValue @@ -108,7 +113,14 @@ protocol OptionalLanguageShortcut { extension OptionalLanguageShortcut { var name: String? { get { - return language?.swift.name.trimmingCharacters(in: .whitespacesAndNewlines) + if let name = language?.swift.name.trimmingCharacters(in: .whitespacesAndNewlines) { + // apply backticks to reserved keywords + if name.isReservedKeyword { + return "`\(name)`" + } + return name + } + return nil } set { if let val = newValue { diff --git a/src/AutorestSwift/Models/Complex/OperationGroup.swift b/src/AutorestSwift/Models/Complex/OperationGroup.swift index 49d8ceec..b8726c1e 100644 --- a/src/AutorestSwift/Models/Complex/OperationGroup.swift +++ b/src/AutorestSwift/Models/Complex/OperationGroup.swift @@ -38,7 +38,7 @@ class OperationGroup: Metadata { } var modelName: String { - return name.isReserved ? name + "Operation" : name + return name.isReservedType ? name + "Operation" : name } public required init(from decoder: Decoder) throws { diff --git a/src/AutorestSwift/Models/Complex/Schema.swift b/src/AutorestSwift/Models/Complex/Schema.swift index 052133a1..ab6ca8af 100644 --- a/src/AutorestSwift/Models/Complex/Schema.swift +++ b/src/AutorestSwift/Models/Complex/Schema.swift @@ -157,7 +157,7 @@ class Schema: Codable, LanguageShortcut { } var modelName: String { - return name.isReserved ? name + "Type" : name + return name.isReservedType ? name + "Type" : name } var bodyParamStrategy: BodyParamStrategy { diff --git a/src/AutorestSwift/Utils/ReservedKeywords.swift b/src/AutorestSwift/Utils/ReservedKeywords.swift new file mode 100644 index 00000000..61a0f4ec --- /dev/null +++ b/src/AutorestSwift/Utils/ReservedKeywords.swift @@ -0,0 +1,105 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import Foundation + +private let reservedTypes: Set = [ + "Error", + "Int", + "String", + "Bool", + "Enum", + "Array", + "Date", + "Self", + "Any" +] + +private let reservedKeywords: Set = [ + "associatedtype", + "class", + "deinit", + "enum", + "extension", + "fileprivate", + "func", + "import", + "init", + "inout", + "internal", + "let", + "open", + "operator", + "private", + "protocol", + "public", + "static", + "struct", + "subscript", + "typealias", + "var", + "break", + "case", + "continue", + "default", + "defer", + "do", + "else", + "fallthrough", + "for", + "guard", + "if", + "in", + "repeat", + "return", + "switch", + "where", + "while", + "as", + "catch", + "false", + "is", + "nil", + "rethrows", + "super", + "self", + "throw", + "throws", + "true", + "try" +] + +extension String { + /// Returns `true` if the string corresponds to a reserved type + var isReservedType: Bool { + return reservedTypes.contains(self) + } + + /// Returns `true` if the string corresponds to a reserved Swift keyword + var isReservedKeyword: Bool { + return reservedKeywords.contains(self) + } +} diff --git a/src/AutorestSwift/Utils/String+Extensions.swift b/src/AutorestSwift/Utils/String+Extensions.swift index 4321eb74..80460476 100644 --- a/src/AutorestSwift/Utils/String+Extensions.swift +++ b/src/AutorestSwift/Utils/String+Extensions.swift @@ -76,6 +76,7 @@ extension String { return components } + /// Returns the substring without any trailing or leading whitespace. func trimmed() -> Substring { guard let firstElementIndex = firstIndex(where: { !$0.isWhitespace }) else { return Substring("") @@ -85,20 +86,9 @@ extension String { return self[firstElementIndex ..< lastElementIndex.base] } + /// Returns the string with the first character lowercased. var lowercasedFirst: String { return prefix(1).lowercased() + dropFirst() } + /// Returns the string with the first character uppercased. var uppercasedFirst: String { return prefix(1).uppercased() + dropFirst() } - - var isReserved: Bool { - let reserved = [ - "Error", - "Int", - "String", - "Bool", - "Enum", - "Array", - "Date" - ] - return reserved.contains(self) - } }