├── .codeclimate.yml ├── .gitignore ├── .tailor.yml ├── .travis.yml ├── GraphQL.playground ├── Contents.swift ├── contents.xcplayground └── playground.xcworkspace │ └── contents.xcworkspacedata ├── LICENSE ├── README.md ├── Sources ├── GraphQL.h ├── Info-OSX.plist ├── Info-iOS.plist ├── Info-tvOS.plist ├── Info-watchOS.plist ├── graphql.swift └── language │ ├── Ast.swift │ ├── Lexer.swift │ ├── Parser.swift │ ├── Printer.swift │ └── Visitor.swift ├── Tests ├── Info-OSX.plist ├── Info-iOS.plist ├── Info-tvOS.plist ├── language │ ├── LexerTests.swift │ ├── ParserTests.swift │ ├── PrinterTests.swift │ └── VisitorTests.swift ├── resources │ └── kitchen_sink.graphql └── utilities │ └── TestUtilities.swift ├── graphql.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ ├── GraphQL OS X Tests.xcscheme │ ├── GraphQL OS X.xcscheme │ ├── GraphQL iOS Tests.xcscheme │ ├── GraphQL iOS.xcscheme │ ├── GraphQL tvOS Tests.xcscheme │ ├── GraphQL tvOS.xcscheme │ └── GraphQL watchOS.xcscheme ├── graphql.xcworkspace └── contents.xcworkspacedata └── scripts ├── ci └── tailor /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | --- 2 | engines: 3 | fixme: 4 | enabled: true 5 | tailor: 6 | enabled: true 7 | ratings: 8 | paths: 9 | - Sources/**.swift 10 | exclude_paths: 11 | - Tests 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | target/ 3 | 4 | # AppCode 5 | .idea/ 6 | 7 | # Xcode 8 | # 9 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 10 | 11 | ## Build generated 12 | build/ 13 | DerivedData/ 14 | 15 | ## Various settings 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | xcuserdata/ 25 | 26 | ## Other 27 | *.moved-aside 28 | *.xcuserstate 29 | 30 | ## Obj-C/Swift specific 31 | *.hmap 32 | *.ipa 33 | 34 | ## Playgrounds 35 | timeline.xctimeline 36 | playground.xcworkspace 37 | 38 | # Swift Package Manager 39 | # 40 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 41 | # Packages/ 42 | .build/ 43 | 44 | # CocoaPods 45 | # 46 | # We recommend against adding the Pods directory to your .gitignore. However 47 | # you should judge for yourself, the pros and cons are mentioned at: 48 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 49 | # 50 | # Pods/ 51 | 52 | # Carthage 53 | # 54 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 55 | # Carthage/Checkouts 56 | 57 | Carthage/Build 58 | 59 | # fastlane 60 | # 61 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 62 | # screenshots whenever they are needed. 63 | # For more information about the recommended setup visit: 64 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 65 | 66 | fastlane/report.xml 67 | fastlane/Preview.html 68 | fastlane/screenshots 69 | fastlane/test_output 70 | 71 | tailor_report.html 72 | -------------------------------------------------------------------------------- /.tailor.yml: -------------------------------------------------------------------------------- 1 | include: 2 | - Sources 3 | - Tests 4 | exclude: 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode7.3 3 | before_install: 4 | - gem install xcpretty 5 | - gem install xcpretty-travis-formatter 6 | script: scripts/ci $platform 7 | env: 8 | - platform=iOS 9 | - platform=tvOS 10 | - platform=OSX 11 | -------------------------------------------------------------------------------- /GraphQL.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | var str = "Hello, playground" 4 | -------------------------------------------------------------------------------- /GraphQL.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /GraphQL.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Vincent Garrigues 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **ABANDONED** check this out: [https://github.com/graphqlswift](https://github.com/graphqlswift) 2 | 3 | # GraphQL Swift [![Build Status](https://travis-ci.org/garriguv/graphql-swift.svg?branch=master)](https://travis-ci.org/garriguv/graphql-swift) [![Code Climate](https://codeclimate.com/github/garriguv/graphql-swift/badges/gpa.svg)](https://codeclimate.com/github/garriguv/graphql-swift) 4 | 5 | Swift implementation of [GraphQL]. 6 | 7 | ## Unit tests 8 | 9 | ./scripts/ci OSX 10 | ./scripts/ci iOS 11 | ./scripts/ci tvOS 12 | 13 | ## Linter 14 | 15 | ./scripts/tailor 16 | 17 | [GraphQL]: http://graphql.org/ 18 | -------------------------------------------------------------------------------- /Sources/GraphQL.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #if (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR) 4 | @import UIKit; 5 | #else 6 | #import 7 | #endif 8 | 9 | //! Project version number for GraphQL. 10 | FOUNDATION_EXPORT double GraphQLVersionNumber; 11 | 12 | //! Project version string for GraphQL. 13 | FOUNDATION_EXPORT const unsigned char GraphQLVersionString[]; 14 | -------------------------------------------------------------------------------- /Sources/Info-OSX.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 | -------------------------------------------------------------------------------- /Sources/Info-iOS.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 | -------------------------------------------------------------------------------- /Sources/Info-tvOS.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 | -------------------------------------------------------------------------------- /Sources/Info-watchOS.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 | -------------------------------------------------------------------------------- /Sources/graphql.swift: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/garriguv/graphql-swift/ebe7a325a1683d1e8659fbd7ecafc525665c1481/Sources/graphql.swift -------------------------------------------------------------------------------- /Sources/language/Ast.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public protocol Node {} 4 | 5 | public struct Document: Node { 6 | let definitions: [Definition] 7 | } 8 | 9 | extension Document: Equatable {} 10 | 11 | public func == (lhs: Document, rhs: Document) -> Bool { 12 | return lhs.definitions == rhs.definitions 13 | } 14 | 15 | public enum Definition: Node { 16 | case Operation(OperationDefinition) 17 | case Fragment(FragmentDefinition) 18 | case Type(TypeDefinition) 19 | case TypeExtension(TypeExtensionDefinition) 20 | } 21 | 22 | extension Definition: Equatable {} 23 | 24 | public func == (lhs: Definition, rhs: Definition) -> Bool { 25 | switch (lhs, rhs) { 26 | case (.Operation(let lhsOperation), .Operation(let rhsOperation)): 27 | return lhsOperation == rhsOperation 28 | case (.Fragment(let lhsFragment), .Fragment(let rhsFragment)): 29 | return lhsFragment == rhsFragment 30 | case (.Type(let lhsType), .Type(let rhsType)): 31 | return lhsType == rhsType 32 | case (.TypeExtension(let lhsTypeExtension), .TypeExtension(let rhsTypeExtension)): 33 | return lhsTypeExtension == rhsTypeExtension 34 | default: 35 | return false 36 | } 37 | } 38 | 39 | public struct VariableDefinition: Node { 40 | let variable: Variable 41 | let type: Type 42 | let defaultValue: Value? 43 | } 44 | 45 | extension VariableDefinition: Equatable {} 46 | 47 | public func == (lhs: VariableDefinition, rhs: VariableDefinition) -> Bool { 48 | return lhs.variable == rhs.variable && 49 | lhs.type == rhs.type && 50 | lhs.defaultValue == rhs.defaultValue 51 | } 52 | 53 | public struct Variable: Node { 54 | let name: Name 55 | } 56 | 57 | extension Variable: Equatable {} 58 | 59 | public func == (lhs: Variable, rhs: Variable) -> Bool { 60 | return lhs.name == rhs.name 61 | } 62 | 63 | public struct SelectionSet: Node { 64 | let selections: [Selection] 65 | } 66 | 67 | extension SelectionSet: Equatable {} 68 | 69 | public func == (lhs: SelectionSet, rhs: SelectionSet) -> Bool { 70 | return lhs.selections == rhs.selections 71 | } 72 | 73 | public enum Selection: Node { 74 | case FieldSelection(Field) 75 | case FragmentSpreadSelection(FragmentSpread) 76 | case InlineFragmentSelection(InlineFragment) 77 | } 78 | 79 | extension Selection: Equatable {} 80 | 81 | public func == (lhs: Selection, rhs: Selection) -> Bool { 82 | switch (lhs, rhs) { 83 | case (.FieldSelection(let lhsField), .FieldSelection(let rhsField)): 84 | return lhsField == rhsField 85 | case (.FragmentSpreadSelection(let lhsFragmentSpread), .FragmentSpreadSelection(let rhsFragmentSpread)): 86 | return lhsFragmentSpread == rhsFragmentSpread 87 | case (.InlineFragmentSelection(let lhsInlineFragment), .InlineFragmentSelection(let rhsInlineFragment)): 88 | return lhsInlineFragment == rhsInlineFragment 89 | default: 90 | return false 91 | } 92 | } 93 | 94 | public struct FragmentSpread: Node { 95 | let name: Name 96 | let directives: [Directive] 97 | } 98 | 99 | extension FragmentSpread: Equatable {} 100 | 101 | public func == (lhs: FragmentSpread, rhs: FragmentSpread) -> Bool { 102 | return lhs.name == rhs.name && 103 | lhs.directives == rhs.directives 104 | } 105 | 106 | public struct InlineFragment: Node { 107 | let typeCondition: Type? 108 | let directives: [Directive] 109 | let selectionSet: SelectionSet 110 | } 111 | 112 | extension InlineFragment: Equatable {} 113 | 114 | public func == (lhs: InlineFragment, rhs: InlineFragment) -> Bool { 115 | return lhs.typeCondition == rhs.typeCondition && 116 | lhs.directives == rhs.directives && 117 | lhs.selectionSet == rhs.selectionSet 118 | } 119 | 120 | public struct FragmentDefinition: Node { 121 | let name: Name 122 | let typeCondition: Type 123 | let directives: [Directive] 124 | let selectionSet: SelectionSet 125 | } 126 | 127 | extension FragmentDefinition: Equatable {} 128 | 129 | public func == (lhs: FragmentDefinition, rhs: FragmentDefinition) -> Bool { 130 | return lhs.name == rhs.name && 131 | lhs.typeCondition == rhs.typeCondition && 132 | lhs.directives == rhs.directives && 133 | lhs.selectionSet == rhs.selectionSet 134 | } 135 | 136 | public indirect enum Value: Node { 137 | case VariableValue(Variable) 138 | case IntValue(String) 139 | case FloatValue(String) 140 | case StringValue(String) 141 | case BoolValue(String) 142 | case Enum(String) 143 | case List([Value]) 144 | case Object([ObjectField]) 145 | } 146 | 147 | extension Value: Equatable {} 148 | 149 | public func == (lhs: Value, rhs: Value) -> Bool { 150 | switch (lhs, rhs) { 151 | case (.VariableValue(let lhsValue), .VariableValue(let rhsValue)): 152 | return lhsValue == rhsValue 153 | case (.IntValue(let lhsValue), .IntValue(let rhsValue)): 154 | return lhsValue == rhsValue 155 | case (.FloatValue(let lhsValue), .FloatValue(let rhsValue)): 156 | return lhsValue == rhsValue 157 | case (.StringValue(let lhsValue), .StringValue(let rhsValue)): 158 | return lhsValue == rhsValue 159 | case (.BoolValue(let lhsValue), .BoolValue(let rhsValue)): 160 | return lhsValue == rhsValue 161 | case (.Enum(let lhsValue), .Enum(let rhsValue)): 162 | return lhsValue == rhsValue 163 | case (.List(let lhsValue), .List(let rhsValue)): 164 | return lhsValue == rhsValue 165 | case (.Object(let lhsValue), .Object(let rhsValue)): 166 | return lhsValue == rhsValue 167 | default: 168 | return false 169 | } 170 | } 171 | 172 | public struct ObjectField: Node { 173 | let name: Name 174 | let value: Value 175 | } 176 | 177 | extension ObjectField: Equatable {} 178 | 179 | public func == (lhs: ObjectField, rhs: ObjectField) -> Bool { 180 | return lhs.name == rhs.name && 181 | lhs.value == rhs.value 182 | } 183 | 184 | public struct Directive: Node { 185 | let name: Name 186 | let arguments: [Argument] 187 | } 188 | 189 | extension Directive: Equatable {} 190 | 191 | public func == (lhs: Directive, rhs: Directive) -> Bool { 192 | return lhs.name == rhs.name && 193 | lhs.arguments == rhs.arguments 194 | } 195 | 196 | public indirect enum Type: Node { 197 | case Named(Name) 198 | case List(Type) 199 | case NonNull(Type) 200 | } 201 | 202 | extension Type: Equatable {} 203 | 204 | public func == (lhs: Type, rhs: Type) -> Bool { 205 | switch (lhs, rhs) { 206 | case (.Named(let lhsName), .Named(let rhsName)): 207 | return lhsName == rhsName 208 | case (.List(let lhsList), .List(let rhsList)): 209 | return lhsList == rhsList 210 | case (.NonNull(let lhsType), .NonNull(let rhsType)): 211 | return lhsType == rhsType 212 | default: 213 | return false 214 | } 215 | } 216 | 217 | public struct Argument: Node { 218 | let name: Name 219 | let value: Value 220 | } 221 | 222 | extension Argument: Equatable {} 223 | 224 | public func == (lhs: Argument, rhs: Argument) -> Bool { 225 | return lhs.name == rhs.name && 226 | lhs.value == rhs.value 227 | } 228 | 229 | public enum OperationType: String { 230 | case Query = "query", Mutation = "mutation", Subscription = "subscription" 231 | } 232 | 233 | public struct OperationDefinition: Node { 234 | let type: OperationType 235 | let name: Name? 236 | let variableDefinitions: [VariableDefinition] 237 | let directives: [Directive] 238 | let selectionSet: SelectionSet 239 | } 240 | 241 | extension OperationDefinition: Equatable {} 242 | 243 | public func == (lhs: OperationDefinition, rhs: OperationDefinition) -> Bool { 244 | return lhs.type == rhs.type && 245 | lhs.name == rhs.name && 246 | lhs.variableDefinitions == rhs.variableDefinitions && 247 | lhs.directives == rhs.directives && 248 | lhs.selectionSet == rhs.selectionSet 249 | } 250 | 251 | public struct Name: Node { 252 | let value: String? 253 | } 254 | 255 | extension Name: Equatable {} 256 | 257 | public func == (lhs: Name, rhs: Name) -> Bool { 258 | return lhs.value == rhs.value 259 | } 260 | 261 | public struct Field: Node { 262 | let alias: Name? 263 | let name: Name 264 | let arguments: [Argument] 265 | let directives: [Directive] 266 | let selectionSet: SelectionSet? 267 | } 268 | 269 | extension Field: Equatable {} 270 | 271 | public func == (lhs: Field, rhs: Field) -> Bool { 272 | return lhs.alias == rhs.alias && 273 | lhs.name == rhs.name && 274 | lhs.arguments == rhs.arguments && 275 | lhs.directives == rhs.directives && 276 | lhs.selectionSet == rhs.selectionSet 277 | } 278 | 279 | public enum TypeDefinition: Node { 280 | case Object(ObjectTypeDefinition) 281 | case Interface(InterfaceTypeDefinition) 282 | case Union(UnionTypeDefinition) 283 | case Scalar(ScalarTypeDefinition) 284 | case Enum(EnumTypeDefinition) 285 | case InputObject(InputObjectTypeDefinition) 286 | } 287 | 288 | extension TypeDefinition: Equatable {} 289 | 290 | public func == (lhs: TypeDefinition, rhs: TypeDefinition) -> Bool { 291 | switch (lhs, rhs) { 292 | case (.Object(let rhsObject), .Object(let lhsObject)): 293 | return rhsObject == lhsObject 294 | case (.Interface(let rhsInterface), .Interface(let lhsInterface)): 295 | return rhsInterface == lhsInterface 296 | case (.Union(let rhsUnion), .Union(let lhsUnion)): 297 | return rhsUnion == lhsUnion 298 | case (.Scalar(let rhsScalar), .Scalar(let lhsScalar)): 299 | return rhsScalar == lhsScalar 300 | case (.Enum(let rhsEnum), .Enum(let lhsEnum)): 301 | return rhsEnum == lhsEnum 302 | case (.InputObject(let rhsInputObject), .InputObject(let lhsInputObject)): 303 | return rhsInputObject == lhsInputObject 304 | default: 305 | return false 306 | } 307 | } 308 | 309 | public struct ObjectTypeDefinition: Node { 310 | let name: Name 311 | let interfaces: [Type] 312 | let fields: [FieldDefinition] 313 | } 314 | 315 | extension ObjectTypeDefinition: Equatable {} 316 | 317 | public func == (lhs: ObjectTypeDefinition, rhs: ObjectTypeDefinition) -> Bool { 318 | return lhs.name == rhs.name && 319 | lhs.interfaces == rhs.interfaces && 320 | lhs.fields == rhs.fields 321 | } 322 | 323 | public struct FieldDefinition: Node { 324 | let name: Name 325 | let arguments: [InputValueDefinition] 326 | let type: Type 327 | } 328 | 329 | extension FieldDefinition: Equatable {} 330 | 331 | public func == (lhs: FieldDefinition, rhs: FieldDefinition) -> Bool { 332 | return lhs.name == rhs.name && 333 | lhs.arguments == rhs.arguments && 334 | lhs.type == rhs.type 335 | } 336 | 337 | public struct InputValueDefinition: Node { 338 | let name: Name 339 | let type: Type 340 | let defaultValue: Value? 341 | } 342 | 343 | extension InputValueDefinition: Equatable {} 344 | 345 | public func == (lhs: InputValueDefinition, rhs: InputValueDefinition) -> Bool { 346 | return lhs.name == rhs.name && 347 | lhs.type == rhs.type && 348 | lhs.defaultValue == rhs.defaultValue 349 | } 350 | 351 | public struct InterfaceTypeDefinition: Node { 352 | let name: Name 353 | let fields: [FieldDefinition] 354 | } 355 | 356 | extension InterfaceTypeDefinition: Equatable {} 357 | 358 | public func == (lhs: InterfaceTypeDefinition, rhs: InterfaceTypeDefinition) -> Bool { 359 | return lhs.name == rhs.name && 360 | lhs.fields == rhs.fields 361 | } 362 | 363 | public struct UnionTypeDefinition: Node { 364 | let name: Name 365 | let types: [Type] 366 | } 367 | 368 | extension UnionTypeDefinition: Equatable {} 369 | 370 | public func == (lhs: UnionTypeDefinition, rhs: UnionTypeDefinition) -> Bool { 371 | return lhs.name == rhs.name && 372 | lhs.types == rhs.types 373 | } 374 | 375 | public struct ScalarTypeDefinition: Node { 376 | let name: Name 377 | } 378 | 379 | extension ScalarTypeDefinition: Equatable {} 380 | 381 | public func == (lhs: ScalarTypeDefinition, rhs: ScalarTypeDefinition) -> Bool { 382 | return lhs.name == rhs.name 383 | } 384 | 385 | public struct EnumTypeDefinition: Node { 386 | let name: Name 387 | let values: [EnumValueDefinition] 388 | } 389 | 390 | extension EnumTypeDefinition: Equatable {} 391 | 392 | public func == (lhs: EnumTypeDefinition, rhs: EnumTypeDefinition) -> Bool { 393 | return lhs.name == rhs.name && 394 | lhs.values == rhs.values 395 | } 396 | 397 | public struct EnumValueDefinition: Node { 398 | let name: Name 399 | } 400 | 401 | extension EnumValueDefinition: Equatable {} 402 | 403 | public func == (lhs: EnumValueDefinition, rhs: EnumValueDefinition) -> Bool { 404 | return lhs.name == rhs.name 405 | } 406 | 407 | public struct InputObjectTypeDefinition: Node { 408 | let name: Name 409 | let fields: [InputValueDefinition] 410 | } 411 | 412 | extension InputObjectTypeDefinition: Equatable {} 413 | 414 | public func == (lhs: InputObjectTypeDefinition, rhs: InputObjectTypeDefinition) -> Bool { 415 | return lhs.name == rhs.name && 416 | lhs.fields == rhs.fields 417 | } 418 | 419 | public struct TypeExtensionDefinition: Node { 420 | let definition: ObjectTypeDefinition 421 | } 422 | 423 | extension TypeExtensionDefinition: Equatable {} 424 | 425 | public func == (lhs: TypeExtensionDefinition, rhs: TypeExtensionDefinition) -> Bool { 426 | return lhs.definition == rhs.definition 427 | } 428 | -------------------------------------------------------------------------------- /Sources/language/Lexer.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public enum TokenKind { 4 | case EOF, Bang, Dollar, ParenL, ParenR, Spread, Colon, Equals, At, BracketL, BracketR, BraceL, BraceR, Pipe, Name, Int, Float, String 5 | } 6 | 7 | public struct Token { 8 | let kind: TokenKind 9 | let start: String.UnicodeScalarView.Index 10 | let end: String.UnicodeScalarView.Index 11 | let value: String? 12 | } 13 | 14 | extension Token: Equatable {} 15 | 16 | public func == (lhs: Token, rhs: Token) -> Bool { 17 | return lhs.kind == rhs.kind && lhs.start == rhs.start && lhs.end == rhs.end && lhs.value == rhs.value 18 | } 19 | 20 | enum LexerError: ErrorType { 21 | case UnexpectedCharacter(String.UnicodeScalarView.Index, Character) 22 | case InvalidCharacter(String.UnicodeScalarView.Index, Character) 23 | case InvalidCharacterWithinString(String.UnicodeScalarView.Index, Character) 24 | case InvalidEscapeSequence(String.UnicodeScalarView.Index, String) 25 | case UnterminatedString(String.UnicodeScalarView.Index) 26 | case UnexpectedCharacterInNumberAfterZero(String.UnicodeScalarView.Index, Character) 27 | case UnexpectedCharacterInNumber(String.UnicodeScalarView.Index, Character) 28 | } 29 | 30 | public class Lexer { 31 | private let source: String.UnicodeScalarView 32 | private var position: String.UnicodeScalarView.Index 33 | 34 | init(source: String) { 35 | self.source = source.unicodeScalars 36 | self.position = source.unicodeScalars.startIndex 37 | } 38 | } 39 | 40 | extension Lexer { 41 | 42 | @warn_unused_result public func next() throws -> Token { 43 | return try readToken() 44 | } 45 | 46 | } 47 | 48 | extension Lexer { 49 | 50 | private func readToken() throws -> Token { 51 | skipWhitespace() 52 | 53 | if position >= source.endIndex { 54 | return Token(kind: .EOF, start: source.endIndex, end: source.endIndex, value: nil) 55 | } 56 | 57 | let scalar = source[position] 58 | let code = scalar.value 59 | 60 | if code < 0x0020 && code != 0x0009 && code != 0x000A && code != 0x000D { 61 | throw LexerError.InvalidCharacter(position, Character(source[position])) 62 | } 63 | 64 | switch code { 65 | case 34: // " 66 | return try readString() 67 | case 65...90: // A-Z 68 | fallthrough 69 | case 95: // _ 70 | fallthrough 71 | case 97...122: // a-z 72 | return try readName() 73 | case 45: // - 74 | fallthrough 75 | case 48...57: // 0-9 76 | return try readNumber() 77 | case 33: // ! 78 | position = position.successor() 79 | return Token(kind: .Bang, start: position.predecessor(), end: position, value: nil) 80 | case 36: // $ 81 | position = position.successor() 82 | return Token(kind: .Dollar, start: position.predecessor(), end: position, value: nil) 83 | case 40: // ( 84 | position = position.successor() 85 | return Token(kind: .ParenL, start: position.predecessor(), end: position, value: nil) 86 | case 41: // ) 87 | position = position.successor() 88 | return Token(kind: .ParenR, start: position.predecessor(), end: position, value: nil) 89 | case 46: // . 90 | if source[position.successor()].value == 46 && source[position.successor().successor()].value == 46 { 91 | let start = position 92 | position = position.successor().successor().successor() 93 | return Token(kind: .Spread, start: start, end: position, value: nil) 94 | } 95 | case 58: // : 96 | position = position.successor() 97 | return Token(kind: .Colon, start: position.predecessor(), end: position, value: nil) 98 | case 61: // = 99 | position = position.successor() 100 | return Token(kind: .Equals, start: position.predecessor(), end: position, value: nil) 101 | case 64: // @ 102 | position = position.successor() 103 | return Token(kind: .At, start: position.predecessor(), end: position, value: nil) 104 | case 91: // [ 105 | position = position.successor() 106 | return Token(kind: .BracketL, start: position.predecessor(), end: position, value: nil) 107 | case 93: // ] 108 | position = position.successor() 109 | return Token(kind: .BracketR, start: position.predecessor(), end: position, value: nil) 110 | case 123: // { 111 | position = position.successor() 112 | return Token(kind: .BraceL, start: position.predecessor(), end: position, value: nil) 113 | case 124: // | 114 | position = position.successor() 115 | return Token(kind: .Pipe, start: position.predecessor(), end: position, value: nil) 116 | case 125: // } 117 | position = position.successor() 118 | return Token(kind: .BraceR, start: position.predecessor(), end: position, value: nil) 119 | default: 120 | throw LexerError.UnexpectedCharacter(position, Character(scalar)) 121 | } 122 | throw LexerError.UnexpectedCharacter(position, Character(scalar)) 123 | } 124 | 125 | private func readName() throws -> Token { 126 | let start = position 127 | while position < source.endIndex { 128 | let code = source[position].value 129 | if !codeIsAlphanumeric(code) { 130 | break 131 | } 132 | position = position.successor() 133 | } 134 | 135 | return Token(kind: .Name, start: start, end: position.predecessor(), value: String(source[start.. Bool { 139 | return 140 | 48...57 ~= code || // 0-9 141 | 65...90 ~= code || // A-Z 142 | code == 95 || // _ 143 | 97...122 ~= code // A-Z 144 | } 145 | 146 | private func readString() throws -> Token { 147 | position = position.successor() 148 | let start = position 149 | var chunkStart = start 150 | var value = "" 151 | 152 | while position < source.endIndex { 153 | var code = source[position].value 154 | if code == 0x000A || // line feed 155 | code == 0x000D || // carriage return 156 | code == 34 { // " 157 | break 158 | } 159 | 160 | if code < 0x0020 && code != 0x0009 { 161 | throw LexerError.InvalidCharacterWithinString(position, Character(source[position])) 162 | } 163 | 164 | position = position.successor() 165 | if code == 92 { // \\ 166 | value += String(source[chunkStart.. UnicodeScalar { 201 | position = position.successor() 202 | let substring = String(source[position...position.successor().successor().successor()]) 203 | guard let unicodeCode = UInt32(substring, radix: 16) else { 204 | throw LexerError.InvalidEscapeSequence(position, "\\u\(substring)") 205 | } 206 | position = position.successor().successor().successor() 207 | return UnicodeScalar(unicodeCode) 208 | } 209 | 210 | private func readNumber() throws -> Token { 211 | let start = position 212 | var isFloat = false 213 | var code = source[position].value 214 | 215 | if code == 45 { // - 216 | position = position.successor() 217 | code = source[position].value 218 | } 219 | 220 | if code == 48 { // 0 221 | position = position.successor() 222 | code = source[position].value 223 | if code >= 48 && code <= 57 { 224 | throw LexerError.UnexpectedCharacterInNumberAfterZero(position, Character(source[position])) 225 | } 226 | } else { 227 | try readDigits() 228 | } 229 | 230 | code = source[position].value 231 | if code == 46 { // . 232 | isFloat = true 233 | 234 | position = position.successor() 235 | try readDigits() 236 | } 237 | 238 | code = source[position].value 239 | if code == 69 || code == 101 { // E e 240 | isFloat = true 241 | position = position.successor() 242 | 243 | code = source[position].value 244 | if code == 43 || code == 45 { // - + 245 | position = position.successor() 246 | } 247 | try readDigits() 248 | } 249 | 250 | return Token(kind: (isFloat ? .Float : .Int), start: start, end: position, value: String(source[start.. Document { 24 | token = try lexer.next() 25 | return try parseDocument() 26 | } 27 | 28 | } 29 | 30 | extension Parser { 31 | 32 | private func parseDocument() throws -> Document { 33 | var definitions: [Definition] = [] 34 | 35 | repeat { 36 | definitions.append(try parseDefinition()) 37 | } while try !skip(.EOF) 38 | 39 | return Document(definitions: definitions) 40 | } 41 | 42 | private func parseDefinition() throws -> Definition { 43 | if peek(.BraceL) { 44 | return .Operation(try parseOperationDefinition()) 45 | } 46 | 47 | guard peek(.Name), let value = token.value, keyword = Keyword(rawValue: value) else { 48 | throw ParserError.UnexpectedToken(token) 49 | } 50 | 51 | switch keyword { 52 | case .Query, .Mutation, .Subscription: 53 | return .Operation(try parseOperationDefinition()) 54 | case .Fragment: 55 | return .Fragment(try parseFragmentDefinition()) 56 | case .Type, .Interface, .Union, .Scalar, .EnumType, .Input: 57 | return .Type(try parseTypeDefinition()) 58 | case .Extend: 59 | return .TypeExtension(try parseTypeExtensionDefinition()) 60 | default: 61 | throw ParserError.UnexpectedToken(token) 62 | } 63 | } 64 | 65 | } 66 | 67 | extension Parser { 68 | 69 | private func parseOperationDefinition() throws -> OperationDefinition { 70 | if peek(.BraceL) { 71 | return OperationDefinition( 72 | type: .Query, 73 | name: nil, 74 | variableDefinitions: [], 75 | directives: [], 76 | selectionSet: try parseSelectionSet()) 77 | } 78 | 79 | let operationToken = try expect(.Name) 80 | 81 | guard let typeString = operationToken.value, type = OperationType(rawValue: typeString) else { 82 | throw ParserError.UnexpectedToken(operationToken) 83 | } 84 | 85 | let name: Name? = peek(.Name) ? try parseName() : nil 86 | 87 | return OperationDefinition( 88 | type: type, 89 | name: name, 90 | variableDefinitions: try parseVariableDefinitions(), 91 | directives: try parseDirectives(), 92 | selectionSet: try parseSelectionSet()) 93 | } 94 | 95 | private func parseVariableDefinitions() throws -> [VariableDefinition] { 96 | return peek(.ParenL) ? try many(openKind: .ParenL, parseFn: parseVariableDefinition, closeKind: .ParenR) : [] 97 | } 98 | 99 | private func parseVariableDefinition() throws -> VariableDefinition { 100 | let variable = try parseVariable() 101 | try expect(.Colon) 102 | let type = try parseType() 103 | let defaultValue: Value? = try skip(.Equals) ? try parseValueLiteral(isConst: true) : nil 104 | return VariableDefinition(variable: variable, type: type, defaultValue: defaultValue) 105 | } 106 | 107 | private func parseVariable() throws -> Variable { 108 | try expect(.Dollar) 109 | return Variable(name: try parseName()) 110 | } 111 | 112 | private func parseSelectionSet() throws -> SelectionSet { 113 | return SelectionSet(selections: try many(openKind: .BraceL, parseFn: parseSelection, closeKind: .BraceR)) 114 | } 115 | 116 | private func parseSelection() throws -> Selection { 117 | return peek(.Spread) ? try parseFragment() : Selection.FieldSelection(try parseField()) 118 | } 119 | 120 | private func parseField() throws -> Field { 121 | let nameOrAlias = try parseName() 122 | let alias: Name? 123 | let name: Name 124 | if try skip(.Colon) { 125 | alias = nameOrAlias 126 | name = try parseName() 127 | } else { 128 | alias = nil 129 | name = nameOrAlias 130 | } 131 | 132 | return Field( 133 | alias: alias, 134 | name: name, 135 | arguments: try parseArguments(), 136 | directives: try parseDirectives(), 137 | selectionSet: peek(.BraceL) ? try parseSelectionSet() : nil) 138 | } 139 | 140 | private func parseArguments() throws -> [Argument] { 141 | return peek(.ParenL) ? try many(openKind: .ParenL, parseFn: parseArgument, closeKind: .ParenR) : [] 142 | } 143 | 144 | private func parseArgument() throws -> Argument { 145 | let name = try parseName() 146 | try expect(.Colon) 147 | let value = try parseValueLiteral(isConst: false) 148 | return Argument(name: name, value: value) 149 | } 150 | 151 | private func parseName() throws -> Name { 152 | let nameToken = try expect(.Name) 153 | return Name(value: nameToken.value) 154 | } 155 | 156 | } 157 | 158 | extension Parser { 159 | 160 | private func parseFragment() throws -> Selection { 161 | try expect(.Spread) 162 | 163 | if peek(.Name) && token.value != Keyword.On.rawValue { 164 | return .FragmentSpreadSelection(FragmentSpread( 165 | name: try parseFragmentName(), 166 | directives: try parseDirectives())) 167 | } 168 | 169 | let typeCondition: Type? 170 | if token.value == Keyword.On.rawValue { 171 | try advance() 172 | typeCondition = try parseNamedType() 173 | } else { 174 | typeCondition = nil 175 | } 176 | 177 | return .InlineFragmentSelection(InlineFragment( 178 | typeCondition: typeCondition, 179 | directives: try parseDirectives(), 180 | selectionSet: try parseSelectionSet())) 181 | } 182 | 183 | private func parseFragmentDefinition() throws -> FragmentDefinition { 184 | try expectKeyword(.Fragment) 185 | let name = try parseFragmentName() 186 | try expectKeyword(.On) 187 | let typeCondition = try parseNamedType() 188 | return FragmentDefinition( 189 | name: name, 190 | typeCondition: typeCondition, 191 | directives: try parseDirectives(), 192 | selectionSet: try parseSelectionSet() 193 | ) 194 | } 195 | 196 | private func parseFragmentName() throws -> Name { 197 | if token.value == Keyword.On.rawValue { 198 | throw ParserError.UnexpectedToken(token) 199 | } 200 | return try parseName() 201 | } 202 | 203 | } 204 | 205 | extension Parser { 206 | 207 | private func parseValueLiteral(isConst isConst: Bool) throws -> Value { 208 | switch token.kind { 209 | case .BracketL: 210 | return try parseList(isConst: isConst) 211 | case .BraceL: 212 | return try parseObject(isConst: isConst) 213 | case .Int: 214 | guard let value = token.value else { 215 | throw ParserError.UnexpectedToken(token) 216 | } 217 | try advance() 218 | return .IntValue(value) 219 | case .Float: 220 | guard let value = token.value else { 221 | throw ParserError.UnexpectedToken(token) 222 | } 223 | try advance() 224 | return .FloatValue(value) 225 | case .String: 226 | guard let value = token.value else { 227 | throw ParserError.UnexpectedToken(token) 228 | } 229 | try advance() 230 | return .StringValue(value) 231 | case .Name: 232 | if let value = token.value where (value == Keyword.BoolFalse.rawValue || value == Keyword.BoolTrue.rawValue) { 233 | try advance() 234 | return .BoolValue(value) 235 | } else if token.value != Keyword.Null.rawValue { 236 | guard let value = token.value else { 237 | throw ParserError.UnexpectedToken(token) 238 | } 239 | try advance() 240 | return .Enum(value) 241 | } 242 | case .Dollar: 243 | if !isConst { 244 | return .VariableValue(try parseVariable()) 245 | } 246 | default: 247 | throw ParserError.UnexpectedToken(token) 248 | } 249 | throw ParserError.UnexpectedToken(token) 250 | } 251 | 252 | private func parseList(isConst isConst: Bool) throws -> Value { 253 | return .List(try any(openKind: .BracketL, parseFn: { return try self.parseValueLiteral(isConst: isConst) }, closeKind: .BracketR)) 254 | } 255 | 256 | private func parseObject(isConst isConst: Bool) throws -> Value { 257 | try expect(.BraceL) 258 | var fields: [ObjectField] = [] 259 | while try !skip(.BraceR) { 260 | fields.append(try parseObjectField(isConst: isConst)) 261 | } 262 | return .Object(fields) 263 | } 264 | 265 | private func parseObjectField(isConst isConst: Bool) throws -> ObjectField { 266 | let name = try parseName() 267 | try expect(.Colon) 268 | let value = try parseValueLiteral(isConst: isConst) 269 | return ObjectField(name: name, value: value) 270 | } 271 | 272 | } 273 | 274 | extension Parser { 275 | 276 | private func parseDirectives() throws -> [Directive] { 277 | var directives: [Directive] = [] 278 | while peek(.At) { 279 | directives.append(try parseDirective()) 280 | } 281 | return directives 282 | } 283 | 284 | private func parseDirective() throws -> Directive { 285 | try expect(.At) 286 | return Directive(name: try parseName(), arguments: try parseArguments()) 287 | } 288 | 289 | } 290 | 291 | extension Parser { 292 | 293 | private func parseType() throws -> Type { 294 | let type: Type 295 | if try skip(.BracketL) { 296 | let listType = try parseType() 297 | try expect(.BracketR) 298 | type = .List(listType) 299 | } else { 300 | type = try parseNamedType() 301 | } 302 | if try skip(.Bang) { 303 | return .NonNull(type) 304 | } 305 | return type 306 | } 307 | 308 | private func parseNamedType() throws -> Type { 309 | return .Named(try parseName()) 310 | } 311 | 312 | } 313 | 314 | extension Parser { 315 | 316 | private func parseTypeDefinition() throws -> TypeDefinition { 317 | if !peek(.Name) { 318 | throw ParserError.UnexpectedToken(token) 319 | } 320 | 321 | guard let value = token.value, type = Keyword(rawValue: value) else { 322 | throw ParserError.UnexpectedToken(token) 323 | } 324 | 325 | switch type { 326 | case .Type: 327 | return .Object(try parseObjectTypeDefinition()) 328 | case .Interface: 329 | return .Interface(try parseInterfaceTypeDefinition()) 330 | case .Union: 331 | return .Union(try parseUnionTypeDefinition()) 332 | case .Scalar: 333 | return .Scalar(try parseScalarTypeDefinition()) 334 | case .EnumType: 335 | return .Enum(try parseEnumTypeDefinition()) 336 | case .Input: 337 | return .InputObject(try parseInputObjectTypeDefinition()) 338 | default: 339 | throw ParserError.UnexpectedToken(token) 340 | } 341 | } 342 | 343 | private func parseObjectTypeDefinition() throws -> ObjectTypeDefinition { 344 | try expectKeyword(.Type) 345 | return ObjectTypeDefinition( 346 | name: try parseName(), 347 | interfaces: try parseImplementsInterfaces(), 348 | fields: try any(openKind: .BraceL, parseFn: parseFieldDefinition, closeKind: .BraceR)) 349 | } 350 | 351 | private func parseImplementsInterfaces() throws -> [Type] { 352 | if token.value == Keyword.Implements.rawValue { 353 | try advance() 354 | var types: [Type] = [] 355 | repeat { 356 | types.append(try parseNamedType()) 357 | } while !peek(.BraceL) 358 | return types 359 | } 360 | return [] 361 | } 362 | 363 | private func parseFieldDefinition() throws -> FieldDefinition { 364 | let name = try parseName() 365 | let arguments = try parseArgumentDefinitions() 366 | try expect(.Colon) 367 | let type = try parseType() 368 | return FieldDefinition(name: name, arguments: arguments, type: type) 369 | } 370 | 371 | private func parseArgumentDefinitions() throws -> [InputValueDefinition] { 372 | if peek(.ParenL) { 373 | return try many(openKind: .ParenL, parseFn: parseInputValueDefinition, closeKind: .ParenR) 374 | } 375 | return [] 376 | } 377 | 378 | private func parseInputValueDefinition() throws -> InputValueDefinition { 379 | let name = try parseName() 380 | try expect(.Colon) 381 | let type = try parseType() 382 | let defaultValue: Value? = try skip(.Equals) ? try parseValueLiteral(isConst: true) : nil 383 | return InputValueDefinition(name: name, type: type, defaultValue: defaultValue) 384 | } 385 | 386 | private func parseInterfaceTypeDefinition() throws -> InterfaceTypeDefinition { 387 | try expectKeyword(.Interface) 388 | return InterfaceTypeDefinition( 389 | name: try parseName(), 390 | fields: try any(openKind: .BraceL, parseFn: parseFieldDefinition, closeKind: .BraceR)) 391 | } 392 | 393 | private func parseUnionTypeDefinition() throws -> UnionTypeDefinition { 394 | try expectKeyword(.Union) 395 | let name = try parseName() 396 | try expect(.Equals) 397 | let types = try parseUnionMembers() 398 | return UnionTypeDefinition(name: name, types: types) 399 | } 400 | 401 | private func parseUnionMembers() throws -> [Type] { 402 | var members: [Type] = [] 403 | repeat { 404 | members.append(try parseNamedType()) 405 | } while try skip(.Pipe) 406 | return members 407 | } 408 | 409 | private func parseScalarTypeDefinition() throws -> ScalarTypeDefinition { 410 | try expectKeyword(.Scalar) 411 | return ScalarTypeDefinition(name: try parseName()) 412 | } 413 | 414 | private func parseEnumTypeDefinition() throws -> EnumTypeDefinition { 415 | try expectKeyword(.EnumType) 416 | return EnumTypeDefinition( 417 | name: try parseName(), 418 | values: try many(openKind: .BraceL, parseFn: parseEnumValueDefinition, closeKind: .BraceR)) 419 | } 420 | 421 | private func parseEnumValueDefinition() throws -> EnumValueDefinition { 422 | return EnumValueDefinition(name: try parseName()) 423 | } 424 | 425 | private func parseInputObjectTypeDefinition() throws -> InputObjectTypeDefinition { 426 | try expectKeyword(.Input) 427 | return InputObjectTypeDefinition( 428 | name: try parseName(), 429 | fields: try any(openKind: .BraceL, parseFn: parseInputValueDefinition, closeKind: .BraceR)) 430 | } 431 | 432 | private func parseTypeExtensionDefinition() throws -> TypeExtensionDefinition { 433 | try expectKeyword(.Extend) 434 | return TypeExtensionDefinition(definition: try parseObjectTypeDefinition()) 435 | } 436 | 437 | } 438 | 439 | extension Parser { 440 | 441 | private func advance() throws { 442 | token = try lexer.next() 443 | } 444 | 445 | private func skip(kind: TokenKind) throws -> Bool { 446 | let match = token.kind == kind 447 | if match { 448 | try advance() 449 | } 450 | return match 451 | } 452 | 453 | private func peek(kind: TokenKind) -> Bool { 454 | return token.kind == kind 455 | } 456 | 457 | private func expect(kind: TokenKind) throws -> Token { 458 | let currentToken = token 459 | if currentToken.kind == kind { 460 | try advance() 461 | return currentToken 462 | } 463 | throw ParserError.WrongTokenKind(kind, currentToken.kind) 464 | } 465 | 466 | private func expectKeyword(keyword: Keyword) throws -> Token { 467 | let currentToken = token 468 | if token.kind == .Name && token.value == keyword.rawValue { 469 | try advance() 470 | return currentToken 471 | } 472 | throw ParserError.UnexpectedKeyword(keyword, currentToken) 473 | } 474 | 475 | private func any(openKind openKind: TokenKind, parseFn: () throws -> T, closeKind: TokenKind) throws -> [T] { 476 | try expect(openKind) 477 | var nodes: [T] = [] 478 | while try !skip(closeKind) { 479 | nodes.append(try parseFn()) 480 | } 481 | return nodes 482 | } 483 | 484 | private func many(openKind openKind: TokenKind, parseFn: () throws -> T, closeKind: TokenKind) throws -> [T] { 485 | try expect(openKind) 486 | var nodes = [try parseFn()] 487 | while try !skip(closeKind) { 488 | nodes.append(try parseFn()) 489 | } 490 | return nodes 491 | } 492 | 493 | } 494 | 495 | extension Parser { 496 | 497 | private func syntaxError(token: Token) throws { 498 | throw ParserError.UnexpectedToken(token) 499 | } 500 | 501 | } 502 | -------------------------------------------------------------------------------- /Sources/language/Printer.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public protocol PrettyPrintable { 4 | func prettyPrint() -> String 5 | } 6 | 7 | extension Document: PrettyPrintable { 8 | public func prettyPrint() -> String { 9 | return definitions.flatMap { 10 | $0.prettyPrint() 11 | }.joinWithSeparator("\n\n") + "\n" 12 | } 13 | } 14 | 15 | extension Definition: PrettyPrintable { 16 | public func prettyPrint() -> String { 17 | switch self { 18 | case Definition.Operation(let operationDefinition): 19 | return operationDefinition.prettyPrint() 20 | case Definition.Fragment(let fragmentDefinition): 21 | return fragmentDefinition.prettyPrint() 22 | case Definition.Type(let typeDefinition): 23 | return typeDefinition.prettyPrint() 24 | case Definition.TypeExtension(let typeExtensionDefinition): 25 | return typeExtensionDefinition.prettyPrint() 26 | } 27 | } 28 | } 29 | 30 | extension OperationDefinition: PrettyPrintable { 31 | public func prettyPrint() -> String { 32 | let renderedVariableDefinitions = variableDefinitions.prettyPrintWithSeparator(", ").surroundWith("(", ")") 33 | let renderedDirectives = directives.prettyPrintWithSeparator(" ") 34 | if type == .Query && name == nil && renderedDirectives.isEmpty && renderedVariableDefinitions.isEmpty { 35 | return selectionSet.prettyPrint() 36 | } else { 37 | let arr = [ 38 | type.rawValue, 39 | [ 40 | name?.prettyPrint(), 41 | renderedVariableDefinitions 42 | ].compactJoinWithSeparator(""), 43 | renderedDirectives, 44 | selectionSet.prettyPrint() 45 | ].compactJoinWithSeparator(" ") 46 | return arr 47 | } 48 | } 49 | } 50 | 51 | extension VariableDefinition: PrettyPrintable { 52 | public func prettyPrint() -> String { 53 | var variableString = "\(variable.prettyPrint()): \(type.prettyPrint())" 54 | if let defaultValue = defaultValue { 55 | variableString += " = \(defaultValue.prettyPrint())" 56 | } 57 | return variableString 58 | } 59 | } 60 | 61 | extension SelectionSet: PrettyPrintable { 62 | public func prettyPrint() -> String { 63 | return selections.prettyPrintBlock() 64 | } 65 | } 66 | 67 | extension Selection: PrettyPrintable { 68 | public func prettyPrint() -> String { 69 | switch self { 70 | case Selection.FieldSelection(let field): 71 | return field.prettyPrint() 72 | case Selection.FragmentSpreadSelection(let fragmentSpread): 73 | return fragmentSpread.prettyPrint() 74 | case Selection.InlineFragmentSelection(let inlineFragment): 75 | return inlineFragment.prettyPrint() 76 | } 77 | } 78 | } 79 | 80 | extension Field: PrettyPrintable { 81 | public func prettyPrint() -> String { 82 | return [ 83 | alias?.prettyPrint().surroundWith("", ": "), 84 | name.prettyPrint(), 85 | arguments.prettyPrintWithSeparator(", ").surroundWith("(", ")"), 86 | directives.prettyPrintWithSeparator(" "), 87 | selectionSet?.prettyPrint() 88 | ].compactJoinWithSeparator(" ") 89 | } 90 | } 91 | 92 | extension Argument: PrettyPrintable { 93 | public func prettyPrint() -> String { 94 | return [name.prettyPrint(), value.prettyPrint()].compactJoinWithSeparator(": ") 95 | } 96 | } 97 | 98 | extension FragmentSpread: PrettyPrintable { 99 | public func prettyPrint() -> String { 100 | return "...\(name.prettyPrint())" + directives.prettyPrintWithSeparator(" ").surroundWith(" ", " ") 101 | } 102 | } 103 | 104 | extension InlineFragment: PrettyPrintable { 105 | public func prettyPrint() -> String { 106 | return [ 107 | "...", 108 | typeCondition?.prettyPrint().surroundWith("on "), 109 | directives.flatMap { 110 | $0.prettyPrint() 111 | }.joinWithSeparator(" "), 112 | selectionSet.prettyPrint() 113 | ].compactJoinWithSeparator(" ") 114 | } 115 | } 116 | 117 | extension FragmentDefinition: PrettyPrintable { 118 | public func prettyPrint() -> String { 119 | return [ 120 | "fragment", 121 | name.prettyPrint(), 122 | "on", 123 | typeCondition.prettyPrint(), 124 | directives.flatMap { 125 | $0.prettyPrint() 126 | }.joinWithSeparator(" "), 127 | selectionSet.prettyPrint() 128 | ].compactJoinWithSeparator(" ") 129 | } 130 | } 131 | 132 | extension Value: PrettyPrintable { 133 | public func prettyPrint() -> String { 134 | switch self { 135 | case Value.IntValue(let value): 136 | return "\(value)" 137 | case Value.FloatValue(let value): 138 | return "\(value)" 139 | case Value.StringValue(let value): 140 | return "\"\(value)\"" 141 | case Value.BoolValue(let value): 142 | return "\(value)" 143 | case Value.Enum(let value): 144 | return "\(value)" 145 | case Value.VariableValue(let variable): 146 | return variable.prettyPrint() 147 | case Value.List(let values): 148 | return "[" + values.flatMap { 149 | $0.prettyPrint() 150 | }.joinWithSeparator(", ") + "]" 151 | case Value.Object(let fields): 152 | return "{" + fields.flatMap { 153 | $0.prettyPrint() 154 | }.joinWithSeparator(", ") + "}" 155 | } 156 | } 157 | } 158 | 159 | extension ObjectField: PrettyPrintable { 160 | public func prettyPrint() -> String { 161 | return "\(name.prettyPrint()): \(value.prettyPrint())" 162 | } 163 | } 164 | 165 | extension Directive: PrettyPrintable { 166 | public func prettyPrint() -> String { 167 | return "@\(name.prettyPrint())" + arguments.prettyPrintWithSeparator(", ").surroundWith("(", ")") 168 | } 169 | } 170 | 171 | extension Type: PrettyPrintable { 172 | public func prettyPrint() -> String { 173 | switch self { 174 | case Type.List(let type): 175 | return "[\(type.prettyPrint())]" 176 | case Type.NonNull(let type): 177 | return "\(type.prettyPrint())!" 178 | case Type.Named(let name): 179 | return name.prettyPrint() 180 | } 181 | } 182 | } 183 | 184 | extension ObjectTypeDefinition: PrettyPrintable { 185 | public func prettyPrint() -> String { 186 | return [ 187 | "type", 188 | name.prettyPrint(), 189 | interfaces.prettyPrintWithSeparator(", ").surroundWith("implements "), 190 | fields.prettyPrintBlock() 191 | ].compactJoinWithSeparator(" ") 192 | } 193 | } 194 | 195 | extension FieldDefinition: PrettyPrintable { 196 | public func prettyPrint() -> String { 197 | return "\(name.prettyPrint())" + arguments.prettyPrintWithSeparator(", ").surroundWith("(", ")") 198 | } 199 | } 200 | 201 | extension TypeDefinition: PrettyPrintable { 202 | public func prettyPrint() -> String { 203 | switch self { 204 | case Object(let definition): 205 | return definition.prettyPrint() 206 | case Interface(let definition): 207 | return definition.prettyPrint() 208 | case Union(let definition): 209 | return definition.prettyPrint() 210 | case Scalar(let definition): 211 | return definition.prettyPrint() 212 | case Enum(let definition): 213 | return definition.prettyPrint() 214 | case InputObject(let definition): 215 | return definition.prettyPrint() 216 | } 217 | } 218 | } 219 | 220 | extension InputValueDefinition: PrettyPrintable { 221 | public func prettyPrint() -> String { 222 | return name.prettyPrint() + ": " + "\(type.prettyPrint())" + (defaultValue?.prettyPrint().surroundWith(" = ") ?? "") 223 | } 224 | } 225 | 226 | extension InterfaceTypeDefinition: PrettyPrintable { 227 | public func prettyPrint() -> String { 228 | return "interface " + name.prettyPrint() + " " + fields.prettyPrintBlock() 229 | } 230 | } 231 | 232 | extension UnionTypeDefinition: PrettyPrintable { 233 | public func prettyPrint() -> String { 234 | return "union " + name.prettyPrint() + " = " + types.prettyPrintWithSeparator(" | ") 235 | } 236 | } 237 | 238 | extension ScalarTypeDefinition: PrettyPrintable { 239 | public func prettyPrint() -> String { 240 | return "scalar " + name.prettyPrint() 241 | } 242 | } 243 | 244 | extension EnumTypeDefinition: PrettyPrintable { 245 | public func prettyPrint() -> String { 246 | return "enum " + name.prettyPrint() + " " + values.prettyPrintBlock() 247 | } 248 | } 249 | 250 | extension EnumValueDefinition: PrettyPrintable { 251 | public func prettyPrint() -> String { 252 | return name.prettyPrint() 253 | } 254 | } 255 | 256 | extension InputObjectTypeDefinition: PrettyPrintable { 257 | public func prettyPrint() -> String { 258 | return "input " + name.prettyPrint() + fields.prettyPrintBlock() 259 | } 260 | } 261 | 262 | extension TypeExtensionDefinition: PrettyPrintable { 263 | public func prettyPrint() -> String { 264 | return "extend " + (definition.prettyPrint() ?? "") 265 | } 266 | } 267 | 268 | extension Variable: PrettyPrintable { 269 | public func prettyPrint() -> String { 270 | return "$\(name.prettyPrint())" 271 | } 272 | } 273 | 274 | extension Name: PrettyPrintable { 275 | public func prettyPrint() -> String { 276 | return value ?? "" 277 | } 278 | } 279 | 280 | extension SequenceType where Generator.Element == String? { 281 | private func compactJoinWithSeparator(separator: String) -> String { 282 | return self.flatMap { 283 | $0 284 | }.filter { 285 | !$0.isEmpty 286 | }.joinWithSeparator(separator) ?? "" 287 | } 288 | } 289 | 290 | extension SequenceType where Generator.Element: PrettyPrintable { 291 | private func prettyPrintWithSeparator(separator: String) -> String { 292 | return self.flatMap { 293 | $0.prettyPrint() 294 | }.filter { 295 | !$0.isEmpty 296 | }.joinWithSeparator(separator) ?? "" 297 | } 298 | 299 | private func prettyPrintBlock() -> String { 300 | return self.flatMap { 301 | $0.prettyPrint() 302 | }.filter { 303 | !$0.isEmpty 304 | }.block() ?? "" 305 | } 306 | } 307 | 308 | extension CollectionType where Generator.Element == String { 309 | private func block() -> String { 310 | if self.isEmpty { 311 | return "" 312 | } else { 313 | return ("{\n" + joinWithSeparator("\n")).indent() + "\n}" 314 | } 315 | } 316 | } 317 | 318 | extension String { 319 | private func indent() -> String { 320 | return stringByReplacingOccurrencesOfString("\n", withString: "\n ") 321 | } 322 | 323 | private func surroundWith(left: String, _ right: String = "") -> String { 324 | if isEmpty { 325 | return "" 326 | } else { 327 | return left + self + right 328 | } 329 | } 330 | } 331 | -------------------------------------------------------------------------------- /Sources/language/Visitor.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public struct Visitor: SequenceType { 4 | let node: Node 5 | 6 | @warn_unused_result public func generate() -> VisitorGenerator { 7 | return VisitorGenerator(node: node) 8 | } 9 | 10 | } 11 | 12 | public class VisitorGenerator: GeneratorType { 13 | private var allNodes: [Node] = [] 14 | private var nodesSlice: ArraySlice 15 | 16 | init(node: Node) { 17 | var nodes: [Node] = [] 18 | visit(node, enter: { node in 19 | nodes.append(node) 20 | return .Continue 21 | }, leave: { node in 22 | return .Continue 23 | }) 24 | allNodes = nodes 25 | nodesSlice = allNodes[allNodes.indices] 26 | } 27 | 28 | @warn_unused_result public func next() -> Node? { 29 | return nodesSlice.popFirst() 30 | } 31 | 32 | } 33 | 34 | public enum VisitorBehavior { 35 | case Continue 36 | case SkipNode 37 | } 38 | 39 | public typealias VisitorFunction = (Node) -> (VisitorBehavior) 40 | 41 | public func visit(node: Node, enter: VisitorFunction, leave: VisitorFunction) { 42 | let behavior = enter(node) 43 | 44 | defer { 45 | leave(node) 46 | } 47 | 48 | if behavior == .SkipNode { 49 | return 50 | } 51 | 52 | switch node { 53 | case let document as Document: 54 | document.definitions.forEach { visit($0, enter: enter, leave: leave) } 55 | case Definition.Operation(let operationDefinition): 56 | visit(operationDefinition, enter: enter, leave: leave) 57 | case Definition.Fragment(let fragmentDefinition): 58 | visit(fragmentDefinition, enter: enter, leave: leave) 59 | case Definition.Type(let typeDefinition): 60 | visit(typeDefinition, enter: enter, leave: leave) 61 | case Definition.TypeExtension(let typeExtensionDefinition): 62 | visit(typeExtensionDefinition, enter: enter, leave: leave) 63 | case let variableDefinition as VariableDefinition: 64 | visit(variableDefinition.variable, enter: enter, leave: leave) 65 | visit(variableDefinition.type, enter: enter, leave: leave) 66 | if let defaulValue = variableDefinition.defaultValue { 67 | visit(defaulValue, enter: enter, leave: leave) 68 | } 69 | case let variable as Variable: 70 | visit(variable.name, enter: enter, leave: leave) 71 | case let selectionSet as SelectionSet: 72 | selectionSet.selections.forEach { visit($0, enter: enter, leave: leave) } 73 | case Selection.FieldSelection(let field): 74 | visit(field, enter: enter, leave: leave) 75 | case Selection.FragmentSpreadSelection(let fragmentSpread): 76 | visit(fragmentSpread, enter: enter, leave: leave) 77 | case Selection.InlineFragmentSelection(let inlineFragment): 78 | visit(inlineFragment, enter: enter, leave: leave) 79 | case let fragmentSpread as FragmentSpread: 80 | visit(fragmentSpread.name, enter: enter, leave: leave) 81 | fragmentSpread.directives.forEach { visit($0, enter: enter, leave: leave) } 82 | case let inlineFragment as InlineFragment: 83 | if let typeCondition = inlineFragment.typeCondition { 84 | visit(typeCondition, enter: enter, leave: leave) 85 | } 86 | inlineFragment.directives.forEach { visit($0, enter: enter, leave: leave)} 87 | visit(inlineFragment.selectionSet, enter: enter, leave: leave) 88 | case let fragmentDefinition as FragmentDefinition: 89 | visit(fragmentDefinition.name, enter: enter, leave: leave) 90 | visit(fragmentDefinition.typeCondition, enter: enter, leave: leave) 91 | fragmentDefinition.directives.forEach { visit($0, enter: enter, leave: leave) } 92 | visit(fragmentDefinition.selectionSet, enter: enter, leave: leave) 93 | case Value.VariableValue(let variable): 94 | visit(variable, enter: enter, leave: leave) 95 | case Value.IntValue: 96 | break 97 | case Value.FloatValue: 98 | break 99 | case Value.StringValue: 100 | break 101 | case Value.BoolValue: 102 | break 103 | case Value.Enum: 104 | break 105 | case Value.List(let values): 106 | values.forEach { visit($0, enter: enter, leave: leave) } 107 | case Value.Object(let objectFields): 108 | objectFields.forEach { visit($0, enter: enter, leave: leave) } 109 | case let objectField as ObjectField: 110 | visit(objectField.name, enter: enter, leave: leave) 111 | visit(objectField.value, enter: enter, leave: leave) 112 | case let directive as Directive: 113 | visit(directive.name, enter: enter, leave: leave) 114 | case Type.Named(let name): 115 | visit(name, enter: enter, leave: leave) 116 | case Type.List(let type): 117 | visit(type, enter: enter, leave: leave) 118 | case Type.NonNull(let type): 119 | visit(type, enter: enter, leave: leave) 120 | case let argument as Argument: 121 | visit(argument.name, enter: enter, leave: leave) 122 | visit(argument.value, enter: enter, leave: leave) 123 | case let operationDefinition as OperationDefinition: 124 | if let name = operationDefinition.name { 125 | visit(name, enter: enter, leave: leave) 126 | } 127 | operationDefinition.variableDefinitions.forEach { visit($0, enter: enter, leave: leave) } 128 | operationDefinition.directives.forEach { visit($0, enter: enter, leave: leave) } 129 | visit(operationDefinition.selectionSet, enter: enter, leave: leave) 130 | case is Name: 131 | break 132 | case let field as Field: 133 | if let alias = field.alias { 134 | visit(alias, enter: enter, leave: leave) 135 | } 136 | visit(field.name, enter: enter, leave: leave) 137 | field.arguments.forEach { visit($0, enter: enter, leave: leave) } 138 | field.directives.forEach { visit($0, enter: enter, leave: leave) } 139 | if let selectionSet = field.selectionSet { 140 | visit(selectionSet, enter: enter, leave: leave) 141 | } 142 | case TypeDefinition.Object(let objectTypeDefinition): 143 | visit(objectTypeDefinition, enter: enter, leave: leave) 144 | case TypeDefinition.Interface(let interfaceTypeDefinition): 145 | visit(interfaceTypeDefinition, enter: enter, leave: leave) 146 | case TypeDefinition.Union(let unionTypeDefinition): 147 | visit(unionTypeDefinition, enter: enter, leave: leave) 148 | case TypeDefinition.Scalar(let scalarTypeDefinition): 149 | visit(scalarTypeDefinition, enter: enter, leave: leave) 150 | case TypeDefinition.Enum(let enumTypeDefinition): 151 | visit(enumTypeDefinition, enter: enter, leave: leave) 152 | case TypeDefinition.InputObject(let inputObjectTypeDefinition): 153 | visit(inputObjectTypeDefinition, enter: enter, leave: leave) 154 | case let objectTypeDefinition as ObjectTypeDefinition: 155 | visit(objectTypeDefinition.name, enter: enter, leave: leave) 156 | objectTypeDefinition.interfaces.forEach { visit($0, enter: enter, leave: leave) } 157 | objectTypeDefinition.fields.forEach { visit($0, enter: enter, leave: leave) } 158 | case let fieldDefinition as FieldDefinition: 159 | visit(fieldDefinition.name, enter: enter, leave: leave) 160 | fieldDefinition.arguments.forEach { visit($0, enter: enter, leave: leave) } 161 | visit(fieldDefinition.type, enter: enter, leave: leave) 162 | case let inputValueDefinition as InputValueDefinition: 163 | visit(inputValueDefinition.name, enter: enter, leave: leave) 164 | visit(inputValueDefinition.type, enter: enter, leave: leave) 165 | if let defaultValue = inputValueDefinition.defaultValue { 166 | visit(defaultValue, enter: enter, leave: leave) 167 | } 168 | case let interfaceTypeDefinition as InterfaceTypeDefinition: 169 | visit(interfaceTypeDefinition.name, enter: enter, leave: leave) 170 | interfaceTypeDefinition.fields.forEach { visit($0, enter: enter, leave: leave) } 171 | case let unionTypeDefinition as UnionTypeDefinition: 172 | visit(unionTypeDefinition.name, enter: enter, leave: leave) 173 | unionTypeDefinition.types.forEach { visit($0, enter: enter, leave: leave) } 174 | case let scalarTypeDefinition as ScalarTypeDefinition: 175 | visit(scalarTypeDefinition.name, enter: enter, leave: leave) 176 | case let enumTypeDefinition as EnumTypeDefinition: 177 | visit(enumTypeDefinition.name, enter: enter, leave: leave) 178 | enumTypeDefinition.values.forEach { visit($0, enter: enter, leave: leave) } 179 | case let enumValutDefinition as EnumValueDefinition: 180 | visit(enumValutDefinition.name, enter: enter, leave: leave) 181 | case let inputObjectTypeDefinition as InputObjectTypeDefinition: 182 | visit(inputObjectTypeDefinition.name, enter: enter, leave: leave) 183 | inputObjectTypeDefinition.fields.forEach { visit($0, enter: enter, leave: leave) } 184 | case let typeExtensionDefinition as TypeExtensionDefinition: 185 | visit(typeExtensionDefinition.definition, enter: enter, leave: leave) 186 | default: 187 | break 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /Tests/Info-OSX.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 | -------------------------------------------------------------------------------- /Tests/Info-iOS.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 | -------------------------------------------------------------------------------- /Tests/Info-tvOS.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 | -------------------------------------------------------------------------------- /Tests/language/LexerTests.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import XCTest 3 | @testable import GraphQL 4 | 5 | class LexerTests: XCTestCase { 6 | private let idx = "".unicodeScalars.startIndex 7 | 8 | func testAcceptsBOMHeader() { 9 | checkTokenKindAndValue(firstToken("\u{FEFF} foo"), kind: .Name, value: "foo") 10 | } 11 | 12 | func testSkipsWhitespace() { 13 | checkTokenKindAndValue(firstToken(" \n foo\n \n"), kind: .Name, value: "foo") 14 | } 15 | 16 | func testSkipsComments() { 17 | checkTokenKindAndValue(firstToken("\n#comment\nfoo#comment"), kind: .Name, value: "foo") 18 | } 19 | 20 | func testSkipsCommas() { 21 | checkTokenKindAndValue(firstToken(",,,foo,,,"), kind: .Name, value: "foo") 22 | } 23 | 24 | func testLexesSimpleString() { 25 | checkTokenKindAndValue(firstToken("\"simple\""), kind: .String, value: "simple") 26 | } 27 | 28 | func testLexesWhiteSpaceString() { 29 | checkTokenKindAndValue(firstToken("\" white space \""), kind: .String, value: " white space ") 30 | } 31 | 32 | func testLexesQuote() { 33 | checkTokenKindAndValue(firstToken("\"escaped \\\"\""), kind: .String, value: "escaped \"") 34 | } 35 | 36 | func testLexesEscapedChars() { 37 | checkTokenKindAndValue(firstToken("\"escaped \\n\\r\\t\""), kind: .String, value: "escaped \n\r\t") 38 | } 39 | 40 | func testLexesSlashes() { 41 | checkTokenKindAndValue(firstToken("\"slashes \\\\ \\/\""), kind: .String, value: "slashes \\ /") 42 | } 43 | 44 | func testLexesUnicode() { 45 | checkTokenKindAndValue(firstToken("\"unicode \\u1234\\u5678\\u90AB\\uCDEF\""), kind: .String, value: "unicode \u{1234}\u{5678}\u{90AB}\u{CDEF}") 46 | } 47 | 48 | func testLexesMultibyteCharacters() { 49 | let sut = Lexer(source: "# This comment has a \u{0A0A} multi-byte character.\n{ field(arg: \"Has a \u{0A0A} multi-byte character.\") }") 50 | 51 | do { 52 | var token: Token 53 | repeat { 54 | token = try sut.next() 55 | } while token.kind != .EOF 56 | } catch { 57 | XCTFail("Unexpected error: \(error)") 58 | } 59 | } 60 | 61 | func testUnterminatedShortStringError() { 62 | checkError("\"", expectedError: .UnterminatedString(idx)) 63 | } 64 | 65 | func testUnterminatedLongStringError() { 66 | checkError("\"not terminated", expectedError: .UnterminatedString(idx)) 67 | } 68 | 69 | func testUnescapedControlCharError() { 70 | checkError("\"unescaped \u{0007} control char\"", expectedError: .InvalidCharacterWithinString(idx, Character(UnicodeScalar(0x07)))) 71 | } 72 | 73 | func testNullByteInTheMiddleOfStringError() { 74 | checkError("\"null byte \u{0000} not at end of file\"", expectedError: .InvalidCharacterWithinString(idx, Character(UnicodeScalar(0x0)))) 75 | } 76 | 77 | func testMultilineStringError0() { 78 | checkError("\"multi\nline\"", expectedError: .UnterminatedString(idx)) 79 | } 80 | 81 | func testMultilineStringError1() { 82 | checkError("\"multi\rline\"", expectedError: .UnterminatedString(idx)) 83 | } 84 | 85 | func testBadEscapeError0() { 86 | checkError("\"bad \\z esc\"", expectedError: .InvalidEscapeSequence(idx, "\\z")) 87 | } 88 | 89 | func testBadEscapeError1() { 90 | checkError("\"bad \\x esc\"", expectedError: .InvalidEscapeSequence(idx, "\\x")) 91 | } 92 | 93 | func testBadUnicodeEscapeError() { 94 | checkError("\"bad \\u1 esc\"", expectedError: .InvalidEscapeSequence(idx, "\\u1 es")) 95 | } 96 | 97 | func testBadUnicodeEscapeError1() { 98 | checkError("\"bad \\u0XX1 esc\"", expectedError: .InvalidEscapeSequence(idx, "\\u0XX1")) 99 | } 100 | 101 | func testBadUnicodeEscapeError2() { 102 | checkError("\"bad \\uXXXX esc\"", expectedError: .InvalidEscapeSequence(idx, "\\uXXXX")) 103 | } 104 | 105 | func testBadUnicodeEscapeError3() { 106 | checkError("\"bad \\uFXXX esc\"", expectedError: .InvalidEscapeSequence(idx, "\\uFXXX")) 107 | } 108 | 109 | func testBadUnicodeEscapeError4() { 110 | checkError("\"bad \\uXXXF esc\"", expectedError: .InvalidEscapeSequence(idx, "\\uXXXF")) 111 | } 112 | 113 | func testLexesZero() { 114 | checkTokenKindAndValue(firstToken("0"), kind: .Int, value: "0") 115 | } 116 | 117 | func testLexesInt() { 118 | checkTokenKindAndValue(firstToken("42"), kind: .Int, value: "42") 119 | } 120 | 121 | func testLexesNegativeInt() { 122 | checkTokenKindAndValue(firstToken("-9"), kind: .Int, value: "-9") 123 | } 124 | 125 | func testLexesFloat() { 126 | checkTokenKindAndValue(firstToken("1.234"), kind: .Float, value: "1.234") 127 | } 128 | 129 | func testLexesNegativeFloat() { 130 | checkTokenKindAndValue(firstToken("-1.234"), kind: .Float, value: "-1.234") 131 | } 132 | 133 | func testLexesSmallFloat() { 134 | checkTokenKindAndValue(firstToken("0.234"), kind: .Float, value: "0.234") 135 | } 136 | 137 | func testLexesSmallExponents() { 138 | checkTokenKindAndValue(firstToken("123e4"), kind: .Float, value: "123e4") 139 | } 140 | 141 | func testLexesBigExponents() { 142 | checkTokenKindAndValue(firstToken("123E4"), kind: .Float, value: "123E4") 143 | } 144 | 145 | func testLexesSmallNegativeExponents() { 146 | checkTokenKindAndValue(firstToken("123e-4"), kind: .Float, value: "123e-4") 147 | } 148 | 149 | func testLexesBigNegativeExponents() { 150 | checkTokenKindAndValue(firstToken("123E-4"), kind: .Float, value: "123E-4") 151 | } 152 | 153 | func testLexesNegativeSmallExponents() { 154 | checkTokenKindAndValue(firstToken("-123e4"), kind: .Float, value: "-123e4") 155 | } 156 | 157 | func testLexesNegativeBigExponents() { 158 | checkTokenKindAndValue(firstToken("-123E4"), kind: .Float, value: "-123E4") 159 | } 160 | 161 | func testLexesNegativeSmallNegativeExponents() { 162 | checkTokenKindAndValue(firstToken("-123e-4"), kind: .Float, value: "-123e-4") 163 | } 164 | 165 | func testLexesNegativeBigNegativeExponents() { 166 | checkTokenKindAndValue(firstToken("-123E-4"), kind: .Float, value: "-123E-4") 167 | } 168 | 169 | func testLexesDecimalSmallExponents() { 170 | checkTokenKindAndValue(firstToken("1.23e4"), kind: .Float, value: "1.23e4") 171 | } 172 | 173 | func testLexesDecimalBigExponents() { 174 | checkTokenKindAndValue(firstToken("1.23E4"), kind: .Float, value: "1.23E4") 175 | } 176 | 177 | func testLexesDecimalSmallNegativeExponents() { 178 | checkTokenKindAndValue(firstToken("1.23e-4"), kind: .Float, value: "1.23e-4") 179 | } 180 | 181 | func testLexesDecimalBigNegativeExponents() { 182 | checkTokenKindAndValue(firstToken("1.23E-4"), kind: .Float, value: "1.23E-4") 183 | } 184 | 185 | func testLexesDecimalNegativeSmallExponents() { 186 | checkTokenKindAndValue(firstToken("-1.23e4"), kind: .Float, value: "-1.23e4") 187 | } 188 | 189 | func testLexesDecimalNegativeBigExponents() { 190 | checkTokenKindAndValue(firstToken("-1.23E4"), kind: .Float, value: "-1.23E4") 191 | } 192 | 193 | func testLexesDecimalNegativeSmallNegativeExponents() { 194 | checkTokenKindAndValue(firstToken("-1.23e-4"), kind: .Float, value: "-1.23e-4") 195 | } 196 | 197 | func testLexesDecimalNegativeBigNegativeExponents() { 198 | checkTokenKindAndValue(firstToken("-1.23E-4"), kind: .Float, value: "-1.23E-4") 199 | } 200 | 201 | func testNumberZeroError() { 202 | checkError("00", expectedError: .UnexpectedCharacterInNumberAfterZero(idx, "0")) 203 | } 204 | 205 | func testNumberPlusError() { 206 | checkError("+1", expectedError: .UnexpectedCharacter(idx, "+")) 207 | } 208 | 209 | func testNumberInvalidDotNotationError0() { 210 | checkError("123.", expectedError: .UnexpectedCharacterInNumber(idx, Character(UnicodeScalar(0xFFFD)))) 211 | } 212 | 213 | func testNumberInvalidDotNotationError1() { 214 | checkError(".123", expectedError: .UnexpectedCharacter(idx, Character("."))) 215 | } 216 | 217 | func testNumberInvalidDotNotationError2() { 218 | checkError("1.A", expectedError: .UnexpectedCharacterInNumber(idx, Character("A"))) 219 | } 220 | 221 | func testNumberInvalidNegativeError() { 222 | checkError("-A", expectedError: .UnexpectedCharacterInNumber(idx, Character("A"))) 223 | } 224 | 225 | func testNumberInvalidExponentError0() { 226 | checkError("1.0e", expectedError: .UnexpectedCharacterInNumber(idx, Character(UnicodeScalar(0xFFFD)))) 227 | } 228 | 229 | func testNumberInvalidExponentError1() { 230 | checkError("1.0eA", expectedError: .UnexpectedCharacterInNumber(idx, Character("A"))) 231 | } 232 | 233 | func testLexesBang() { 234 | checkTokenKindAndValue(firstToken("!"), kind: .Bang, value: nil) 235 | } 236 | 237 | func testLexesDollar() { 238 | checkTokenKindAndValue(firstToken("$"), kind: .Dollar, value: nil) 239 | } 240 | 241 | func testLexesParenL() { 242 | checkTokenKindAndValue(firstToken("("), kind: .ParenL, value: nil) 243 | } 244 | 245 | func testLexesParenR() { 246 | checkTokenKindAndValue(firstToken(")"), kind: .ParenR, value: nil) 247 | } 248 | 249 | func testLexesSpread() { 250 | checkTokenKindAndValue(firstToken("..."), kind: .Spread, value: nil) 251 | } 252 | 253 | func testLexesColon() { 254 | checkTokenKindAndValue(firstToken(":"), kind: .Colon, value: nil) 255 | } 256 | 257 | func testLexesEquals() { 258 | checkTokenKindAndValue(firstToken("="), kind: .Equals, value: nil) 259 | } 260 | 261 | func testLexesAt() { 262 | checkTokenKindAndValue(firstToken("@"), kind: .At, value: nil) 263 | } 264 | 265 | func testLexesBracketL() { 266 | checkTokenKindAndValue(firstToken("["), kind: .BracketL, value: nil) 267 | } 268 | 269 | func testLexesBracketR() { 270 | checkTokenKindAndValue(firstToken("]"), kind: .BracketR, value: nil) 271 | } 272 | 273 | func testLexesBraceL() { 274 | checkTokenKindAndValue(firstToken("{"), kind: .BraceL, value: nil) 275 | } 276 | 277 | func testLexesBraceR() { 278 | checkTokenKindAndValue(firstToken("}"), kind: .BraceR, value: nil) 279 | } 280 | 281 | func testLexesPipe() { 282 | checkTokenKindAndValue(firstToken("|"), kind: .Pipe, value: nil) 283 | } 284 | 285 | func testUnexpectedCharacterError0() { 286 | checkError("?", expectedError: .UnexpectedCharacter(idx, "?")) 287 | } 288 | 289 | func testUnexpectedCharacterError1() { 290 | checkError("..", expectedError: .UnexpectedCharacter(idx, ".")) 291 | } 292 | 293 | func testUnexpectedCharacterError2() { 294 | checkError("\u{203B}", expectedError: .UnexpectedCharacter(idx, Character(UnicodeScalar(0x203B)))) 295 | } 296 | 297 | func testUnexpectedCharacterError3() { 298 | checkError("\u{200b}", expectedError: .UnexpectedCharacter(idx, Character(UnicodeScalar(0x200B)))) 299 | } 300 | 301 | func testDashesInNames() { 302 | let source = "a-b" 303 | let sut = Lexer(source: source) 304 | 305 | checkTokenKindAndValue(try! sut.next(), kind: .Name, value: "a") 306 | 307 | do { 308 | let _ = try sut.next() 309 | } catch LexerError.UnexpectedCharacterInNumber(_, let character) { 310 | XCTAssertEqual(character, Character("b")) 311 | } catch { 312 | XCTFail("Unexpected error: \(error).") 313 | } 314 | } 315 | 316 | func testLexesSpreadDigit() { 317 | let sut = Lexer(source: "... 123") 318 | 319 | let firstToken = try! sut.next() 320 | let secondToken = try! sut.next() 321 | let thirdToken = try! sut.next() 322 | 323 | checkTokenKindAndValue(firstToken, kind: .Spread, value: nil) 324 | checkTokenKindAndValue(secondToken, kind: .Int, value: "123") 325 | checkTokenKindAndValue(thirdToken, kind: .EOF, value: nil) 326 | } 327 | 328 | func testLexesKitchenSink() { 329 | let sut = Lexer(source: graphQlQuery("kitchen_sink")) 330 | 331 | do { 332 | var token: Token 333 | repeat { 334 | token = try sut.next() 335 | } while token.kind != .EOF 336 | } catch { 337 | XCTFail("Unexpected error: \(error)") 338 | } 339 | } 340 | 341 | } 342 | 343 | extension LexerError: Equatable {} 344 | 345 | func == (lhs: LexerError, rhs: LexerError) -> Bool { 346 | switch (lhs, rhs) { 347 | case (.UnexpectedCharacter(_, let lhsCharacter), .UnexpectedCharacter(_, let rhsCharacter)): 348 | return lhsCharacter == rhsCharacter 349 | case (.InvalidCharacter(_, let lhsCharacter), .InvalidCharacter(_, let rhsCharacter)): 350 | return lhsCharacter == rhsCharacter 351 | case (.InvalidCharacterWithinString(_, let lhsCharacter), .InvalidCharacterWithinString(_, let rhsCharacter)): 352 | return lhsCharacter == rhsCharacter 353 | case (.InvalidEscapeSequence(_, let lhsCharacter), .InvalidEscapeSequence(_, let rhsCharacter)): 354 | return lhsCharacter == rhsCharacter 355 | case (.UnterminatedString, .UnterminatedString): 356 | return true 357 | case (.UnexpectedCharacterInNumberAfterZero(_, let lhsCharacter), .UnexpectedCharacterInNumberAfterZero(_, let rhsCharacter)): 358 | return lhsCharacter == rhsCharacter 359 | case (.UnexpectedCharacterInNumber(_, let lhsCharacter), .UnexpectedCharacterInNumber(_, let rhsCharacter)): 360 | return lhsCharacter == rhsCharacter 361 | default: 362 | return false 363 | } 364 | } 365 | 366 | extension LexerTests { 367 | 368 | private func firstToken(source: String) -> Token { 369 | return try! Lexer(source: source).next() 370 | } 371 | 372 | private func checkError(source: String, expectedError: LexerError, file: String = #file, line: UInt = #line) { 373 | let sut = Lexer(source: source) 374 | 375 | do { 376 | let token = try sut.next() 377 | let failureMessage = "checkError failed: did not throw but returned (\(token))" 378 | recordFailureWithDescription(failureMessage, inFile: file, atLine: line, expected: true) 379 | } catch let error as LexerError { 380 | XCTAssertEqual(error, expectedError) 381 | if error != expectedError { 382 | recordFailureWithDescription("checkError failed: \(error) is not equal to \(expectedError)", inFile: file, atLine: line, expected: true) 383 | } 384 | } catch { 385 | recordFailureWithDescription("checkError failed: \(error) is not a LexerError", inFile: file, atLine: line, expected: true) 386 | } 387 | } 388 | 389 | private func checkTokenKindAndValue(lhs: Token, kind: TokenKind, value: String?, file: String = #file, line: UInt = #line) { 390 | if lhs.kind != kind || lhs.value != value { 391 | let message = "checkTokenKindAndValue failed: (\(lhs.kind), \(lhs.value)) is not equal to (\(kind), \(value))" 392 | recordFailureWithDescription(message, inFile: file, atLine: line, expected: true) 393 | } 394 | } 395 | 396 | } 397 | -------------------------------------------------------------------------------- /Tests/language/ParserTests.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import XCTest 3 | @testable import GraphQL 4 | 5 | class ParserTests: XCTestCase { 6 | 7 | override func setUp() { 8 | super.setUp() 9 | } 10 | 11 | override func tearDown() { 12 | super.tearDown() 13 | } 14 | 15 | func testCreatesAst() { 16 | let sut = Parser(source: "{ node(id: 4) { id, name } }") 17 | 18 | let ast = try! sut.parse() 19 | 20 | XCTAssertEqual(ast, 21 | Document(definitions: [ 22 | .Operation(OperationDefinition(type: .Query, name: nil, variableDefinitions: [], directives: [], selectionSet: SelectionSet(selections: [ 23 | .FieldSelection(Field(alias: nil, name: Name(value: "node"), arguments: [Argument(name: Name(value: "id"), value: .IntValue("4"))], directives: [], selectionSet: SelectionSet(selections: [ 24 | .FieldSelection(Field(alias: nil, name: Name(value: "id"), arguments: [], directives: [], selectionSet: nil)), 25 | .FieldSelection(Field(alias: nil, name: Name(value: "name"), arguments: [], directives: [], selectionSet: nil)) 26 | ]))) 27 | ])))]) 28 | ) 29 | } 30 | 31 | func testUnexpectedKeywordError() { 32 | let sut = Parser(source: "{ ...MissingOn }\nfragment MissingOn Type\n") 33 | 34 | do { 35 | let _ = try sut.parse() 36 | } catch ParserError.UnexpectedKeyword(let expectedKeyword, let actualToken) { 37 | XCTAssertEqual(expectedKeyword, Keyword.On) 38 | XCTAssertEqual(actualToken.kind, TokenKind.Name) 39 | XCTAssertEqual(actualToken.value, "Type") 40 | } catch { 41 | XCTFail("wrong error \(error)") 42 | } 43 | } 44 | 45 | func testWrongTokenKindError0() { 46 | let sut = Parser(source: "{ field: {} }") 47 | 48 | do { 49 | let _ = try sut.parse() 50 | } catch ParserError.WrongTokenKind(let expectedTokenKind, let actualTokenKind) { 51 | XCTAssertEqual(expectedTokenKind, TokenKind.Name) 52 | XCTAssertEqual(actualTokenKind, TokenKind.BraceL) 53 | } catch { 54 | XCTFail("wrong error \(error)") 55 | } 56 | } 57 | 58 | func testWrongTokenKindError1() { 59 | let sut = Parser(source: "{") 60 | 61 | do { 62 | let _ = try sut.parse() 63 | } catch ParserError.WrongTokenKind(let expectedToken, let actualToken) { 64 | XCTAssertEqual(expectedToken, TokenKind.Name) 65 | XCTAssertEqual(actualToken, TokenKind.EOF) 66 | } catch { 67 | XCTFail("wrong error \(error)") 68 | } 69 | } 70 | 71 | func testUnexpectedToken0() { 72 | let sut = Parser(source: "notanoperation Foo { field }") 73 | 74 | do { 75 | let _ = try sut.parse() 76 | } catch ParserError.UnexpectedToken(let actualToken) { 77 | XCTAssertEqual(actualToken.kind, TokenKind.Name) 78 | XCTAssertEqual(actualToken.value, "notanoperation") 79 | } catch { 80 | XCTFail("wrong error \(error)") 81 | } 82 | } 83 | 84 | func testUnexpectedToken1() { 85 | let sut = Parser(source: "...") 86 | 87 | do { 88 | let _ = try sut.parse() 89 | } catch ParserError.UnexpectedToken(let actualToken) { 90 | XCTAssertEqual(actualToken.kind, TokenKind.Spread) 91 | } catch { 92 | XCTFail("wrong error \(error)") 93 | } 94 | } 95 | 96 | func testParsesVariableInlineValues() { 97 | let sut = Parser(source: "{ field(complex: { a: { b: [ $var ] } }) }") 98 | 99 | do { 100 | let _ = try sut.parse() 101 | } catch { 102 | XCTFail("should not throw any error: \(error)") 103 | } 104 | } 105 | 106 | func testDoesNotAcceptFragmentsNamedOn() { 107 | let sut = Parser(source: "fragment on on on { on }") 108 | 109 | do { 110 | let _ = try sut.parse() 111 | } catch ParserError.UnexpectedToken(let actualToken) { 112 | XCTAssertEqual(actualToken.kind, TokenKind.Name) 113 | XCTAssertEqual(actualToken.value, "on") 114 | } catch { 115 | XCTFail("wrong error \(error)") 116 | } 117 | } 118 | 119 | func testDoesNotAcceptFragmentsSpreadOfOn() { 120 | let sut = Parser(source: "{ ...on }") 121 | 122 | do { 123 | let _ = try sut.parse() 124 | } catch ParserError.WrongTokenKind(let expectedToken, let actualToken) { 125 | XCTAssertEqual(expectedToken, TokenKind.Name) 126 | XCTAssertEqual(actualToken, TokenKind.BraceR) 127 | } catch { 128 | XCTFail("wrong error \(error)") 129 | } 130 | } 131 | 132 | func testDoesNotAllowNullAsAValue() { 133 | let sut = Parser(source: "{ fieldWithNullableStringInput(input: null) }") 134 | 135 | do { 136 | let _ = try sut.parse() 137 | } catch ParserError.UnexpectedToken(let actualToken) { 138 | XCTAssertEqual(actualToken.kind, TokenKind.Name) 139 | XCTAssertEqual(actualToken.value, "null") 140 | } catch { 141 | XCTFail("wrong error \(error)") 142 | } 143 | } 144 | 145 | func testParsesKitchenSink() { 146 | parseWithoutError(graphQlQuery("kitchen_sink")) 147 | } 148 | 149 | func testAllowsNonKeywordAnywhereANameIsAllowed() { 150 | let nonKeywords = ["on", "fragment", "query", "mutation", "subscription", "true", "false"] 151 | 152 | nonKeywords.forEach { keyword in 153 | let fragmentName = keyword == "on" ? "a" : keyword 154 | let source = "query \(keyword) {\n ... \(fragmentName)\n ... on \(keyword) { field }\n }\n fragment \(fragmentName) on Type {\n \(keyword)(\(keyword): $\(keyword)) @\(keyword)(\(keyword): \(keyword))\n }" 155 | 156 | parseWithoutError(source) 157 | } 158 | } 159 | 160 | func testParsesAnonymousMutationOperations() { 161 | parseWithoutError("\n mutation {\n mutationField\n }\n") 162 | } 163 | 164 | func testParsesAnonymousSubscriptionOperations() { 165 | parseWithoutError("\n subscription {\n subscriptionField\n }\n") 166 | } 167 | 168 | func testParsesNamedMutationOperations() { 169 | parseWithoutError("\n mutation Foo {\n mutationField\n }\n") 170 | } 171 | 172 | func testParsesNamedSubscriptionOperations() { 173 | parseWithoutError("\n subscription Foo {\n subscriptionField\n }\n") 174 | } 175 | 176 | } 177 | 178 | extension ParserTests { 179 | 180 | func parseWithoutError(source: String, file: String = #file, line: UInt = #line) { 181 | let sut = Parser(source: source) 182 | 183 | do { 184 | try sut.parse() 185 | } catch { 186 | recordFailureWithDescription("Unexpected error: \(error)", inFile: file, atLine: line, expected: true) 187 | } 188 | } 189 | 190 | } 191 | -------------------------------------------------------------------------------- /Tests/language/PrinterTests.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import XCTest 3 | @testable import GraphQL 4 | 5 | class PrinterTests: XCTestCase { 6 | 7 | func testPrintsMinimalAst() { 8 | let ast = Field(alias: nil, name: Name(value: "foo"), arguments: [], directives: [], selectionSet: SelectionSet(selections: [])) 9 | 10 | XCTAssertEqual(ast.prettyPrint(), "foo") 11 | } 12 | 13 | func testCorrectlyPrintsNonQueryOperationsWithoutName() { 14 | let ast = try! Parser(source: "query { id, name }").parse() 15 | 16 | let expected = "{\n" + 17 | " id\n" + 18 | " name\n" + 19 | "}\n" 20 | 21 | XCTAssertEqual(ast.prettyPrint(), expected) 22 | } 23 | 24 | func testCorrectlyPrintsMutationsWithName() { 25 | let ast = try! Parser(source: "mutation { id, name }").parse() 26 | 27 | let expected = "mutation {\n" + 28 | " id\n" + 29 | " name\n" + 30 | "}\n" 31 | 32 | XCTAssertEqual(ast.prettyPrint(), expected) 33 | } 34 | 35 | func testCorrectlyPrintsQueryWithArgumentAndDirective() { 36 | let ast = try! Parser(source: "query ($foo: TestType) @testDirective { id, name }").parse() 37 | 38 | let expected = "query ($foo: TestType) @testDirective {\n" + 39 | " id\n" + 40 | " name\n" + 41 | "}\n" 42 | 43 | XCTAssertEqual(ast.prettyPrint(), expected) 44 | } 45 | 46 | func testCorrectlyPrintsMutationWithArgumentAndDirective() { 47 | let ast = try! Parser(source: "mutation ($foo: TestType) @testDirective { id, name }").parse() 48 | 49 | let expected = "mutation ($foo: TestType) @testDirective {\n" + 50 | " id\n" + 51 | " name\n" + 52 | "}\n" 53 | 54 | XCTAssertEqual(ast.prettyPrint(), expected) 55 | } 56 | 57 | func testPrintsKitchenSink() { 58 | let ast = try! Parser(source: graphQlQuery("kitchen_sink")).parse() 59 | 60 | let expectedKitchenSink = "query queryName($foo: ComplexType, $site: Site = MOBILE) {\n" + 61 | " whoever123is: node (id: [123, 456]) {\n" + 62 | " id\n" + 63 | " ... on User @defer {\n" + 64 | " field2 {\n" + 65 | " id\n" + 66 | " alias: field1 (first: 10, after: $foo) @include(if: $foo) {\n" + 67 | " id\n" + 68 | " ...frag\n" + 69 | " }\n" + 70 | " }\n" + 71 | " }\n" + 72 | " ... @skip(unless: $foo) {\n" + 73 | " id\n" + 74 | " }\n" + 75 | " ... {\n" + 76 | " id\n" + 77 | " }\n" + 78 | " }\n" + 79 | "}\n" + 80 | "\n" + 81 | "mutation likeStory {\n" + 82 | " like (story: 123) @defer {\n" + 83 | " story {\n" + 84 | " id\n" + 85 | " }\n" + 86 | " }\n" + 87 | "}\n" + 88 | "\n" + 89 | "subscription StoryLikeSubscription($input: StoryLikeSubscribeInput) {\n" + 90 | " storyLikeSubscribe (input: $input) {\n" + 91 | " story {\n" + 92 | " likers {\n" + 93 | " count\n" + 94 | " }\n" + 95 | " likeSentence {\n" + 96 | " text\n" + 97 | " }\n" + 98 | " }\n" + 99 | " }\n" + 100 | "}\n" + 101 | "\n" + 102 | "fragment frag on Friend {\n" + 103 | " foo (size: $size, bar: $b, obj: {key: \"value\"})\n" + 104 | "}\n" + 105 | "\n" + 106 | "{\n" + 107 | " unnamed (truthy: true, falsey: false)\n" + 108 | " query\n" + 109 | "}\n" 110 | 111 | XCTAssertEqual(ast.prettyPrint(), expectedKitchenSink) 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /Tests/language/VisitorTests.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import XCTest 3 | @testable import GraphQL 4 | 5 | class VisitorTests: XCTestCase { 6 | 7 | func testVisitorSequenceType() { 8 | let ast = try! Parser(source: "{ a, b { x }, c }").parse() 9 | let sut = Visitor(node: ast) 10 | 11 | let result = sut.map { 12 | return "\($0.dynamicType)" 13 | } 14 | 15 | XCTAssertEqual(result, [ 16 | "Document", 17 | "Definition", 18 | "OperationDefinition", 19 | "SelectionSet", 20 | "Selection", 21 | "Field", 22 | "Name", 23 | "Selection", 24 | "Field", 25 | "Name", 26 | "SelectionSet", 27 | "Selection", 28 | "Field", 29 | "Name", 30 | "Selection", 31 | "Field", 32 | "Name"]) 33 | } 34 | 35 | func testAllowsSkippingSubtree() { 36 | let ast = try! Parser(source: "{ a, b { x }, c }").parse() 37 | var array: [String] = [] 38 | 39 | visit(ast, enter: { node in 40 | array.append("enter \(node.dynamicType)") 41 | switch node { 42 | case let field as Field where field.name.value == "b": 43 | return .SkipNode 44 | default: 45 | return .Continue 46 | } 47 | }, leave: { node in 48 | array.append("leave \(node.dynamicType)") 49 | return .Continue 50 | }) 51 | 52 | XCTAssertEqual(array, [ 53 | "enter Document", 54 | "enter Definition", 55 | "enter OperationDefinition", 56 | "enter SelectionSet", 57 | "enter Selection", 58 | "enter Field", 59 | "enter Name", 60 | "leave Name", 61 | "leave Field", 62 | "leave Selection", 63 | "enter Selection", 64 | "enter Field", 65 | "leave Field", 66 | "leave Selection", 67 | "enter Selection", 68 | "enter Field", 69 | "enter Name", 70 | "leave Name", 71 | "leave Field", 72 | "leave Selection", 73 | "leave SelectionSet", 74 | "leave OperationDefinition", 75 | "leave Definition", 76 | "leave Document"]) 77 | } 78 | 79 | func testVisitsKitchenSink() { 80 | let ast = try! Parser(source: graphQlQuery("kitchen_sink")).parse() 81 | 82 | var array: [String] = [] 83 | 84 | func visitorFn(marker: String) -> VisitorFunction { 85 | return { 86 | (node: Node) in 87 | switch node { 88 | case Value.IntValue(let value): 89 | array.append("\(marker) Value.IntValue \(value)") 90 | case Value.FloatValue(let value): 91 | array.append("\(marker) Value.FloatValue \(value)") 92 | case Value.StringValue(let value): 93 | array.append("\(marker) Value.StringValue \(value)") 94 | case Value.BoolValue(let value): 95 | array.append("\(marker) Value.BoolValue \(value)") 96 | case Value.Enum(let value): 97 | array.append("\(marker) Value.Enum \(value)") 98 | case let name as Name: 99 | array.append("\(marker) \(node.dynamicType) \(name.value ?? "null")") 100 | default: 101 | array.append("\(marker) \(node.dynamicType)") 102 | } 103 | return .Continue 104 | } 105 | } 106 | 107 | visit(ast, enter: visitorFn("enter"), leave: visitorFn("leave")) 108 | 109 | XCTAssertEqual(array, [ 110 | "enter Document", 111 | "enter Definition", 112 | "enter OperationDefinition", 113 | "enter Name queryName", 114 | "leave Name queryName", 115 | "enter VariableDefinition", 116 | "enter Variable", 117 | "enter Name foo", 118 | "leave Name foo", 119 | "leave Variable", 120 | "enter Type", 121 | "enter Name ComplexType", 122 | "leave Name ComplexType", 123 | "leave Type", 124 | "leave VariableDefinition", 125 | "enter VariableDefinition", 126 | "enter Variable", 127 | "enter Name site", 128 | "leave Name site", 129 | "leave Variable", 130 | "enter Type", 131 | "enter Name Site", 132 | "leave Name Site", 133 | "leave Type", 134 | "enter Value.Enum MOBILE", 135 | "leave Value.Enum MOBILE", 136 | "leave VariableDefinition", 137 | "enter SelectionSet", 138 | "enter Selection", 139 | "enter Field", 140 | "enter Name whoever123is", 141 | "leave Name whoever123is", 142 | "enter Name node", 143 | "leave Name node", 144 | "enter Argument", 145 | "enter Name id", 146 | "leave Name id", 147 | "enter Value", 148 | "enter Value.IntValue 123", 149 | "leave Value.IntValue 123", 150 | "enter Value.IntValue 456", 151 | "leave Value.IntValue 456", 152 | "leave Value", 153 | "leave Argument", 154 | "enter SelectionSet", 155 | "enter Selection", 156 | "enter Field", 157 | "enter Name id", 158 | "leave Name id", 159 | "leave Field", 160 | "leave Selection", 161 | "enter Selection", 162 | "enter InlineFragment", 163 | "enter Type", 164 | "enter Name User", 165 | "leave Name User", 166 | "leave Type", 167 | "enter Directive", 168 | "enter Name defer", 169 | "leave Name defer", 170 | "leave Directive", 171 | "enter SelectionSet", 172 | "enter Selection", 173 | "enter Field", 174 | "enter Name field2", 175 | "leave Name field2", 176 | "enter SelectionSet", 177 | "enter Selection", 178 | "enter Field", 179 | "enter Name id", 180 | "leave Name id", 181 | "leave Field", 182 | "leave Selection", 183 | "enter Selection", 184 | "enter Field", 185 | "enter Name alias", 186 | "leave Name alias", 187 | "enter Name field1", 188 | "leave Name field1", 189 | "enter Argument", 190 | "enter Name first", 191 | "leave Name first", 192 | "enter Value.IntValue 10", 193 | "leave Value.IntValue 10", 194 | "leave Argument", 195 | "enter Argument", 196 | "enter Name after", 197 | "leave Name after", 198 | "enter Value", 199 | "enter Variable", 200 | "enter Name foo", 201 | "leave Name foo", 202 | "leave Variable", 203 | "leave Value", 204 | "leave Argument", 205 | "enter Directive", 206 | "enter Name include", 207 | "leave Name include", 208 | "leave Directive", 209 | "enter SelectionSet", 210 | "enter Selection", 211 | "enter Field", 212 | "enter Name id", 213 | "leave Name id", 214 | "leave Field", 215 | "leave Selection", 216 | "enter Selection", 217 | "enter FragmentSpread", 218 | "enter Name frag", 219 | "leave Name frag", 220 | "leave FragmentSpread", 221 | "leave Selection", 222 | "leave SelectionSet", 223 | "leave Field", 224 | "leave Selection", 225 | "leave SelectionSet", 226 | "leave Field", 227 | "leave Selection", 228 | "leave SelectionSet", 229 | "leave InlineFragment", 230 | "leave Selection", 231 | "enter Selection", 232 | "enter InlineFragment", 233 | "enter Directive", 234 | "enter Name skip", 235 | "leave Name skip", 236 | "leave Directive", 237 | "enter SelectionSet", 238 | "enter Selection", 239 | "enter Field", 240 | "enter Name id", 241 | "leave Name id", 242 | "leave Field", 243 | "leave Selection", 244 | "leave SelectionSet", 245 | "leave InlineFragment", 246 | "leave Selection", 247 | "enter Selection", 248 | "enter InlineFragment", 249 | "enter SelectionSet", 250 | "enter Selection", 251 | "enter Field", 252 | "enter Name id", 253 | "leave Name id", 254 | "leave Field", 255 | "leave Selection", 256 | "leave SelectionSet", 257 | "leave InlineFragment", 258 | "leave Selection", 259 | "leave SelectionSet", 260 | "leave Field", 261 | "leave Selection", 262 | "leave SelectionSet", 263 | "leave OperationDefinition", 264 | "leave Definition", 265 | "enter Definition", 266 | "enter OperationDefinition", 267 | "enter Name likeStory", 268 | "leave Name likeStory", 269 | "enter SelectionSet", 270 | "enter Selection", 271 | "enter Field", 272 | "enter Name like", 273 | "leave Name like", 274 | "enter Argument", 275 | "enter Name story", 276 | "leave Name story", 277 | "enter Value.IntValue 123", 278 | "leave Value.IntValue 123", 279 | "leave Argument", 280 | "enter Directive", 281 | "enter Name defer", 282 | "leave Name defer", 283 | "leave Directive", 284 | "enter SelectionSet", 285 | "enter Selection", 286 | "enter Field", 287 | "enter Name story", 288 | "leave Name story", 289 | "enter SelectionSet", 290 | "enter Selection", 291 | "enter Field", 292 | "enter Name id", 293 | "leave Name id", 294 | "leave Field", 295 | "leave Selection", 296 | "leave SelectionSet", 297 | "leave Field", 298 | "leave Selection", 299 | "leave SelectionSet", 300 | "leave Field", 301 | "leave Selection", 302 | "leave SelectionSet", 303 | "leave OperationDefinition", 304 | "leave Definition", 305 | "enter Definition", 306 | "enter OperationDefinition", 307 | "enter Name StoryLikeSubscription", 308 | "leave Name StoryLikeSubscription", 309 | "enter VariableDefinition", 310 | "enter Variable", 311 | "enter Name input", 312 | "leave Name input", 313 | "leave Variable", 314 | "enter Type", 315 | "enter Name StoryLikeSubscribeInput", 316 | "leave Name StoryLikeSubscribeInput", 317 | "leave Type", 318 | "leave VariableDefinition", 319 | "enter SelectionSet", 320 | "enter Selection", 321 | "enter Field", 322 | "enter Name storyLikeSubscribe", 323 | "leave Name storyLikeSubscribe", 324 | "enter Argument", 325 | "enter Name input", 326 | "leave Name input", 327 | "enter Value", 328 | "enter Variable", 329 | "enter Name input", 330 | "leave Name input", 331 | "leave Variable", 332 | "leave Value", 333 | "leave Argument", 334 | "enter SelectionSet", 335 | "enter Selection", 336 | "enter Field", 337 | "enter Name story", 338 | "leave Name story", 339 | "enter SelectionSet", 340 | "enter Selection", 341 | "enter Field", 342 | "enter Name likers", 343 | "leave Name likers", 344 | "enter SelectionSet", 345 | "enter Selection", 346 | "enter Field", 347 | "enter Name count", 348 | "leave Name count", 349 | "leave Field", 350 | "leave Selection", 351 | "leave SelectionSet", 352 | "leave Field", 353 | "leave Selection", 354 | "enter Selection", 355 | "enter Field", 356 | "enter Name likeSentence", 357 | "leave Name likeSentence", 358 | "enter SelectionSet", 359 | "enter Selection", 360 | "enter Field", 361 | "enter Name text", 362 | "leave Name text", 363 | "leave Field", 364 | "leave Selection", 365 | "leave SelectionSet", 366 | "leave Field", 367 | "leave Selection", 368 | "leave SelectionSet", 369 | "leave Field", 370 | "leave Selection", 371 | "leave SelectionSet", 372 | "leave Field", 373 | "leave Selection", 374 | "leave SelectionSet", 375 | "leave OperationDefinition", 376 | "leave Definition", 377 | "enter Definition", 378 | "enter FragmentDefinition", 379 | "enter Name frag", 380 | "leave Name frag", 381 | "enter Type", 382 | "enter Name Friend", 383 | "leave Name Friend", 384 | "leave Type", 385 | "enter SelectionSet", 386 | "enter Selection", 387 | "enter Field", 388 | "enter Name foo", 389 | "leave Name foo", 390 | "enter Argument", 391 | "enter Name size", 392 | "leave Name size", 393 | "enter Value", 394 | "enter Variable", 395 | "enter Name size", 396 | "leave Name size", 397 | "leave Variable", 398 | "leave Value", 399 | "leave Argument", 400 | "enter Argument", 401 | "enter Name bar", 402 | "leave Name bar", 403 | "enter Value", 404 | "enter Variable", 405 | "enter Name b", 406 | "leave Name b", 407 | "leave Variable", 408 | "leave Value", 409 | "leave Argument", 410 | "enter Argument", 411 | "enter Name obj", 412 | "leave Name obj", 413 | "enter Value", 414 | "enter ObjectField", 415 | "enter Name key", 416 | "leave Name key", 417 | "enter Value.StringValue value", 418 | "leave Value.StringValue value", 419 | "leave ObjectField", 420 | "leave Value", 421 | "leave Argument", 422 | "leave Field", 423 | "leave Selection", 424 | "leave SelectionSet", 425 | "leave FragmentDefinition", 426 | "leave Definition", 427 | "enter Definition", 428 | "enter OperationDefinition", 429 | "enter SelectionSet", 430 | "enter Selection", 431 | "enter Field", 432 | "enter Name unnamed", 433 | "leave Name unnamed", 434 | "enter Argument", 435 | "enter Name truthy", 436 | "leave Name truthy", 437 | "enter Value.BoolValue true", 438 | "leave Value.BoolValue true", 439 | "leave Argument", 440 | "enter Argument", 441 | "enter Name falsey", 442 | "leave Name falsey", 443 | "enter Value.BoolValue false", 444 | "leave Value.BoolValue false", 445 | "leave Argument", 446 | "leave Field", 447 | "leave Selection", 448 | "enter Selection", 449 | "enter Field", 450 | "enter Name query", 451 | "leave Name query", 452 | "leave Field", 453 | "leave Selection", 454 | "leave SelectionSet", 455 | "leave OperationDefinition", 456 | "leave Definition", 457 | "leave Document"]) 458 | } 459 | 460 | } 461 | -------------------------------------------------------------------------------- /Tests/resources/kitchen_sink.graphql: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015, Facebook, Inc. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the BSD-style license found in the 5 | # LICENSE file in the root directory of this source tree. An additional grant 6 | # of patent rights can be found in the PATENTS file in the same directory. 7 | 8 | query queryName($foo: ComplexType, $site: Site = MOBILE) { 9 | whoever123is: node(id: [123, 456]) { 10 | id , 11 | ... on User @defer { 12 | field2 { 13 | id , 14 | alias: field1(first:10, after:$foo,) @include(if: $foo) { 15 | id, 16 | ...frag 17 | } 18 | } 19 | } 20 | ... @skip(unless: $foo) { 21 | id 22 | } 23 | ... { 24 | id 25 | } 26 | } 27 | } 28 | 29 | mutation likeStory { 30 | like(story: 123) @defer { 31 | story { 32 | id 33 | } 34 | } 35 | } 36 | 37 | subscription StoryLikeSubscription($input: StoryLikeSubscribeInput) { 38 | storyLikeSubscribe(input: $input) { 39 | story { 40 | likers { 41 | count 42 | } 43 | likeSentence { 44 | text 45 | } 46 | } 47 | } 48 | } 49 | 50 | fragment frag on Friend { 51 | foo(size: $size, bar: $b, obj: {key: "value"}) 52 | } 53 | 54 | { 55 | unnamed(truthy: true, falsey: false), 56 | query 57 | } 58 | -------------------------------------------------------------------------------- /Tests/utilities/TestUtilities.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | func graphQlQuery(name: String) -> String { 4 | let bundle = NSBundle(forClass: LexerTests.self) 5 | guard let queryURL = bundle.URLForResource(name, withExtension: "graphql") else { 6 | fatalError("GraphQL query not found: \(name).") 7 | } 8 | return try! String(contentsOfURL: queryURL, encoding: NSUTF8StringEncoding) 9 | } 10 | -------------------------------------------------------------------------------- /graphql.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 9FD5B00BAA7342997F2379F0 /* Printer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B4588A548B3FEE7818C7 /* Printer.swift */; }; 11 | 9FD5B01AE078BBCC03E0343A /* TestUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B96BAE4947686275B11A /* TestUtilities.swift */; }; 12 | 9FD5B0736CB906E9FFBFE497 /* VisitorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B86B508316BC661AA552 /* VisitorTests.swift */; }; 13 | 9FD5B07E2C696751E4AF616B /* LexerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B21F5E7A0CFDC1C106F9 /* LexerTests.swift */; }; 14 | 9FD5B092368674ACDB082D17 /* Printer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B4588A548B3FEE7818C7 /* Printer.swift */; }; 15 | 9FD5B13F5F720BF712D0FB46 /* LexerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B21F5E7A0CFDC1C106F9 /* LexerTests.swift */; }; 16 | 9FD5B14626E62EB3D41D2BBE /* Visitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5BE04DBE114F484075A3A /* Visitor.swift */; }; 17 | 9FD5B1521A5E0236B6A856A5 /* Printer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B4588A548B3FEE7818C7 /* Printer.swift */; }; 18 | 9FD5B1752AFD5F5AF4AFF778 /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B6C1CA5762C3E9FABC13 /* Parser.swift */; }; 19 | 9FD5B355A1534F5AD107F338 /* kitchen_sink.graphql in Resources */ = {isa = PBXBuildFile; fileRef = 9FD5B989A98F64119A07BCFC /* kitchen_sink.graphql */; }; 20 | 9FD5B37A2B64F8AADA46B21A /* ParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5BAF9AC8C6404E631914E /* ParserTests.swift */; }; 21 | 9FD5B3889D5E08538A91A7BA /* PrinterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B0245CB6552FC4F36653 /* PrinterTests.swift */; }; 22 | 9FD5B3A79EE79B7FB88E1DD4 /* ParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5BAF9AC8C6404E631914E /* ParserTests.swift */; }; 23 | 9FD5B486361EA0C29CFE013E /* VisitorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B86B508316BC661AA552 /* VisitorTests.swift */; }; 24 | 9FD5B522488732CCBB06461B /* Lexer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B3BAC305189E35253A1C /* Lexer.swift */; }; 25 | 9FD5B5C31F18FE7640FA2DCF /* Visitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5BE04DBE114F484075A3A /* Visitor.swift */; }; 26 | 9FD5B6AA14E899F274331144 /* TestUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B96BAE4947686275B11A /* TestUtilities.swift */; }; 27 | 9FD5B6B45CE0AF6F23683331 /* Ast.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B4DE56C84A88027883C1 /* Ast.swift */; }; 28 | 9FD5B752A4093BEB3C8DFF5D /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B6C1CA5762C3E9FABC13 /* Parser.swift */; }; 29 | 9FD5B79D58304FED5724796E /* TestUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B96BAE4947686275B11A /* TestUtilities.swift */; }; 30 | 9FD5B7B84A03277E87DD5FCB /* ParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5BAF9AC8C6404E631914E /* ParserTests.swift */; }; 31 | 9FD5B88A85FE4E66CDA3DB29 /* PrinterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B0245CB6552FC4F36653 /* PrinterTests.swift */; }; 32 | 9FD5B92A3A3E3CD0525EC946 /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B6C1CA5762C3E9FABC13 /* Parser.swift */; }; 33 | 9FD5B9A8224465ADFD354677 /* Lexer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B3BAC305189E35253A1C /* Lexer.swift */; }; 34 | 9FD5B9E7484D4769C3813316 /* PrinterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B0245CB6552FC4F36653 /* PrinterTests.swift */; }; 35 | 9FD5BA37879CD36B768EACB1 /* kitchen_sink.graphql in Resources */ = {isa = PBXBuildFile; fileRef = 9FD5B989A98F64119A07BCFC /* kitchen_sink.graphql */; }; 36 | 9FD5BA42DC5B3035134F07A6 /* Lexer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B3BAC305189E35253A1C /* Lexer.swift */; }; 37 | 9FD5BA6284D3000CA76C1A9A /* Ast.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B4DE56C84A88027883C1 /* Ast.swift */; }; 38 | 9FD5BAF09770EE234A5945AF /* Printer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B4588A548B3FEE7818C7 /* Printer.swift */; }; 39 | 9FD5BB52B21F7E18FDA01138 /* Visitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5BE04DBE114F484075A3A /* Visitor.swift */; }; 40 | 9FD5BC88E8CFBFB1787AAB32 /* Ast.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B4DE56C84A88027883C1 /* Ast.swift */; }; 41 | 9FD5BC92D72CEA3B760C6257 /* VisitorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B86B508316BC661AA552 /* VisitorTests.swift */; }; 42 | 9FD5BCA6D3C6EA0383944B6D /* kitchen_sink.graphql in Resources */ = {isa = PBXBuildFile; fileRef = 9FD5B989A98F64119A07BCFC /* kitchen_sink.graphql */; }; 43 | 9FD5BD28B4AE136B2BAA2834 /* Lexer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B3BAC305189E35253A1C /* Lexer.swift */; }; 44 | 9FD5BDAB5BEB9E304170ACBF /* Visitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5BE04DBE114F484075A3A /* Visitor.swift */; }; 45 | 9FD5BE26AE0249521238FE71 /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B6C1CA5762C3E9FABC13 /* Parser.swift */; }; 46 | 9FD5BF64173E8E065DACFB35 /* LexerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B21F5E7A0CFDC1C106F9 /* LexerTests.swift */; }; 47 | 9FD5BFBFE7F98A235568BECF /* Ast.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD5B4DE56C84A88027883C1 /* Ast.swift */; }; 48 | EB4791B91CBD85E200C04D13 /* GraphQL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EB86F1C31CBD813B00021DCE /* GraphQL.framework */; }; 49 | EB4791C81CBD85F400C04D13 /* GraphQL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EB86F19B1CBD810200021DCE /* GraphQL.framework */; }; 50 | EB4791D71CBD8AF700C04D13 /* GraphQL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EB86F1B61CBD812C00021DCE /* GraphQL.framework */; }; 51 | EBB78EA71CC9332400D366AB /* GraphQL.h in Headers */ = {isa = PBXBuildFile; fileRef = EBB78EA11CC9332400D366AB /* GraphQL.h */; settings = {ATTRIBUTES = (Public, ); }; }; 52 | EBB78EA81CC9332400D366AB /* graphql.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBB78EA21CC9332400D366AB /* graphql.swift */; }; 53 | EBB78EAD1CC9332800D366AB /* graphql.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBB78EA21CC9332400D366AB /* graphql.swift */; }; 54 | EBB78EAE1CC9332900D366AB /* graphql.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBB78EA21CC9332400D366AB /* graphql.swift */; }; 55 | EBB78EAF1CC9332900D366AB /* graphql.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBB78EA21CC9332400D366AB /* graphql.swift */; }; 56 | EBB78EB01CC9332D00D366AB /* GraphQL.h in Headers */ = {isa = PBXBuildFile; fileRef = EBB78EA11CC9332400D366AB /* GraphQL.h */; settings = {ATTRIBUTES = (Public, ); }; }; 57 | EBB78EB11CC9332D00D366AB /* GraphQL.h in Headers */ = {isa = PBXBuildFile; fileRef = EBB78EA11CC9332400D366AB /* GraphQL.h */; settings = {ATTRIBUTES = (Public, ); }; }; 58 | EBB78EB21CC9332E00D366AB /* GraphQL.h in Headers */ = {isa = PBXBuildFile; fileRef = EBB78EA11CC9332400D366AB /* GraphQL.h */; settings = {ATTRIBUTES = (Public, ); }; }; 59 | /* End PBXBuildFile section */ 60 | 61 | /* Begin PBXContainerItemProxy section */ 62 | EB4791BA1CBD85E200C04D13 /* PBXContainerItemProxy */ = { 63 | isa = PBXContainerItemProxy; 64 | containerPortal = EB2B587A1CBD80750007387E /* Project object */; 65 | proxyType = 1; 66 | remoteGlobalIDString = EB86F1C21CBD813B00021DCE; 67 | remoteInfo = "GraphQL OS X"; 68 | }; 69 | EB4791C91CBD85F400C04D13 /* PBXContainerItemProxy */ = { 70 | isa = PBXContainerItemProxy; 71 | containerPortal = EB2B587A1CBD80750007387E /* Project object */; 72 | proxyType = 1; 73 | remoteGlobalIDString = EB86F19A1CBD810200021DCE; 74 | remoteInfo = "GraphQL iOS"; 75 | }; 76 | EB4791D81CBD8AF700C04D13 /* PBXContainerItemProxy */ = { 77 | isa = PBXContainerItemProxy; 78 | containerPortal = EB2B587A1CBD80750007387E /* Project object */; 79 | proxyType = 1; 80 | remoteGlobalIDString = EB86F1B51CBD812C00021DCE; 81 | remoteInfo = "GraphQL tvOS"; 82 | }; 83 | /* End PBXContainerItemProxy section */ 84 | 85 | /* Begin PBXFileReference section */ 86 | 9FD5B0245CB6552FC4F36653 /* PrinterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PrinterTests.swift; sourceTree = ""; }; 87 | 9FD5B21F5E7A0CFDC1C106F9 /* LexerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LexerTests.swift; sourceTree = ""; }; 88 | 9FD5B3BAC305189E35253A1C /* Lexer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Lexer.swift; sourceTree = ""; }; 89 | 9FD5B4588A548B3FEE7818C7 /* Printer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Printer.swift; sourceTree = ""; }; 90 | 9FD5B4DE56C84A88027883C1 /* Ast.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Ast.swift; sourceTree = ""; }; 91 | 9FD5B6C1CA5762C3E9FABC13 /* Parser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Parser.swift; sourceTree = ""; }; 92 | 9FD5B86B508316BC661AA552 /* VisitorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VisitorTests.swift; sourceTree = ""; }; 93 | 9FD5B96BAE4947686275B11A /* TestUtilities.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestUtilities.swift; sourceTree = ""; }; 94 | 9FD5B989A98F64119A07BCFC /* kitchen_sink.graphql */ = {isa = PBXFileReference; lastKnownFileType = file.graphql; path = kitchen_sink.graphql; sourceTree = ""; }; 95 | 9FD5BAF9AC8C6404E631914E /* ParserTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParserTests.swift; sourceTree = ""; }; 96 | 9FD5BE04DBE114F484075A3A /* Visitor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Visitor.swift; sourceTree = ""; }; 97 | EB4791B41CBD85E200C04D13 /* GraphQL OS X Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "GraphQL OS X Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 98 | EB4791C31CBD85F400C04D13 /* GraphQL iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "GraphQL iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 99 | EB4791D21CBD8AF700C04D13 /* GraphQL tvOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "GraphQL tvOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 100 | EB86F19B1CBD810200021DCE /* GraphQL.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = GraphQL.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 101 | EB86F1A91CBD811D00021DCE /* GraphQL.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = GraphQL.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 102 | EB86F1B61CBD812C00021DCE /* GraphQL.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = GraphQL.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 103 | EB86F1C31CBD813B00021DCE /* GraphQL.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = GraphQL.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 104 | EBB78EA11CC9332400D366AB /* GraphQL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GraphQL.h; sourceTree = ""; }; 105 | EBB78EA21CC9332400D366AB /* graphql.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = graphql.swift; sourceTree = ""; }; 106 | EBB78EA31CC9332400D366AB /* Info-iOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = ""; }; 107 | EBB78EA41CC9332400D366AB /* Info-OSX.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-OSX.plist"; sourceTree = ""; }; 108 | EBB78EA51CC9332400D366AB /* Info-tvOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-tvOS.plist"; sourceTree = ""; }; 109 | EBB78EA61CC9332400D366AB /* Info-watchOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-watchOS.plist"; sourceTree = ""; }; 110 | EBB78EB31CCAAE2E00D366AB /* Info-iOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = ""; }; 111 | EBB78EB41CCAAE2E00D366AB /* Info-OSX.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-OSX.plist"; sourceTree = ""; }; 112 | EBB78EB51CCAAE2E00D366AB /* Info-tvOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-tvOS.plist"; sourceTree = ""; }; 113 | /* End PBXFileReference section */ 114 | 115 | /* Begin PBXFrameworksBuildPhase section */ 116 | EB4791B11CBD85E200C04D13 /* Frameworks */ = { 117 | isa = PBXFrameworksBuildPhase; 118 | buildActionMask = 2147483647; 119 | files = ( 120 | EB4791B91CBD85E200C04D13 /* GraphQL.framework in Frameworks */, 121 | ); 122 | runOnlyForDeploymentPostprocessing = 0; 123 | }; 124 | EB4791C01CBD85F400C04D13 /* Frameworks */ = { 125 | isa = PBXFrameworksBuildPhase; 126 | buildActionMask = 2147483647; 127 | files = ( 128 | EB4791C81CBD85F400C04D13 /* GraphQL.framework in Frameworks */, 129 | ); 130 | runOnlyForDeploymentPostprocessing = 0; 131 | }; 132 | EB4791CF1CBD8AF700C04D13 /* Frameworks */ = { 133 | isa = PBXFrameworksBuildPhase; 134 | buildActionMask = 2147483647; 135 | files = ( 136 | EB4791D71CBD8AF700C04D13 /* GraphQL.framework in Frameworks */, 137 | ); 138 | runOnlyForDeploymentPostprocessing = 0; 139 | }; 140 | EB86F1971CBD810200021DCE /* Frameworks */ = { 141 | isa = PBXFrameworksBuildPhase; 142 | buildActionMask = 2147483647; 143 | files = ( 144 | ); 145 | runOnlyForDeploymentPostprocessing = 0; 146 | }; 147 | EB86F1A51CBD811D00021DCE /* Frameworks */ = { 148 | isa = PBXFrameworksBuildPhase; 149 | buildActionMask = 2147483647; 150 | files = ( 151 | ); 152 | runOnlyForDeploymentPostprocessing = 0; 153 | }; 154 | EB86F1B21CBD812C00021DCE /* Frameworks */ = { 155 | isa = PBXFrameworksBuildPhase; 156 | buildActionMask = 2147483647; 157 | files = ( 158 | ); 159 | runOnlyForDeploymentPostprocessing = 0; 160 | }; 161 | EB86F1BF1CBD813B00021DCE /* Frameworks */ = { 162 | isa = PBXFrameworksBuildPhase; 163 | buildActionMask = 2147483647; 164 | files = ( 165 | ); 166 | runOnlyForDeploymentPostprocessing = 0; 167 | }; 168 | /* End PBXFrameworksBuildPhase section */ 169 | 170 | /* Begin PBXGroup section */ 171 | 9FD5B2B252E7F777F61BE458 /* language */ = { 172 | isa = PBXGroup; 173 | children = ( 174 | 9FD5BAF9AC8C6404E631914E /* ParserTests.swift */, 175 | 9FD5B21F5E7A0CFDC1C106F9 /* LexerTests.swift */, 176 | 9FD5B86B508316BC661AA552 /* VisitorTests.swift */, 177 | 9FD5B0245CB6552FC4F36653 /* PrinterTests.swift */, 178 | ); 179 | path = language; 180 | sourceTree = ""; 181 | }; 182 | 9FD5B5634E161C8329C9556E /* resources */ = { 183 | isa = PBXGroup; 184 | children = ( 185 | 9FD5B989A98F64119A07BCFC /* kitchen_sink.graphql */, 186 | ); 187 | path = resources; 188 | sourceTree = ""; 189 | }; 190 | 9FD5B82CBE7745EDB92D233A /* Tests */ = { 191 | isa = PBXGroup; 192 | children = ( 193 | EBB78EB31CCAAE2E00D366AB /* Info-iOS.plist */, 194 | EBB78EB41CCAAE2E00D366AB /* Info-OSX.plist */, 195 | EBB78EB51CCAAE2E00D366AB /* Info-tvOS.plist */, 196 | 9FD5B2B252E7F777F61BE458 /* language */, 197 | 9FD5BA606FC338C69E048251 /* utilities */, 198 | 9FD5B5634E161C8329C9556E /* resources */, 199 | ); 200 | path = Tests; 201 | sourceTree = ""; 202 | }; 203 | 9FD5B9734122131C8D20C00F /* language */ = { 204 | isa = PBXGroup; 205 | children = ( 206 | 9FD5B6C1CA5762C3E9FABC13 /* Parser.swift */, 207 | 9FD5B3BAC305189E35253A1C /* Lexer.swift */, 208 | 9FD5B4DE56C84A88027883C1 /* Ast.swift */, 209 | 9FD5BE04DBE114F484075A3A /* Visitor.swift */, 210 | 9FD5B4588A548B3FEE7818C7 /* Printer.swift */, 211 | ); 212 | path = language; 213 | sourceTree = ""; 214 | }; 215 | 9FD5BA606FC338C69E048251 /* utilities */ = { 216 | isa = PBXGroup; 217 | children = ( 218 | 9FD5B96BAE4947686275B11A /* TestUtilities.swift */, 219 | ); 220 | path = utilities; 221 | sourceTree = ""; 222 | }; 223 | EB2B58791CBD80750007387E = { 224 | isa = PBXGroup; 225 | children = ( 226 | EB86F1CF1CBD819200021DCE /* Sources */, 227 | EB86F19C1CBD810200021DCE /* Products */, 228 | 9FD5B82CBE7745EDB92D233A /* Tests */, 229 | ); 230 | sourceTree = ""; 231 | }; 232 | EB86F19C1CBD810200021DCE /* Products */ = { 233 | isa = PBXGroup; 234 | children = ( 235 | EB86F19B1CBD810200021DCE /* GraphQL.framework */, 236 | EB86F1A91CBD811D00021DCE /* GraphQL.framework */, 237 | EB86F1B61CBD812C00021DCE /* GraphQL.framework */, 238 | EB86F1C31CBD813B00021DCE /* GraphQL.framework */, 239 | EB4791B41CBD85E200C04D13 /* GraphQL OS X Tests.xctest */, 240 | EB4791C31CBD85F400C04D13 /* GraphQL iOS Tests.xctest */, 241 | EB4791D21CBD8AF700C04D13 /* GraphQL tvOS Tests.xctest */, 242 | ); 243 | name = Products; 244 | sourceTree = ""; 245 | }; 246 | EB86F1CF1CBD819200021DCE /* Sources */ = { 247 | isa = PBXGroup; 248 | children = ( 249 | EBB78EA11CC9332400D366AB /* GraphQL.h */, 250 | EBB78EA21CC9332400D366AB /* graphql.swift */, 251 | EBB78EA31CC9332400D366AB /* Info-iOS.plist */, 252 | EBB78EA41CC9332400D366AB /* Info-OSX.plist */, 253 | EBB78EA51CC9332400D366AB /* Info-tvOS.plist */, 254 | EBB78EA61CC9332400D366AB /* Info-watchOS.plist */, 255 | 9FD5B9734122131C8D20C00F /* language */, 256 | ); 257 | path = Sources; 258 | sourceTree = ""; 259 | }; 260 | /* End PBXGroup section */ 261 | 262 | /* Begin PBXHeadersBuildPhase section */ 263 | EB86F1981CBD810200021DCE /* Headers */ = { 264 | isa = PBXHeadersBuildPhase; 265 | buildActionMask = 2147483647; 266 | files = ( 267 | EBB78EA71CC9332400D366AB /* GraphQL.h in Headers */, 268 | ); 269 | runOnlyForDeploymentPostprocessing = 0; 270 | }; 271 | EB86F1A61CBD811D00021DCE /* Headers */ = { 272 | isa = PBXHeadersBuildPhase; 273 | buildActionMask = 2147483647; 274 | files = ( 275 | EBB78EB01CC9332D00D366AB /* GraphQL.h in Headers */, 276 | ); 277 | runOnlyForDeploymentPostprocessing = 0; 278 | }; 279 | EB86F1B31CBD812C00021DCE /* Headers */ = { 280 | isa = PBXHeadersBuildPhase; 281 | buildActionMask = 2147483647; 282 | files = ( 283 | EBB78EB11CC9332D00D366AB /* GraphQL.h in Headers */, 284 | ); 285 | runOnlyForDeploymentPostprocessing = 0; 286 | }; 287 | EB86F1C01CBD813B00021DCE /* Headers */ = { 288 | isa = PBXHeadersBuildPhase; 289 | buildActionMask = 2147483647; 290 | files = ( 291 | EBB78EB21CC9332E00D366AB /* GraphQL.h in Headers */, 292 | ); 293 | runOnlyForDeploymentPostprocessing = 0; 294 | }; 295 | /* End PBXHeadersBuildPhase section */ 296 | 297 | /* Begin PBXNativeTarget section */ 298 | EB4791B31CBD85E200C04D13 /* GraphQL OS X Tests */ = { 299 | isa = PBXNativeTarget; 300 | buildConfigurationList = EB4791BE1CBD85E200C04D13 /* Build configuration list for PBXNativeTarget "GraphQL OS X Tests" */; 301 | buildPhases = ( 302 | EB4791B01CBD85E200C04D13 /* Sources */, 303 | EB4791B11CBD85E200C04D13 /* Frameworks */, 304 | EB4791B21CBD85E200C04D13 /* Resources */, 305 | ); 306 | buildRules = ( 307 | ); 308 | dependencies = ( 309 | EB4791BB1CBD85E200C04D13 /* PBXTargetDependency */, 310 | ); 311 | name = "GraphQL OS X Tests"; 312 | productName = "GraphQL OS X Tests"; 313 | productReference = EB4791B41CBD85E200C04D13 /* GraphQL OS X Tests.xctest */; 314 | productType = "com.apple.product-type.bundle.unit-test"; 315 | }; 316 | EB4791C21CBD85F400C04D13 /* GraphQL iOS Tests */ = { 317 | isa = PBXNativeTarget; 318 | buildConfigurationList = EB4791CB1CBD85F400C04D13 /* Build configuration list for PBXNativeTarget "GraphQL iOS Tests" */; 319 | buildPhases = ( 320 | EB4791BF1CBD85F400C04D13 /* Sources */, 321 | EB4791C01CBD85F400C04D13 /* Frameworks */, 322 | EB4791C11CBD85F400C04D13 /* Resources */, 323 | ); 324 | buildRules = ( 325 | ); 326 | dependencies = ( 327 | EB4791CA1CBD85F400C04D13 /* PBXTargetDependency */, 328 | ); 329 | name = "GraphQL iOS Tests"; 330 | productName = "GraphQL iOS Tests"; 331 | productReference = EB4791C31CBD85F400C04D13 /* GraphQL iOS Tests.xctest */; 332 | productType = "com.apple.product-type.bundle.unit-test"; 333 | }; 334 | EB4791D11CBD8AF700C04D13 /* GraphQL tvOS Tests */ = { 335 | isa = PBXNativeTarget; 336 | buildConfigurationList = EB4791DA1CBD8AF700C04D13 /* Build configuration list for PBXNativeTarget "GraphQL tvOS Tests" */; 337 | buildPhases = ( 338 | EB4791CE1CBD8AF700C04D13 /* Sources */, 339 | EB4791CF1CBD8AF700C04D13 /* Frameworks */, 340 | EB4791D01CBD8AF700C04D13 /* Resources */, 341 | ); 342 | buildRules = ( 343 | ); 344 | dependencies = ( 345 | EB4791D91CBD8AF700C04D13 /* PBXTargetDependency */, 346 | ); 347 | name = "GraphQL tvOS Tests"; 348 | productName = "GraphQL tvOS Tests"; 349 | productReference = EB4791D21CBD8AF700C04D13 /* GraphQL tvOS Tests.xctest */; 350 | productType = "com.apple.product-type.bundle.unit-test"; 351 | }; 352 | EB86F19A1CBD810200021DCE /* GraphQL iOS */ = { 353 | isa = PBXNativeTarget; 354 | buildConfigurationList = EB86F1A31CBD810200021DCE /* Build configuration list for PBXNativeTarget "GraphQL iOS" */; 355 | buildPhases = ( 356 | EB86F1961CBD810200021DCE /* Sources */, 357 | EB86F1971CBD810200021DCE /* Frameworks */, 358 | EB86F1981CBD810200021DCE /* Headers */, 359 | EB86F1991CBD810200021DCE /* Resources */, 360 | ); 361 | buildRules = ( 362 | ); 363 | dependencies = ( 364 | ); 365 | name = "GraphQL iOS"; 366 | productName = "GraphQL iOS"; 367 | productReference = EB86F19B1CBD810200021DCE /* GraphQL.framework */; 368 | productType = "com.apple.product-type.framework"; 369 | }; 370 | EB86F1A81CBD811D00021DCE /* GraphQL watchOS */ = { 371 | isa = PBXNativeTarget; 372 | buildConfigurationList = EB86F1AE1CBD811D00021DCE /* Build configuration list for PBXNativeTarget "GraphQL watchOS" */; 373 | buildPhases = ( 374 | EB86F1A41CBD811D00021DCE /* Sources */, 375 | EB86F1A51CBD811D00021DCE /* Frameworks */, 376 | EB86F1A61CBD811D00021DCE /* Headers */, 377 | EB86F1A71CBD811D00021DCE /* Resources */, 378 | ); 379 | buildRules = ( 380 | ); 381 | dependencies = ( 382 | ); 383 | name = "GraphQL watchOS"; 384 | productName = "GraphQL watchOS"; 385 | productReference = EB86F1A91CBD811D00021DCE /* GraphQL.framework */; 386 | productType = "com.apple.product-type.framework"; 387 | }; 388 | EB86F1B51CBD812C00021DCE /* GraphQL tvOS */ = { 389 | isa = PBXNativeTarget; 390 | buildConfigurationList = EB86F1BB1CBD812C00021DCE /* Build configuration list for PBXNativeTarget "GraphQL tvOS" */; 391 | buildPhases = ( 392 | EB86F1B11CBD812C00021DCE /* Sources */, 393 | EB86F1B21CBD812C00021DCE /* Frameworks */, 394 | EB86F1B31CBD812C00021DCE /* Headers */, 395 | EB86F1B41CBD812C00021DCE /* Resources */, 396 | ); 397 | buildRules = ( 398 | ); 399 | dependencies = ( 400 | ); 401 | name = "GraphQL tvOS"; 402 | productName = "GraphQL tvOS"; 403 | productReference = EB86F1B61CBD812C00021DCE /* GraphQL.framework */; 404 | productType = "com.apple.product-type.framework"; 405 | }; 406 | EB86F1C21CBD813B00021DCE /* GraphQL OS X */ = { 407 | isa = PBXNativeTarget; 408 | buildConfigurationList = EB86F1C81CBD813B00021DCE /* Build configuration list for PBXNativeTarget "GraphQL OS X" */; 409 | buildPhases = ( 410 | EB86F1BE1CBD813B00021DCE /* Sources */, 411 | EB86F1BF1CBD813B00021DCE /* Frameworks */, 412 | EB86F1C01CBD813B00021DCE /* Headers */, 413 | EB86F1C11CBD813B00021DCE /* Resources */, 414 | ); 415 | buildRules = ( 416 | ); 417 | dependencies = ( 418 | ); 419 | name = "GraphQL OS X"; 420 | productName = "GraphQL OS X"; 421 | productReference = EB86F1C31CBD813B00021DCE /* GraphQL.framework */; 422 | productType = "com.apple.product-type.framework"; 423 | }; 424 | /* End PBXNativeTarget section */ 425 | 426 | /* Begin PBXProject section */ 427 | EB2B587A1CBD80750007387E /* Project object */ = { 428 | isa = PBXProject; 429 | attributes = { 430 | LastSwiftUpdateCheck = 0730; 431 | LastUpgradeCheck = 0730; 432 | TargetAttributes = { 433 | EB4791B31CBD85E200C04D13 = { 434 | CreatedOnToolsVersion = 7.3; 435 | }; 436 | EB4791C21CBD85F400C04D13 = { 437 | CreatedOnToolsVersion = 7.3; 438 | }; 439 | EB4791D11CBD8AF700C04D13 = { 440 | CreatedOnToolsVersion = 7.3; 441 | }; 442 | EB86F19A1CBD810200021DCE = { 443 | CreatedOnToolsVersion = 7.3; 444 | }; 445 | EB86F1A81CBD811D00021DCE = { 446 | CreatedOnToolsVersion = 7.3; 447 | }; 448 | EB86F1B51CBD812C00021DCE = { 449 | CreatedOnToolsVersion = 7.3; 450 | }; 451 | EB86F1C21CBD813B00021DCE = { 452 | CreatedOnToolsVersion = 7.3; 453 | }; 454 | }; 455 | }; 456 | buildConfigurationList = EB2B587D1CBD80750007387E /* Build configuration list for PBXProject "graphql" */; 457 | compatibilityVersion = "Xcode 3.2"; 458 | developmentRegion = English; 459 | hasScannedForEncodings = 0; 460 | knownRegions = ( 461 | en, 462 | ); 463 | mainGroup = EB2B58791CBD80750007387E; 464 | productRefGroup = EB86F19C1CBD810200021DCE /* Products */; 465 | projectDirPath = ""; 466 | projectRoot = ""; 467 | targets = ( 468 | EB86F19A1CBD810200021DCE /* GraphQL iOS */, 469 | EB86F1A81CBD811D00021DCE /* GraphQL watchOS */, 470 | EB86F1B51CBD812C00021DCE /* GraphQL tvOS */, 471 | EB86F1C21CBD813B00021DCE /* GraphQL OS X */, 472 | EB4791B31CBD85E200C04D13 /* GraphQL OS X Tests */, 473 | EB4791C21CBD85F400C04D13 /* GraphQL iOS Tests */, 474 | EB4791D11CBD8AF700C04D13 /* GraphQL tvOS Tests */, 475 | ); 476 | }; 477 | /* End PBXProject section */ 478 | 479 | /* Begin PBXResourcesBuildPhase section */ 480 | EB4791B21CBD85E200C04D13 /* Resources */ = { 481 | isa = PBXResourcesBuildPhase; 482 | buildActionMask = 2147483647; 483 | files = ( 484 | 9FD5B355A1534F5AD107F338 /* kitchen_sink.graphql in Resources */, 485 | ); 486 | runOnlyForDeploymentPostprocessing = 0; 487 | }; 488 | EB4791C11CBD85F400C04D13 /* Resources */ = { 489 | isa = PBXResourcesBuildPhase; 490 | buildActionMask = 2147483647; 491 | files = ( 492 | 9FD5BCA6D3C6EA0383944B6D /* kitchen_sink.graphql in Resources */, 493 | ); 494 | runOnlyForDeploymentPostprocessing = 0; 495 | }; 496 | EB4791D01CBD8AF700C04D13 /* Resources */ = { 497 | isa = PBXResourcesBuildPhase; 498 | buildActionMask = 2147483647; 499 | files = ( 500 | 9FD5BA37879CD36B768EACB1 /* kitchen_sink.graphql in Resources */, 501 | ); 502 | runOnlyForDeploymentPostprocessing = 0; 503 | }; 504 | EB86F1991CBD810200021DCE /* Resources */ = { 505 | isa = PBXResourcesBuildPhase; 506 | buildActionMask = 2147483647; 507 | files = ( 508 | ); 509 | runOnlyForDeploymentPostprocessing = 0; 510 | }; 511 | EB86F1A71CBD811D00021DCE /* Resources */ = { 512 | isa = PBXResourcesBuildPhase; 513 | buildActionMask = 2147483647; 514 | files = ( 515 | ); 516 | runOnlyForDeploymentPostprocessing = 0; 517 | }; 518 | EB86F1B41CBD812C00021DCE /* Resources */ = { 519 | isa = PBXResourcesBuildPhase; 520 | buildActionMask = 2147483647; 521 | files = ( 522 | ); 523 | runOnlyForDeploymentPostprocessing = 0; 524 | }; 525 | EB86F1C11CBD813B00021DCE /* Resources */ = { 526 | isa = PBXResourcesBuildPhase; 527 | buildActionMask = 2147483647; 528 | files = ( 529 | ); 530 | runOnlyForDeploymentPostprocessing = 0; 531 | }; 532 | /* End PBXResourcesBuildPhase section */ 533 | 534 | /* Begin PBXSourcesBuildPhase section */ 535 | EB4791B01CBD85E200C04D13 /* Sources */ = { 536 | isa = PBXSourcesBuildPhase; 537 | buildActionMask = 2147483647; 538 | files = ( 539 | 9FD5B7B84A03277E87DD5FCB /* ParserTests.swift in Sources */, 540 | 9FD5B07E2C696751E4AF616B /* LexerTests.swift in Sources */, 541 | 9FD5B79D58304FED5724796E /* TestUtilities.swift in Sources */, 542 | 9FD5BC92D72CEA3B760C6257 /* VisitorTests.swift in Sources */, 543 | 9FD5B9E7484D4769C3813316 /* PrinterTests.swift in Sources */, 544 | ); 545 | runOnlyForDeploymentPostprocessing = 0; 546 | }; 547 | EB4791BF1CBD85F400C04D13 /* Sources */ = { 548 | isa = PBXSourcesBuildPhase; 549 | buildActionMask = 2147483647; 550 | files = ( 551 | 9FD5B3A79EE79B7FB88E1DD4 /* ParserTests.swift in Sources */, 552 | 9FD5BF64173E8E065DACFB35 /* LexerTests.swift in Sources */, 553 | 9FD5B01AE078BBCC03E0343A /* TestUtilities.swift in Sources */, 554 | 9FD5B0736CB906E9FFBFE497 /* VisitorTests.swift in Sources */, 555 | 9FD5B88A85FE4E66CDA3DB29 /* PrinterTests.swift in Sources */, 556 | ); 557 | runOnlyForDeploymentPostprocessing = 0; 558 | }; 559 | EB4791CE1CBD8AF700C04D13 /* Sources */ = { 560 | isa = PBXSourcesBuildPhase; 561 | buildActionMask = 2147483647; 562 | files = ( 563 | 9FD5B37A2B64F8AADA46B21A /* ParserTests.swift in Sources */, 564 | 9FD5B13F5F720BF712D0FB46 /* LexerTests.swift in Sources */, 565 | 9FD5B6AA14E899F274331144 /* TestUtilities.swift in Sources */, 566 | 9FD5B486361EA0C29CFE013E /* VisitorTests.swift in Sources */, 567 | 9FD5B3889D5E08538A91A7BA /* PrinterTests.swift in Sources */, 568 | ); 569 | runOnlyForDeploymentPostprocessing = 0; 570 | }; 571 | EB86F1961CBD810200021DCE /* Sources */ = { 572 | isa = PBXSourcesBuildPhase; 573 | buildActionMask = 2147483647; 574 | files = ( 575 | EBB78EA81CC9332400D366AB /* graphql.swift in Sources */, 576 | 9FD5BE26AE0249521238FE71 /* Parser.swift in Sources */, 577 | 9FD5B9A8224465ADFD354677 /* Lexer.swift in Sources */, 578 | 9FD5BFBFE7F98A235568BECF /* Ast.swift in Sources */, 579 | 9FD5BDAB5BEB9E304170ACBF /* Visitor.swift in Sources */, 580 | 9FD5B092368674ACDB082D17 /* Printer.swift in Sources */, 581 | ); 582 | runOnlyForDeploymentPostprocessing = 0; 583 | }; 584 | EB86F1A41CBD811D00021DCE /* Sources */ = { 585 | isa = PBXSourcesBuildPhase; 586 | buildActionMask = 2147483647; 587 | files = ( 588 | EBB78EAD1CC9332800D366AB /* graphql.swift in Sources */, 589 | 9FD5B92A3A3E3CD0525EC946 /* Parser.swift in Sources */, 590 | 9FD5B522488732CCBB06461B /* Lexer.swift in Sources */, 591 | 9FD5BA6284D3000CA76C1A9A /* Ast.swift in Sources */, 592 | 9FD5B5C31F18FE7640FA2DCF /* Visitor.swift in Sources */, 593 | 9FD5B00BAA7342997F2379F0 /* Printer.swift in Sources */, 594 | ); 595 | runOnlyForDeploymentPostprocessing = 0; 596 | }; 597 | EB86F1B11CBD812C00021DCE /* Sources */ = { 598 | isa = PBXSourcesBuildPhase; 599 | buildActionMask = 2147483647; 600 | files = ( 601 | EBB78EAE1CC9332900D366AB /* graphql.swift in Sources */, 602 | 9FD5B752A4093BEB3C8DFF5D /* Parser.swift in Sources */, 603 | 9FD5BA42DC5B3035134F07A6 /* Lexer.swift in Sources */, 604 | 9FD5BC88E8CFBFB1787AAB32 /* Ast.swift in Sources */, 605 | 9FD5BB52B21F7E18FDA01138 /* Visitor.swift in Sources */, 606 | 9FD5B1521A5E0236B6A856A5 /* Printer.swift in Sources */, 607 | ); 608 | runOnlyForDeploymentPostprocessing = 0; 609 | }; 610 | EB86F1BE1CBD813B00021DCE /* Sources */ = { 611 | isa = PBXSourcesBuildPhase; 612 | buildActionMask = 2147483647; 613 | files = ( 614 | EBB78EAF1CC9332900D366AB /* graphql.swift in Sources */, 615 | 9FD5B1752AFD5F5AF4AFF778 /* Parser.swift in Sources */, 616 | 9FD5BD28B4AE136B2BAA2834 /* Lexer.swift in Sources */, 617 | 9FD5B6B45CE0AF6F23683331 /* Ast.swift in Sources */, 618 | 9FD5B14626E62EB3D41D2BBE /* Visitor.swift in Sources */, 619 | 9FD5BAF09770EE234A5945AF /* Printer.swift in Sources */, 620 | ); 621 | runOnlyForDeploymentPostprocessing = 0; 622 | }; 623 | /* End PBXSourcesBuildPhase section */ 624 | 625 | /* Begin PBXTargetDependency section */ 626 | EB4791BB1CBD85E200C04D13 /* PBXTargetDependency */ = { 627 | isa = PBXTargetDependency; 628 | target = EB86F1C21CBD813B00021DCE /* GraphQL OS X */; 629 | targetProxy = EB4791BA1CBD85E200C04D13 /* PBXContainerItemProxy */; 630 | }; 631 | EB4791CA1CBD85F400C04D13 /* PBXTargetDependency */ = { 632 | isa = PBXTargetDependency; 633 | target = EB86F19A1CBD810200021DCE /* GraphQL iOS */; 634 | targetProxy = EB4791C91CBD85F400C04D13 /* PBXContainerItemProxy */; 635 | }; 636 | EB4791D91CBD8AF700C04D13 /* PBXTargetDependency */ = { 637 | isa = PBXTargetDependency; 638 | target = EB86F1B51CBD812C00021DCE /* GraphQL tvOS */; 639 | targetProxy = EB4791D81CBD8AF700C04D13 /* PBXContainerItemProxy */; 640 | }; 641 | /* End PBXTargetDependency section */ 642 | 643 | /* Begin XCBuildConfiguration section */ 644 | EB2B587E1CBD80750007387E /* Debug */ = { 645 | isa = XCBuildConfiguration; 646 | buildSettings = { 647 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 648 | MACOSX_DEPLOYMENT_TARGET = 10.10; 649 | TVOS_DEPLOYMENT_TARGET = 9.0; 650 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 651 | }; 652 | name = Debug; 653 | }; 654 | EB2B587F1CBD80750007387E /* Release */ = { 655 | isa = XCBuildConfiguration; 656 | buildSettings = { 657 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 658 | MACOSX_DEPLOYMENT_TARGET = 10.10; 659 | TVOS_DEPLOYMENT_TARGET = 9.0; 660 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 661 | }; 662 | name = Release; 663 | }; 664 | EB4791BC1CBD85E200C04D13 /* Debug */ = { 665 | isa = XCBuildConfiguration; 666 | buildSettings = { 667 | ALWAYS_SEARCH_USER_PATHS = NO; 668 | CLANG_ANALYZER_NONNULL = YES; 669 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 670 | CLANG_CXX_LIBRARY = "libc++"; 671 | CLANG_ENABLE_MODULES = YES; 672 | CLANG_ENABLE_OBJC_ARC = YES; 673 | CLANG_WARN_BOOL_CONVERSION = YES; 674 | CLANG_WARN_CONSTANT_CONVERSION = YES; 675 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 676 | CLANG_WARN_EMPTY_BODY = YES; 677 | CLANG_WARN_ENUM_CONVERSION = YES; 678 | CLANG_WARN_INT_CONVERSION = YES; 679 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 680 | CLANG_WARN_UNREACHABLE_CODE = YES; 681 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 682 | CODE_SIGN_IDENTITY = "-"; 683 | COMBINE_HIDPI_IMAGES = YES; 684 | COPY_PHASE_STRIP = NO; 685 | DEBUG_INFORMATION_FORMAT = dwarf; 686 | ENABLE_STRICT_OBJC_MSGSEND = YES; 687 | ENABLE_TESTABILITY = YES; 688 | GCC_C_LANGUAGE_STANDARD = gnu99; 689 | GCC_DYNAMIC_NO_PIC = NO; 690 | GCC_NO_COMMON_BLOCKS = YES; 691 | GCC_OPTIMIZATION_LEVEL = 0; 692 | GCC_PREPROCESSOR_DEFINITIONS = ( 693 | "DEBUG=1", 694 | "$(inherited)", 695 | ); 696 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 697 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 698 | GCC_WARN_UNDECLARED_SELECTOR = YES; 699 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 700 | GCC_WARN_UNUSED_FUNCTION = YES; 701 | GCC_WARN_UNUSED_VARIABLE = YES; 702 | INFOPLIST_FILE = "Tests/Info-OSX.plist"; 703 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 704 | MACOSX_DEPLOYMENT_TARGET = 10.11; 705 | MTL_ENABLE_DEBUG_INFO = YES; 706 | ONLY_ACTIVE_ARCH = YES; 707 | PRODUCT_BUNDLE_IDENTIFIER = "io.garriguv.GraphQL-OS-X-Tests"; 708 | PRODUCT_NAME = "$(TARGET_NAME)"; 709 | SDKROOT = macosx; 710 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 711 | }; 712 | name = Debug; 713 | }; 714 | EB4791BD1CBD85E200C04D13 /* Release */ = { 715 | isa = XCBuildConfiguration; 716 | buildSettings = { 717 | ALWAYS_SEARCH_USER_PATHS = NO; 718 | CLANG_ANALYZER_NONNULL = YES; 719 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 720 | CLANG_CXX_LIBRARY = "libc++"; 721 | CLANG_ENABLE_MODULES = YES; 722 | CLANG_ENABLE_OBJC_ARC = YES; 723 | CLANG_WARN_BOOL_CONVERSION = YES; 724 | CLANG_WARN_CONSTANT_CONVERSION = YES; 725 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 726 | CLANG_WARN_EMPTY_BODY = YES; 727 | CLANG_WARN_ENUM_CONVERSION = YES; 728 | CLANG_WARN_INT_CONVERSION = YES; 729 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 730 | CLANG_WARN_UNREACHABLE_CODE = YES; 731 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 732 | CODE_SIGN_IDENTITY = "-"; 733 | COMBINE_HIDPI_IMAGES = YES; 734 | COPY_PHASE_STRIP = NO; 735 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 736 | ENABLE_NS_ASSERTIONS = NO; 737 | ENABLE_STRICT_OBJC_MSGSEND = YES; 738 | GCC_C_LANGUAGE_STANDARD = gnu99; 739 | GCC_NO_COMMON_BLOCKS = YES; 740 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 741 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 742 | GCC_WARN_UNDECLARED_SELECTOR = YES; 743 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 744 | GCC_WARN_UNUSED_FUNCTION = YES; 745 | GCC_WARN_UNUSED_VARIABLE = YES; 746 | INFOPLIST_FILE = "Tests/Info-OSX.plist"; 747 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 748 | MACOSX_DEPLOYMENT_TARGET = 10.11; 749 | MTL_ENABLE_DEBUG_INFO = NO; 750 | PRODUCT_BUNDLE_IDENTIFIER = "io.garriguv.GraphQL-OS-X-Tests"; 751 | PRODUCT_NAME = "$(TARGET_NAME)"; 752 | SDKROOT = macosx; 753 | }; 754 | name = Release; 755 | }; 756 | EB4791CC1CBD85F400C04D13 /* Debug */ = { 757 | isa = XCBuildConfiguration; 758 | buildSettings = { 759 | ALWAYS_SEARCH_USER_PATHS = NO; 760 | CLANG_ANALYZER_NONNULL = YES; 761 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 762 | CLANG_CXX_LIBRARY = "libc++"; 763 | CLANG_ENABLE_MODULES = YES; 764 | CLANG_ENABLE_OBJC_ARC = YES; 765 | CLANG_WARN_BOOL_CONVERSION = YES; 766 | CLANG_WARN_CONSTANT_CONVERSION = YES; 767 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 768 | CLANG_WARN_EMPTY_BODY = YES; 769 | CLANG_WARN_ENUM_CONVERSION = YES; 770 | CLANG_WARN_INT_CONVERSION = YES; 771 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 772 | CLANG_WARN_UNREACHABLE_CODE = YES; 773 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 774 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 775 | COPY_PHASE_STRIP = NO; 776 | DEBUG_INFORMATION_FORMAT = dwarf; 777 | ENABLE_STRICT_OBJC_MSGSEND = YES; 778 | ENABLE_TESTABILITY = YES; 779 | GCC_C_LANGUAGE_STANDARD = gnu99; 780 | GCC_DYNAMIC_NO_PIC = NO; 781 | GCC_NO_COMMON_BLOCKS = YES; 782 | GCC_OPTIMIZATION_LEVEL = 0; 783 | GCC_PREPROCESSOR_DEFINITIONS = ( 784 | "DEBUG=1", 785 | "$(inherited)", 786 | ); 787 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 788 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 789 | GCC_WARN_UNDECLARED_SELECTOR = YES; 790 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 791 | GCC_WARN_UNUSED_FUNCTION = YES; 792 | GCC_WARN_UNUSED_VARIABLE = YES; 793 | INFOPLIST_FILE = "Tests/Info-iOS.plist"; 794 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 795 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 796 | MTL_ENABLE_DEBUG_INFO = YES; 797 | ONLY_ACTIVE_ARCH = YES; 798 | PRODUCT_BUNDLE_IDENTIFIER = "io.garriguv.GraphQL-iOS-Tests"; 799 | PRODUCT_NAME = "$(TARGET_NAME)"; 800 | SDKROOT = iphoneos; 801 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 802 | }; 803 | name = Debug; 804 | }; 805 | EB4791CD1CBD85F400C04D13 /* Release */ = { 806 | isa = XCBuildConfiguration; 807 | buildSettings = { 808 | ALWAYS_SEARCH_USER_PATHS = NO; 809 | CLANG_ANALYZER_NONNULL = YES; 810 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 811 | CLANG_CXX_LIBRARY = "libc++"; 812 | CLANG_ENABLE_MODULES = YES; 813 | CLANG_ENABLE_OBJC_ARC = YES; 814 | CLANG_WARN_BOOL_CONVERSION = YES; 815 | CLANG_WARN_CONSTANT_CONVERSION = YES; 816 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 817 | CLANG_WARN_EMPTY_BODY = YES; 818 | CLANG_WARN_ENUM_CONVERSION = YES; 819 | CLANG_WARN_INT_CONVERSION = YES; 820 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 821 | CLANG_WARN_UNREACHABLE_CODE = YES; 822 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 823 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 824 | COPY_PHASE_STRIP = NO; 825 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 826 | ENABLE_NS_ASSERTIONS = NO; 827 | ENABLE_STRICT_OBJC_MSGSEND = YES; 828 | GCC_C_LANGUAGE_STANDARD = gnu99; 829 | GCC_NO_COMMON_BLOCKS = YES; 830 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 831 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 832 | GCC_WARN_UNDECLARED_SELECTOR = YES; 833 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 834 | GCC_WARN_UNUSED_FUNCTION = YES; 835 | GCC_WARN_UNUSED_VARIABLE = YES; 836 | INFOPLIST_FILE = "Tests/Info-iOS.plist"; 837 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 838 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 839 | MTL_ENABLE_DEBUG_INFO = NO; 840 | PRODUCT_BUNDLE_IDENTIFIER = "io.garriguv.GraphQL-iOS-Tests"; 841 | PRODUCT_NAME = "$(TARGET_NAME)"; 842 | SDKROOT = iphoneos; 843 | VALIDATE_PRODUCT = YES; 844 | }; 845 | name = Release; 846 | }; 847 | EB4791DB1CBD8AF700C04D13 /* Debug */ = { 848 | isa = XCBuildConfiguration; 849 | buildSettings = { 850 | ALWAYS_SEARCH_USER_PATHS = NO; 851 | CLANG_ANALYZER_NONNULL = YES; 852 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 853 | CLANG_CXX_LIBRARY = "libc++"; 854 | CLANG_ENABLE_MODULES = YES; 855 | CLANG_ENABLE_OBJC_ARC = YES; 856 | CLANG_WARN_BOOL_CONVERSION = YES; 857 | CLANG_WARN_CONSTANT_CONVERSION = YES; 858 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 859 | CLANG_WARN_EMPTY_BODY = YES; 860 | CLANG_WARN_ENUM_CONVERSION = YES; 861 | CLANG_WARN_INT_CONVERSION = YES; 862 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 863 | CLANG_WARN_UNREACHABLE_CODE = YES; 864 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 865 | COPY_PHASE_STRIP = NO; 866 | DEBUG_INFORMATION_FORMAT = dwarf; 867 | ENABLE_STRICT_OBJC_MSGSEND = YES; 868 | ENABLE_TESTABILITY = YES; 869 | GCC_C_LANGUAGE_STANDARD = gnu99; 870 | GCC_DYNAMIC_NO_PIC = NO; 871 | GCC_NO_COMMON_BLOCKS = YES; 872 | GCC_OPTIMIZATION_LEVEL = 0; 873 | GCC_PREPROCESSOR_DEFINITIONS = ( 874 | "DEBUG=1", 875 | "$(inherited)", 876 | ); 877 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 878 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 879 | GCC_WARN_UNDECLARED_SELECTOR = YES; 880 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 881 | GCC_WARN_UNUSED_FUNCTION = YES; 882 | GCC_WARN_UNUSED_VARIABLE = YES; 883 | INFOPLIST_FILE = "Tests/Info-tvOS.plist"; 884 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 885 | MTL_ENABLE_DEBUG_INFO = YES; 886 | ONLY_ACTIVE_ARCH = YES; 887 | PRODUCT_BUNDLE_IDENTIFIER = "io.garriguv.GraphQL-tvOS-Tests"; 888 | PRODUCT_NAME = "$(TARGET_NAME)"; 889 | SDKROOT = appletvos; 890 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 891 | TVOS_DEPLOYMENT_TARGET = 9.2; 892 | }; 893 | name = Debug; 894 | }; 895 | EB4791DC1CBD8AF700C04D13 /* Release */ = { 896 | isa = XCBuildConfiguration; 897 | buildSettings = { 898 | ALWAYS_SEARCH_USER_PATHS = NO; 899 | CLANG_ANALYZER_NONNULL = YES; 900 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 901 | CLANG_CXX_LIBRARY = "libc++"; 902 | CLANG_ENABLE_MODULES = YES; 903 | CLANG_ENABLE_OBJC_ARC = YES; 904 | CLANG_WARN_BOOL_CONVERSION = YES; 905 | CLANG_WARN_CONSTANT_CONVERSION = YES; 906 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 907 | CLANG_WARN_EMPTY_BODY = YES; 908 | CLANG_WARN_ENUM_CONVERSION = YES; 909 | CLANG_WARN_INT_CONVERSION = YES; 910 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 911 | CLANG_WARN_UNREACHABLE_CODE = YES; 912 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 913 | COPY_PHASE_STRIP = NO; 914 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 915 | ENABLE_NS_ASSERTIONS = NO; 916 | ENABLE_STRICT_OBJC_MSGSEND = YES; 917 | GCC_C_LANGUAGE_STANDARD = gnu99; 918 | GCC_NO_COMMON_BLOCKS = YES; 919 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 920 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 921 | GCC_WARN_UNDECLARED_SELECTOR = YES; 922 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 923 | GCC_WARN_UNUSED_FUNCTION = YES; 924 | GCC_WARN_UNUSED_VARIABLE = YES; 925 | INFOPLIST_FILE = "Tests/Info-tvOS.plist"; 926 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 927 | MTL_ENABLE_DEBUG_INFO = NO; 928 | PRODUCT_BUNDLE_IDENTIFIER = "io.garriguv.GraphQL-tvOS-Tests"; 929 | PRODUCT_NAME = "$(TARGET_NAME)"; 930 | SDKROOT = appletvos; 931 | TVOS_DEPLOYMENT_TARGET = 9.2; 932 | VALIDATE_PRODUCT = YES; 933 | }; 934 | name = Release; 935 | }; 936 | EB86F1A11CBD810200021DCE /* Debug */ = { 937 | isa = XCBuildConfiguration; 938 | buildSettings = { 939 | ALWAYS_SEARCH_USER_PATHS = NO; 940 | APPLICATION_EXTENSION_API_ONLY = YES; 941 | CLANG_ANALYZER_NONNULL = YES; 942 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 943 | CLANG_CXX_LIBRARY = "libc++"; 944 | CLANG_ENABLE_MODULES = YES; 945 | CLANG_ENABLE_OBJC_ARC = YES; 946 | CLANG_WARN_BOOL_CONVERSION = YES; 947 | CLANG_WARN_CONSTANT_CONVERSION = YES; 948 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 949 | CLANG_WARN_EMPTY_BODY = YES; 950 | CLANG_WARN_ENUM_CONVERSION = YES; 951 | CLANG_WARN_INT_CONVERSION = YES; 952 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 953 | CLANG_WARN_UNREACHABLE_CODE = YES; 954 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 955 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 956 | COPY_PHASE_STRIP = NO; 957 | CURRENT_PROJECT_VERSION = 1; 958 | DEBUG_INFORMATION_FORMAT = dwarf; 959 | DEFINES_MODULE = YES; 960 | DYLIB_COMPATIBILITY_VERSION = 1; 961 | DYLIB_CURRENT_VERSION = 1; 962 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 963 | ENABLE_STRICT_OBJC_MSGSEND = YES; 964 | ENABLE_TESTABILITY = YES; 965 | GCC_C_LANGUAGE_STANDARD = gnu99; 966 | GCC_DYNAMIC_NO_PIC = NO; 967 | GCC_NO_COMMON_BLOCKS = YES; 968 | GCC_OPTIMIZATION_LEVEL = 0; 969 | GCC_PREPROCESSOR_DEFINITIONS = ( 970 | "DEBUG=1", 971 | "$(inherited)", 972 | ); 973 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 974 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 975 | GCC_WARN_UNDECLARED_SELECTOR = YES; 976 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 977 | GCC_WARN_UNUSED_FUNCTION = YES; 978 | GCC_WARN_UNUSED_VARIABLE = YES; 979 | INFOPLIST_FILE = "Sources/Info-iOS.plist"; 980 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 981 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 982 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 983 | MTL_ENABLE_DEBUG_INFO = YES; 984 | ONLY_ACTIVE_ARCH = YES; 985 | PRODUCT_BUNDLE_IDENTIFIER = "io.garriguv.GraphQL-iOS"; 986 | PRODUCT_NAME = GraphQL; 987 | SDKROOT = iphoneos; 988 | SKIP_INSTALL = YES; 989 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 990 | TARGETED_DEVICE_FAMILY = "1,2"; 991 | VERSIONING_SYSTEM = "apple-generic"; 992 | VERSION_INFO_PREFIX = ""; 993 | }; 994 | name = Debug; 995 | }; 996 | EB86F1A21CBD810200021DCE /* Release */ = { 997 | isa = XCBuildConfiguration; 998 | buildSettings = { 999 | ALWAYS_SEARCH_USER_PATHS = NO; 1000 | APPLICATION_EXTENSION_API_ONLY = YES; 1001 | CLANG_ANALYZER_NONNULL = YES; 1002 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 1003 | CLANG_CXX_LIBRARY = "libc++"; 1004 | CLANG_ENABLE_MODULES = YES; 1005 | CLANG_ENABLE_OBJC_ARC = YES; 1006 | CLANG_WARN_BOOL_CONVERSION = YES; 1007 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1008 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1009 | CLANG_WARN_EMPTY_BODY = YES; 1010 | CLANG_WARN_ENUM_CONVERSION = YES; 1011 | CLANG_WARN_INT_CONVERSION = YES; 1012 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1013 | CLANG_WARN_UNREACHABLE_CODE = YES; 1014 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1015 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 1016 | COPY_PHASE_STRIP = NO; 1017 | CURRENT_PROJECT_VERSION = 1; 1018 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 1019 | DEFINES_MODULE = YES; 1020 | DYLIB_COMPATIBILITY_VERSION = 1; 1021 | DYLIB_CURRENT_VERSION = 1; 1022 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1023 | ENABLE_NS_ASSERTIONS = NO; 1024 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1025 | GCC_C_LANGUAGE_STANDARD = gnu99; 1026 | GCC_NO_COMMON_BLOCKS = YES; 1027 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1028 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1029 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1030 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1031 | GCC_WARN_UNUSED_FUNCTION = YES; 1032 | GCC_WARN_UNUSED_VARIABLE = YES; 1033 | INFOPLIST_FILE = "Sources/Info-iOS.plist"; 1034 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1035 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 1036 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1037 | MTL_ENABLE_DEBUG_INFO = NO; 1038 | PRODUCT_BUNDLE_IDENTIFIER = "io.garriguv.GraphQL-iOS"; 1039 | PRODUCT_NAME = GraphQL; 1040 | SDKROOT = iphoneos; 1041 | SKIP_INSTALL = YES; 1042 | TARGETED_DEVICE_FAMILY = "1,2"; 1043 | VALIDATE_PRODUCT = YES; 1044 | VERSIONING_SYSTEM = "apple-generic"; 1045 | VERSION_INFO_PREFIX = ""; 1046 | }; 1047 | name = Release; 1048 | }; 1049 | EB86F1AF1CBD811D00021DCE /* Debug */ = { 1050 | isa = XCBuildConfiguration; 1051 | buildSettings = { 1052 | ALWAYS_SEARCH_USER_PATHS = NO; 1053 | APPLICATION_EXTENSION_API_ONLY = YES; 1054 | CLANG_ANALYZER_NONNULL = YES; 1055 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 1056 | CLANG_CXX_LIBRARY = "libc++"; 1057 | CLANG_ENABLE_MODULES = YES; 1058 | CLANG_ENABLE_OBJC_ARC = YES; 1059 | CLANG_WARN_BOOL_CONVERSION = YES; 1060 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1061 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1062 | CLANG_WARN_EMPTY_BODY = YES; 1063 | CLANG_WARN_ENUM_CONVERSION = YES; 1064 | CLANG_WARN_INT_CONVERSION = YES; 1065 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1066 | CLANG_WARN_UNREACHABLE_CODE = YES; 1067 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1068 | COPY_PHASE_STRIP = NO; 1069 | CURRENT_PROJECT_VERSION = 1; 1070 | DEBUG_INFORMATION_FORMAT = dwarf; 1071 | DEFINES_MODULE = YES; 1072 | DYLIB_COMPATIBILITY_VERSION = 1; 1073 | DYLIB_CURRENT_VERSION = 1; 1074 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1075 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1076 | ENABLE_TESTABILITY = YES; 1077 | GCC_C_LANGUAGE_STANDARD = gnu99; 1078 | GCC_DYNAMIC_NO_PIC = NO; 1079 | GCC_NO_COMMON_BLOCKS = YES; 1080 | GCC_OPTIMIZATION_LEVEL = 0; 1081 | GCC_PREPROCESSOR_DEFINITIONS = ( 1082 | "DEBUG=1", 1083 | "$(inherited)", 1084 | ); 1085 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1086 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1087 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1088 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1089 | GCC_WARN_UNUSED_FUNCTION = YES; 1090 | GCC_WARN_UNUSED_VARIABLE = YES; 1091 | INFOPLIST_FILE = "Sources/Info-watchOS.plist"; 1092 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1093 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1094 | MTL_ENABLE_DEBUG_INFO = YES; 1095 | ONLY_ACTIVE_ARCH = YES; 1096 | PRODUCT_BUNDLE_IDENTIFIER = "io.garriguv.GraphQL-watchOS"; 1097 | PRODUCT_NAME = GraphQL; 1098 | SDKROOT = watchos; 1099 | SKIP_INSTALL = YES; 1100 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 1101 | TARGETED_DEVICE_FAMILY = 4; 1102 | VERSIONING_SYSTEM = "apple-generic"; 1103 | VERSION_INFO_PREFIX = ""; 1104 | WATCHOS_DEPLOYMENT_TARGET = 2.2; 1105 | }; 1106 | name = Debug; 1107 | }; 1108 | EB86F1B01CBD811D00021DCE /* Release */ = { 1109 | isa = XCBuildConfiguration; 1110 | buildSettings = { 1111 | ALWAYS_SEARCH_USER_PATHS = NO; 1112 | APPLICATION_EXTENSION_API_ONLY = YES; 1113 | CLANG_ANALYZER_NONNULL = YES; 1114 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 1115 | CLANG_CXX_LIBRARY = "libc++"; 1116 | CLANG_ENABLE_MODULES = YES; 1117 | CLANG_ENABLE_OBJC_ARC = YES; 1118 | CLANG_WARN_BOOL_CONVERSION = YES; 1119 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1120 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1121 | CLANG_WARN_EMPTY_BODY = YES; 1122 | CLANG_WARN_ENUM_CONVERSION = YES; 1123 | CLANG_WARN_INT_CONVERSION = YES; 1124 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1125 | CLANG_WARN_UNREACHABLE_CODE = YES; 1126 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1127 | COPY_PHASE_STRIP = NO; 1128 | CURRENT_PROJECT_VERSION = 1; 1129 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 1130 | DEFINES_MODULE = YES; 1131 | DYLIB_COMPATIBILITY_VERSION = 1; 1132 | DYLIB_CURRENT_VERSION = 1; 1133 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1134 | ENABLE_NS_ASSERTIONS = NO; 1135 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1136 | GCC_C_LANGUAGE_STANDARD = gnu99; 1137 | GCC_NO_COMMON_BLOCKS = YES; 1138 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1139 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1140 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1141 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1142 | GCC_WARN_UNUSED_FUNCTION = YES; 1143 | GCC_WARN_UNUSED_VARIABLE = YES; 1144 | INFOPLIST_FILE = "Sources/Info-watchOS.plist"; 1145 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1146 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1147 | MTL_ENABLE_DEBUG_INFO = NO; 1148 | PRODUCT_BUNDLE_IDENTIFIER = "io.garriguv.GraphQL-watchOS"; 1149 | PRODUCT_NAME = GraphQL; 1150 | SDKROOT = watchos; 1151 | SKIP_INSTALL = YES; 1152 | TARGETED_DEVICE_FAMILY = 4; 1153 | VALIDATE_PRODUCT = YES; 1154 | VERSIONING_SYSTEM = "apple-generic"; 1155 | VERSION_INFO_PREFIX = ""; 1156 | WATCHOS_DEPLOYMENT_TARGET = 2.2; 1157 | }; 1158 | name = Release; 1159 | }; 1160 | EB86F1BC1CBD812C00021DCE /* Debug */ = { 1161 | isa = XCBuildConfiguration; 1162 | buildSettings = { 1163 | ALWAYS_SEARCH_USER_PATHS = NO; 1164 | APPLICATION_EXTENSION_API_ONLY = YES; 1165 | CLANG_ANALYZER_NONNULL = YES; 1166 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 1167 | CLANG_CXX_LIBRARY = "libc++"; 1168 | CLANG_ENABLE_MODULES = YES; 1169 | CLANG_ENABLE_OBJC_ARC = YES; 1170 | CLANG_WARN_BOOL_CONVERSION = YES; 1171 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1172 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1173 | CLANG_WARN_EMPTY_BODY = YES; 1174 | CLANG_WARN_ENUM_CONVERSION = YES; 1175 | CLANG_WARN_INT_CONVERSION = YES; 1176 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1177 | CLANG_WARN_UNREACHABLE_CODE = YES; 1178 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1179 | COPY_PHASE_STRIP = NO; 1180 | CURRENT_PROJECT_VERSION = 1; 1181 | DEBUG_INFORMATION_FORMAT = dwarf; 1182 | DEFINES_MODULE = YES; 1183 | DYLIB_COMPATIBILITY_VERSION = 1; 1184 | DYLIB_CURRENT_VERSION = 1; 1185 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1186 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1187 | ENABLE_TESTABILITY = YES; 1188 | GCC_C_LANGUAGE_STANDARD = gnu99; 1189 | GCC_DYNAMIC_NO_PIC = NO; 1190 | GCC_NO_COMMON_BLOCKS = YES; 1191 | GCC_OPTIMIZATION_LEVEL = 0; 1192 | GCC_PREPROCESSOR_DEFINITIONS = ( 1193 | "DEBUG=1", 1194 | "$(inherited)", 1195 | ); 1196 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1197 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1198 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1199 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1200 | GCC_WARN_UNUSED_FUNCTION = YES; 1201 | GCC_WARN_UNUSED_VARIABLE = YES; 1202 | INFOPLIST_FILE = "Sources/Info-tvOS.plist"; 1203 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1204 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1205 | MTL_ENABLE_DEBUG_INFO = YES; 1206 | ONLY_ACTIVE_ARCH = YES; 1207 | PRODUCT_BUNDLE_IDENTIFIER = "io.garriguv.GraphQL-tvOS"; 1208 | PRODUCT_NAME = GraphQL; 1209 | SDKROOT = appletvos; 1210 | SKIP_INSTALL = YES; 1211 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 1212 | TARGETED_DEVICE_FAMILY = 3; 1213 | TVOS_DEPLOYMENT_TARGET = 9.2; 1214 | VERSIONING_SYSTEM = "apple-generic"; 1215 | VERSION_INFO_PREFIX = ""; 1216 | }; 1217 | name = Debug; 1218 | }; 1219 | EB86F1BD1CBD812C00021DCE /* Release */ = { 1220 | isa = XCBuildConfiguration; 1221 | buildSettings = { 1222 | ALWAYS_SEARCH_USER_PATHS = NO; 1223 | APPLICATION_EXTENSION_API_ONLY = YES; 1224 | CLANG_ANALYZER_NONNULL = YES; 1225 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 1226 | CLANG_CXX_LIBRARY = "libc++"; 1227 | CLANG_ENABLE_MODULES = YES; 1228 | CLANG_ENABLE_OBJC_ARC = YES; 1229 | CLANG_WARN_BOOL_CONVERSION = YES; 1230 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1231 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1232 | CLANG_WARN_EMPTY_BODY = YES; 1233 | CLANG_WARN_ENUM_CONVERSION = YES; 1234 | CLANG_WARN_INT_CONVERSION = YES; 1235 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1236 | CLANG_WARN_UNREACHABLE_CODE = YES; 1237 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1238 | COPY_PHASE_STRIP = NO; 1239 | CURRENT_PROJECT_VERSION = 1; 1240 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 1241 | DEFINES_MODULE = YES; 1242 | DYLIB_COMPATIBILITY_VERSION = 1; 1243 | DYLIB_CURRENT_VERSION = 1; 1244 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1245 | ENABLE_NS_ASSERTIONS = NO; 1246 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1247 | GCC_C_LANGUAGE_STANDARD = gnu99; 1248 | GCC_NO_COMMON_BLOCKS = YES; 1249 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1250 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1251 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1252 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1253 | GCC_WARN_UNUSED_FUNCTION = YES; 1254 | GCC_WARN_UNUSED_VARIABLE = YES; 1255 | INFOPLIST_FILE = "Sources/Info-tvOS.plist"; 1256 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1257 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1258 | MTL_ENABLE_DEBUG_INFO = NO; 1259 | PRODUCT_BUNDLE_IDENTIFIER = "io.garriguv.GraphQL-tvOS"; 1260 | PRODUCT_NAME = GraphQL; 1261 | SDKROOT = appletvos; 1262 | SKIP_INSTALL = YES; 1263 | TARGETED_DEVICE_FAMILY = 3; 1264 | TVOS_DEPLOYMENT_TARGET = 9.2; 1265 | VALIDATE_PRODUCT = YES; 1266 | VERSIONING_SYSTEM = "apple-generic"; 1267 | VERSION_INFO_PREFIX = ""; 1268 | }; 1269 | name = Release; 1270 | }; 1271 | EB86F1C91CBD813B00021DCE /* Debug */ = { 1272 | isa = XCBuildConfiguration; 1273 | buildSettings = { 1274 | ALWAYS_SEARCH_USER_PATHS = NO; 1275 | APPLICATION_EXTENSION_API_ONLY = YES; 1276 | CLANG_ANALYZER_NONNULL = YES; 1277 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 1278 | CLANG_CXX_LIBRARY = "libc++"; 1279 | CLANG_ENABLE_MODULES = YES; 1280 | CLANG_ENABLE_OBJC_ARC = YES; 1281 | CLANG_WARN_BOOL_CONVERSION = YES; 1282 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1283 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1284 | CLANG_WARN_EMPTY_BODY = YES; 1285 | CLANG_WARN_ENUM_CONVERSION = YES; 1286 | CLANG_WARN_INT_CONVERSION = YES; 1287 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1288 | CLANG_WARN_UNREACHABLE_CODE = YES; 1289 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1290 | CODE_SIGN_IDENTITY = "-"; 1291 | COMBINE_HIDPI_IMAGES = YES; 1292 | COPY_PHASE_STRIP = NO; 1293 | CURRENT_PROJECT_VERSION = 1; 1294 | DEBUG_INFORMATION_FORMAT = dwarf; 1295 | DEFINES_MODULE = YES; 1296 | DYLIB_COMPATIBILITY_VERSION = 1; 1297 | DYLIB_CURRENT_VERSION = 1; 1298 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1299 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1300 | ENABLE_TESTABILITY = YES; 1301 | FRAMEWORK_VERSION = A; 1302 | GCC_C_LANGUAGE_STANDARD = gnu99; 1303 | GCC_DYNAMIC_NO_PIC = NO; 1304 | GCC_NO_COMMON_BLOCKS = YES; 1305 | GCC_OPTIMIZATION_LEVEL = 0; 1306 | GCC_PREPROCESSOR_DEFINITIONS = ( 1307 | "DEBUG=1", 1308 | "$(inherited)", 1309 | ); 1310 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1311 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1312 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1313 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1314 | GCC_WARN_UNUSED_FUNCTION = YES; 1315 | GCC_WARN_UNUSED_VARIABLE = YES; 1316 | INFOPLIST_FILE = "Sources/Info-OSX.plist"; 1317 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1318 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 1319 | MACOSX_DEPLOYMENT_TARGET = 10.11; 1320 | MTL_ENABLE_DEBUG_INFO = YES; 1321 | ONLY_ACTIVE_ARCH = YES; 1322 | PRODUCT_BUNDLE_IDENTIFIER = "io.garriguv.GraphQL-OS-X"; 1323 | PRODUCT_NAME = GraphQL; 1324 | SDKROOT = macosx; 1325 | SKIP_INSTALL = YES; 1326 | SWIFT_OBJC_INTERFACE_HEADER_NAME = "$(SWIFT_MODULE_NAME)-Swift.h"; 1327 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 1328 | VERSIONING_SYSTEM = "apple-generic"; 1329 | VERSION_INFO_PREFIX = ""; 1330 | }; 1331 | name = Debug; 1332 | }; 1333 | EB86F1CA1CBD813B00021DCE /* Release */ = { 1334 | isa = XCBuildConfiguration; 1335 | buildSettings = { 1336 | ALWAYS_SEARCH_USER_PATHS = NO; 1337 | APPLICATION_EXTENSION_API_ONLY = YES; 1338 | CLANG_ANALYZER_NONNULL = YES; 1339 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 1340 | CLANG_CXX_LIBRARY = "libc++"; 1341 | CLANG_ENABLE_MODULES = YES; 1342 | CLANG_ENABLE_OBJC_ARC = YES; 1343 | CLANG_WARN_BOOL_CONVERSION = YES; 1344 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1345 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1346 | CLANG_WARN_EMPTY_BODY = YES; 1347 | CLANG_WARN_ENUM_CONVERSION = YES; 1348 | CLANG_WARN_INT_CONVERSION = YES; 1349 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1350 | CLANG_WARN_UNREACHABLE_CODE = YES; 1351 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1352 | CODE_SIGN_IDENTITY = "-"; 1353 | COMBINE_HIDPI_IMAGES = YES; 1354 | COPY_PHASE_STRIP = NO; 1355 | CURRENT_PROJECT_VERSION = 1; 1356 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 1357 | DEFINES_MODULE = YES; 1358 | DYLIB_COMPATIBILITY_VERSION = 1; 1359 | DYLIB_CURRENT_VERSION = 1; 1360 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1361 | ENABLE_NS_ASSERTIONS = NO; 1362 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1363 | FRAMEWORK_VERSION = A; 1364 | GCC_C_LANGUAGE_STANDARD = gnu99; 1365 | GCC_NO_COMMON_BLOCKS = YES; 1366 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1367 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1368 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1369 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1370 | GCC_WARN_UNUSED_FUNCTION = YES; 1371 | GCC_WARN_UNUSED_VARIABLE = YES; 1372 | INFOPLIST_FILE = "Sources/Info-OSX.plist"; 1373 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1374 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 1375 | MACOSX_DEPLOYMENT_TARGET = 10.11; 1376 | MTL_ENABLE_DEBUG_INFO = NO; 1377 | PRODUCT_BUNDLE_IDENTIFIER = "io.garriguv.GraphQL-OS-X"; 1378 | PRODUCT_NAME = GraphQL; 1379 | SDKROOT = macosx; 1380 | SKIP_INSTALL = YES; 1381 | SWIFT_OBJC_INTERFACE_HEADER_NAME = "$(SWIFT_MODULE_NAME)-Swift.h"; 1382 | VERSIONING_SYSTEM = "apple-generic"; 1383 | VERSION_INFO_PREFIX = ""; 1384 | }; 1385 | name = Release; 1386 | }; 1387 | /* End XCBuildConfiguration section */ 1388 | 1389 | /* Begin XCConfigurationList section */ 1390 | EB2B587D1CBD80750007387E /* Build configuration list for PBXProject "graphql" */ = { 1391 | isa = XCConfigurationList; 1392 | buildConfigurations = ( 1393 | EB2B587E1CBD80750007387E /* Debug */, 1394 | EB2B587F1CBD80750007387E /* Release */, 1395 | ); 1396 | defaultConfigurationIsVisible = 0; 1397 | defaultConfigurationName = Release; 1398 | }; 1399 | EB4791BE1CBD85E200C04D13 /* Build configuration list for PBXNativeTarget "GraphQL OS X Tests" */ = { 1400 | isa = XCConfigurationList; 1401 | buildConfigurations = ( 1402 | EB4791BC1CBD85E200C04D13 /* Debug */, 1403 | EB4791BD1CBD85E200C04D13 /* Release */, 1404 | ); 1405 | defaultConfigurationIsVisible = 0; 1406 | defaultConfigurationName = Release; 1407 | }; 1408 | EB4791CB1CBD85F400C04D13 /* Build configuration list for PBXNativeTarget "GraphQL iOS Tests" */ = { 1409 | isa = XCConfigurationList; 1410 | buildConfigurations = ( 1411 | EB4791CC1CBD85F400C04D13 /* Debug */, 1412 | EB4791CD1CBD85F400C04D13 /* Release */, 1413 | ); 1414 | defaultConfigurationIsVisible = 0; 1415 | defaultConfigurationName = Release; 1416 | }; 1417 | EB4791DA1CBD8AF700C04D13 /* Build configuration list for PBXNativeTarget "GraphQL tvOS Tests" */ = { 1418 | isa = XCConfigurationList; 1419 | buildConfigurations = ( 1420 | EB4791DB1CBD8AF700C04D13 /* Debug */, 1421 | EB4791DC1CBD8AF700C04D13 /* Release */, 1422 | ); 1423 | defaultConfigurationIsVisible = 0; 1424 | defaultConfigurationName = Release; 1425 | }; 1426 | EB86F1A31CBD810200021DCE /* Build configuration list for PBXNativeTarget "GraphQL iOS" */ = { 1427 | isa = XCConfigurationList; 1428 | buildConfigurations = ( 1429 | EB86F1A11CBD810200021DCE /* Debug */, 1430 | EB86F1A21CBD810200021DCE /* Release */, 1431 | ); 1432 | defaultConfigurationIsVisible = 0; 1433 | defaultConfigurationName = Release; 1434 | }; 1435 | EB86F1AE1CBD811D00021DCE /* Build configuration list for PBXNativeTarget "GraphQL watchOS" */ = { 1436 | isa = XCConfigurationList; 1437 | buildConfigurations = ( 1438 | EB86F1AF1CBD811D00021DCE /* Debug */, 1439 | EB86F1B01CBD811D00021DCE /* Release */, 1440 | ); 1441 | defaultConfigurationIsVisible = 0; 1442 | defaultConfigurationName = Release; 1443 | }; 1444 | EB86F1BB1CBD812C00021DCE /* Build configuration list for PBXNativeTarget "GraphQL tvOS" */ = { 1445 | isa = XCConfigurationList; 1446 | buildConfigurations = ( 1447 | EB86F1BC1CBD812C00021DCE /* Debug */, 1448 | EB86F1BD1CBD812C00021DCE /* Release */, 1449 | ); 1450 | defaultConfigurationIsVisible = 0; 1451 | defaultConfigurationName = Release; 1452 | }; 1453 | EB86F1C81CBD813B00021DCE /* Build configuration list for PBXNativeTarget "GraphQL OS X" */ = { 1454 | isa = XCConfigurationList; 1455 | buildConfigurations = ( 1456 | EB86F1C91CBD813B00021DCE /* Debug */, 1457 | EB86F1CA1CBD813B00021DCE /* Release */, 1458 | ); 1459 | defaultConfigurationIsVisible = 0; 1460 | defaultConfigurationName = Release; 1461 | }; 1462 | /* End XCConfigurationList section */ 1463 | }; 1464 | rootObject = EB2B587A1CBD80750007387E /* Project object */; 1465 | } 1466 | -------------------------------------------------------------------------------- /graphql.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /graphql.xcodeproj/xcshareddata/xcschemes/GraphQL OS X Tests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 55 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 74 | 76 | 77 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /graphql.xcodeproj/xcshareddata/xcschemes/GraphQL OS X.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /graphql.xcodeproj/xcshareddata/xcschemes/GraphQL iOS Tests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 55 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 74 | 76 | 77 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /graphql.xcodeproj/xcshareddata/xcschemes/GraphQL iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /graphql.xcodeproj/xcshareddata/xcschemes/GraphQL tvOS Tests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 55 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 74 | 76 | 77 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /graphql.xcodeproj/xcshareddata/xcschemes/GraphQL tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /graphql.xcodeproj/xcshareddata/xcschemes/GraphQL watchOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /graphql.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /scripts/ci: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | readonly WORKSPACE="graphql.xcworkspace" 4 | 5 | build() { 6 | local scheme=$1 7 | local destination=$2 8 | set -o pipefail && xcodebuild -workspace $WORKSPACE -scheme "$scheme" -destination "$destination" test CODE_SIGNING_REQUIRED=NO \ 9 | | xcpretty -f `xcpretty-travis-formatter` 10 | } 11 | 12 | main() { 13 | local platform=$1 14 | case $platform in 15 | iOS) build 'GraphQL iOS Tests' 'platform=iOS Simulator,OS=9.3,name=iPhone 6s';; 16 | tvOS) build 'GraphQL tvOS Tests' 'platform=tvOS Simulator,OS=9.2,name=Apple TV 1080p';; 17 | OSX) build 'GraphQL OS X Tests' 'platform=OS X,arch=x86_64';; 18 | *) echo "Unknown platform: $platform [iOS,tvOS,OSX]" && exit 1;; 19 | esac 20 | } 21 | main $1 22 | -------------------------------------------------------------------------------- /scripts/tailor: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | main() { 4 | tailor -f html > tailor_report.html 5 | } 6 | main 7 | --------------------------------------------------------------------------------