From 8119873d459fd1870ed85c497ebf70c05660bf94 Mon Sep 17 00:00:00 2001 From: Rahul Malik Date: Thu, 27 Apr 2017 10:14:20 -0700 Subject: [PATCH] Add lang attribute to provide future flexibility for additional languages in Plank --- Sources/Core/FileGenerator.swift | 73 ++++++++++++++++------ Sources/Core/ObjectiveCFileGenerator.swift | 4 ++ Sources/plank/Cli.swift | 15 ++++- 3 files changed, 72 insertions(+), 20 deletions(-) diff --git a/Sources/Core/FileGenerator.swift b/Sources/Core/FileGenerator.swift index 301cec53..1fef5e11 100644 --- a/Sources/Core/FileGenerator.swift +++ b/Sources/Core/FileGenerator.swift @@ -19,11 +19,16 @@ public enum GenerationParameterType { case includeRuntime } -protocol FileGeneratorManager { +public enum Languages: String { + case objectiveC = "objc" +} + +public protocol FileGeneratorManager { static func filesToGenerate(descriptor: SchemaObjectRoot, generatorParameters: GenerationParameters) -> [FileGenerator] + static func runtimeFiles() -> [FileGenerator] } -protocol FileGenerator { +public protocol FileGenerator { func renderFile() -> String var fileName: String { mutating get } } @@ -54,23 +59,48 @@ extension FileGenerator { return header.joined(separator: "\n") } - } -func generateFile(_ schema: SchemaObjectRoot, outputDirectory: URL, generationParameters: GenerationParameters) { - for var file in ObjectiveCFileGenerator.filesToGenerate(descriptor: schema, generatorParameters: generationParameters) { - let fileContents = file.renderFile() + "\n" // Ensure there is exactly one new line a the end of the file - do { - try fileContents.write( - to: URL(string: file.fileName, relativeTo: outputDirectory)!, - atomically: true, - encoding: String.Encoding.utf8) - } catch { - assert(false) +extension FileGeneratorManager { + func generateFile(_ schema: SchemaObjectRoot, outputDirectory: URL, generationParameters: GenerationParameters) { + for var file in Self.filesToGenerate(descriptor: schema, generatorParameters: generationParameters) { + let fileContents = file.renderFile() + "\n" // Ensure there is exactly one new line a the end of the file + do { + try fileContents.write( + to: URL(string: file.fileName, relativeTo: outputDirectory)!, + atomically: true, + encoding: String.Encoding.utf8) + } catch { + assert(false) + } + } + } + + public func generateFileRuntime(outputDirectory: URL) { + let files: [FileGenerator] = Self.runtimeFiles() + for var file in files { + let fileContents = file.renderFile() + "\n" // Ensure there is exactly one new line a the end of the file + do { + try fileContents.write( + to: URL(string: file.fileName, relativeTo: outputDirectory)!, + atomically: true, + encoding: String.Encoding.utf8) + } catch { + assert(false) + } } } } + + +func generator(forLanguage language: Languages) -> FileGeneratorManager { + switch language { + case .objectiveC: + return ObjectiveCFileGenerator() + } +} + public func generateFileRuntime(outputDirectory: URL) { let files: [FileGenerator] = [ObjCRuntimeHeaderFile(), ObjCRuntimeImplementationFile()] for var file in files { @@ -100,7 +130,8 @@ public func generateDeps(urls: Set) { } } -public func generateFiles(urls: Set, outputDirectory: URL, generationParameters: GenerationParameters) { +public func generateFiles(urls: Set, outputDirectory: URL, generationParameters: GenerationParameters, forLanguages languages: [Languages]) { + let fileGenerators: [FileGeneratorManager] = languages.map(generator) _ = loadSchemasForUrls(urls: urls) var processedSchemas = Set([]) repeat { @@ -111,17 +142,21 @@ public func generateFiles(urls: Set, outputDirectory: URL, generationParame processedSchemas.insert(url) switch schema { case .object(let rootObject): - generateFile(rootObject, - outputDirectory: outputDirectory, - generationParameters: generationParameters) + fileGenerators.forEach { generator in + generator.generateFile(rootObject, + outputDirectory: outputDirectory, + generationParameters: generationParameters) + } default: - assert(false, "Incorrect Schema for root") // TODO Better error message. + assert(false, "Incorrect Schema for root.") // TODO Better error message. } }) } while ( generationParameters[.recursive] != nil && processedSchemas.count != FileSchemaLoader.sharedInstance.refs.keys.count) if generationParameters[.includeRuntime] != nil { - generateFileRuntime(outputDirectory: outputDirectory) + fileGenerators.forEach { + $0.generateFileRuntime(outputDirectory: outputDirectory) + } } } diff --git a/Sources/Core/ObjectiveCFileGenerator.swift b/Sources/Core/ObjectiveCFileGenerator.swift index 89e7a70c..f4c2392c 100644 --- a/Sources/Core/ObjectiveCFileGenerator.swift +++ b/Sources/Core/ObjectiveCFileGenerator.swift @@ -20,6 +20,10 @@ struct ObjectiveCFileGenerator: FileGeneratorManager { ObjCImplementationFile(roots: rootsRenderer.renderRoots(), className: rootsRenderer.className) ] } + + static func runtimeFiles() -> [FileGenerator] { + return [ObjCRuntimeHeaderFile(), ObjCRuntimeImplementationFile()] + } } struct ObjCHeaderFile: FileGenerator { diff --git a/Sources/plank/Cli.swift b/Sources/plank/Cli.swift index 325133ff..32639419 100644 --- a/Sources/plank/Cli.swift +++ b/Sources/plank/Cli.swift @@ -19,6 +19,7 @@ enum FlagOptions: String { case printDeps = "print_deps" case noRecursive = "no_recursive" case onlyRuntime = "only_runtime" + case lang = "lang" case help = "help" func needsArgument() -> Bool { @@ -28,6 +29,7 @@ enum FlagOptions: String { case .printDeps: return false case .noRecursive: return false case .onlyRuntime: return false + case .lang: return true case .help: return false } } @@ -41,6 +43,7 @@ extension FlagOptions : HelpCommandOutput { " --\(FlagOptions.printDeps.rawValue) - Just print the path to the dependent schemas necessary to generate the schemas provided and exit.", " --\(FlagOptions.noRecursive.rawValue) - Don't generate files recursively. Only generate the one file I ask for.", " --\(FlagOptions.onlyRuntime.rawValue) - Only generate runtime files and exit.", + " --\(FlagOptions.lang.rawValue) - Comma separated list of target language(s) for generating code. Default: \"objc\"", " --\(FlagOptions.help.rawValue) - Show this text and exit." ].joined(separator: "\n") } @@ -165,9 +168,19 @@ func handleGenerateCommand(withArguments arguments: [String]) { } else if flags[.onlyRuntime] != nil { generateFileRuntime(outputDirectory: outputDirectory) } else { + let languages: [Languages] = flags[.lang]?.trimmingCharacters(in: .whitespaces).components(separatedBy: ",").flatMap { + guard let lang = Languages.init(rawValue: $0) else { + fatalError("Invalid or unsupported language: \($0)") + } + return lang + } ?? [.objectiveC] + guard languages.count > 0 else { + fatalError("Unsupported value for lang: \"\(String(describing:flags[.lang]))\"") + } generateFiles(urls: Set(urls), outputDirectory: outputDirectory, - generationParameters: generationParameters) + generationParameters: generationParameters, + forLanguages: languages) } }