├── Sources
└── Cleanse
├── Tests
└── CleanseTests
├── Documentation
├── README.rst
├── .gitignore
├── Components.png
├── cleanse_logo.png
├── ChangeToolchain.png
├── cleanse_logo_small.png
├── under-construction.gif
├── index.rst
└── Binding Grammar.rst
├── .coveralls.yml
├── cleansec
├── .gitignore
├── Sandbox
│ ├── Sandbox
│ │ ├── Assets.xcassets
│ │ │ └── Contents.json
│ │ ├── ViewController.swift
│ │ ├── AppComponent.swift
│ │ ├── AppDelegate.swift
│ │ └── Base.lproj
│ │ │ ├── Main.storyboard
│ │ │ └── LaunchScreen.storyboard
│ └── Sandbox.xcodeproj
│ │ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── swiftpm
│ │ └── Package.resolved
├── script
│ ├── Fixtures.template
│ ├── create-fixtures.rb
│ └── swiftc-ast.rb
├── cleansec.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── swiftpm
│ │ └── Package.resolved
├── cleansec.xcodeproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── CleansecFramework
│ ├── main.swift
│ ├── Linking
│ │ ├── LinkedInterface.swift
│ │ ├── LinkedModule.swift
│ │ └── LinkedComponent.swift
│ ├── Visitors
│ │ ├── Representations
│ │ │ ├── DebugData.swift
│ │ │ └── ProviderModels.swift
│ │ └── Provider Visitor
│ │ │ ├── ComponentRootVisitor.swift
│ │ │ └── APITypes.swift
│ ├── CleansecFramework.h
│ ├── Info.plist
│ └── Resolver
│ │ ├── LinkedMerging.swift
│ │ └── ResolvedComponent.swift
├── Cleansec-Generate-Fixtures
│ ├── Code Fixtures
│ │ ├── DoesNotImportCleanse.swift
│ │ ├── ImportsCleanse.swift
│ │ ├── NestedModule.swift
│ │ ├── ModuleWithImplicitType.swift
│ │ ├── ModuleIncludesModule.swift
│ │ ├── ModuleWithImplicitInitFactory.swift
│ │ ├── PropertyInjection.swift
│ │ ├── SimpleRootComponent.swift
│ │ ├── GenericType.swift
│ │ ├── BasicBindings.swift
│ │ ├── ModuleWithTaggedProvider.swift
│ │ ├── TaggedProviderDependency.swift
│ │ ├── ComponentWithSeed.swift
│ │ ├── AssistedInjection.swift
│ │ ├── InnerTag.swift
│ │ ├── ManyDependencies.swift
│ │ ├── CustomScopeBinding.swift
│ │ ├── ModuleIncludesSubcomponent.swift
│ │ ├── ModuleWithDependencies.swift
│ │ ├── PropertyInjectorRoot.swift
│ │ ├── SimpleComponent.swift
│ │ └── CollectionBindings.swift
│ ├── Cleansec_Generate_Fixtures.h
│ └── Info.plist
├── SwiftAstParser
│ ├── Syntax.swift
│ ├── Parsing
│ │ ├── DataStringMapper.swift
│ │ ├── SyntaxParser.swift
│ │ └── ASTStringHelpers.swift
│ ├── Nodes
│ │ ├── TypedSyntax.swift
│ │ └── InheritableSyntax.swift
│ ├── SwiftAstParser.h
│ ├── script
│ │ ├── Nodes.template
│ │ └── SyntaxVisitor.template
│ ├── Info.plist
│ └── README.md
├── cleansec
│ └── PluginRunner.swift
├── Makefile
├── SwiftAstParserTests
│ ├── Info.plist
│ └── SwiftAstParserTests.swift
└── CleansecFrameworkTests
│ ├── Info.plist
│ ├── LinkerTests.swift
│ └── PluginTests.swift
├── arities-autogen.sh
├── Gemfile
├── Examples
├── CleanseGithubBrowser
│ ├── CleanseGithubBrowser
│ │ ├── Assets.xcassets
│ │ │ ├── Contents.json
│ │ │ ├── TabBarIcons
│ │ │ │ ├── Contents.json
│ │ │ │ ├── Members.imageset
│ │ │ │ │ ├── icon_member.pdf
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── Settings.imageset
│ │ │ │ │ ├── icon_settings.pdf
│ │ │ │ │ └── Contents.json
│ │ │ │ └── Repositories.imageset
│ │ │ │ │ ├── icon_repository.pdf
│ │ │ │ │ └── Contents.json
│ │ │ └── AppIcon.appiconset
│ │ │ │ ├── app-icon-ipad.png
│ │ │ │ ├── cleanse_logo.png
│ │ │ │ ├── app-icon-ipad@2x.png
│ │ │ │ ├── app-icon-iphone@2x.png
│ │ │ │ ├── app-icon-iphone@3x.png
│ │ │ │ ├── app-icon-spotlight.png
│ │ │ │ ├── app-icon-setting@2x-1.png
│ │ │ │ ├── app-icon-setting@2x-2.png
│ │ │ │ ├── app-icon-setting@3x-1.png
│ │ │ │ ├── app-icon-spotlight@2x-1.png
│ │ │ │ ├── app-icon-spotlight@2x.png
│ │ │ │ └── app-icon-spotlight@3x.png
│ │ ├── SingletonScope.swift
│ │ ├── HTTPError.swift
│ │ ├── FoundationCommonModule.swift
│ │ ├── TableViewController.swift
│ │ ├── SplitViewController.swift
│ │ ├── NetworkModule.swift
│ │ ├── GithubMemberService.swift
│ │ ├── GithubRepositoriesService.swift
│ │ ├── Info.plist
│ │ ├── GithubServicesModule.swift
│ │ ├── Base.lproj
│ │ │ └── LaunchScreen.storyboard
│ │ ├── NSURLSessionAdditions.swift
│ │ └── UIKitCommonModule.swift
│ ├── CleanseGithubBrowser.xcodeproj
│ │ └── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── CleanseGithubBrowserTests
│ │ ├── Info.plist
│ │ └── CleanseGithubBrowserTests.swift
│ └── CleanseGithubBrowserUITests
│ │ └── Info.plist
├── CleanseSwiftUIExample
│ ├── CleanseSwiftUIExample
│ │ ├── SupportingFiles
│ │ │ ├── Assets.xcassets
│ │ │ │ ├── Contents.json
│ │ │ │ ├── me.imageset
│ │ │ │ │ ├── me.png
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── cat-solid.imageset
│ │ │ │ │ ├── cat-solid.png
│ │ │ │ │ ├── cat-solid@2x.png
│ │ │ │ │ ├── cat-solid@3x.png
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── dog-solid.imageset
│ │ │ │ │ ├── dog-solid.png
│ │ │ │ │ ├── dog-solid@2x.png
│ │ │ │ │ ├── dog-solid@3x.png
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── paw-solid.imageset
│ │ │ │ │ ├── paw-solid.png
│ │ │ │ │ ├── paw-solid@2x.png
│ │ │ │ │ ├── paw-solid@3x.png
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── otter-solid.imageset
│ │ │ │ │ ├── otter-solid.png
│ │ │ │ │ ├── otter-solid@2x.png
│ │ │ │ │ ├── otter-solid@3x.png
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── illustration-cat.imageset
│ │ │ │ │ ├── illustration-cat.png
│ │ │ │ │ ├── illustration-cat@2x.png
│ │ │ │ │ ├── illustration-cat@3x.png
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── illustration-dog.imageset
│ │ │ │ │ ├── illustration-dog.png
│ │ │ │ │ ├── illustration-dog@2x.png
│ │ │ │ │ ├── illustration-dog@3x.png
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── on-primary.colorset
│ │ │ │ │ └── Contents.json
│ │ │ │ └── primary.colorset
│ │ │ │ │ └── Contents.json
│ │ │ └── Info.plist
│ │ ├── Preview Content
│ │ │ └── Preview Assets.xcassets
│ │ │ │ ├── Contents.json
│ │ │ │ ├── me.imageset
│ │ │ │ ├── me.png
│ │ │ │ └── Contents.json
│ │ │ │ ├── cat-solid.imageset
│ │ │ │ ├── cat-solid.png
│ │ │ │ ├── cat-solid@2x.png
│ │ │ │ ├── cat-solid@3x.png
│ │ │ │ └── Contents.json
│ │ │ │ ├── dog-solid.imageset
│ │ │ │ ├── dog-solid.png
│ │ │ │ ├── dog-solid@2x.png
│ │ │ │ ├── dog-solid@3x.png
│ │ │ │ └── Contents.json
│ │ │ │ ├── paw-solid.imageset
│ │ │ │ ├── paw-solid.png
│ │ │ │ ├── paw-solid@2x.png
│ │ │ │ ├── paw-solid@3x.png
│ │ │ │ └── Contents.json
│ │ │ │ ├── otter-solid.imageset
│ │ │ │ ├── otter-solid.png
│ │ │ │ ├── otter-solid@2x.png
│ │ │ │ ├── otter-solid@3x.png
│ │ │ │ └── Contents.json
│ │ │ │ ├── illustration-cat.imageset
│ │ │ │ ├── illustration-cat.png
│ │ │ │ ├── illustration-cat@2x.png
│ │ │ │ ├── illustration-cat@3x.png
│ │ │ │ └── Contents.json
│ │ │ │ ├── illustration-dog.imageset
│ │ │ │ ├── illustration-dog.png
│ │ │ │ ├── illustration-dog@2x.png
│ │ │ │ ├── illustration-dog@3x.png
│ │ │ │ └── Contents.json
│ │ │ │ ├── primary.colorset
│ │ │ │ └── Contents.json
│ │ │ │ └── on-primary.colorset
│ │ │ │ └── Contents.json
│ │ ├── Resources
│ │ │ ├── cat-peep.jpg
│ │ │ ├── cat-pine.jpg
│ │ │ ├── cat-unit.jpg
│ │ │ ├── dog-link.jpg
│ │ │ ├── cat-crawler.jpg
│ │ │ ├── cat-payton.jpg
│ │ │ ├── cat-rumble.jpg
│ │ │ ├── cat-wiley.jpg
│ │ │ ├── dog-squeek.jpg
│ │ │ └── chameleon-isaac.jpg
│ │ ├── Models
│ │ │ ├── UserData.swift
│ │ │ ├── User.swift
│ │ │ ├── Data.swift
│ │ │ ├── Pet.swift
│ │ │ └── ImageStore.swift
│ │ ├── Views
│ │ │ ├── Components
│ │ │ │ ├── LikeButton.swift
│ │ │ │ ├── PetBadge.swift
│ │ │ │ ├── PetHeader.swift
│ │ │ │ ├── ProgressBar.swift
│ │ │ │ ├── PetSize.swift
│ │ │ │ └── PetRow.swift
│ │ │ └── Screens
│ │ │ │ └── HomeView.swift
│ │ ├── DI
│ │ │ └── AppComponent.swift
│ │ └── App
│ │ │ └── AdoptmeApp.swift
│ └── CleanseSwiftUIExample.xcodeproj
│ │ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── swiftpm
│ │ └── Package.resolved
└── Examples.xcworkspace
│ ├── xcshareddata
│ └── IDEWorkspaceChecks.plist
│ └── contents.xcworkspacedata
├── .slather.yml
├── Cleanse.xcodeproj
└── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ └── IDEWorkspaceChecks.plist
├── CleansePlayground.playground
├── playground.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── CleansePlayground.xcscmblueprint
├── Pages
│ └── Index.xcplaygroundpage
│ │ └── Contents.swift
└── contents.xcplayground
├── Cleanse
├── Component.swift
├── ScopedModule.swift
├── BindingReceipt.swift
├── Lock.swift
├── AssistedFactory.swift
├── Finalizable.swift
├── Assisted.swift
├── ScopedBindingBuilder.swift
├── AssistedInjectionSeedDecorator.swift
├── Factory.swift
├── Cleanse.h
├── BindToable.swift
├── ComponentBinding.swift
├── AnyBinder.swift
├── CombinedHashable.swift
├── ScopedBindingDecorator.swift
├── LegacyKey.swift
├── DelegatedHashable.swift
├── TaggedBindingBuilderDecorator.swift
├── BaseBindingBuilder.swift
├── Installer.swift
├── TypeKeyProtocol.swift
├── CleanseServiceLoader.swift
├── RawProviderBinding.swift
├── SourceLocation.swift
├── ComponentBase.swift
├── Module.swift
├── Info.plist
├── Binder.swift
├── Scope.swift
├── CleanseErrorReporter.swift
├── CleanseBindingPlugin.swift
├── RootComponent.swift
├── AssistedInjectionBuilder.swift
├── AssistedInjection.swift
├── WeakProvider.swift
├── WrappedBinder.swift
├── TaggedProvider.swift
├── ScopedProvider.swift
├── PropertyInjectionReceiptBinder.swift
├── ProviderProvider.swift
├── CollectionBindingBuilderDecorator.swift
├── ReceiptBinder.swift
├── SingularCollectionBindingBuilderDecorator.swift
├── ScopedBinder.swift
├── PropertyInjector.swift
├── ComponentFactory.swift
└── BindingBuilderDecorator.swift
├── Cleanse.xcworkspace
├── xcshareddata
│ └── IDEWorkspaceChecks.plist
└── contents.xcworkspacedata
├── CleanseTests
├── ObjectGraphTests.swift
├── ScopeTests.swift
├── NoopVisitor.swift
├── Info.plist
├── TaggedProviderTests.swift
├── SPITests.swift
├── DebuggingTests.swift
└── SubcomponentTests.swift
├── Package.swift
├── Cleanse.podspec
├── CleanseGen
├── CleanseGen.h
└── Info.plist
├── LICENSE
├── Makefile
├── .gitignore
├── .github
└── workflows
│ └── main.yml
└── CHANGELOG.md
/Sources/Cleanse:
--------------------------------------------------------------------------------
1 | ../Cleanse
--------------------------------------------------------------------------------
/Tests/CleanseTests:
--------------------------------------------------------------------------------
1 | ../CleanseTests
--------------------------------------------------------------------------------
/Documentation/README.rst:
--------------------------------------------------------------------------------
1 | ../README.rst
--------------------------------------------------------------------------------
/Documentation/.gitignore:
--------------------------------------------------------------------------------
1 | _build/
2 | .*
3 |
--------------------------------------------------------------------------------
/.coveralls.yml:
--------------------------------------------------------------------------------
1 | service_name: travis-ci
2 |
3 |
--------------------------------------------------------------------------------
/cleansec/.gitignore:
--------------------------------------------------------------------------------
1 | *.ast
2 | *.xcarchive
3 | *.zip
4 | build/
5 | bin/
6 |
--------------------------------------------------------------------------------
/arities-autogen.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | swift CleanseGen/main.swift
4 |
--------------------------------------------------------------------------------
/Documentation/Components.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Documentation/Components.png
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem 'cocoapods', '~> 1.8'
4 | gem 'cocoapods-generate'
5 |
--------------------------------------------------------------------------------
/Documentation/cleanse_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Documentation/cleanse_logo.png
--------------------------------------------------------------------------------
/Documentation/ChangeToolchain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Documentation/ChangeToolchain.png
--------------------------------------------------------------------------------
/Documentation/cleanse_logo_small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Documentation/cleanse_logo_small.png
--------------------------------------------------------------------------------
/Documentation/under-construction.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Documentation/under-construction.gif
--------------------------------------------------------------------------------
/cleansec/Sandbox/Sandbox/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/.slather.yml:
--------------------------------------------------------------------------------
1 | coverage_service: coveralls
2 | xcodeproj: Cleanse.xcodeproj
3 | scheme: Cleanse
4 | ignore:
5 | - Cleanse/PropertyInjectionArities.swift
6 | - Cleanse/BinderArities.swift
7 |
8 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Resources/cat-peep.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Resources/cat-peep.jpg
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Resources/cat-pine.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Resources/cat-pine.jpg
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Resources/cat-unit.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Resources/cat-unit.jpg
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Resources/dog-link.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Resources/dog-link.jpg
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Resources/cat-crawler.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Resources/cat-crawler.jpg
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Resources/cat-payton.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Resources/cat-payton.jpg
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Resources/cat-rumble.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Resources/cat-rumble.jpg
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Resources/cat-wiley.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Resources/cat-wiley.jpg
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Resources/dog-squeek.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Resources/dog-squeek.jpg
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Resources/chameleon-isaac.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Resources/chameleon-isaac.jpg
--------------------------------------------------------------------------------
/cleansec/script/Fixtures.template:
--------------------------------------------------------------------------------
1 | // This file is generated! DO NOT EDIT!
2 |
3 | struct Fixtures {
4 | <% for @f in @fixtures %>
5 | static let <%= @f.var_name %> = """
6 | <%= @f.contents %>
7 | """
8 | <% end %>
9 | }
--------------------------------------------------------------------------------
/Cleanse.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CleansePlayground.playground/playground.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/TabBarIcons/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | },
6 | "properties" : {
7 | "provides-namespace" : true
8 | }
9 | }
--------------------------------------------------------------------------------
/cleansec/Sandbox/Sandbox.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/cleansec/cleansec.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/cleansec/cleansec.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-ipad.png
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/cleanse_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/cleanse_logo.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/me.imageset/me.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/me.imageset/me.png
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-ipad@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-ipad@2x.png
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-iphone@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-iphone@2x.png
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-iphone@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-iphone@3x.png
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-spotlight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-spotlight.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-setting@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-setting@2x-1.png
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-setting@2x-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-setting@2x-2.png
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-setting@3x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-setting@3x-1.png
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-spotlight@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-spotlight@2x-1.png
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-spotlight@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-spotlight@2x.png
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-spotlight@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/AppIcon.appiconset/app-icon-spotlight@3x.png
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/TabBarIcons/Members.imageset/icon_member.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/TabBarIcons/Members.imageset/icon_member.pdf
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/me.imageset/me.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/me.imageset/me.png
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/TabBarIcons/Settings.imageset/icon_settings.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/TabBarIcons/Settings.imageset/icon_settings.pdf
--------------------------------------------------------------------------------
/cleansec/CleansecFramework/main.swift:
--------------------------------------------------------------------------------
1 | //
2 | // main.swift
3 | // cleansec
4 | //
5 | // Created by Sebastian Edward Shanus on 5/6/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | print("Hello, World!")
12 |
13 |
--------------------------------------------------------------------------------
/CleansePlayground.playground/Pages/Index.xcplaygroundpage/Contents.swift:
--------------------------------------------------------------------------------
1 | //: # Cleanse - Swift Dependency Injection
2 |
3 | /*:
4 | ## Index:
5 |
6 | 1. [CoffeeMaker Example](CoffeeMakerExample)
7 | 1. [GitHub Client Example](GithubClientExample)
8 |
9 | */
10 |
11 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/cat-solid.imageset/cat-solid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/cat-solid.imageset/cat-solid.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/dog-solid.imageset/dog-solid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/dog-solid.imageset/dog-solid.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/paw-solid.imageset/paw-solid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/paw-solid.imageset/paw-solid.png
--------------------------------------------------------------------------------
/Cleanse/Component.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Component.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 7/6/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | public protocol Component : ComponentBase {
13 | }
14 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/TabBarIcons/Repositories.imageset/icon_repository.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/TabBarIcons/Repositories.imageset/icon_repository.pdf
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/cat-solid.imageset/cat-solid@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/cat-solid.imageset/cat-solid@2x.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/cat-solid.imageset/cat-solid@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/cat-solid.imageset/cat-solid@3x.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/dog-solid.imageset/dog-solid@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/dog-solid.imageset/dog-solid@2x.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/dog-solid.imageset/dog-solid@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/dog-solid.imageset/dog-solid@3x.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/paw-solid.imageset/paw-solid@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/paw-solid.imageset/paw-solid@2x.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/paw-solid.imageset/paw-solid@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/paw-solid.imageset/paw-solid@3x.png
--------------------------------------------------------------------------------
/Cleanse/ScopedModule.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ScopedModule.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 3/14/17.
6 | // Copyright © 2017 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | public protocol ScopedModule : Module {
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/otter-solid.imageset/otter-solid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/otter-solid.imageset/otter-solid.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/cat-solid.imageset/cat-solid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/cat-solid.imageset/cat-solid.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/dog-solid.imageset/dog-solid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/dog-solid.imageset/dog-solid.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/paw-solid.imageset/paw-solid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/paw-solid.imageset/paw-solid.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/otter-solid.imageset/otter-solid@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/otter-solid.imageset/otter-solid@2x.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/otter-solid.imageset/otter-solid@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/otter-solid.imageset/otter-solid@3x.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/cat-solid.imageset/cat-solid@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/cat-solid.imageset/cat-solid@2x.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/cat-solid.imageset/cat-solid@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/cat-solid.imageset/cat-solid@3x.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/dog-solid.imageset/dog-solid@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/dog-solid.imageset/dog-solid@2x.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/dog-solid.imageset/dog-solid@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/dog-solid.imageset/dog-solid@3x.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/paw-solid.imageset/paw-solid@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/paw-solid.imageset/paw-solid@2x.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/paw-solid.imageset/paw-solid@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/paw-solid.imageset/paw-solid@3x.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/otter-solid.imageset/otter-solid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/otter-solid.imageset/otter-solid.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/otter-solid.imageset/otter-solid@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/otter-solid.imageset/otter-solid@2x.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/otter-solid.imageset/otter-solid@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/otter-solid.imageset/otter-solid@3x.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/illustration-cat.imageset/illustration-cat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/illustration-cat.imageset/illustration-cat.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/illustration-dog.imageset/illustration-dog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/illustration-dog.imageset/illustration-dog.png
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Code Fixtures/DoesNotImportCleanse.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DoesNotImportCleanse.swift
3 | // cleansec-generate-fixtures
4 | //
5 | // Created by Sebastian Edward Shanus on 5/1/20.
6 | // Copyright © 2020 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/illustration-cat.imageset/illustration-cat@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/illustration-cat.imageset/illustration-cat@2x.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/illustration-cat.imageset/illustration-cat@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/illustration-cat.imageset/illustration-cat@3x.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/illustration-dog.imageset/illustration-dog@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/illustration-dog.imageset/illustration-dog@2x.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/illustration-dog.imageset/illustration-dog@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/illustration-dog.imageset/illustration-dog@3x.png
--------------------------------------------------------------------------------
/Cleanse.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/TabBarIcons/Members.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "icon_member.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/TabBarIcons/Settings.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "icon_settings.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Code Fixtures/ImportsCleanse.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ImportsCleanse.swift
3 | // cleansec-generate-fixtures
4 | //
5 | // Created by Sebastian Edward Shanus on 5/1/20.
6 | // Copyright © 2020 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
--------------------------------------------------------------------------------
/Cleanse.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/illustration-cat.imageset/illustration-cat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/illustration-cat.imageset/illustration-cat.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/illustration-dog.imageset/illustration-dog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/illustration-dog.imageset/illustration-dog.png
--------------------------------------------------------------------------------
/CleanseTests/ObjectGraphTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ObjectGraphTests.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 4/26/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | import Cleanse
12 |
13 | class ObjectGraphTests : XCTestCase {
14 |
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Assets.xcassets/TabBarIcons/Repositories.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "icon_repository.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/illustration-cat.imageset/illustration-cat@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/illustration-cat.imageset/illustration-cat@2x.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/illustration-cat.imageset/illustration-cat@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/illustration-cat.imageset/illustration-cat@3x.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/illustration-dog.imageset/illustration-dog@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/illustration-dog.imageset/illustration-dog@2x.png
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/illustration-dog.imageset/illustration-dog@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/square/Cleanse/master/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/illustration-dog.imageset/illustration-dog@3x.png
--------------------------------------------------------------------------------
/Examples/Examples.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/cleansec/cleansec.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Cleanse.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Examples/Examples.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/cleansec/cleansec.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/CleanseTests/ScopeTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ScopeTests.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 4/28/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 | import XCTest
9 |
10 | @testable import Cleanse
11 |
12 | class ScopeTests: XCTestCase {
13 |
14 | func testScopes() {
15 | }
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/cleansec/Sandbox/Sandbox.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Cleanse/BindingReceipt.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BindingReceipt.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 1/6/17.
6 | // Copyright © 2017 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | /// This is used to fulfill contracts that a binding has occured
13 | public struct BindingReceipt {
14 | }
15 |
--------------------------------------------------------------------------------
/CleansePlayground.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/SingletonScope.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SingletonScope.swift
3 | // CleanseGithubBrowser
4 | //
5 | // Created by holmes on 6/28/17.
6 | // Copyright © 2017 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | public typealias SingletonBinder = Binder
13 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.1
2 |
3 | import PackageDescription
4 |
5 | let package = Package(
6 | name: "Cleanse",
7 | products: [
8 | .library(name: "Cleanse", targets: ["Cleanse"]),
9 | ],
10 | dependencies: [],
11 | targets: [
12 | .target(name: "Cleanse", dependencies: [], path: "Cleanse"),
13 | ]
14 | )
15 |
16 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/cleansec/SwiftAstParser/Syntax.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | /// Represents a raw syntax element in a source file.
4 | public protocol Syntax {
5 | var raw: String { get }
6 | var children: [Syntax] { get }
7 | }
8 |
9 | public extension SyntaxVisitor {
10 | mutating func walkChildren(_ node: Syntax) {
11 | node.children.forEach { walk($0) }
12 | }
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/CleanseTests/NoopVisitor.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NoopVisitor.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 5/3/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | import XCTest
12 |
13 | @testable import Cleanse
14 |
15 | final class NoopVisitor : SimpleComponentVisitor {
16 | var visitorState = VisitorState()
17 | }
18 |
--------------------------------------------------------------------------------
/cleansec/SwiftAstParser/Parsing/DataStringMapper.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | extension Data {
4 | func mapToLines(seperator: UInt8) -> [String] {
5 | return withUnsafeBytes { bytes in
6 | return bytes
7 | .split(separator: seperator)
8 | .map { String(decoding: UnsafeRawBufferPointer(rebasing: $0), as: UTF8.self) }
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Cleanse/Lock.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Lock.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 4/25/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | extension NSLock {
13 | func with(_ closure: () throws -> Element) rethrows -> Element {
14 | lock()
15 | defer { unlock() }
16 |
17 | return try closure()
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Cleanse/AssistedFactory.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AssistedFactory.swift
3 | // Cleanse
4 | //
5 | // Created by Sebastian Edward Shanus on 9/5/19.
6 | // Copyright © 2019 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public protocol AssistedFactory: Tag {
12 | associatedtype Seed
13 | }
14 |
15 | public struct EmptySeed : AssistedFactory {
16 | public typealias Seed = Void
17 | public typealias Element = E
18 | }
19 |
--------------------------------------------------------------------------------
/Cleanse/Finalizable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Finalizable.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 7/6/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | protocol Finalizable {
10 | func finalize() throws
11 | }
12 |
13 | struct AnonymousFinalizable : Finalizable {
14 | let finalizeFunc: () throws -> Void
15 |
16 | func finalize() throws {
17 | try self.finalizeFunc()
18 | }
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/cleansec/Sandbox/Sandbox/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // Sandbox
4 | //
5 | // Created by Sebastian Edward Shanus on 5/13/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 | // Do any additional setup after loading the view.
16 | }
17 |
18 |
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Code Fixtures/NestedModule.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NestedModule.swift
3 | // cleasecTests
4 | //
5 | // Created by Sebastian Edward Shanus on 5/1/20.
6 | // Copyright © 2020 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | struct Blah {
13 | struct Module: Cleanse.Module {
14 | static func configure(binder: Binder) {
15 |
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/cleansec/cleansec.xcworkspace/xcshareddata/swiftpm/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "object": {
3 | "pins": [
4 | {
5 | "package": "swift-argument-parser",
6 | "repositoryURL": "https://github.com/apple/swift-argument-parser",
7 | "state": {
8 | "branch": null,
9 | "revision": "9f04d1ff1afbccd02279338a2c91e5f27c45e93a",
10 | "version": "0.0.5"
11 | }
12 | }
13 | ]
14 | },
15 | "version": 1
16 | }
17 |
--------------------------------------------------------------------------------
/cleansec/cleansec/PluginRunner.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PluginRunner.swift
3 | // cleansec
4 | //
5 | // Created by Sebastian Edward Shanus on 5/21/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import CleansecFramework
11 |
12 | struct PluginRunner {
13 | static func run(plugin path: String, astFiles: [String]) -> [ModuleRepresentation] {
14 | astFiles.compactMap { Cleansec.run(plugin: path, astFilePath: $0) }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/cleansec/CleansecFramework/Linking/LinkedInterface.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LinkedInterface.swift
3 | // CleansecFramework
4 | //
5 | // Created by Sebastian Edward Shanus on 5/12/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /// Representation of all components and modules with their providers linked.
12 | public struct LinkedInterface {
13 | public let components: [LinkedComponent]
14 | public let modules: [LinkedModule]
15 | }
16 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/me.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "me.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/cleansec/Sandbox/Sandbox.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "object": {
3 | "pins": [
4 | {
5 | "package": "swift-argument-parser",
6 | "repositoryURL": "https://github.com/apple/swift-argument-parser",
7 | "state": {
8 | "branch": null,
9 | "revision": "9f04d1ff1afbccd02279338a2c91e5f27c45e93a",
10 | "version": "0.0.5"
11 | }
12 | }
13 | ]
14 | },
15 | "version": 1
16 | }
17 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "object": {
3 | "pins": [
4 | {
5 | "package": "Cleanse",
6 | "repositoryURL": "https://github.com/square/Cleanse.git",
7 | "state": {
8 | "branch": null,
9 | "revision": "c854787f83d99527587b5387f04ccd0030e6133a",
10 | "version": "4.2.6"
11 | }
12 | }
13 | ]
14 | },
15 | "version": 1
16 | }
17 |
--------------------------------------------------------------------------------
/Cleanse.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'Cleanse'
3 | s.version = '4.2.6'
4 | s.license = 'Apache License, Version 2.0'
5 | s.summary = 'Lightweight Swift Dependency Injection Framework'
6 | s.homepage = 'https://github.com/square/Cleanse'
7 | s.authors = 'Square'
8 | s.source = { :git => 'https://github.com/square/Cleanse.git', :tag => s.version }
9 | s.source_files = 'Cleanse/*.swift'
10 | s.ios.deployment_target = '8.3'
11 | s.swift_versions = ['4.2', '5.0']
12 | end
13 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/me.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "me.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/on-primary.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "color" : {
5 | "color-space" : "srgb",
6 | "components" : {
7 | "alpha" : "1.000",
8 | "blue" : "0.380",
9 | "green" : "0.580",
10 | "red" : "0.965"
11 | }
12 | },
13 | "idiom" : "universal"
14 | }
15 | ],
16 | "info" : {
17 | "author" : "xcode",
18 | "version" : 1
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/primary.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "color" : {
5 | "color-space" : "srgb",
6 | "components" : {
7 | "alpha" : "1.000",
8 | "blue" : "0.882",
9 | "green" : "0.886",
10 | "red" : "0.988"
11 | }
12 | },
13 | "idiom" : "universal"
14 | }
15 | ],
16 | "info" : {
17 | "author" : "xcode",
18 | "version" : 1
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/primary.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "color" : {
5 | "color-space" : "srgb",
6 | "components" : {
7 | "alpha" : "1.000",
8 | "blue" : "0.882",
9 | "green" : "0.886",
10 | "red" : "0.988"
11 | }
12 | },
13 | "idiom" : "universal"
14 | }
15 | ],
16 | "info" : {
17 | "author" : "xcode",
18 | "version" : 1
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/cleansec/Makefile:
--------------------------------------------------------------------------------
1 |
2 | WORKSPACE=cleansec.xcworkspace
3 | XCODEBUILD_WORKSPACE=xcodebuild -workspace $(WORKSPACE)
4 |
5 | clean:
6 | rm -fr bin
7 | $(XCODEBUILD_WORKSPACE) -scheme cleansec clean
8 |
9 | build:
10 | $(XCODEBUILD_WORKSPACE) -scheme cleansec build
11 |
12 | release: clean
13 | mkdir bin
14 | $(XCODEBUILD_WORKSPACE) -scheme cleansec archive -archivePath bin/cleansec
15 | zip -j bin/cleansec bin/cleansec.xcarchive/Products/usr/local/bin/cleansec script/swiftc-ast.rb
16 | rm -fr bin/cleansec.xcarchive
17 |
18 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/on-primary.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "color" : {
5 | "color-space" : "srgb",
6 | "components" : {
7 | "alpha" : "1.000",
8 | "blue" : "0.380",
9 | "green" : "0.580",
10 | "red" : "0.965"
11 | }
12 | },
13 | "idiom" : "universal"
14 | }
15 | ],
16 | "info" : {
17 | "author" : "xcode",
18 | "version" : 1
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Cleanse/Assisted.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Assisted.swift
3 | // Cleanse
4 | //
5 | // Created by Sebastian Edward Shanus on 9/5/19.
6 | // Copyright © 2019 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct Assisted : ProviderProtocol {
12 | public typealias Element = E
13 |
14 | let getter: () -> Element
15 | public init(getter: @escaping () -> E) {
16 | self.getter = getter
17 | }
18 |
19 | public func get() -> E {
20 | return getter()
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Code Fixtures/ModuleWithImplicitType.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ModuleWithImplicitType.swift
3 | // cleansec-generate-fixtures
4 | //
5 | // Created by Sebastian Edward Shanus on 5/1/20.
6 | // Copyright © 2020 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | struct CoreAppModule7 : Cleanse.Module {
13 | static func configure(binder: Binder) {
14 | binder
15 | .bind()
16 | .to(factory: A.init)
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Cleanse/ScopedBindingBuilder.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ScopedBindingBuilder.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 3/14/17.
6 | // Copyright © 2017 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension BindingBuilder where Binder: BinderType, MaybeScope == Unscoped, Binder.Scope: Scope {
12 | // Declares binding as scoped. Also known as singletons in some contexts
13 | public func sharedInScope() -> ScopedBindingDecorator {
14 | return self.with()
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Cleanse/AssistedInjectionSeedDecorator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AssistedInjectionSeedDecorator.swift
3 | // Cleanse
4 | //
5 | // Created by Sebastian Edward Shanus on 9/5/19.
6 | // Copyright © 2019 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct AssistedInjectionSeedDecorator : AssistedInjectionBuilder {
12 | public typealias Binder = Binder
13 | public typealias Element = S.Element
14 | public typealias Tag = S
15 |
16 | public let binder: Binder
17 | }
18 |
--------------------------------------------------------------------------------
/Cleanse/Factory.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Factory.swift
3 | // Cleanse
4 | //
5 | // Created by Sebastian Edward Shanus on 9/5/19.
6 | // Copyright © 2019 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct Factory {
12 | let factory: (Tag.Seed) -> Tag.Element
13 | public init(factory: @escaping (Tag.Seed) -> Tag.Element) {
14 | self.factory = factory
15 | }
16 |
17 | public func build(_ seed: Tag.Seed) -> Tag.Element {
18 | return factory(seed)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/cleansec/CleansecFramework/Visitors/Representations/DebugData.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DebugData.swift
3 | // CleansecFramework
4 | //
5 | // Created by Sebastian Edward Shanus on 5/26/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct DebugData: Equatable, Codable {
12 | public let location: String?
13 |
14 | public static var empty = DebugData(location: nil)
15 |
16 | public static func location(_ loc: String) -> DebugData {
17 | DebugData(location: loc)
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/cleansec/CleansecFramework/Linking/LinkedModule.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LinkedModule.swift
3 | // CleansecFramework
4 | //
5 | // Created by Sebastian Edward Shanus on 5/12/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /// `Cleanse.Module` representation with all standard providers and linked reference providers.
12 | public struct LinkedModule {
13 | public let type: String
14 | public let providers: [StandardProvider]
15 | public let includedModules: [String]
16 | public let subcomponents: [String]
17 | }
18 |
--------------------------------------------------------------------------------
/Cleanse/Cleanse.h:
--------------------------------------------------------------------------------
1 | //
2 | // Cleanse.h
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 4/22/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for Cleanse.
12 | FOUNDATION_EXPORT double CleanseVersionNumber;
13 |
14 | //! Project version string for Cleanse.
15 | FOUNDATION_EXPORT const unsigned char CleanseVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/HTTPError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HTTPError.swift
3 | // CleanseGithubBrowser
4 | //
5 | // Created by Mike Lewis on 6/12/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | struct HTTPError : Error {
13 | let statusCode: Int
14 |
15 | /// - returns: nil if status code isn't an error code
16 | init?(statusCode: Int) {
17 | guard 400..<600 ~= statusCode else {
18 | return nil
19 | }
20 |
21 | self.statusCode = statusCode
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Documentation/index.rst:
--------------------------------------------------------------------------------
1 | .. Cleanse documentation master file, created by
2 | sphinx-quickstart on Fri Jun 10 12:46:56 2016.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Welcome to Cleanse's documentation!
7 | ===================================
8 |
9 | Contents:
10 |
11 | .. toctree::
12 | :maxdepth: 2
13 |
14 | The README
15 | Binding Grammar
16 |
17 |
18 | Indices and tables
19 | ==================
20 |
21 | * :ref:`genindex`
22 | * :ref:`modindex`
23 | * :ref:`search`
24 |
25 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/paw-solid.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "paw-solid.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "paw-solid@2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "filename" : "paw-solid@3x.png",
15 | "idiom" : "universal",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "author" : "xcode",
21 | "version" : 1
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/CleanseGen/CleanseGen.h:
--------------------------------------------------------------------------------
1 | //
2 | // CleanseGen.h
3 | // CleanseGen
4 | //
5 | // Created by holmes on 6/28/17.
6 | // Copyright © 2017 Square, Inc. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for CleanseGen.
12 | FOUNDATION_EXPORT double CleanseGenVersionNumber;
13 |
14 | //! Project version string for CleanseGen.
15 | FOUNDATION_EXPORT const unsigned char CleanseGenVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/paw-solid.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "paw-solid.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "paw-solid@2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "filename" : "paw-solid@3x.png",
15 | "idiom" : "universal",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "author" : "xcode",
21 | "version" : 1
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Code Fixtures/ModuleIncludesModule.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ModuleIncludesModule.swift
3 | // cleasecTests
4 | //
5 | // Created by Sebastian Edward Shanus on 5/1/20.
6 | // Copyright © 2020 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | struct AnotherModule: Cleanse.Module {
13 | static func configure(binder: Binder) {}
14 | }
15 |
16 | struct CoreAppModule5 : Cleanse.Module {
17 | static func configure(binder: Binder) {
18 | binder.include(module: AnotherModule.self)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Cleanse/BindToable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BindToable.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 1/6/17.
6 | // Copyright © 2017 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public protocol BindToable {
12 | associatedtype Input
13 | associatedtype Binder : BinderBase
14 |
15 | func _innerTo(
16 | file: StaticString,
17 | line: Int,
18 | function: StaticString,
19 | provider: Provider) -> BindingReceipt
20 |
21 | var _finalProviderType: Any.Type { get }
22 |
23 | var binder: Binder { get }
24 | }
25 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/FoundationCommonModule.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FoundationCommonModule.swift
3 | // CleanseGithubBrowser
4 | //
5 | // Created by Mike Lewis on 6/12/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | /// Module that configures common bindings from the `Foundation` framework
13 | struct FoundationCommonModule : Module {
14 | static func configure(binder: SingletonBinder) {
15 | binder
16 | .bind(ProcessInfo.self)
17 | .to { ProcessInfo.processInfo }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Code Fixtures/ModuleWithImplicitInitFactory.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ModuleWithImplicitInitFactory.swift
3 | // cleasecTests
4 | //
5 | // Created by Sebastian Edward Shanus on 5/1/20.
6 | // Copyright © 2020 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | struct A {
13 | let string: String
14 | let number: Int
15 | }
16 |
17 | struct CoreAppModule3 : Cleanse.Module {
18 | static func configure(binder: Binder) {
19 | binder
20 | .bind(A.self)
21 | .to(factory: A.init)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/illustration-cat.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "illustration-cat.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "illustration-cat@2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "filename" : "illustration-cat@3x.png",
15 | "idiom" : "universal",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "author" : "xcode",
21 | "version" : 1
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/illustration-dog.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "illustration-dog.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "illustration-dog@2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "filename" : "illustration-dog@3x.png",
15 | "idiom" : "universal",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "author" : "xcode",
21 | "version" : 1
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/cleansec/CleansecFramework/CleansecFramework.h:
--------------------------------------------------------------------------------
1 | //
2 | // Cleansec.h
3 | // Cleansec
4 | //
5 | // Created by Sebastian Edward Shanus on 5/11/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for Cleansec.
12 | FOUNDATION_EXPORT double CleansecVersionNumber;
13 |
14 | //! Project version string for Cleansec.
15 | FOUNDATION_EXPORT const unsigned char CleansecVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Cleanse/ComponentBinding.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ComponentBinding.swift
3 | // Cleanse
4 | //
5 | // Created by Sebastian Edward Shanus on 10/11/19.
6 | // Copyright © 2019 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /// Describes the object graph for a component node.
12 | public protocol ComponentBinding {
13 | var scope: Scope.Type? { get }
14 | var seed: Any.Type { get }
15 | var parent: ComponentBinding? { get }
16 | var subcomponents: [ComponentBinding] { get }
17 | var componentType: Any.Type? { get }
18 |
19 | var providers: [ProviderKey: [ProviderInfo]] { get }
20 | }
21 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/illustration-cat.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "illustration-cat.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "illustration-cat@2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "filename" : "illustration-cat@3x.png",
15 | "idiom" : "universal",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "author" : "xcode",
21 | "version" : 1
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/illustration-dog.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "illustration-dog.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "illustration-dog@2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "filename" : "illustration-dog@3x.png",
15 | "idiom" : "universal",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "author" : "xcode",
21 | "version" : 1
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Code Fixtures/PropertyInjection.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PropertyInjection.swift
3 | // cleansec-generate-fixtures
4 | //
5 | // Created by Sebastian Edward Shanus on 5/1/20.
6 | // Copyright © 2020 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | class PropertyClass {
13 | }
14 |
15 | struct PropertyInjectionModule: Module {
16 | static func configure(binder: Binder) {
17 | binder
18 | .bindPropertyInjectionOf(PropertyClass.self)
19 | .to { (a: PropertyClass, number: Int) in
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Code Fixtures/SimpleRootComponent.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SimpleRootComponent.swift
3 | // cleansec-generate-fixtures
4 | //
5 | // Created by Sebastian Edward Shanus on 5/1/20.
6 | // Copyright © 2020 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | struct MyRootComponent2: Cleanse.RootComponent {
13 | static func configure(binder: Binder) {
14 |
15 | }
16 | static func configureRoot(binder bind: ReceiptBinder) -> BindingReceipt {
17 | return bind.to(value: 3)
18 | }
19 | typealias Root = Int
20 | }
21 |
--------------------------------------------------------------------------------
/Cleanse/AnyBinder.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AnyBinder.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 1/6/17.
6 | // Copyright © 2017 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /// Type erased binder
12 | public struct AnyBinder : BinderBase, WrappedBinder {
13 | public let binder: BinderBase
14 |
15 | public init(binder: BinderBase) {
16 | // Optimization to reduce nesting of wrapped binders
17 | if let binder = binder as? WrappedBinder {
18 | self.binder = binder.binder
19 | } else {
20 | self.binder = binder
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/cleansec/SwiftAstParser/Nodes/TypedSyntax.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TypedSyntax.swift
3 | // SwiftAstParser
4 | //
5 | // Created by Sebastian Edward Shanus on 5/12/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public protocol TypedSyntax: Syntax {
12 | var type: String { get }
13 | }
14 |
15 | extension TypedSyntax {
16 | public var type: String {
17 | raw.trimmedLeadingWhitespace.firstCapture(#"(? {
13 | let dependencyA: A
14 | }
15 |
16 | fileprivate struct GenericTypeModule: Module {
17 | static func configure(binder: Binder) {
18 | binder
19 | .bind(GenericType.self)
20 | .to(factory: GenericType.init)
21 | }
22 |
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/cleansec/CleansecFramework/Linking/LinkedComponent.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LinkedComponent.swift
3 | // CleansecFramework
4 | //
5 | // Created by Sebastian Edward Shanus on 5/12/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /// `Cleanse.Component` representation with all linked providers.
12 | public struct LinkedComponent {
13 | public let type: String
14 | public let rootType: String
15 | public let providers: [StandardProvider]
16 | public let seed: String
17 | public let includedModules: [String]
18 | public let subcomponents: [String]
19 | public let isRoot: Bool
20 | }
21 |
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Code Fixtures/BasicBindings.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BasicBindings.swift
3 | // Cleansec-Generate-Fixtures
4 | //
5 | // Created by Sebastian Edward Shanus on 7/8/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | fileprivate struct BasicBindingsModule: Cleanse.Module {
13 | static func configure(binder: Binder) {
14 | binder
15 | .bind(Int.self)
16 | .to { (floatFactory: () -> Float, boolFactory: @escaping () -> Bool, float2Factory:()->Float) in
17 | return 3
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/cleansec/SwiftAstParser/SwiftAstParser.h:
--------------------------------------------------------------------------------
1 | //
2 | // SwiftAstParser.h
3 | // SwiftAstParser
4 | //
5 | // Created by Sebastian Edward Shanus on 5/7/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for SwiftAstParser.
12 | FOUNDATION_EXPORT double SwiftAstParserVersionNumber;
13 |
14 | //! Project version string for SwiftAstParser.
15 | FOUNDATION_EXPORT const unsigned char SwiftAstParserVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Cleanse/CombinedHashable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CombinedHashable.swift
3 | // Appointments
4 | //
5 | // Created by Mike Lewis on 2/2/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | /// Combines two hashable values. Useful for paths of hashable values
13 | struct CombinedHashable : Hashable {
14 | let l: L
15 | let r: R
16 |
17 | init(_ l: L, _ r: R) {
18 | self.l = l
19 | self.r = r
20 | }
21 | }
22 |
23 | func == (lhs: CombinedHashable, rhs: CombinedHashable) -> Bool {
24 | return lhs.l == rhs.l && lhs.r == rhs.r
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/cat-solid.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "cat-solid.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "cat-solid@2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "filename" : "cat-solid@3x.png",
15 | "idiom" : "universal",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "author" : "xcode",
21 | "version" : 1
22 | },
23 | "properties" : {
24 | "template-rendering-intent" : "original"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/dog-solid.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "dog-solid.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "dog-solid@2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "filename" : "dog-solid@3x.png",
15 | "idiom" : "universal",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "author" : "xcode",
21 | "version" : 1
22 | },
23 | "properties" : {
24 | "template-rendering-intent" : "original"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Code Fixtures/ModuleWithTaggedProvider.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ModuleWithTaggedProvider.swift
3 | // cleasecTests
4 | //
5 | // Created by Sebastian Edward Shanus on 5/1/20.
6 | // Copyright © 2020 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 |
13 | struct MyTag: Tag {
14 | typealias Element = A
15 | }
16 |
17 | struct CoreAppModule4 : Cleanse.Module {
18 | static func configure(binder: Binder) {
19 | binder
20 | .bind(A.self)
21 | .tagged(with: MyTag.self)
22 | .sharedInScope()
23 | .to(factory: A.init)
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Models/UserData.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UserData.swift
3 | // Exam1
4 | //
5 | // Created by Abdul Chathil on 6/7/20.
6 | // Copyright © 2020 Abdul Chathil. All rights reserved.
7 | //
8 |
9 | import Combine
10 | import SwiftUI
11 | import Cleanse
12 |
13 | final class UserData: ObservableObject {
14 | @Published var showMineOnly = false
15 | @Published var pets = petData
16 | }
17 |
18 | extension UserData {
19 | struct Module: Cleanse.Module {
20 | static func configure(binder: Binder) {
21 | binder.bind(UserData.self).to(factory: UserData.init)
22 | }
23 | }
24 | }
25 |
26 |
27 |
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Code Fixtures/TaggedProviderDependency.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TaggedProviderDependency.swift
3 | // cleansec-generate-fixtures
4 | //
5 | // Created by Sebastian Edward Shanus on 5/1/20.
6 | // Copyright © 2020 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | struct MyTag2: Tag {
13 | typealias Element = Int
14 | }
15 |
16 | struct TaggedDependency {
17 | let provider: TaggedProvider
18 | }
19 | struct TaggedDepModule: Module {
20 | static func configure(binder: Binder) {
21 | binder.bind(TaggedDependency.self).to(factory: TaggedDependency.init)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/cat-solid.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "cat-solid.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "cat-solid@2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "filename" : "cat-solid@3x.png",
15 | "idiom" : "universal",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "author" : "xcode",
21 | "version" : 1
22 | },
23 | "properties" : {
24 | "template-rendering-intent" : "original"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/dog-solid.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "dog-solid.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "dog-solid@2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "filename" : "dog-solid@3x.png",
15 | "idiom" : "universal",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "author" : "xcode",
21 | "version" : 1
22 | },
23 | "properties" : {
24 | "template-rendering-intent" : "original"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Assets.xcassets/otter-solid.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "otter-solid.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "otter-solid@2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "filename" : "otter-solid@3x.png",
15 | "idiom" : "universal",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "author" : "xcode",
21 | "version" : 1
22 | },
23 | "properties" : {
24 | "template-rendering-intent" : "original"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Preview Content/Preview Assets.xcassets/otter-solid.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "otter-solid.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "otter-solid@2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "filename" : "otter-solid@3x.png",
15 | "idiom" : "universal",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "author" : "xcode",
21 | "version" : 1
22 | },
23 | "properties" : {
24 | "template-rendering-intent" : "original"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Views/Components/LikeButton.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LikeButton.swift
3 | // Exam1
4 | //
5 | // Created by Abdul Chathil on 6/8/20.
6 | // Copyright © 2020 Abdul Chathil. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct LikeButton: View {
12 | let isLiked: Bool
13 | var body: some View {
14 | Image(systemName: isLiked ? "heart.fill" : "heart").resizable().scaledToFill().frame(width: 24, height: 24, alignment: .center).foregroundColor(.red)
15 | }
16 | }
17 |
18 | struct LikeButton_Previews: PreviewProvider {
19 | static var previews: some View {
20 | LikeButton(isLiked: true)
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/cleansec/SwiftAstParser/Nodes/InheritableSyntax.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InheritableSyntax.swift
3 | // SwiftAstParser
4 | //
5 | // Created by Sebastian Edward Shanus on 5/12/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /// Syntax node types that can have an inherited type.
12 | public protocol InheritableSyntax: Syntax {
13 | var inherits: String? { get }
14 | }
15 |
16 | extension InheritableSyntax {
17 | public var inherits: String? {
18 | raw.trimmedLeadingWhitespace.firstCapture(#"inherits:\s*(\w+)"#)
19 | }
20 | }
21 |
22 | extension ClassDecl: InheritableSyntax {}
23 | extension StructDecl: InheritableSyntax {}
24 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/TableViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TableViewController.swift
3 | // CleanseGithubBrowser
4 | //
5 | // Created by Mike Lewis on 6/12/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | /// Common base class for UITableViewController that has better default constructors
13 | class TableViewController : UITableViewController {
14 | init() {
15 | super.init(nibName: nil, bundle: nil)
16 | }
17 |
18 | @available(*, unavailable)
19 | required init?(coder aDecoder: NSCoder) {
20 | fatalError("init(coder:) has not been implemented")
21 | }
22 | }
--------------------------------------------------------------------------------
/Cleanse/ScopedBindingDecorator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ScopedBindingDecorator.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 5/6/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /// Internal type used for binding. We decorate a provider with this to indicate if we're scoped or not
12 | public struct ScopedBindingDecorator : BindingBuilderDecorator {
13 | public typealias MaybeScope = S
14 |
15 | public typealias FinalProvider = Wrapped.FinalProvider
16 |
17 | public let wrapped: Wrapped
18 |
19 | public init(wrapped: Wrapped) {
20 | self.wrapped = wrapped
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Cleanse/LegacyKey.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LegacyKey.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 4/27/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | #if SUPPORT_LEGACY_OBJECT_GRAPH
12 |
13 | /// Similar to how we keyed stuff inside LegacyObjectGraph
14 | struct LegacyKey : Hashable, DelegatedHashable {
15 | var cls: Any.Type
16 | var name: String?
17 |
18 | var hashable: CombinedHashable {
19 | return CombinedHashable(.init(cls), name ?? "NIL")
20 | }
21 | }
22 |
23 | func ==(lhs: LegacyKey, rhs: LegacyKey) -> Bool {
24 | return lhs.cls == rhs.cls && lhs.name == rhs.name
25 | }
26 |
27 | #endif
--------------------------------------------------------------------------------
/Cleanse/DelegatedHashable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DelegatedHashable.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 4/22/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /// Easy way to make a hashable object. Delegates it to a hashable property.
12 | public protocol DelegatedHashable : Hashable {
13 | associatedtype H: Hashable
14 | var hashable: H { get }
15 | }
16 |
17 | extension DelegatedHashable {
18 | public func hash(into hasher: inout Hasher) {
19 | hasher.combine(hashable)
20 | }
21 | }
22 |
23 | public func ==(lhs: DH, rhs: DH) -> Bool {
24 | return lhs.hashable == rhs.hashable
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Code Fixtures/ComponentWithSeed.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ComponentWithSeed.swift
3 | // Cleansec-Generate-Fixtures
4 | //
5 | // Created by Sebastian Edward Shanus on 7/9/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | fileprivate struct MySeed {}
13 |
14 | fileprivate struct SeededComponent: Cleanse.Component {
15 | typealias Root = Int
16 | typealias Seed = MySeed
17 |
18 | static func configure(binder: Binder) {
19 |
20 | }
21 |
22 | static func configureRoot(binder bind: ReceiptBinder) -> BindingReceipt {
23 | return bind.to(value: 3)
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Cleanse/TaggedBindingBuilderDecorator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TaggedBindingBuilderDecorator.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 5/7/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /// Internal type used for binding. We decorate a provider with this to indicate if we're scoped or not
12 | public struct TaggedBindingBuilderDecorator : BindingBuilderDecorator where Tag.Element == Wrapped.FinalProvider.Element {
13 | public typealias FinalProvider = TaggedProvider
14 |
15 | public let wrapped: Wrapped
16 |
17 | public init(wrapped: Wrapped) {
18 | self.wrapped = wrapped
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Cleanse
2 | Copyright 2016 Square, Inc.
3 | A full list of contributors is available at https://github.com/square/Cleanse/contributors
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
--------------------------------------------------------------------------------
/Cleanse/BaseBindingBuilder.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BaseBindingBuilder.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 5/9/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct BaseBindingBuilder : BindingBuilder {
12 | public typealias FinalProvider = Provider
13 | public typealias Input = Element
14 | public typealias Binder = B
15 | public let binder: B
16 | public static func mapElement(input: Input) -> FinalProvider.Element {
17 | return input
18 | }
19 |
20 | public static var collectionMergeFunc: Optional<([FinalProvider.Element]) -> FinalProvider.Element> {
21 | return nil
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Cleanse/Installer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Installer.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 5/2/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | /// The portion of the `Binder` Protocol that is responsible for installing module dependencies
13 | public protocol Installer {
14 | /**
15 | Installs a module as a dependnecy of the caller
16 |
17 | - parameter module: Module to install as a dependency of the caller (usually a `Module` or `RootComponent`).
18 | */
19 | func include(module: M.Type) where M.Scope == Unscoped
20 |
21 | func install(dependency: C.Type)
22 | func install(dependency: C.Type)
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/Cleanse/TypeKeyProtocol.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TypeKeyProtocol.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 4/29/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /// An implementation of this is used to have a hashable of a type.
12 | /// This is preferable to using ObjectIdentifier since it can be typed and has a better description
13 | public protocol TypeKeyProtocol : DelegatedHashable, CustomStringConvertible {
14 | var type: Any.Type { get }
15 | }
16 |
17 | extension TypeKeyProtocol {
18 | public var hashable: ObjectIdentifier {
19 | return ObjectIdentifier(type)
20 | }
21 |
22 | public var description: String {
23 | return "\(type)"
24 | }
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Cleansec_Generate_Fixtures.h:
--------------------------------------------------------------------------------
1 | //
2 | // Cleansec_Generate_Fixtures.h
3 | // Cleansec-Generate-Fixtures
4 | //
5 | // Created by Sebastian Edward Shanus on 5/11/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for Cleansec_Generate_Fixtures.
12 | FOUNDATION_EXPORT double Cleansec_Generate_FixturesVersionNumber;
13 |
14 | //! Project version string for Cleansec_Generate_Fixtures.
15 | FOUNDATION_EXPORT const unsigned char Cleansec_Generate_FixturesVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Code Fixtures/AssistedInjection.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AssistedInjection.swift
3 | // cleansec-generate-fixtures
4 | //
5 | // Created by Sebastian Edward Shanus on 5/1/20.
6 | // Copyright © 2020 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | struct AssistedObject {
13 | let assisted: Assisted
14 | let string: String
15 | }
16 |
17 | class AssistedSeed: AssistedFactory {
18 | typealias Seed = Int
19 | typealias Element = AssistedObject
20 | }
21 |
22 | struct AssistedModule: Module {
23 | static func configure(binder: Binder) {
24 | binder.bindFactory(AssistedObject.self).with(AssistedSeed.self).to(factory: AssistedObject.init)
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Code Fixtures/InnerTag.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InnerTag.swift
3 | // cleansec-generate-fixtures
4 | //
5 | // Created by Sebastian Edward Shanus on 5/1/20.
6 | // Copyright © 2020 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | fileprivate extension NSObject {
13 | /// This will represent the rootViewController that is assigned to our main window
14 | struct Root : Tag {
15 | typealias Element = NSObject
16 | }
17 | }
18 |
19 | struct InnerTagModule: Module {
20 | static func configure(binder: Binder) {
21 | binder
22 | .bind(NSObject.self)
23 | .tagged(with: NSObject.Root.self)
24 | .to(value: NSObject())
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Code Fixtures/ManyDependencies.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ManyDependencies.swift
3 | // Cleansec-Generate-Fixtures
4 | //
5 | // Created by Sebastian Edward Shanus on 5/23/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | struct BigLot {
13 | let one: Int
14 | let two: Int
15 | let three: Int
16 | let four: Int
17 | let five: Int
18 | let six: Int
19 | let seven: Int
20 | let eight: Int
21 | let nine: Int
22 | let ten: Int
23 | }
24 |
25 | fileprivate struct ManyDependenciesModule: Module {
26 | static func configure(binder: Binder) {
27 | binder.bind(BigLot.self).to(factory: BigLot.init)
28 | }
29 |
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/Cleanse/CleanseServiceLoader.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CleanseServiceLoader.swift
3 | // Cleanse
4 | //
5 | // Created by Sebastian Edward Shanus on 10/10/19.
6 | // Copyright © 2019 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /// Service loader for binding plugins. Passed into `RootComponent` factory function.
12 | public final class CleanseServiceLoader {
13 | var services: [CleanseBindingPlugin]
14 | public init(_ services: [CleanseBindingPlugin] = []) {
15 | self.services = services
16 | }
17 |
18 | public func register(_ plugin: CleanseBindingPlugin) {
19 | services.append(plugin)
20 | }
21 |
22 | public static var instance: CleanseServiceLoader {
23 | return CleanseServiceLoader()
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Code Fixtures/CustomScopeBinding.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CustomScopeBinding.swift
3 | // Cleansec-Generate-Fixtures
4 | //
5 | // Created by Sebastian Edward Shanus on 8/12/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | fileprivate struct CustomScope: Cleanse.Scope {}
13 | fileprivate typealias ShortScope = Binder
14 | fileprivate struct CustomScopeModule: Cleanse.Module {
15 | static func configure(binder: Binder) {
16 | binder.bind(Int.self).to(value: 3)
17 | }
18 | }
19 |
20 | fileprivate struct CustomScopeTypealiasModule: Cleanse.Module {
21 | static func configure(binder: ShortScope) {
22 | binder.bind(Int.self).to(value: 3)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Code Fixtures/ModuleIncludesSubcomponent.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ModuleIncludesSubcomponent.swift
3 | // cleasecTests
4 | //
5 | // Created by Sebastian Edward Shanus on 5/1/20.
6 | // Copyright © 2020 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 |
13 | struct Subcomponent: Component {
14 | static func configure(binder: Binder) {
15 |
16 | }
17 | static func configureRoot(binder bind: ReceiptBinder) -> BindingReceipt {
18 | return bind.to(value: 3)
19 | }
20 | typealias Root = Int
21 | }
22 |
23 | struct CoreAppModule6 : Cleanse.Module {
24 | static func configure(binder: Binder) {
25 | binder.install(dependency: Subcomponent.self)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Code Fixtures/ModuleWithDependencies.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ModuleWithDependencies.swift
3 | // cleasecTests
4 | //
5 | // Created by Sebastian Edward Shanus on 5/1/20.
6 | // Copyright © 2020 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | struct CoreAppModule : Cleanse.Module {
13 | static func configure(binder: Binder) {
14 | binder
15 | .bind(String.self)
16 | .to { (a: Int, b: Character, c: Float) -> String in
17 | return "\(a)\(b)\(c)"
18 | }
19 | }
20 | }
21 |
22 | struct CoreAppModule2 : Cleanse.Module {
23 | static func configure(binder: Binder) {
24 | binder
25 | .bind(String.self)
26 | .to(value: "square")
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Cleanse/RawProviderBinding.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ProviderRegistry.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 5/7/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | /// Constains information about what needs to be registered
13 | public struct RawProviderBinding {
14 | let scope: Scope.Type?
15 |
16 | /// This is the provider. The key of this is what will be provided.
17 | let provider: AnyProvider
18 |
19 | /// Input is actually `[Element]` where `Element: Collection`
20 | let collectionMergeFunc: Optional<([Any]) -> Any>
21 |
22 | let sourceLocation: SourceLocation?
23 | }
24 |
25 |
26 | extension RawProviderBinding {
27 | var isCollectionProvider: Bool {
28 | return collectionMergeFunc != nil
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Models/User.swift:
--------------------------------------------------------------------------------
1 | //
2 | // User.swift
3 | // Exam1
4 | //
5 | // Created by Abdul Chathil on 6/8/20.
6 | // Copyright © 2020 Abdul Chathil. All rights reserved.
7 | //
8 |
9 | import Cleanse
10 |
11 | struct User {
12 | let firstName: String
13 | let lastName: String
14 | let photo: String
15 | var fullName : String {
16 | get {
17 | firstName + " " + lastName
18 | }
19 | }
20 | let email: String
21 | }
22 |
23 | extension User {
24 | struct Module: Cleanse.Module {
25 | static func configure(binder: Binder) {
26 | binder.bind(User.self).to {
27 | User(firstName: "John", lastName: "Doe", photo: "me", email: "abcd@ef.com")
28 | }
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/cleansec/Sandbox/Sandbox/AppComponent.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppComponent.swift
3 | // Sandbox
4 | //
5 | // Created by Sebastian Edward Shanus on 5/13/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | struct AppComponent: RootComponent {
13 | static func configure(binder: Binder) {
14 | binder
15 | .bind(String.self)
16 | .to { (amount: Double) -> String in
17 | return "hello"
18 | }
19 |
20 | binder
21 | .bind(Double.self)
22 | .to(value: 3.0)
23 | }
24 |
25 | static func configureRoot(binder bind: ReceiptBinder) -> BindingReceipt {
26 | return bind.to(value: 3)
27 | }
28 |
29 | typealias Root = Int
30 | }
31 |
--------------------------------------------------------------------------------
/CleanseTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/cleansec/SwiftAstParserTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/cleansec/CleansecFrameworkTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/cleansec/SwiftAstParser/Parsing/SyntaxParser.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | /**
4 | Parses the output from `swiftc -dump-ast` and emits its parsed `Syntax` nodes.
5 | */
6 | public struct SyntaxParser {
7 | /**
8 | Parses data input and returns syntax nodes.
9 | - returns: List of `Syntax` nodes.
10 | - parameter data: Raw data.
11 | */
12 | public static func parse(data: Data) -> [Syntax] {
13 | return InputParser.parse(lines: data.mapToLines(seperator: UInt8(ascii: "\n")))
14 | }
15 |
16 | /**
17 | Parses text input and returns syntax nodes.
18 | - returns: List of `Syntax` nodes.
19 | - parameter text: Raw text.
20 | */
21 | public static func parse(text: String) -> [Syntax] {
22 | return InputParser.parse(lines: text.split(separator: "\n").map { String($0) })
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Cleanse/SourceLocation.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DebugInfo.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 4/28/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | /// This is used to pass around source info similar to what one would get from stack traces
13 |
14 | public struct SourceLocation : CustomStringConvertible {
15 | public let file: StaticString
16 | public let line: Int
17 | public let function: StaticString
18 |
19 | public init(
20 | file: StaticString,
21 | line: Int,
22 | function: StaticString
23 | ) {
24 |
25 | self.file = file
26 | self.line = line
27 | self.function = function
28 | }
29 |
30 | public var description: String {
31 | return "\(file):\(line)"
32 | }
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/CleanseGen/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Documentation/Binding Grammar.rst:
--------------------------------------------------------------------------------
1 |
2 |
3 | DSL Grammars
4 | ============
5 |
6 | Binding Grammar
7 | ```````````````
8 |
9 | .. productionlist::
10 | bind_stmt : "binder"
11 | : `bind_step`
12 | bind_step : ".bind(" [ element_metatype_expr ] ")"
13 | : `collection_step`
14 | collection_step : [ ".intoCollection()" ]
15 | : `tag_step`
16 | tag_step : [ ".tagged(with: " tag_metatype_expr ")" ]
17 | : `scope_step`
18 | scope_step : [ ".asSingleton()" ]
19 | : `terminating_step`
20 | terminating_step: `provider_terminator`
21 | : | `factory_terminator`
22 | : | `value_terminator`
23 | provider_terminator: ".to(provider:)"
24 | factory_terminator: ".to(factory:)"
25 | value_terminator: ".to(value:)"
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Cleanse/ComponentBase.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ComponentBase.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 5/5/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | /// Base protocol for both Components and RootComponents. Generally want to implement Components or RootComponent instead
13 | public protocol ComponentBase {
14 | /// This is the binding required to construct a new Component. Think of it as somewhat of an initialization value.
15 | associatedtype Seed = Void
16 |
17 | /// This should be set to the root type of object that is created.
18 | associatedtype Root
19 |
20 | associatedtype Scope: Cleanse._ScopeBase = Unscoped
21 |
22 | static func configure(binder: Binder)
23 |
24 | static func configureRoot(binder bind: ReceiptBinder) -> BindingReceipt
25 | }
26 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowserTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowserUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/DI/AppComponent.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppComponent.swift
3 | // adoptme
4 | //
5 | // Created by Abdul Chathil on 12/25/20.
6 | // Copyright © 2020 Abdul Chathil. All rights reserved.
7 | //
8 |
9 | import Cleanse
10 |
11 | struct AppComponent: Cleanse.RootComponent {
12 | typealias Root = PropertyInjector
13 |
14 | static func configure(binder: Binder) {
15 | binder.include(module: UserData.Module.self)
16 | binder.include(module: User.Module.self)
17 | }
18 |
19 | static func configureRoot(binder bind: ReceiptBinder>) -> BindingReceipt> {
20 | bind.propertyInjector { (bind) -> BindingReceipt> in
21 | return bind.to(injector: AdoptmeApp.injectProperties)
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Code Fixtures/PropertyInjectorRoot.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PropertyInjectorRoot.swift
3 | // cleansec-generate-fixtures
4 | //
5 | // Created by Sebastian Edward Shanus on 5/1/20.
6 | // Copyright © 2020 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | class MainPropertyClass {}
13 |
14 | struct RootComponent: Cleanse.RootComponent {
15 | static func configureRoot(binder bind: ReceiptBinder>) -> BindingReceipt> {
16 | return bind.to { (injector: PropertyInjector) -> PropertyInjector in
17 | return injector
18 | }
19 | }
20 |
21 | typealias Root = PropertyInjector
22 |
23 | static func configure(binder: Binder) {
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/cleansec/SwiftAstParser/script/Nodes.template:
--------------------------------------------------------------------------------
1 | // This file is generated! DO NOT EDIT!
2 |
3 | public enum NodeIdentifier: String {
4 | <% for @item in @decl_items %>
5 | case <%= @item.case_var_name %> = "<%= @item.case_name %>"
6 | <% end %>
7 | }
8 |
9 | <% for @item in @decl_items %>
10 | public struct <%= @item.class_name %>: Syntax {
11 | public let raw: String
12 | public let children: [Syntax]
13 | }
14 | <% end %>
15 |
16 | public struct UnknownSyntax: Syntax {
17 | public let raw: String
18 | public let children: [Syntax]
19 | }
20 |
21 | extension String {
22 | func createNode(id: NodeIdentifier, children: [Syntax]) -> Syntax {
23 | switch id {
24 | <% for @item in @decl_items %>
25 | case .<%= @item.case_var_name %>:
26 | return <%= @item.class_name %>(raw: self, children: children)
27 | <% end %>
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Cleanse/Module.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Module.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 4/28/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | /**
13 | Basic building block for an object graph or component. A module defines how instances are created that are exposed to the rest of the object graph as well as requirements to construct these provided instances.
14 |
15 | In the words of Guice documentation, _["Modules should be fast and side-effect free"](https://github.com/google/guice/wiki/ModulesShouldBeFastAndSideEffectFree)_.
16 |
17 | This is the same for modules in Cleanse, if not even moreso since "configure" may be called more than once to validate the object graph.
18 | */
19 | public protocol Module {
20 | associatedtype Scope: Cleanse._ScopeBase = Unscoped
21 |
22 | static func configure(binder: Binder)
23 | }
24 |
--------------------------------------------------------------------------------
/Cleanse/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Cleanse/Binder.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Binder.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 4/25/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | /**
13 | Internal representation of a completed `BindingBuilder`. It is consolidated into a protocol to make message signatures simpler.
14 | */
15 | public protocol _InternalBindInfoProtocol {
16 | associatedtype BP : BindingBuilder
17 |
18 | var bindingProvider: BP { get }
19 | var provider: BP.FinalProvider { get }
20 | }
21 |
22 | struct InternalBindInfo : _InternalBindInfoProtocol {
23 | typealias BP = BP_
24 |
25 | let bindingProvider: BP
26 | let provider: BP_.FinalProvider
27 | }
28 |
29 | public protocol BinderBase : Installer, ProviderProvider {
30 | /// Authoritative bind function.
31 | func _internalBind(binding: RawProviderBinding)
32 | }
33 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/SplitViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SplitViewController.swift
3 | // CleanseGithubBrowser
4 | //
5 | // Created by Mike Lewis on 6/12/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /// Common base class for UISplitViewController that has better default constructors
12 | class SplitViewController : UISplitViewController {
13 | init(masterViewController: RootVC) where RootVC: UISplitViewControllerDelegate {
14 | super.init(nibName: nil, bundle: nil)
15 |
16 | self.delegate = masterViewController
17 | self.viewControllers = [UINavigationController(rootViewController: masterViewController)]
18 | }
19 |
20 | @available(*, unavailable)
21 | required init?(coder aDecoder: NSCoder) {
22 | fatalError("init(coder:) has not been implemented")
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/NetworkModule.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NetworkModule.swift
3 | // CleanseGithubBrowser
4 | //
5 | // Created by Mike Lewis on 6/12/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | /// Wires up NSURLSession and friends
13 | struct NetworkModule : Module {
14 | static func configure(binder: SingletonBinder) {
15 |
16 | binder
17 | .bind()
18 | .sharedInScope()
19 | .to(value: URLSessionConfiguration.ephemeral)
20 |
21 | binder
22 | .bind(URLSession.self)
23 | .sharedInScope()
24 | .to { URLSession(configuration: $0, delegate: nil, delegateQueue: OperationQueue.main) }
25 |
26 | binder
27 | .bind(URL.self)
28 | .tagged(with: GithubBaseURL.self)
29 | .to(value: URL(string: "https://api.github.com")!)
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/cleansec/SwiftAstParser/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSHumanReadableCopyright
22 | Copyright © 2020 Square. All rights reserved.
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Cleanse/Scope.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Scope.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 4/22/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | // Type erased version of Scope
12 |
13 | public protocol _ScopeBase {
14 | }
15 |
16 |
17 | /// Currently there are only two scopes, `Unscoped` and `Singleton`.
18 | public protocol Scope : _ScopeBase {
19 | }
20 |
21 |
22 | /// This a special scope that means its not scoped
23 | public struct Unscoped : _ScopeBase {
24 | }
25 |
26 | /// Default provided scope for the consumer to use in the Root Component. One does not have to use this scope
27 | /// and may use their own in the root component, but this is provided for convenience.
28 | public struct Singleton : Scope {}
29 |
30 | extension _ScopeBase {
31 |
32 | // Returns our metatype if we're not `Unscoped`
33 | static var scopeOrNil: Scope.Type? {
34 | return self as? Scope.Type
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/cleansec/CleansecFramework/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSHumanReadableCopyright
22 | Copyright © 2020 Square. All rights reserved.
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Views/Components/PetBadge.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PetBadge.swift
3 | // Exam1
4 | //
5 | // Created by Abdul Chathil on 6/8/20.
6 | // Copyright © 2020 Abdul Chathil. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 |
12 | struct PetBadge: View {
13 | var type: Pet.PetType
14 | var body: some View {
15 | HStack {
16 | Image(petTypeIcon[type]!).renderingMode(.template).resizable().frame(width: 16, height: 16).foregroundColor(Color("on-primary"))
17 | Text(type.rawValue)
18 | .font(.caption)
19 | .fontWeight(.bold).foregroundColor(Color("on-primary"))
20 | }.padding(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16)).background(Color("primary")).clipShape(Capsule())
21 | }
22 | }
23 |
24 | struct PetBadge_Previews: PreviewProvider {
25 | static var previews: some View {
26 | PetBadge(type: Pet.PetType.dog)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSHumanReadableCopyright
22 | Copyright © 2020 Square. All rights reserved.
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Cleanse/CleanseErrorReporter.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CleanseErrorReporter.swift
3 | // Cleanse
4 | //
5 | // Created by Sebastian Edward Shanus on 10/11/19.
6 | // Copyright © 2019 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public final class CleanseErrorReporter {
12 | var errors: [CleanseError] = []
13 |
14 | public func append(error: CleanseError) {
15 | errors.append(error)
16 | }
17 |
18 | public func append(contentsOf errorSet: [CleanseError]) {
19 | errors.append(contentsOf: errorSet)
20 | }
21 |
22 | func report() throws {
23 | errors.sort {
24 | return $0.description < $1.description
25 | }
26 |
27 | switch errors.count {
28 | case 0:
29 | // Everything is cool
30 | break
31 | case 1:
32 | throw errors[0]
33 | default:
34 | throw MultiError(errors: errors)
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Cleanse/CleanseBindingPlugin.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SPI.swift
3 | // Cleanse
4 | //
5 | // Created by Sebastian Edward Shanus on 10/9/19.
6 | // Copyright © 2019 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | Plugin hook that gives conforming objects read-only access to the Cleanse object graph.
13 |
14 | In order for your plugin to be run, it must registered with an instance of a `CleanseServiceLoader` and passed into
15 | the `ComponentFactory.of(_:validate:serviceLoader:)` function. Plugins will only be run if the `validate` param is `true`.
16 | **/
17 |
18 | public protocol CleanseBindingPlugin {
19 | /// Plugin entry point function that is called by the service loader.
20 | ///
21 | /// - Parameter root: Root component of the object graph.
22 | /// - Parameter errorReporter: Reporter used to append errors that are used to fail validation.
23 | ///
24 | func visit(root: ComponentBinding, errorReporter: CleanseErrorReporter)
25 | }
26 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | .DUMMY: build documentation
2 |
3 | SWIFT_ROOT=/Library/Developer/Toolchains/swift-latest.xctoolchain
4 | SWIFT=$(SWIFT_ROOT)/usr/bin/swift
5 |
6 | # This can go away once
7 | SWIFT_ARGS=-Xswiftc=-suppress-warnings
8 |
9 | .build:
10 |
11 | build: .build generated_sources
12 | $(SWIFT) build $(SWIFT_ARGS)
13 |
14 | test: build
15 | $(SWIFT) test
16 |
17 | clean:
18 | $(SWIFT) build --clean
19 |
20 | generated_sources: Cleanse/BinderArities.swift Cleanse/PropertyInjectionArities.swift
21 |
22 | Cleanse/BinderArities.swift: CleanseGen/GenerateBinderArities.swift
23 | xcrun swift CleanseGen/GenerateBinderArities.swift > Cleanse/BinderArities.swift
24 |
25 | Cleanse/PropertyInjectionArities.swift: CleanseGen/GeneratePropertyInjectionArities.swift
26 | xcrun swift CleanseGen/GeneratePropertyInjectionArities.swift > Cleanse/PropertyInjectionArities.swift
27 |
28 | docs/index.html: build
29 | jazzy
30 |
31 | docs: docs/index.html
32 |
33 | sphinx:
34 | make -C Documentation html
35 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/App/AdoptmeApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AdoptmeApp.swift
3 | // adoptme
4 | //
5 | // Created by Abdul Chathil on 12/25/20.
6 | // Copyright © 2020 Abdul Chathil. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 | import Cleanse
11 |
12 | @main
13 | class AdoptmeApp: App {
14 | var userData: UserData!
15 | var user: User!
16 |
17 | required init() {
18 | let propertyInjector = try? ComponentFactory.of(AppComponent.self).build(())
19 | propertyInjector?.injectProperties(into: self)
20 | precondition(userData != nil)
21 | precondition(user != nil)
22 | }
23 | var body: some Scene {
24 | WindowGroup {
25 | HomeScreen(currentUser: user).environmentObject(userData)
26 | }
27 | }
28 | }
29 |
30 | extension AdoptmeApp {
31 | func injectProperties(_ userData: UserData, _ user: User) {
32 | self.userData = userData
33 | self.user = user
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Models/Data.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Data.swift
3 | // Exam1
4 | //
5 | // Created by Abdul Chathil on 6/7/20.
6 | // Copyright © 2020 Abdul Chathil. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SwiftUI
11 |
12 | let petData: [Pet] = load("pets.json")
13 |
14 | func load(_ filename: String) -> T {
15 | let data: Data
16 |
17 | guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
18 | else {
19 | fatalError("Couldn't find \(filename) in main bundle.")
20 | }
21 |
22 | do {
23 | data = try Data(contentsOf: file)
24 | } catch {
25 | fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
26 | }
27 |
28 | do {
29 | let decoder = JSONDecoder()
30 | return try decoder.decode(T.self, from: data)
31 | } catch {
32 | fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Code Fixtures/SimpleComponent.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SimpleComponent.swift
3 | // cleansec-generate-fixtures
4 | //
5 | // Created by Sebastian Edward Shanus on 5/1/20.
6 | // Copyright © 2020 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | struct Subcomponent2: Component {
13 | static func configure(binder: Binder) {
14 |
15 | }
16 | static func configureRoot(binder bind: ReceiptBinder) -> BindingReceipt {
17 | return bind.to(value: 3)
18 | }
19 | typealias Root = Int
20 | }
21 |
22 | fileprivate struct Container {
23 | fileprivate struct NestedSubcomponent: Component {
24 | static func configure(binder: Binder) {
25 |
26 | }
27 | static func configureRoot(binder bind: ReceiptBinder) -> BindingReceipt {
28 | return bind.to(value: 3)
29 | }
30 | typealias Root = Int
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Cleanse/RootComponent.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RootComponent.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 5/2/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | public protocol RootComponent : ComponentBase {
13 | }
14 |
15 | public extension ComponentFactoryProtocol where ComponentElement : RootComponent {
16 | static func of(_ componentType: ComponentElement.Type, validate: Bool = true, serviceLoader: CleanseServiceLoader = CleanseServiceLoader.instance) throws -> ComponentFactory {
17 |
18 | if validate {
19 | let validator = ValidationVisitor()
20 | validator.install(dependency: ComponentElement.self)
21 | try validator.finalize(serviceLoader)
22 | }
23 |
24 | let graph = Graph(scope: nil)
25 |
26 | let p = graph.provider(ComponentFactory.self)
27 |
28 | graph.install(dependency: ComponentElement.self)
29 |
30 | try graph.finalize()
31 |
32 | return p.get()
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #Ignore the Mac OS X .DS_Store files
2 | .DS_Store
3 | .LSOverride
4 |
5 | #Ignore user-specific settings
6 | *.mode1v3
7 | *.mode2v3
8 | *.pbxuser
9 | *.perspectivev3
10 | xcuserdata
11 |
12 | #Ignore textmate build errors
13 | *.tm_build_errors
14 |
15 | #Ignore temp nibs and swap files
16 | *.swp
17 | *~.nib
18 |
19 | #Ignore the build, since we don't want archived builds
20 | build
21 |
22 | .gitattributes
23 |
24 | #Probably don't want to check in xcuserdata
25 | xcuserdata/
26 |
27 | *.orig
28 | .idea
29 |
30 | #Ignore the token from the asset update script
31 | *.LastAssetUpdate_*
32 |
33 | env/
34 |
35 | .build_env/
36 |
37 | *.pyc
38 |
39 | # Instruments' output during UI Automation test
40 | traces
41 | instrumentscli*.trace
42 |
43 | git-cmp
44 |
45 | TestResults/*
46 | */TestResults/*
47 |
48 | .*.sw?
49 | .sw?
50 |
51 | DerivedCache_DerivedData/
52 | DerivedCache/
53 | .build/
54 |
55 |
56 | # Not sure if we want to commit Jazzy docs yet
57 | /docs/
58 |
59 | Carthage/
60 |
61 | *.xcscmblueprint
62 |
63 | # Cocoapods
64 | gen/
65 |
66 | # Swift PM
67 | .swiftpm
68 |
--------------------------------------------------------------------------------
/Cleanse/AssistedInjectionBuilder.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AssistedInjectionBuilder.swift
3 | // Cleanse
4 | //
5 | // Created by Sebastian Edward Shanus on 9/5/19.
6 | // Copyright © 2019 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public protocol BaseAssistedInjectionBuilder {
12 | associatedtype Binder: BinderBase
13 | associatedtype Tag: AssistedFactory = EmptySeed
14 | associatedtype Element
15 | var binder: Binder { get }
16 | }
17 |
18 | public protocol AssistedInjectionBuilder : BaseAssistedInjectionBuilder where Tag.Element == Element {}
19 |
20 | public struct AssistedInjectionBindingBuilder : AssistedInjectionBuilder {
21 | public typealias Binder = B
22 | public typealias Element = E
23 |
24 | public let binder: Binder
25 | }
26 |
27 | extension AssistedInjectionBindingBuilder {
28 | public func with(_ seed: S.Type) -> AssistedInjectionSeedDecorator where S.Element == Element {
29 | return AssistedInjectionSeedDecorator(binder: binder)
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/cleansec/CleansecFramework/Resolver/LinkedMerging.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LinkedMerging.swift
3 | // CleansecFramework
4 | //
5 | // Created by Sebastian Edward Shanus on 5/21/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension LinkedModule {
12 | func merge(from other: LinkedModule) -> LinkedModule {
13 | LinkedModule(
14 | type: type,
15 | providers: providers + other.providers,
16 | includedModules: includedModules + other.includedModules,
17 | subcomponents: subcomponents + other.subcomponents
18 | )
19 | }
20 | }
21 |
22 | extension LinkedComponent {
23 | func merge(from other: LinkedComponent) -> LinkedComponent {
24 | LinkedComponent(
25 | type: type,
26 | rootType: rootType,
27 | providers: providers + other.providers,
28 | seed: seed,
29 | includedModules: includedModules + other.includedModules,
30 | subcomponents: subcomponents + other.subcomponents,
31 | isRoot: isRoot
32 | )
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Views/Components/PetHeader.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PetHeader.swift
3 | // Exam1
4 | //
5 | // Created by Abdul Chathil on 6/8/20.
6 | // Copyright © 2020 Abdul Chathil. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct PetHeader: View {
12 | var body: some View {
13 | HStack {
14 |
15 | Image("illustration-cat").resizable().scaledToFill().frame(width: 186, height: 186).padding(.bottom, 16)
16 | Spacer()
17 | VStack(alignment: .leading) {
18 | Text("Find").font(.largeTitle).fontWeight(.bold)
19 | Text("Some descriptions about pets.\nThis description would look good\nin 2 lines or more").font(.caption).fontWeight(.medium).foregroundColor(.gray).multilineTextAlignment(.leading)
20 | .fixedSize(horizontal: false, vertical: true)
21 | .foregroundColor(.gray)
22 | }
23 | }
24 | }
25 | }
26 |
27 | struct PetHeader_Previews: PreviewProvider {
28 | static var previews: some View {
29 | PetHeader()
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Views/Components/ProgressBar.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ProgressBar.swift
3 | // Exam1
4 | //
5 | // Created by Abdul Chathil on 6/8/20.
6 | // Copyright © 2020 Abdul Chathil. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct ProgressBar: View {
12 | let progress = 0.7
13 | var body: some View {
14 | GeometryReader { geometry in
15 | ZStack(alignment: .leading) {
16 | Rectangle().frame(width: geometry.size.width , height: geometry.size.height)
17 | .opacity(0.3)
18 | .foregroundColor(Color("primary"))
19 |
20 | Rectangle().frame(width: min(CGFloat(self.progress)*geometry.size.width, geometry.size.width), height: geometry.size.height)
21 | .foregroundColor(Color("primary"))
22 | .animation(.linear)
23 | }.frame(height: 8).cornerRadius(45.0)
24 | }
25 | }}
26 |
27 | struct ProgressBar_Previews: PreviewProvider {
28 | static var previews: some View {
29 | ProgressBar()
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Views/Components/PetSize.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PetSize.swift
3 | // Exam1
4 | //
5 | // Created by Abdul Chathil on 6/8/20.
6 | // Copyright © 2020 Abdul Chathil. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct PetSize: View {
12 | let pet: Pet
13 | var body: some View {
14 | HStack(alignment: .bottom) {
15 | Image(petTypeIcon[pet.type]!).resizable().renderingMode(.template).frame(width: 24, height: 24).foregroundColor(pet.size == Pet.PetSize.s ? Color("on-primary") : Color("primary"))
16 | Image(petTypeIcon[pet.type]!).resizable().renderingMode(.template).frame(width: 48, height: 48).foregroundColor(pet.size == Pet.PetSize.m ? Color("on-primary") : Color("primary"))
17 | Image(petTypeIcon[pet.type]!).resizable().renderingMode(.template).frame(width: 72, height: 72).foregroundColor(pet.size == Pet.PetSize.l ? Color("on-primary") : Color("primary"))
18 | }
19 | }
20 | }
21 |
22 | struct PetSize_Previews: PreviewProvider {
23 | static var previews: some View {
24 | PetSize(pet: petData[0])
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowserTests/CleanseGithubBrowserTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CleanseGithubBrowserTests.swift
3 | // CleanseGithubBrowserTests
4 | //
5 | // Created by Mike Lewis on 6/10/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import CleanseGithubBrowser
11 | import Cleanse
12 |
13 | /// Using the DI framework doens't mean its required to unit test its components.
14 | class CleanseGithubBrowserTests: XCTestCase {
15 | func testMembersViewController_Title() {
16 | // Tests that the member's view controller sets the title appropriately.
17 | let factory = Factory { _ in
18 | return MembersPageSettings()
19 | }
20 | let vc = MembersViewController(
21 | memberService: FakeGithubMembersService(),
22 | githubOrganizationName: .init(value: "Organiztion Name"),
23 | settings: factory
24 | )
25 |
26 | XCTAssertEqual(vc.navigationItem.title, "Members of Organiztion Name")
27 | XCTAssertEqual(vc.title, "Members")
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Models/Pet.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Pet.swift
3 | // Exam1
4 | //
5 | // Created by Abdul Chathil on 6/7/20.
6 | // Copyright © 2020 Abdul Chathil. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | let petTypeIcon = [Pet.PetType.cat: "cat-solid", Pet.PetType.dog: "dog-solid", Pet.PetType.chameleon: "otter-solid"]
12 |
13 | struct Pet: Hashable, Codable, Identifiable {
14 | var id: Int
15 | var name: String
16 | fileprivate var imageName: String
17 | var type: PetType
18 | var desc: String
19 | var isLiked: Bool
20 | var isMale: Bool
21 | var size: PetSize
22 | var location: String
23 |
24 | enum PetType: String, CaseIterable, Codable, Hashable {
25 | case cat = "Cat"
26 | case dog = "Dog"
27 | case chameleon = "Chameleon"
28 | }
29 |
30 | enum PetSize: String, CaseIterable, Codable, Hashable {
31 | case s = "S"
32 | case m = "M"
33 | case l = "L"
34 | }
35 |
36 | }
37 |
38 | extension Pet {
39 | var image: Image {
40 | ImageStore.shared.image(name: imageName)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/cleansec/Cleansec-Generate-Fixtures/Code Fixtures/CollectionBindings.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CollectionBindings.swift
3 | // cleansec-generate-fixtures
4 | //
5 | // Created by Sebastian Edward Shanus on 5/1/20.
6 | // Copyright © 2020 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | struct Singular {
13 | let a: Array
14 | }
15 |
16 | struct CollectionModule: Module {
17 | static func configure(binder: Binder) {
18 | binder.bind(Singular.self).to { (a:Array) -> Singular in
19 | return Singular(a: a)
20 | }
21 |
22 | binder.bind(Singular.self).to { (a: [ [Int] ]) in
23 | return Singular(a: a.first!)
24 | }
25 |
26 | binder
27 | .bind(Int.self)
28 | .intoCollection()
29 | .to(value: 5)
30 |
31 | binder
32 | .bind(Int.self)
33 | .intoCollection()
34 | .to(value: [1,2,3])
35 |
36 | binder
37 | .bind([Int].self)
38 | .intoCollection()
39 | .to(value: [2])
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Cleanse/AssistedInjection.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AssistedInjection.swift
3 | // Cleanse
4 | //
5 | // Created by Sebastian Edward Shanus on 9/5/19.
6 | // Copyright © 2019 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension BinderBase {
12 | public func bindFactory(_ class: Element.Type) -> AssistedInjectionBindingBuilder {
13 | return AssistedInjectionBindingBuilder(binder: self)
14 | }
15 | }
16 |
17 | extension AssistedInjectionBuilder {
18 | @discardableResult public func to(file: StaticString=#file, line: Int=#line, function: StaticString=#function, factory: @escaping (Assisted) -> Element) -> BindingReceipt> {
19 | let binder = self.binder
20 |
21 | binder
22 | .bind(Factory.self)
23 | .to(value: Factory { seed in
24 | return factory(
25 | Assisted { seed }
26 | )
27 | },
28 | file: file,
29 | line: line,
30 | function: function)
31 | return BindingReceipt()
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/cleansec/SwiftAstParser/Parsing/ASTStringHelpers.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | /**
4 | These are string helpers unique to the -dump-ast format output.
5 | */
6 | extension String {
7 | var isValidNewlineStart: Bool {
8 | if matches(#"^\(source_file"#) {
9 | return true
10 | }
11 | if let _ = firstCapture(#"^\s{2,}\((\w+)"#) {
12 | return true
13 | } else if matches(#"\s+\($"#) {
14 | return true
15 | } else {
16 | return false
17 | }
18 | }
19 |
20 | var isOnlyWhitespace: Bool {
21 | allSatisfy { $0.isWhitespace }
22 | }
23 | }
24 |
25 | extension String {
26 | var whitespaceIndentCount: Int {
27 | prefix { $0.isWhitespace }.count
28 | }
29 |
30 | var trimmedLeadingWhitespace: String {
31 | String(suffix(count - whitespaceIndentCount))
32 | }
33 |
34 | var identifier: NodeIdentifier? {
35 | let pattern = #"\((\w+)"#
36 | guard let found = firstCapture(pattern) else {
37 | return nil
38 | }
39 | return NodeIdentifier(rawValue: found)
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/cleansec/CleansecFramework/Resolver/ResolvedComponent.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ResolvedComponent.swift
3 | // CleansecFramework
4 | //
5 | // Created by Sebastian Edward Shanus on 5/13/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public final class ResolvedComponent {
12 | public let type: String
13 | public weak var parent: ResolvedComponent?
14 | public var children: [ResolvedComponent]
15 | public let providersByType: [TypeKey:[CanonicalProvider]]
16 | public let diagnostics: [ResolutionError]
17 |
18 | public init(type: String, providersByType: [TypeKey:[CanonicalProvider]], children: [ResolvedComponent], parent: ResolvedComponent? = nil, diagnostics: [ResolutionError] = []) {
19 | self.type = type
20 | self.providersByType = providersByType
21 | self.children = children
22 | self.parent = parent
23 | self.diagnostics = diagnostics
24 | }
25 | }
26 |
27 | extension ResolvedComponent: CustomStringConvertible {
28 | public var description: String {
29 | "COMPONENT: \(type) \n" + "BINDINGS:\n\(providersByType)\n" + "CHILDREN:\n" + "\(children)"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Cleanse/WeakProvider.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WeakProvider.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 7/20/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct WeakProvider : ProviderProtocol {
12 | public typealias Element = E?
13 |
14 | fileprivate let getter: () -> Element
15 |
16 | public init(getter: @escaping () -> Element) {
17 | self.getter = getter
18 | }
19 |
20 | /// - returns: provides an instance of `Element`
21 | public func get() -> Element {
22 | return self.getter()
23 | }
24 | }
25 |
26 | protocol AnyWeakProvider : AnyProvider {
27 | static var standardProviderType: AnyProvider.Type { get }
28 | }
29 |
30 | extension WeakProvider : AnyProvider, AnyWeakProvider {
31 | static func makeNew(getter: @escaping () -> Any) -> AnyProvider {
32 | return WeakProvider(getter: {
33 | getter() as? E
34 | })
35 | }
36 |
37 | var anyGetterProvider: AnyProvider? {
38 | preconditionFailure("Should not get here")
39 | }
40 |
41 | static var standardProviderType: AnyProvider.Type {
42 | return Provider.self
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Cleanse/WrappedBinder.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WrappedBinder.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 3/14/17.
6 | // Copyright © 2017 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /// Makes it easy to wrap binders w/ each other
12 | public protocol WrappedBinder : BinderBase {
13 | var binder: BinderBase { get }
14 | init(binder: BinderBase)
15 | }
16 |
17 |
18 | extension WrappedBinder {
19 | public func _internalBind(binding: RawProviderBinding) {
20 | binder._internalBind(binding: binding)
21 | }
22 |
23 | public func include(module: M.Type) where M.Scope == Unscoped {
24 | return binder.include(module: module)
25 | }
26 |
27 | public func install(dependency: C.Type) {
28 | return binder.install(dependency: dependency)
29 | }
30 |
31 | public func install(dependency: C.Type) {
32 | return binder.install(dependency: dependency)
33 | }
34 |
35 | public func _internalProvider(_ type: Element.Type, debugInfo: ProviderRequestDebugInfo?) -> Provider {
36 | return binder._internalProvider(type, debugInfo: debugInfo)
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Cleanse/TaggedProvider.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TaggedProvider.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 5/3/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct TaggedProvider : ProviderProtocol {
12 | public typealias Element = Tag.Element
13 |
14 | let getter: () -> Element
15 |
16 | public init(getter: @escaping () -> Element) {
17 | self.getter = getter
18 | }
19 |
20 | public func get() -> Element {
21 | return getter()
22 | }
23 |
24 | public func asProvider() -> Provider {
25 | return Provider(getter: getter)
26 | }
27 | }
28 |
29 | protocol AnyTaggedProvider : AnyProvider {
30 | static var tag: _AnyTag.Type { get }
31 | }
32 |
33 | extension TaggedProvider : AnyTaggedProvider {
34 | static func makeNew(getter: @escaping () -> Any) -> AnyProvider {
35 | return TaggedProvider(getter: { getter() as! Element })
36 | }
37 |
38 | /// Cannot be represented w/o tags
39 | var anyGetterProvider: AnyProvider? {
40 | return nil
41 | }
42 |
43 | static var tag: _AnyTag.Type {
44 | return Tag.self
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Cleanse/ScopedProvider.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ScopedProvider.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 7/6/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | private var weakProviderAssociatedObjectKey = 0
12 |
13 | class ScopedProvider {
14 | fileprivate let rawProvider : AnyProvider
15 |
16 | fileprivate let lock = NSLock()
17 |
18 | fileprivate var cachedValue: Any?
19 |
20 | init(rawProvider: AnyProvider) {
21 | self.rawProvider = rawProvider
22 | }
23 |
24 |
25 | /// This retains self
26 | var wrappedProvider: AnyProvider {
27 | return type(of: rawProvider).makeNew(getter: self.provide)
28 | }
29 |
30 | fileprivate func provide() -> Any {
31 | // If we already have it we can avoid locking
32 | if let cachedValue = cachedValue {
33 | return cachedValue
34 | }
35 |
36 | return lock.with {
37 | if let cachedValue = cachedValue {
38 | return cachedValue
39 | }
40 |
41 | let newValue = rawProvider.getAny()
42 |
43 | self.cachedValue = newValue
44 |
45 | return newValue
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: Cleanse-CI
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 |
9 | jobs:
10 | test:
11 | runs-on: macos-latest
12 | env:
13 | DEVELOPER_DIR: /Applications/Xcode.app/Contents/Developer
14 | steps:
15 | - uses: maxim-lobanov/setup-xcode@v1
16 | with:
17 | xcode-version: latest-stable
18 | - uses: actions/checkout@v2
19 | - name: Test
20 | run: xcodebuild test -project Cleanse.xcodeproj -scheme Cleanse -enableCodeCoverage=YES -destination "platform=iOS Simulator,name=iPhone 8"
21 | - name: Test CleanseGithubBrowser Sample App
22 | run: xcodebuild test -project Examples/CleanseGithubBrowser/CleanseGithubBrowser.xcodeproj -scheme CleanseGithubBrowser -destination "platform=iOS Simulator,name=iPhone 8"
23 | - name: Test CleanseSwiftUI Sample App
24 | run: xcodebuild -project Examples/CleanseSwiftUIExample/CleanseSwiftUIExample.xcodeproj -scheme adoptme -destination "platform=iOS Simulator,name=iPhone 8"
25 | - name: Test cleansec
26 | run: xcodebuild test -workspace cleansec.xcworkspace -scheme cleansec -enableCodeCoverage=YES -destination "platform=macos"
27 | working-directory: cleansec
28 |
--------------------------------------------------------------------------------
/cleansec/SwiftAstParserTests/SwiftAstParserTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SwiftAstParserTests.swift
3 | // SwiftAstParserTests
4 | //
5 | // Created by Sebastian Edward Shanus on 5/7/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import SwiftAstParser
11 |
12 | class SwiftAstParserTests: XCTestCase {
13 | func testUnknownNode() {
14 | let fixture = " (unknown )"
15 | let result = SyntaxParser.parse(text: fixture)
16 | XCTAssertEqual(result.count, 1)
17 | let isType = result.first as? UnknownSyntax
18 | XCTAssertNotNil(isType)
19 | }
20 |
21 | func testSoureFileNode() {
22 | let fixture = "(source_file "
23 | let result = SyntaxParser.parse(text: fixture)
24 | XCTAssertEqual(result.count, 1)
25 | let isType = result.first as? SourceFileDecl
26 | XCTAssertNotNil(isType)
27 | }
28 |
29 | func testParsesKnownNode() {
30 | let node = NodeIdentifier.var_decl
31 | let fixture = " (\(node.rawValue) "
32 | let result = SyntaxParser.parse(text: fixture)
33 | XCTAssertEqual(result.count, 1)
34 | let isType = result.first as? VarDecl
35 | XCTAssertNotNil(isType)
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/Cleanse/PropertyInjectionReceiptBinder.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PropertyInjectionReceiptBinder.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 1/6/17.
6 | // Copyright © 2017 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct PropertyInjectionReceiptBinder : PropertyInjectorBindingBuilderProtocol {
12 | public typealias Element = E
13 | public typealias B = AnyBinder
14 |
15 | public let binder: AnyBinder
16 |
17 | init(_ underlyingBindingBuilder: BB) where BB.Element == Element {
18 | self.binder = AnyBinder(binder: underlyingBindingBuilder.binder)
19 | }
20 |
21 | public func toPropertyInjectorBindingBuilder() -> PropertyInjectorBindingBuilder {
22 | return PropertyInjectorBindingBuilder(binder: binder)
23 | }
24 | }
25 |
26 | public extension BindToable where Input: PropertyInjectorProtocol {
27 | func propertyInjector(configuredWith configurationFunction: (PropertyInjectionReceiptBinder) -> BindingReceipt>) -> BindingReceipt> {
28 | return configurationFunction(PropertyInjectionReceiptBinder(PropertyInjectorBindingBuilder(binder: self.binder)))
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/cleansec/script/create-fixtures.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | require 'erb'
4 | require 'pathname'
5 |
6 | class Fixture
7 | attr_accessor :var_name, :contents
8 |
9 | def initialize(var_name, contents)
10 | @var_name = var_name
11 | @contents = contents
12 | end
13 | end
14 |
15 | class Renderer
16 | attr_accessor :fixtures
17 |
18 | def initialize(fixtures)
19 | @fixtures = fixtures
20 | end
21 |
22 | def get_binding
23 | binding()
24 | end
25 | end
26 |
27 | def main
28 | ast_file_path = ARGV[0]
29 | template_path = ARGV[1]
30 | output_path = ARGV[2]
31 | ast_file_contents = File.read(ast_file_path)
32 | source_files = ast_file_contents.split(/(?=\(source_file)/)
33 | filename_regex = %r{\(source_file "(.*)"}
34 | fixtures = []
35 | source_files.each do |f|
36 | if found = f.match(filename_regex)
37 | fixture_name = Pathname.new(found[1]).basename('.swift')
38 | if fixture_name.to_s != "main"
39 | fixtures += [Fixture.new(fixture_name, f)]
40 | end
41 | end
42 | end
43 | renderer = Renderer.new(fixtures)
44 | generated_path = Pathname.new(output_path)
45 | erb_template = ERB.new(File.read(template_path))
46 | output = erb_template.result(renderer.get_binding)
47 | swift_file = File.open(generated_path, 'w')
48 | swift_file.puts output
49 | end
50 |
51 | main
52 |
--------------------------------------------------------------------------------
/CleanseTests/TaggedProviderTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TaggedProviderTests.swift
3 | // Cleanse
4 | //
5 | // Created by holmes on 3/21/17.
6 | // Copyright © 2017 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Cleanse
10 | import Foundation
11 | import XCTest
12 |
13 | fileprivate struct TestTag : Tag {
14 | typealias Element = Int
15 | }
16 |
17 | fileprivate class TagHolder {
18 | fileprivate var value = 42
19 |
20 | func magicNumber() -> Int {
21 | return value
22 | }
23 | }
24 |
25 | class TaggedProviderTests: XCTestCase {
26 | fileprivate var tagHolder: TagHolder!
27 | fileprivate var taggedProvider: TaggedProvider!
28 |
29 | override func setUp() {
30 | tagHolder = TagHolder()
31 | taggedProvider = TaggedProvider(getter: tagHolder.magicNumber)
32 | }
33 |
34 | func testTaggedProviderProvidesCorrectValue() {
35 | XCTAssertEqual(42, taggedProvider.get())
36 | }
37 |
38 | func testAsProviderWorksCorrectly() {
39 | let provider = taggedProvider.asProvider()
40 |
41 | let tagValue = taggedProvider.get()
42 | let providerValue = provider.get()
43 | XCTAssertEqual(tagValue, providerValue)
44 |
45 | tagHolder.value = 1
46 | XCTAssertEqual(1, taggedProvider.get())
47 | XCTAssertEqual(provider.get(), taggedProvider.get())
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/cleansec/SwiftAstParser/README.md:
--------------------------------------------------------------------------------
1 | # SwiftAstParser
2 |
3 | Parsing tool to inspect and traverse the typed-AST generated by `swiftc -dump-ast` mode. This tool is helpful if you would like to inspect the fully typed AST tree when `swift-syntax` or `SourceKit` doesn't provide the information you need. It's important to note that the `-dump-ast` output is not stable and changes between swift versions, which means any parsing implementations written on top of this library may break between swift versions. There are some discussions that discourage parsing the `-dump-ast` output due to no guarantees around stability, and it appears that [`libSyntax` would ideally handle this role one day](https://github.com/apple/swift/tree/master/lib/Syntax), so use this tool at your own risk if you find it useful.
4 |
5 | ### API
6 | _Note:_ API is influenced heavily by Apple's [swift-syntax](https://github.com/apple/swift-syntax)
7 |
8 | #### SyntaxParser
9 | Object responsible for parsing `Data` or raw `String` input from the emitted `-dump-ast` mode.
10 | * `public static func parse(data: Data) -> [Syntax]`
11 | * `public static func parse(text: String) -> [Syntax]`
12 |
13 | #### SyntaxVisitor
14 | Provide an implementation conforming to `SyntaxVisitor` to traverse any `Syntax` node and its children.
15 |
16 | Once you create a `SyntaxVisitor` implementation, you can walk a `Syntax` node by calling `walk(_:)` on it.
17 |
--------------------------------------------------------------------------------
/cleansec/CleansecFramework/Visitors/Provider Visitor/ComponentRootVisitor.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ComponentRootVisitor.swift
3 | // Cleansec
4 | //
5 | // Created by Sebastian Edward Shanus on 5/12/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import SwiftAstParser
11 |
12 | /**
13 | Responsible for extracting out the root provider instance and seed type for a given component body.
14 | */
15 | public struct ComponentRootVisitor: SyntaxVisitor {
16 | public init() {}
17 |
18 | private var seed = "Void"
19 | private var rootProvider: DanglingProvider?
20 |
21 | public mutating func visit(node: Typealias) {
22 | if node.raw.contains("\"Seed\"") {
23 | if let type = node.type.firstCapture(#"(.*)"#), type != "Void" {
24 | seed = type
25 | }
26 | }
27 | }
28 |
29 | public mutating func visit(node: FuncDecl) {
30 | if node.raw.contains("configureRoot(binder:)") {
31 | var rootProviderVisitor = RootProviderVisitor()
32 | rootProviderVisitor.walk(node)
33 | if let danglingRoot = rootProviderVisitor.finalize() {
34 | rootProvider = danglingRoot
35 | }
36 | }
37 | }
38 |
39 | public func finalize() -> (String, DanglingProvider?) {
40 | return (seed, rootProvider)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/cleansec/CleansecFramework/Visitors/Representations/ProviderModels.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | /// Full provider representation bound into object graph.
4 | public struct StandardProvider: Equatable, Codable {
5 | public let type: String
6 | public let dependencies: [String]
7 | public let tag: String?
8 | public let scoped: String?
9 | public let collectionType: String?
10 | public let debugData: DebugData
11 |
12 | public init(type: String, dependencies: [String], tag: String?, scoped: String?, collectionType: String?, debugData: DebugData = .empty) {
13 | self.type = type
14 | self.dependencies = dependencies
15 | self.tag = tag
16 | self.scoped = scoped
17 | self.collectionType = collectionType
18 | self.debugData = debugData
19 | }
20 | }
21 |
22 | /// Partial provider presentation with known dependencies, but isn't bound into object graph yet.
23 | /// In Cleanse this is usually a provider implementation created as a function.
24 | public struct DanglingProvider: Equatable, Codable {
25 | public let type: String
26 | public let dependencies: [String]
27 | public let debugData: DebugData
28 |
29 | public init(type: String, dependencies: [String], debugData: DebugData = .empty) {
30 | self.type = type
31 | self.dependencies = dependencies
32 | self.debugData = debugData
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/GithubMemberService.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GithubService.swift
3 | // CleanseGithubBrowser
4 | //
5 | // Created by Mike Lewis on 6/12/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | struct GithubMember {
13 | let login: String
14 |
15 | static func fromJSON(json: [String: AnyObject]) -> GithubMember {
16 | let username = json["login"] as! String
17 | return GithubMember(login: username)
18 | }
19 | }
20 |
21 | /// Service that lists "Member" for the current organization
22 | protocol GithubMembersService {
23 | func list(handler: @escaping (Result<[GithubMember], Error>) -> Void)
24 | }
25 |
26 | struct GithubMembersServiceImpl : GithubMembersService {
27 | let githubURL: TaggedProvider
28 | let githubOrganizationName: TaggedProvider
29 |
30 | let urlSession: URLSession
31 |
32 | /// Lists members of an organization
33 | func list(handler: @escaping (Result<[GithubMember], Error>) -> Void) {
34 | urlSession.jsonListTask(
35 | baseURL: githubURL.get(),
36 | pathComponents: "orgs", githubOrganizationName.get(), "public_members") { result in
37 | handler(result.map {
38 | $0.map(GithubMember.fromJSON)
39 | })
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Cleanse/ProviderProvider.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ProviderProvider.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 4/26/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | /**
13 | Portion of the binder protocol used to request future providers. This is only used internally and will probably go away
14 | */
15 | public protocol ProviderProvider {
16 | /// Raw inner function to request a provider. One should call standard provider methods instead
17 | func _internalProvider(_ type: Element.Type, debugInfo: ProviderRequestDebugInfo?) -> Provider
18 | }
19 |
20 | extension ProviderProvider {
21 | /// - parameter providerRequiredFor: Only used for debugging
22 | /// - returns: the provider used to obtain instances for the key
23 | func provider(
24 | _ type: Element.Type,
25 | file: StaticString=#file,
26 | line: Int=#line,
27 | function: StaticString=#function,
28 | providerRequiredFor: Any.Type? = nil
29 | ) -> Provider {
30 |
31 | let debugInfo = ProviderRequestDebugInfo(
32 | requestedType: type,
33 | providerRequiredFor: providerRequiredFor,
34 | sourceLocation: SourceLocation(file: file, line: line, function: function))
35 |
36 | return _internalProvider(type, debugInfo: debugInfo)
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Cleanse/CollectionBindingBuilderDecorator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CollectionProvider.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 5/6/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | public struct CollectionBindingBuilderDecorator : BindingBuilderDecorator where Wrapped.CollectionOrUnique == _UniqueBinding, Wrapped.FinalProvider: _StandardProvider, Wrapped.MaybeScope == Unscoped {
13 | public typealias FinalProvider = Provider<[Wrapped.FinalProvider.Element]>
14 | public typealias Input = [Wrapped.Input]
15 | public typealias CollectionOrUnique = _CollectionBinding
16 |
17 | public let wrapped: Wrapped
18 |
19 | public init(wrapped: Wrapped) {
20 | self.wrapped = wrapped
21 | }
22 |
23 | public static func mapElement(input: Input) -> FinalProvider.Element {
24 | return input.map(Wrapped.mapElement)
25 | }
26 |
27 | public static var collectionMergeFunc: Optional<([FinalProvider.Element]) -> FinalProvider.Element> {
28 | return { Array($0.joined()) }
29 | }
30 | }
31 |
32 | public extension BindingBuilder where CollectionOrUnique == _UniqueBinding, FinalProvider: _StandardProvider, MaybeScope == Unscoped {
33 | /// If makes it bind Element to [Element]
34 | func intoCollection() -> CollectionBindingBuilderDecorator {
35 | return with()
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Views/Screens/HomeView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // Exam1
4 | //
5 | // Created by Abdul Chathil on 6/7/20.
6 | // Copyright © 2020 Abdul Chathil. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct HomeScreen: View {
12 | @EnvironmentObject private var userData: UserData
13 | @State var navBarHidden: Bool = true
14 | var body: some View {
15 | NavigationView {
16 | List {
17 | HomeHeader().padding(EdgeInsets(top: 32, leading: 0, bottom: 0, trailing: 0))
18 | ForEach(userData.pets) { pet in
19 | PetRow(pet: pet)
20 | }
21 | }.environment(\.defaultMinListRowHeight, 132).listSeparatorStyleNone()
22 | .navigationBarTitle("")
23 | .navigationBarHidden(self.navBarHidden)
24 | .onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
25 | self.navBarHidden = true
26 | }
27 | .onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in
28 | self.navBarHidden = false
29 | }
30 | }
31 | }
32 | }
33 |
34 | struct ContentView_Previews: PreviewProvider {
35 | static var previews: some View {
36 | HomeScreen().environmentObject(UserData())
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Cleanse/ReceiptBinder.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ReceiptBinder.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 1/6/17.
6 | // Copyright © 2017 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | public struct ReceiptBinder : BindToable {
13 | public typealias Input = Element
14 | public typealias Binder = AnyBinder
15 |
16 | private let innerTo: (_ file: StaticString, _ line: Int, _ function: StaticString, _ provider: Provider) -> BindingReceipt
17 | public let binder: AnyBinder
18 |
19 | public let _finalProviderType : Any.Type
20 |
21 |
22 | init(_ underlyingBindingBuilder: BB) where BB.Input == Input {
23 | self.innerTo = underlyingBindingBuilder._innerTo
24 | self.binder = AnyBinder(binder: underlyingBindingBuilder.binder)
25 | self._finalProviderType = underlyingBindingBuilder._finalProviderType
26 | }
27 |
28 | public func _innerTo(file: StaticString, line: Int, function: StaticString, provider: Provider) -> BindingReceipt {
29 | return innerTo(file, line, function, provider)
30 | }
31 | }
32 |
33 | public extension BindToable {
34 | @discardableResult
35 | func configured(with configurationFunction: (ReceiptBinder) -> BindingReceipt) -> BindingReceipt {
36 | return configurationFunction(ReceiptBinder(self))
37 | }
38 | }
39 |
40 | //public extension BindToable where
41 |
--------------------------------------------------------------------------------
/cleansec/CleansecFramework/Visitors/Provider Visitor/APITypes.swift:
--------------------------------------------------------------------------------
1 | //
2 | // APITypes.swift
3 | // CleansecFramework
4 | //
5 | // Created by Sebastian Edward Shanus on 9/24/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import SwiftAstParser
11 |
12 | enum BaseBindingType: String, CaseIterable {
13 | case provider = "BaseBindingBuilder"
14 | case taggedProvider = "TaggedBindingBuilderDecorator"
15 | case scopedProvider = "ScopedBindingDecorator"
16 | case propertyInjector = "PropertyInjectorBindingBuilder"
17 | case assistedInjectionProvider = "AssistedInjectionSeedDecorator"
18 | case singularCollectionProvider = "SingularCollectionBindingBuilderDecorator"
19 | case collectionProvider = "CollectionBindingBuilderDecorator"
20 | }
21 |
22 | enum BindingAPI: String, CaseIterable {
23 | case toValue = "decl=Cleanse.(file).BindToable extension.to(value:file:line:function:)"
24 | case toFactory = "decl=Cleanse.(file).BindToable extension.to(file:line:function:factory:)"
25 | case toFactoryPropertyInjector = "decl=Cleanse.(file).PropertyInjectorBindingBuilderProtocol extension.to(file:line:function:injector:)"
26 | case toFactoryAssistedInjection = "decl=Cleanse.(file).AssistedInjectionBuilder extension.to(file:line:function:factory:)"
27 | }
28 |
29 |
30 | extension CallExpr {
31 | var isCleanseBinding: Bool {
32 | return type.firstCapture("BindingReceipt<(.*)>") != nil
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/CleanseTests/SPITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SPITests.swift
3 | // CleanseTests
4 | //
5 | // Created by Sebastian Edward Shanus on 11/18/19.
6 | // Copyright © 2019 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 | import XCTest
12 |
13 | final class SPITests: XCTestCase {
14 | struct MyRoot {
15 | let name: String
16 | }
17 |
18 | struct MyRootComponent: RootComponent {
19 | typealias Root = MyRoot
20 |
21 | static func configure(binder: Binder) {
22 |
23 | }
24 |
25 | static func configureRoot(binder bind: ReceiptBinder) -> BindingReceipt {
26 | return bind.to(factory: { MyRoot(name: "Caroline") })
27 | }
28 | }
29 |
30 | struct MyPlugin: CleanseBindingPlugin {
31 | let expectation: XCTestExpectation
32 | func visit(root: ComponentBinding, errorReporter: CleanseErrorReporter) {
33 | expectation.fulfill()
34 | }
35 | }
36 |
37 | func testPluginRuns() {
38 | let expectation = XCTestExpectation(description: "Plugin should run")
39 | let plugin = MyPlugin(expectation: expectation)
40 | let serviceLoader = CleanseServiceLoader([plugin])
41 |
42 | let _ = try! ComponentFactory.of(MyRootComponent.self, validate: true, serviceLoader: serviceLoader)
43 | wait(for: [expectation], timeout: 1.0)
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Cleanse/SingularCollectionBindingBuilderDecorator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SingularCollectionBindingBuilderDecorator.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 5/9/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct SingularCollectionBindingBuilderDecorator : BindingBuilderDecorator
12 | where
13 | Wrapped.CollectionOrUnique == _UniqueBinding,
14 | Wrapped.FinalProvider: _StandardProvider,
15 | Wrapped.MaybeScope == Unscoped
16 | {
17 | public typealias FinalProvider = Provider<[Wrapped.FinalProvider.Element]>
18 | public typealias CollectionOrUnique = _CollectionBinding
19 |
20 | public let wrapped: Wrapped
21 |
22 | public init(wrapped: Wrapped) {
23 | self.wrapped = wrapped
24 | }
25 |
26 | public static func mapElement(input: Wrapped.Input) -> FinalProvider.Element {
27 | return [Wrapped.mapElement(input: input)]
28 | }
29 |
30 | public static var collectionMergeFunc: Optional<([FinalProvider.Element]) -> FinalProvider.Element> {
31 | return { Array($0.joined()) }
32 | }
33 | }
34 |
35 |
36 | public extension BindingBuilder where CollectionOrUnique == _UniqueBinding, FinalProvider: _StandardProvider, MaybeScope == Unscoped {
37 | /// If makes it bind `Element` to `[Element]`
38 | func intoCollection() -> SingularCollectionBindingBuilderDecorator {
39 | return with()
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Cleanse/ScopedBinder.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Binder.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 3/14/17.
6 | // Copyright © 2017 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | /// This is a Binder that is Scope aware
13 | public protocol BinderType : BinderBase {
14 | associatedtype Scope: Cleanse._ScopeBase
15 | }
16 |
17 | public struct Binder : BinderType, WrappedBinder {
18 | public let binder: BinderBase
19 |
20 | public init(binder: BinderBase) {
21 | // Optimization to reduce nesting of wrapped binders
22 | if let binder = binder as? WrappedBinder {
23 | self.binder = binder.binder
24 | } else {
25 | self.binder = binder
26 | }
27 | }
28 |
29 | public typealias Scope = S
30 | }
31 |
32 | extension BinderType {
33 | /// For including scoped modules
34 | public func include(module: M.Type) where M.Scope == Self.Scope, M.Scope: Cleanse.Scope {
35 | return include(module: AnyScopedModule.self)
36 | }
37 | }
38 |
39 | /// Used for making a module looks unscoped. This is so we can disambiguate includes
40 | private struct AnyScopedModule : Module {
41 | typealias Scope = Unscoped
42 |
43 | fileprivate static func configure(binder: UnscopedBinder) {
44 | M.configure(binder: .init(binder: binder))
45 | }
46 | }
47 |
48 | /// Default binder used
49 | public typealias UnscopedBinder = Binder
50 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Models/ImageStore.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ImageStore.swift
3 | // Exam1
4 | //
5 | // Created by Abdul Chathil on 6/8/20.
6 | // Copyright © 2020 Abdul Chathil. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 | import SwiftUI
12 |
13 | final class ImageStore {
14 | typealias _ImageDictionary = [String: CGImage]
15 | fileprivate var images: _ImageDictionary = [:]
16 |
17 | fileprivate static var scale = 2
18 |
19 | static var shared = ImageStore()
20 |
21 | func image(name: String) -> Image {
22 | let index = _guaranteeImage(name: name)
23 |
24 | return Image(images.values[index], scale: CGFloat(ImageStore.scale), label: Text(name))
25 | }
26 |
27 | static func loadImage(name: String) -> CGImage {
28 | guard
29 | let url = Bundle.main.url(forResource: name, withExtension: "jpg"),
30 | let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil),
31 | let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil)
32 | else {
33 | fatalError("Couldn't load image \(name).jpg from main bundle.")
34 | }
35 | return image
36 | }
37 |
38 | fileprivate func _guaranteeImage(name: String) -> _ImageDictionary.Index {
39 | if let index = images.index(forKey: name) { return index }
40 |
41 | images[name] = ImageStore.loadImage(name: name)
42 | return images.index(forKey: name)!
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Cleanse/PropertyInjector.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PropertyInjector.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 4/29/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | public protocol PropertyInjectorProtocol {
13 | associatedtype Element: AnyObject
14 | func injectProperties(into instance: Element)
15 | }
16 |
17 |
18 | /// This the mechanism property injection is done underneath the hood
19 | public struct PropertyInjector : PropertyInjectorProtocol {
20 | let injectionClosure: (Element) -> Void
21 |
22 | /// Call this to inject properties into an instance of an object.
23 | public func injectProperties(into instance: Element) {
24 | injectionClosure(instance)
25 | }
26 | }
27 |
28 |
29 | #if SUPPORT_LEGACY_OBJECT_GRAPH
30 |
31 | /// This is used to for legacy support
32 | protocol AnyPropertyInjectorProtocol {
33 | func untypedInjectProperties(into instance: AnyObject)
34 |
35 | static var injectedType: AnyClass { get }
36 | }
37 |
38 |
39 |
40 | extension PropertyInjectorProtocol {
41 | func untypedInjectProperties(into instance: AnyObject) {
42 | injectProperties(into: instance as! Element)
43 | }
44 |
45 | static var injectedType: AnyClass {
46 | return Element.self
47 | }
48 | }
49 |
50 | extension PropertyInjector : AnyPropertyInjectorProtocol {
51 |
52 | }
53 | #endif
54 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/GithubRepositoriesService.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GithubRepositoriesService.swift
3 | // CleanseGithubBrowser
4 | //
5 | // Created by Mike Lewis on 6/12/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 | struct GithubRepository {
13 | let name: String
14 | let watchersCount: Int
15 |
16 | static func fromJSON(_ json: [String: AnyObject]) -> GithubRepository {
17 | return .init(
18 | name: json["name"] as! String,
19 | watchersCount: json["watchers_count"] as! Int
20 | )
21 | }
22 | }
23 |
24 | /// Service that lists repositories for the current user
25 | protocol GithubRepositoriesService {
26 | func list(_ handler: @escaping (Result<[GithubRepository], Error>) -> Void)
27 | }
28 |
29 | struct GithubRepositoriesServiceImpl : GithubRepositoriesService {
30 | let githubURL: TaggedProvider
31 | let githubOrganizationName: TaggedProvider
32 |
33 | let urlSession: URLSession
34 |
35 | func list(_ handler: @escaping (Result<[GithubRepository], Error>) -> Void) {
36 | urlSession.jsonListTask(
37 | baseURL: githubURL.get(),
38 | pathComponents: "users", githubOrganizationName.get(), "repos",
39 | query: "sort=updated") { result in
40 | handler(result.map {
41 | $0.map(GithubRepository.fromJSON)
42 | })
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Cleanse/ComponentFactory.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ComponentFactory.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 7/6/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public protocol ComponentFactoryProtocol {
12 | associatedtype ComponentElement: Cleanse.ComponentBase
13 |
14 | func build(_ seed: ComponentElement.Seed) -> ComponentElement.Root
15 | }
16 |
17 | public final class ComponentFactory : ComponentFactoryProtocol {
18 | public typealias ComponentElement = C
19 | fileprivate let factoryFunction: (_ seed: ComponentElement.Seed, _ subgraph: Graph) -> C.Root
20 | fileprivate let parent: Graph?
21 | fileprivate var subgraphs: [Graph] = []
22 |
23 | init(parent: Graph?, factoryFunction: @escaping (_ seed: ComponentElement.Seed, _ subgraph: Graph) -> C.Root) {
24 | self.factoryFunction = factoryFunction
25 | self.parent = parent
26 | }
27 |
28 | /// Builds the Component and returns its root object.
29 | public func build(_ seed: ComponentElement.Seed) -> ComponentElement.Root {
30 | let subgraph = Graph(scope: C.Scope.scopeOrNil, parent: parent)
31 | subgraphs.append(subgraph)
32 | return factoryFunction(seed, subgraph)
33 | }
34 | }
35 |
36 | extension ComponentFactoryProtocol where ComponentElement.Seed: ProviderProtocol {
37 | public func build(_ seed: ComponentElement.Seed.Element) -> ComponentElement.Root {
38 | return build(ComponentElement.Seed.init(value: seed))
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/cleansec/Sandbox/Sandbox/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Sandbox
4 | //
5 | // Created by Sebastian Edward Shanus on 5/13/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Cleanse
11 |
12 | @UIApplicationMain
13 | class AppDelegate: UIResponder, UIApplicationDelegate {
14 |
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | // MARK: UISceneSession Lifecycle
23 |
24 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
25 | // Called when a new scene session is being created.
26 | // Use this method to select a configuration to create the new scene with.
27 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
28 | }
29 |
30 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
31 | // Called when the user discards a scene session.
32 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
33 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
34 | }
35 |
36 |
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/cleansec/SwiftAstParser/script/SyntaxVisitor.template:
--------------------------------------------------------------------------------
1 | // This file is generated! DO NOT EDIT!!
2 |
3 | public extension SyntaxVisitor {
4 | mutating func walk(_ node: Syntax) {
5 | var shouldVisitChildren = true
6 | if false {
7 | // Noop
8 | <% for @item in @decl_items %>
9 | } else if let node = node as? <%= @item.class_name %> {
10 | visit(node: node)
11 | shouldVisitChildren = visitChildren(node: node)
12 | <% end %>
13 | } else if let node = node as? UnknownSyntax {
14 | visit(node: node)
15 | shouldVisitChildren = visitChildren(node: node)
16 | }
17 |
18 | if shouldVisitChildren {
19 | node.children.forEach { walk($0) }
20 | }
21 | }
22 | }
23 |
24 | public protocol SyntaxVisitor {
25 | <% for @item in @decl_items %>
26 | mutating func visit(node: <%= @item.class_name %>)
27 | mutating func visitChildren(node: <%= @item.class_name %>) -> Bool
28 | <% end %>
29 | mutating func visit(node: UnknownSyntax)
30 | mutating func visitChildren(node: UnknownSyntax) -> Bool
31 | }
32 |
33 | public extension SyntaxVisitor {
34 | <% for @item in @decl_items %>
35 | mutating func visit(node: <%= @item.class_name %>) {
36 | // Noop
37 | }
38 | mutating func visitChildren(node: <%= @item.class_name %>) -> Bool {
39 | true
40 | }
41 | <% end %>
42 | mutating func visit(node: UnknownSyntax) {
43 | // Noop
44 | }
45 |
46 | mutating func visitChildren(node: UnknownSyntax) -> Bool {
47 | true
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/cleansec/CleansecFrameworkTests/LinkerTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LinkerTests.swift
3 | // CleansecFrameworkTests
4 | //
5 | // Created by Sebastian Edward Shanus on 5/12/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 | @testable import CleansecFramework
12 |
13 | class LinkerTests: XCTestCase {
14 | func testLinking() {
15 | let componentA = Component(
16 | type: "MyComponent",
17 | rootType: "Int",
18 | providers: [
19 | StandardProvider(type: "Int", dependencies: [], tag: nil, scoped: nil, collectionType: nil)
20 | ],
21 | seed: "Void",
22 | includedModules: [],
23 | subcomponents: [],
24 | isRoot: true
25 | )
26 | let componentB = Component(
27 | type: "SecondComponent",
28 | rootType: "Float",
29 | providers: [
30 | StandardProvider(type: "Float", dependencies: [], tag: nil, scoped: nil, collectionType: nil)
31 | ],
32 | seed: "Void",
33 | includedModules: [],
34 | subcomponents: [],
35 | isRoot: true
36 | )
37 | let fileA = FileRepresentation(components: [componentA], modules: [])
38 | let fileB = FileRepresentation(components: [componentB], modules: [])
39 | let moduleA = ModuleRepresentation(files: [fileA])
40 | let moduleB = ModuleRepresentation(files: [fileB])
41 | let interface = Linker.link(modules: [moduleA, moduleB])
42 | XCTAssertEqual(interface.components.count, 2)
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/cleansec/CleansecFrameworkTests/PluginTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PluginTests.swift
3 | // CleansecFrameworkTests
4 | //
5 | // Created by Sebastian Edward Shanus on 5/18/20.
6 | // Copyright © 2020 Square. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 | @testable import CleansecFramework
12 |
13 | class PluginTests: XCTestCase {
14 | func testBadPluginPath() {
15 | XCTAssertNil(Cleansec.run(plugin: "badecho", astFilePath: "."))
16 | }
17 |
18 | func testPluginOutput() {
19 | let provider = StandardProvider(type: "String", dependencies: [], tag: nil, scoped: nil, collectionType: nil)
20 | let module = Module(type: "Module", providers: [provider], includedModules: [], subcomponents: [])
21 | let file = FileRepresentation(components: [], modules: [module])
22 | let moduleRepresentation = ModuleRepresentation(files: [file])
23 | let encoder = JSONEncoder()
24 | encoder.outputFormatting = .prettyPrinted
25 | let data = try! encoder.encode(moduleRepresentation)
26 | let outputString = String(data: data, encoding: .utf8)!
27 |
28 | let pluginOutput = Cleansec.run(plugin: "/bin/echo", astFilePath: outputString)
29 | XCTAssertNotNil(pluginOutput)
30 | XCTAssertNotNil(pluginOutput?.files.first?.modules.first)
31 | XCTAssertEqual(pluginOutput?.files.first?.modules.first?.providers.first, provider)
32 | }
33 |
34 | func testPluginBadOutput() {
35 | let pluginOutput = Cleansec.run(plugin: "/bin/echo", astFilePath: "{\"something\": \"else\"}")
36 | XCTAssertNil(pluginOutput)
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/CleanseTests/DebuggingTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GraphTests.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 5/10/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | @testable import Cleanse
10 | import Foundation
11 | import XCTest
12 |
13 | struct Singleton : Scope {
14 | }
15 |
16 | class DebuggingTests: XCTestCase {
17 | struct FooModule : Module {
18 | static func configure(binder: UnscopedBinder) {
19 | binder.bind().to(value: 3)
20 | binder.bind().to(value: "Imma string")
21 | }
22 | }
23 |
24 | func testGraphDebugDescription() {
25 | // The graph's description should list providers. This may be useful for deubgging. This test is also to exercise code coverage of description methods
26 | let g = Graph(scope: Singleton.self)
27 |
28 | // TODO: make it more descriptive
29 | g.include(module: FooModule.self)
30 |
31 | try! g.finalize()
32 | let description = g.debugDescription
33 |
34 | Assert(description, contains: "Provider")
35 | Assert(description, contains: "Provider")
36 | Assert(description, contains: "Provider<() -> Int>")
37 | Assert(description, contains: "Provider<() -> String>")
38 | }
39 | }
40 |
41 | func Assert(_ entireString: @autoclosure () throws -> String, contains expectedContents: @autoclosure () throws -> String, file: StaticString = #file, line: UInt = #line) {
42 | XCTAssertTrue(try entireString().contains(expectedContents()), "Expected \(try! entireString())\nto contain \(try! expectedContents())", file: file, line: line)
43 | }
44 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/Views/Components/PetRow.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PetRow.swift
3 | // Exam1
4 | //
5 | // Created by Abdul Chathil on 6/7/20.
6 | // Copyright © 2020 Abdul Chathil. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 |
12 |
13 | struct PetRow: View {
14 | @EnvironmentObject var userData: UserData
15 | var pet: Pet
16 | var petIndex: Int {
17 | userData.pets.firstIndex(where: { $0.id == pet.id })!
18 | }
19 | var body: some View {
20 | HStack {
21 | pet.image.resizable().scaledToFill().frame(width: 112, height: 112, alignment: .center).clipped()
22 | VStack(alignment: .leading) {
23 | Text(pet.name)
24 | .font(.headline)
25 | .fontWeight(.bold)
26 | .foregroundColor(.black)
27 | Text(pet.location).foregroundColor(.black)
28 | HStack {
29 | LikeButton(isLiked: self.userData.pets[self.petIndex].isLiked).padding().onTapGesture {
30 | self.userData.pets[self.petIndex].isLiked.toggle()
31 | }
32 | PetBadge(type: pet.type)
33 | }
34 | }
35 | Spacer()
36 | }.clipShape(RoundedRectangle(cornerRadius: 16.0))
37 | }
38 | static let gradientStart = Color(red: 0.0 / 255, green: 150.0 / 255, blue: 136.0 / 255)
39 | static let gradientEnd = Color(red: 224.0 / 255, green: 242.0 / 255, blue: 241.0 / 255)
40 | }
41 |
42 | struct PetRow_Previews: PreviewProvider {
43 | static var previews: some View {
44 | PetRow(pet: petData[0]).environmentObject(UserData())
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/cleansec/Sandbox/Sandbox/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/GithubServicesModule.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GithubServicesModule.swift
3 | // CleanseGithubBrowser
4 | //
5 | // Created by Mike Lewis on 6/12/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cleanse
11 |
12 |
13 | protocol GithubServicesModule : Module {
14 | static func configureGithubMembersService(binder bind: ReceiptBinder) -> BindingReceipt
15 | static func configureRepositoriesMembersService(binder bind: ReceiptBinder) -> BindingReceipt
16 | }
17 |
18 |
19 | /// Wires up common definitions shared across services as well as installing the services's modules
20 | struct RealeaseGithubServicesModule : GithubServicesModule {
21 | static func configure(binder: SingletonBinder) {
22 | binder.include(module: NetworkModule.self)
23 | }
24 |
25 | static func configureGithubMembersService(binder bind: ReceiptBinder) -> BindingReceipt {
26 | return bind.to(factory: GithubMembersServiceImpl.init)
27 | }
28 |
29 | static func configureRepositoriesMembersService(binder bind: ReceiptBinder) -> BindingReceipt {
30 | return bind.to(factory: GithubRepositoriesServiceImpl.init)
31 | }
32 | }
33 |
34 | struct GithubBaseURL : Tag {
35 | typealias Element = URL
36 | }
37 |
38 | /// Represents the github user name we want to query.
39 | struct GithubUserName : Tag {
40 | typealias Element = String
41 | }
42 |
43 | struct GithubOrganizationName : Tag {
44 | typealias Element = String
45 | }
46 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Cleanse CHANGELOG
2 |
3 | ## Master
4 |
5 | #### Features & Updates
6 |
7 | * New Example: CleanseSwiftUIExample.
8 | [Abdul Chathil](https://github.com/chathil)
9 | [#176](https://github.com/square/Cleanse/pull/176)
10 |
11 | #### Bug Fixes
12 |
13 | * None
14 |
15 | ## 4.2.6
16 |
17 | #### Features & Updates
18 |
19 | * cleansec: Cleanse Compiler ([README](https://github.com/square/Cleanse/blob/master/cleansec/README.md))
20 | [Sebastian Shanus](https://github.com/sebastianv1)
21 |
22 | #### Bug Fixes
23 |
24 | * Fix Assisted Injection `SourceLocation` info.
25 | [Sebastian Shanus](https://github.com/sebastianv1)
26 | [#166](https://github.com/square/Cleanse/pull/166)
27 |
28 | * Fix `WeakProviders` becoming deinitialized.
29 | [Sebastian Shanus](https://github.com/sebastianv1)
30 | [#98](https://github.com/square/Cleanse/issues/98)
31 |
32 | ## 4.2.5
33 |
34 | #### Features & Updates
35 |
36 | * Replace demo app's ErrorOptional type with Swift Foundation Result type
37 | [Sihao Lu](https://github.com/DJBen)
38 | [#126](https://github.com/square/Cleanse/pull/126)
39 |
40 | * Xcode 11.2 Support
41 | [Sebastian Shanus](https://github.com/sebastianv1)
42 | [#125](https://github.com/square/Cleanse/issues/125)
43 |
44 | * Service Provider Interface (SPI)
45 | [Sebastian Shanus](https://github.com/sebastianv1)
46 | [#118](https://github.com/square/Cleanse/issues/118)
47 |
48 | * Assisted Injection
49 | [Sebastian Shanus](https://github.com/sebastianv1)
50 | [#112](https://github.com/square/Cleanse/issues/112)
51 |
52 | #### Bug Fixes
53 |
54 | * Retain subcomponent graphs
55 | [Sebastian Shanus](https://github.com/sebastianv1)
56 | [#42](https://github.com/square/Cleanse/issues/42)
57 |
--------------------------------------------------------------------------------
/CleanseTests/SubcomponentTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SubcomponentTests.swift
3 | // CleanseTests
4 | //
5 | // Created by Sebastian Edward Shanus on 12/16/19.
6 | // Copyright © 2019 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 | import Cleanse
12 |
13 | struct A {
14 | let b: Provider
15 | }
16 |
17 | struct B {
18 | let subcomponent: ComponentFactory
19 | }
20 |
21 | struct RootType {
22 | let a: A
23 | }
24 |
25 | struct Subroot {
26 | let name: String
27 | }
28 |
29 | struct AppRootComponent: RootComponent {
30 | static func configure(binder: Binder) {
31 | binder.install(dependency: SubComponent.self)
32 | binder.bind(A.self).to(factory: A.init)
33 | binder.bind(B.self).to(factory: B.init)
34 | }
35 |
36 | static func configureRoot(binder bind: ReceiptBinder) -> BindingReceipt {
37 | return bind.to(factory: RootType.init)
38 | }
39 |
40 | typealias Root = RootType
41 | }
42 |
43 | struct SubComponent: Component {
44 | static func configure(binder: Binder) {
45 | binder
46 | .bind(String.self)
47 | .to(value: "Hello")
48 | }
49 |
50 | static func configureRoot(binder bind: ReceiptBinder) -> BindingReceipt {
51 | return bind.to(factory: Subroot.init)
52 | }
53 |
54 | typealias Root = Subroot
55 | }
56 |
57 |
58 | class SubcomponentTests: XCTestCase {
59 | func testNestedSubcomponents() {
60 | let root = try! ComponentFactory.of(AppRootComponent.self).build(())
61 | let subcomponent = root.a.b.get().subcomponent.build(())
62 | XCTAssert(subcomponent.name == "Hello")
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/cleansec/Sandbox/Sandbox/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Examples/CleanseSwiftUIExample/CleanseSwiftUIExample/SupportingFiles/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | adoptme
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UIApplicationSceneManifest
26 |
27 | UIApplicationSupportsMultipleScenes
28 |
29 |
30 | UIApplicationSupportsIndirectInputEvents
31 |
32 | UILaunchScreen
33 |
34 | UIRequiredDeviceCapabilities
35 |
36 | armv7
37 |
38 | UISupportedInterfaceOrientations
39 |
40 | UIInterfaceOrientationPortrait
41 |
42 | UISupportedInterfaceOrientations~ipad
43 |
44 | UIInterfaceOrientationPortrait
45 | UIInterfaceOrientationPortraitUpsideDown
46 | UIInterfaceOrientationLandscapeLeft
47 | UIInterfaceOrientationLandscapeRight
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/CleansePlayground.playground/playground.xcworkspace/xcshareddata/CleansePlayground.xcscmblueprint:
--------------------------------------------------------------------------------
1 | {
2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "FA78EFA588CAAA527A39EFF7FEB4200B880E2491",
3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
4 |
5 | },
6 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
7 | "FA78EFA588CAAA527A39EFF7FEB4200B880E2491" : 9223372036854775807,
8 | "C29DD0E89C17000393FD71820E9E7C86451DD28A" : 0
9 | },
10 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "C9383146-7609-43F6-A193-8ABE1B105154",
11 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
12 | "FA78EFA588CAAA527A39EFF7FEB4200B880E2491" : "Cleanse\/",
13 | "C29DD0E89C17000393FD71820E9E7C86451DD28A" : ".."
14 | },
15 | "DVTSourceControlWorkspaceBlueprintNameKey" : "CleansePlayground",
16 | "DVTSourceControlWorkspaceBlueprintVersion" : 204,
17 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "CleansePlayground.playground",
18 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
19 | {
20 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "ssh:\/\/git.corp.squareup.com\/ios\/appointments.git",
21 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
22 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "C29DD0E89C17000393FD71820E9E7C86451DD28A"
23 | },
24 | {
25 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "ssh:\/\/git.corp.squareup.com\/ml\/cleanse.git",
26 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
27 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "FA78EFA588CAAA527A39EFF7FEB4200B880E2491"
28 | }
29 | ]
30 | }
--------------------------------------------------------------------------------
/Cleanse/BindingBuilderDecorator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BindingBuilderDecorator.swift
3 | // Cleanse
4 | //
5 | // Created by Mike Lewis on 5/9/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | public protocol BindingBuilderDecorator : BindingBuilder {
13 | associatedtype Wrapped: BindingBuilder
14 |
15 | init(wrapped: Wrapped)
16 | var wrapped: Wrapped { get }
17 |
18 | /// Support for collection binding. Users probably don't have to worry about this. Also they have default implementations
19 | /// TODO: Move elsewhere perhaps
20 | associatedtype MaybeScope = Wrapped.MaybeScope
21 | associatedtype Input = Wrapped.Input
22 | associatedtype Binder = Wrapped.Binder
23 | associatedtype FinalProvider = Wrapped.FinalProvider
24 |
25 | associatedtype CollectionOrUnique = Wrapped.CollectionOrUnique
26 |
27 | static var collectionMergeFunc: Optional<([FinalProvider.Element]) -> FinalProvider.Element> { get }
28 | }
29 |
30 |
31 | extension BindingBuilderDecorator where FinalProvider.Element == Wrapped.FinalProvider.Element {
32 | public static var collectionMergeFunc: Optional<([FinalProvider.Element]) -> FinalProvider.Element> {
33 | guard let wrappedF = Wrapped.collectionMergeFunc else {
34 | return nil
35 | }
36 |
37 | return wrappedF
38 | }
39 | }
40 |
41 | extension BindingBuilderDecorator where Self.Binder == Wrapped.Binder {
42 | public var binder: Self.Binder {
43 | return wrapped.binder
44 | }
45 | }
46 |
47 | extension BindingBuilderDecorator where Input == Wrapped.Input, FinalProvider.Element == Wrapped.FinalProvider.Element {
48 | public static func mapElement(input: Input) -> FinalProvider.Element {
49 | return Wrapped.mapElement(input: input)
50 | }
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/NSURLSessionAdditions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NSURLSessionAdditions.swift
3 | // CleanseGithubBrowser
4 | //
5 | // Created by Mike Lewis on 6/12/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | extension URLSession {
13 | func jsonTask(baseURL: URL, pathComponents: String..., resultHandler: @escaping (Result) -> Void) -> URLSessionDataTask {
14 | let url = baseURL.appendingPathComponent(pathComponents.joined(separator: "/"))
15 | return jsonTask(url: url as URL, resultHandler: resultHandler)
16 | }
17 |
18 | private func jsonTask(url: URL, resultHandler: @escaping (Result) -> Void) -> URLSessionDataTask {
19 | let task = self.dataTask(with: url as URL) { (data, response, error) in
20 | if let error: Error = error ?? HTTPError(statusCode: (response as! HTTPURLResponse).statusCode) {
21 | resultHandler(.failure(error))
22 | return
23 | }
24 |
25 | do {
26 | try resultHandler(.success(JSONSerialization.jsonObject(with: data!, options: [])))
27 | } catch let e {
28 | resultHandler(.failure(e))
29 | return
30 | }
31 | }
32 |
33 | task.resume()
34 | return task
35 | }
36 |
37 | @discardableResult
38 | func jsonListTask(
39 | baseURL: URL,
40 | pathComponents: String...,
41 | query: String? = nil,
42 | resultHandler: @escaping (Result<[[String: AnyObject]], Error>) -> Void
43 | ) -> URLSessionDataTask {
44 | var url = baseURL.appendingPathComponent(pathComponents.joined(separator: "/"))
45 |
46 | if let query = query {
47 | url = URL(string: url.absoluteString + "?" + query)!
48 | }
49 |
50 | return jsonTask(url: url) { resultHandler($0.map { $0 as! [[String: AnyObject]] }) }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Examples/CleanseGithubBrowser/CleanseGithubBrowser/UIKitCommonModule.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppModule.swift
3 | // CleanseGithubBrowser
4 | //
5 | // Created by Mike Lewis on 6/10/16.
6 | // Copyright © 2016 Square, Inc. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Cleanse
11 |
12 | /// Define common UIKit bindings.
13 | public struct UIKitCommonModule : Module {
14 | public static func configure(binder: UnscopedBinder) {
15 |
16 | binder.include(module: UIScreen.Module.self)
17 | binder.include(module: UIWindow.Module.self)
18 | }
19 | }
20 |
21 | extension UIScreen {
22 | /// This is a simple module that binds UIScreen.mainScreen() to UIScreen
23 | public struct Module : Cleanse.Module {
24 | public static func configure(binder: UnscopedBinder) {
25 | binder
26 | .bind(UIScreen.self)
27 | .to { UIScreen.main }
28 | }
29 | }
30 | }
31 |
32 | extension UIWindow {
33 | /// This is the module that configures how we build our main window. It ias assumed when one requests
34 | /// injection of an un-tagged UIWindow, we will be giving them the "main" or "key" window.
35 | public struct Module : Cleanse.Module {
36 | public static func configure(binder: UnscopedBinder) {
37 | binder
38 | .bind(UIWindow.self)
39 | // .sharedInScope() FIXME what does this break?
40 | .to { (rootViewController: TaggedProvider, mainScreen: UIScreen) in
41 | let window = UIWindow(frame: mainScreen.bounds)
42 | window.rootViewController = rootViewController.get()
43 | return window
44 | }
45 | }
46 | }
47 | }
48 |
49 | extension UIViewController {
50 | /// This will represent the rootViewController that is assigned to our main window
51 | public struct Root : Tag {
52 | public typealias Element = UIViewController
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/cleansec/script/swiftc-ast.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | require 'pathname'
4 | require 'fileutils'
5 |
6 | DISALLOWED_ARGUMENTS = {
7 | '-emit-dependencies' => :none,
8 | '-emit-module' => :none,
9 | '-emit-module-path' => :arg,
10 | '-emit-objc-header' => :none,
11 | '-emit-objc-header-path' => :arg,
12 | '-c' => :none,
13 | '-incremental' => :none,
14 | '-parseable-output' => :none
15 | }
16 |
17 | def swiftc_executable
18 | Pathname.new(ENV['DEVELOPER_DIR']).join('Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc')
19 | end
20 |
21 | def strip_disallowed_arguments(disallowed_args, input)
22 | input.each_index.select do |idx|
23 | disallowed_args.key?(input[idx])
24 | end
25 | end
26 |
27 |
28 | def main
29 | input = ARGV
30 | og_command = [swiftc_executable] + input
31 | ast_input = input.clone
32 | indices_to_remove = strip_disallowed_arguments(DISALLOWED_ARGUMENTS, ast_input).flat_map do |idx|
33 | if DISALLOWED_ARGUMENTS[input[idx]] == :arg
34 | [idx, idx+1]
35 | else
36 | [idx]
37 | end
38 | end
39 |
40 | indices_to_remove.sort.reverse.each do |idx|
41 | ast_input.delete_at(idx)
42 | end
43 |
44 | pipe_to_file_command = ['2>&1']
45 | if output_file = input.grep(/DAST_FILE/).first
46 | outpath_file_path = output_file.split('=')[1]
47 | FileUtils.mkdir_p(Pathname.new(outpath_file_path).dirname)
48 | pipe_to_file_command = ['&>'] + [outpath_file_path]
49 | end
50 |
51 | dump_ast_command = [swiftc_executable] + ['-dump-ast', '-suppress-warnings'] + ast_input + pipe_to_file_command
52 | sanitized_og_command = og_command.map { |c| c.to_s.gsub(/\s/, "\\ ") }
53 | sanitized_ast_command = dump_ast_command.map { |c| c.to_s.gsub(/\s/, "\\ ") }
54 | if ENV["DISABLE_DUMP_AST"]
55 | status = system(sanitized_og_command.join(" "))
56 | exit(1) unless status
57 | else
58 | pid = spawn(sanitized_ast_command.join(" "))
59 | status = system(sanitized_og_command.join(" "))
60 | Process.wait(pid)
61 | exit(1) unless status
62 | end
63 | end
64 |
65 | main
66 |
67 |
68 |
--------------------------------------------------------------------------------