Generator/Sources/NeedleFramework/Generating/Pluginized/PluginizedDependencyProviderSerializerTask.swift (69 lines of code) (raw):

// // Copyright (c) 2018. Uber Technologies // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // import Concurrency import Foundation import TSCBasic /// The task that serializes a list of pluginized processed dependency /// providers into exportable foramt. class PluginizedDependencyProviderSerializerTask: AbstractTask<[SerializedProvider]> { /// Initializer. /// /// - parameter providers: The pluginized processed dependency provider /// to serialize. init(providers: [PluginizedProcessedDependencyProvider]) { self.providers = providers super.init(id: TaskIds.pluginizedDependencyProviderSerializerTask.rawValue) } /// Execute the task and returns the in-memory serialized dependency /// provider data models. /// /// - returns: The list of `SerializedProvider`. override func execute() -> [SerializedProvider] { var result = [SerializedProvider]() // Group the providers based on where the properties are coming from // This will allow us to extract common code for multiple depndency providers // into common base classes var counts = OrderedDictionary<[PluginizedProcessedProperty], [PluginizedProcessedDependencyProvider]>() for provider in providers { let properties = provider.processedProperties counts[properties] = (counts[properties] ?? []) + [provider] } for (baseCount, (_, matchingProviders)) in counts.enumerated() { result.append(contentsOf: serialize(matchingProviders, baseCounter: baseCount)) } return result } // MARK: - Private private let providers: [PluginizedProcessedDependencyProvider] private func serialize(_ providers: [PluginizedProcessedDependencyProvider], baseCounter: Int) -> [SerializedProvider] { var result = [SerializedProvider]() let (classNameSerializer, content) = serializedClass(for: providers.first!, counter: baseCounter) if providers.first?.data.isEmptyDependency == false { result.append(SerializedProvider(content: content, registration: "", attributes: ProviderAttributes())) } for (_, provider) in providers.enumerated() { let paramsSerializer = DependencyProviderParamsSerializer(provider: provider.data) let funcNameSerializer = DependencyProviderFuncNameSerializer(classNameSerializer: classNameSerializer, paramsSerializer: paramsSerializer) let content = serializedContent(for: provider, classNameSerializer: classNameSerializer, paramsSerializer: paramsSerializer, funcNameSerializer: funcNameSerializer) let registration = DependencyProviderRegistrationSerializer(provider: provider.data, factoryFuncNameSerializer: funcNameSerializer).serialize() let attributes = calculateAttributes(for: provider.data, funcNameSerializer: funcNameSerializer) result.append(SerializedProvider(content: content, registration: registration, attributes: attributes)) } return result } private func serializedContent(for provider: PluginizedProcessedDependencyProvider, classNameSerializer: Serializer, paramsSerializer: Serializer, funcNameSerializer: Serializer) -> String { if provider.data.isEmptyDependency { return "" } return DependencyProviderFuncSerializer(provider: provider.data, funcNameSerializer: funcNameSerializer, classNameSerializer: classNameSerializer, paramsSerializer: paramsSerializer).serialize() } private func serializedClass(for provider: PluginizedProcessedDependencyProvider, counter: Int) -> (Serializer, String) { let classNameSerializer = DependencyProviderClassNameSerializer(provider: provider.data) let propertiesSerializer = PluginizedPropertiesSerializer(provider: provider) let sourceComponentsSerializer = SourceComponentsSerializer(componentTypes: provider.data.levelMap.keys.sorted()) let initBodySerializer = DependencyProviderBaseInitSerializer(provider: provider.data) let serializer = DependencyProviderClassSerializer(provider: provider.data, classNameSerializer: classNameSerializer, propertiesSerializer: propertiesSerializer, sourceComponentsSerializer: sourceComponentsSerializer, initBodySerializer: initBodySerializer) return (classNameSerializer, serializer.serialize()) } private func calculateAttributes(for provider: ProcessedDependencyProvider, funcNameSerializer: Serializer) -> ProviderAttributes { if provider.isEmptyDependency { return ProviderAttributes() } var maxLevel: Int = 0 for (_, level) in provider.levelMap { if level > maxLevel { maxLevel = level } } var attributes = ProviderAttributes() if maxLevel > 0 { attributes.maxLevel = maxLevel } attributes.factoryName = funcNameSerializer.serialize() return attributes } }