Generator/Sources/NeedleFramework/Generating/DependencyProviderSerializerTask.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 processed dependency providers into /// exportable foramt. class DependencyProviderSerializerTask: AbstractTask<[SerializedProvider]> { /// Initializer. /// /// - parameter providers: The processed dependency provider to serialize. init(providers: [ProcessedDependencyProvider]) { self.providers = providers super.init(id: TaskIds.dependencyProviderSerializerTask.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<[ProcessedProperty], [ProcessedDependencyProvider]>() for provider in providers { let properties = provider.processedProperties counts[properties] = (counts[properties] ?? []) + [provider] } for matchingProviders in counts.values { result.append(contentsOf: serialize(matchingProviders)) } return result } // MARK: - Private private let providers: [ProcessedDependencyProvider] private func serialize(_ providers: [ProcessedDependencyProvider]) -> [SerializedProvider] { var result = [SerializedProvider]() let (classNameSerializer, content) = serializedClass(for: providers.first!) if providers.first?.isEmptyDependency == false { result.append(SerializedProvider(content: content, registration: "", attributes: ProviderAttributes())) } for provider in providers { let paramsSerializer = DependencyProviderParamsSerializer(provider: provider) let funcNameSerializer = DependencyProviderFuncNameSerializer(classNameSerializer: classNameSerializer, paramsSerializer: paramsSerializer) let content = serializedContent(for: provider, classNameSerializer: classNameSerializer, paramsSerializer: paramsSerializer, funcNameSerializer: funcNameSerializer) let registration = DependencyProviderRegistrationSerializer(provider: provider, factoryFuncNameSerializer: funcNameSerializer).serialize() let attributes = calculateAttributes(for: provider, funcNameSerializer: funcNameSerializer) result.append(SerializedProvider(content: content, registration: registration, attributes: attributes)) } return result } private func serializedContent(for provider: ProcessedDependencyProvider, classNameSerializer: Serializer, paramsSerializer: Serializer, funcNameSerializer: Serializer) -> String { if provider.isEmptyDependency { return "" } return DependencyProviderFuncSerializer(provider: provider, funcNameSerializer: funcNameSerializer, classNameSerializer: classNameSerializer, paramsSerializer: paramsSerializer).serialize() } private func serializedClass(for provider: ProcessedDependencyProvider) -> (Serializer, String) { let classNameSerializer = DependencyProviderClassNameSerializer(provider: provider) let propertiesSerializer = PropertiesSerializer(processedProperties: provider.processedProperties) let sourceComponentsSerializer = SourceComponentsSerializer(componentTypes: provider.levelMap.keys.sorted()) let initBodySerializer = DependencyProviderBaseInitSerializer(provider: provider) let serializer = DependencyProviderClassSerializer(provider: provider, 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 } }