Skip to content

Commit

Permalink
Merge pull request #93 from uber/foundation-merge_in_extension-master
Browse files Browse the repository at this point in the history
Merge NeedleFoundationExtension into NeedleFoundation
  • Loading branch information
neakor authored Jun 15, 2018
2 parents 0d890a8 + b5a47ab commit d78305e
Show file tree
Hide file tree
Showing 6 changed files with 505 additions and 97 deletions.
141 changes: 44 additions & 97 deletions Foundation/NeedleFoundation.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,12 @@
objectVersion = 46;
objects = {

/* Begin PBXAggregateTarget section */
"NeedleFoundation::NeedleFoundationPackageTests::ProductTarget" /* NeedleFoundationPackageTests */ = {
isa = PBXAggregateTarget;
buildConfigurationList = OBJ_36 /* Build configuration list for PBXAggregateTarget "NeedleFoundationPackageTests" */;
buildPhases = (
);
dependencies = (
OBJ_39 /* PBXTargetDependency */,
);
name = NeedleFoundationPackageTests;
productName = NeedleFoundationPackageTests;
};
/* End PBXAggregateTarget section */

/* Begin PBXBuildFile section */
41F0681520D45AD100FD67C7 /* PluginizedComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41F0681020D45AD100FD67C7 /* PluginizedComponent.swift */; };
41F0681620D45AD100FD67C7 /* PluginExtensionProviderRegistry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41F0681220D45AD100FD67C7 /* PluginExtensionProviderRegistry.swift */; };
41F0681720D45AD100FD67C7 /* NonCoreComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41F0681320D45AD100FD67C7 /* NonCoreComponent.swift */; };
41F0681820D45AD100FD67C7 /* PluginizedLifecycle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41F0681420D45AD100FD67C7 /* PluginizedLifecycle.swift */; };
41F0681B20D45B1300FD67C7 /* PluginizedComponentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41F0681A20D45B1300FD67C7 /* PluginizedComponentTests.swift */; };
OBJ_25 /* Bootstrap.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* Bootstrap.swift */; };
OBJ_26 /* Component.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_10 /* Component.swift */; };
OBJ_27 /* DependencyProviderRegistry.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* DependencyProviderRegistry.swift */; };
Expand All @@ -37,16 +28,14 @@
remoteGlobalIDString = "NeedleFoundation::NeedleFoundation";
remoteInfo = NeedleFoundation;
};
41B6EE0D20B766FF00BFF8F8 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = OBJ_1 /* Project object */;
proxyType = 1;
remoteGlobalIDString = "NeedleFoundation::NeedleFoundationTests";
remoteInfo = NeedleFoundationTests;
};
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
41F0681020D45AD100FD67C7 /* PluginizedComponent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PluginizedComponent.swift; sourceTree = "<group>"; };
41F0681220D45AD100FD67C7 /* PluginExtensionProviderRegistry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PluginExtensionProviderRegistry.swift; sourceTree = "<group>"; };
41F0681320D45AD100FD67C7 /* NonCoreComponent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NonCoreComponent.swift; sourceTree = "<group>"; };
41F0681420D45AD100FD67C7 /* PluginizedLifecycle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PluginizedLifecycle.swift; sourceTree = "<group>"; };
41F0681A20D45B1300FD67C7 /* PluginizedComponentTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PluginizedComponentTests.swift; sourceTree = "<group>"; };
"NeedleFoundation::NeedleFoundation::Product" /* NeedleFoundation.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = NeedleFoundation.framework; sourceTree = BUILT_PRODUCTS_DIR; };
"NeedleFoundation::NeedleFoundationTests::Product" /* NeedleFoundationTests.xctest */ = {isa = PBXFileReference; lastKnownFileType = file; path = NeedleFoundationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
OBJ_10 /* Component.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Component.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -75,6 +64,33 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
41F0680F20D45ABA00FD67C7 /* Pluginized */ = {
isa = PBXGroup;
children = (
41F0681120D45AD100FD67C7 /* Internal */,
41F0681320D45AD100FD67C7 /* NonCoreComponent.swift */,
41F0681020D45AD100FD67C7 /* PluginizedComponent.swift */,
41F0681420D45AD100FD67C7 /* PluginizedLifecycle.swift */,
);
path = Pluginized;
sourceTree = "<group>";
};
41F0681120D45AD100FD67C7 /* Internal */ = {
isa = PBXGroup;
children = (
41F0681220D45AD100FD67C7 /* PluginExtensionProviderRegistry.swift */,
);
path = Internal;
sourceTree = "<group>";
};
41F0681920D45B0300FD67C7 /* Pluginized */ = {
isa = PBXGroup;
children = (
41F0681A20D45B1300FD67C7 /* PluginizedComponentTests.swift */,
);
path = Pluginized;
sourceTree = "<group>";
};
OBJ_11 /* Internal */ = {
isa = PBXGroup;
children = (
Expand All @@ -94,6 +110,7 @@
OBJ_14 /* NeedleFoundationTests */ = {
isa = PBXGroup;
children = (
41F0681920D45B0300FD67C7 /* Pluginized */,
OBJ_15 /* ComponentTests.swift */,
OBJ_16 /* DependencyProviderRegistryTests.swift */,
);
Expand Down Expand Up @@ -130,6 +147,7 @@
OBJ_8 /* NeedleFoundation */ = {
isa = PBXGroup;
children = (
41F0680F20D45ABA00FD67C7 /* Pluginized */,
OBJ_9 /* Bootstrap.swift */,
OBJ_10 /* Component.swift */,
OBJ_11 /* Internal */,
Expand Down Expand Up @@ -174,20 +192,6 @@
productReference = "NeedleFoundation::NeedleFoundationTests::Product" /* NeedleFoundationTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
"NeedleFoundation::SwiftPMPackageDescription" /* NeedleFoundationPackageDescription */ = {
isa = PBXNativeTarget;
buildConfigurationList = OBJ_30 /* Build configuration list for PBXNativeTarget "NeedleFoundationPackageDescription" */;
buildPhases = (
OBJ_33 /* Sources */,
);
buildRules = (
);
dependencies = (
);
name = NeedleFoundationPackageDescription;
productName = NeedleFoundationPackageDescription;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
Expand All @@ -209,8 +213,6 @@
projectRoot = "";
targets = (
"NeedleFoundation::NeedleFoundation" /* NeedleFoundation */,
"NeedleFoundation::SwiftPMPackageDescription" /* NeedleFoundationPackageDescription */,
"NeedleFoundation::NeedleFoundationPackageTests::ProductTarget" /* NeedleFoundationPackageTests */,
"NeedleFoundation::NeedleFoundationTests" /* NeedleFoundationTests */,
);
};
Expand All @@ -221,36 +223,29 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 0;
files = (
41F0681620D45AD100FD67C7 /* PluginExtensionProviderRegistry.swift in Sources */,
OBJ_25 /* Bootstrap.swift in Sources */,
41F0681820D45AD100FD67C7 /* PluginizedLifecycle.swift in Sources */,
OBJ_26 /* Component.swift in Sources */,
41F0681520D45AD100FD67C7 /* PluginizedComponent.swift in Sources */,
41F0681720D45AD100FD67C7 /* NonCoreComponent.swift in Sources */,
OBJ_27 /* DependencyProviderRegistry.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
OBJ_33 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
OBJ_44 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 0;
files = (
OBJ_45 /* ComponentTests.swift in Sources */,
OBJ_46 /* DependencyProviderRegistryTests.swift in Sources */,
41F0681B20D45B1300FD67C7 /* PluginizedComponentTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */

/* Begin PBXTargetDependency section */
OBJ_39 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = "NeedleFoundation::NeedleFoundationTests" /* NeedleFoundationTests */;
targetProxy = 41B6EE0D20B766FF00BFF8F8 /* PBXContainerItemProxy */;
};
OBJ_49 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = "NeedleFoundation::NeedleFoundation" /* NeedleFoundation */;
Expand Down Expand Up @@ -328,36 +323,6 @@
};
name = Debug;
};
OBJ_31 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
LD = /usr/bin/true;
OTHER_SWIFT_FLAGS = "-swift-version 4 -I $(TOOLCHAIN_DIR)/usr/lib/swift/pm/4 -target x86_64-apple-macosx10.10 -sdk /Applications/Xcode.9.3.0.9E145.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk";
SWIFT_VERSION = 4.0;
};
name = Debug;
};
OBJ_32 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
LD = /usr/bin/true;
OTHER_SWIFT_FLAGS = "-swift-version 4 -I $(TOOLCHAIN_DIR)/usr/lib/swift/pm/4 -target x86_64-apple-macosx10.10 -sdk /Applications/Xcode.9.3.0.9E145.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk";
SWIFT_VERSION = 4.0;
};
name = Release;
};
OBJ_37 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Debug;
};
OBJ_38 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Release;
};
OBJ_4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
Expand Down Expand Up @@ -438,24 +403,6 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
OBJ_30 /* Build configuration list for PBXNativeTarget "NeedleFoundationPackageDescription" */ = {
isa = XCConfigurationList;
buildConfigurations = (
OBJ_31 /* Debug */,
OBJ_32 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
OBJ_36 /* Build configuration list for PBXAggregateTarget "NeedleFoundationPackageTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
OBJ_37 /* Debug */,
OBJ_38 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
OBJ_41 /* Build configuration list for PBXNativeTarget "NeedleFoundationTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//
// 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 COITIONS OF ANY KI, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Foundation

/// Needle internal registry of plugin extension providers.
/// - note: This class is only needed until Swift supports extensions
/// overriding methods. This is an internal class to the Needle dependency
/// injection framework. Application code should never use this class.
// TODO: Remove this once Swift supports extension overriding methods.
// Once that happens, we can declare an `open createPluginExtensionProvider`
// method in the base pluginized component class. Generate extensions to
// all the pluginized component subclasses that override the method to
// instantiate the dependnecy providers.
public class __PluginExtensionProviderRegistry {

/// The singleton instance.
public static let instance = __PluginExtensionProviderRegistry()

/// Register the given factory closure with given key.
///
/// - note: This method is thread-safe.
/// - parameter componentPath: The dependency graph path of the component
/// the provider is for.
/// - parameter pluginExtensionProviderFactory: The closure that takes in
/// a component to be injected and returns a provider instance that conforms
/// to the component's plugin extensions protocol.
public func registerPluginExtensionProviderFactory(`for` componentPath: String, _ pluginExtensionProviderFactory: @escaping (PluginizedComponentType) -> AnyObject) {
// Lock on `providerFactories` access.
lock.lock()
defer {
lock.unlock()
}

providerFactories[componentPath.hashValue] = pluginExtensionProviderFactory
}

func pluginExtensionProvider(`for` component: PluginizedComponentType) -> AnyObject {
// Lock on `providerFactories` access.
lock.lock()
defer {
lock.unlock()
}

if let factory = providerFactories[component.path.hashValue] {
return factory(component)
} else {
fatalError("Missing plugin extension provider factory for \(component.path)")
}
}

private let lock = NSRecursiveLock()
private var providerFactories = [Int: (PluginizedComponentType) -> AnyObject]()

private init() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// 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 Foundation

/// The base protocol for a non-core component defining its lifecycle to
/// support scope activation and deactivation.
///
/// - note: A separate protocol is used to allow `PluginizableComponent`
/// to delcare a non-core component generic without having to specify the
/// dependency protocol nested generics.
public protocol NonCoreComponentType: AnyObject {
/// Initializer.
///
/// - parameter parent: The parent component of this component.
init(parent: ComponentType)

/// Indicate the corresponding core scope has become active, thereby
/// activating this non-core component as well.
///
/// - note: This method is automatically invoked when the non-core component
/// is paired with a `PluginizableComponent` that is bound to a `Router`.
/// Otherwise, this method must be explicitly invoked.
func scopeDidBecomeActive()

/// Indicate the corresponding core scope has become inactive, thereby
/// deactivating this non-core component as well.
///
/// - note: This method is automatically invoked when the non-core component
/// is paired with a `PluginizableComponent` that is bound to a `Router`.
/// Otherwise, this method must be explicitly invoked.
func scopeDidBecomeInactive()
}

/// The base non-core component class. All non-core components should inherit
/// from this class.
open class NonCoreComponent<DependencyType>: Component<DependencyType>, NonCoreComponentType {

/// Initializer.
///
/// - parameter parent: The parent component of this component.
public required override init(parent: ComponentType) {
super.init(parent: parent)
}

/// Indicate the corresponding core scope has become active, thereby
/// activating this non-core component as well.
///
/// - note: This method is automatically invoked when the non-core component
/// is paired with a `PluginizableComponent` that is bound to a `Router`.
/// Otherwise, this method must be explicitly invoked.
open func scopeDidBecomeActive() {}

/// Indicate the corresponding core scope has become inactive, thereby
/// deactivating this non-core component as well.
///
/// - note: This method is automatically invoked when the non-core component
/// is paired with a `PluginizableComponent` that is bound to a `Router`.
/// Otherwise, this method must be explicitly invoked.
open func scopeDidBecomeInactive() {}
}
Loading

0 comments on commit d78305e

Please sign in to comment.