Repository: apollographql/apollo-codegen
Pull request #378 (2018-02-16 06:36:22)

Fix unhandled passthroughCustomScalars option in Flow generator
This is fix for #375 

Should I add test for it? (I couldn't find test about `options` of Flow generator....)

meteor-bot: @asa-taka: Thank you for submitting a pull request! Before we can merge it, you'll need to sign the Meteor Contributor Agreement here: https://contribute.meteor.com/

Patch:
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 00000000..5b1a72fd
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,13 @@
+
+<!--**Issue Labels**
+
+While not necessary, you can help organize our issues by labeling this issue when you open it.  To add a label automatically, simply [x] mark the appropriate box below:
+
+- [ ] has-reproduction
+- [ ] feature
+- [ ] docs
+- [ ] blocking
+- [ ] good first issue
+
+To add a label not listed above, simply place `/label another-label-name` on a line by itself.
+-->
\ No newline at end of file
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 00000000..a168cdf8
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,11 @@
+
+<!--**Pull Request Labels**
+
+While not necessary, you can help organize our pull requests by labeling this issue when you open it.  To add a label automatically, simply [x] mark the appropriate box below:
+
+- [ ] feature
+- [ ] blocking
+- [ ] docs
+
+To add a label not listed above, simply place `/label another-label-name` on a line by itself.
+-->
\ No newline at end of file
diff --git a/README.md b/README.md
index f1bb451d..f82f4d43 100644
--- a/README.md
+++ b/README.md
@@ -75,7 +75,7 @@ In case you specify multiple schemas in your `.graphqlconfig` file, choose which
 
 When using `apollo-codegen` with Typescript or Flow, make sure to add the `__typename` introspection field to every selection set within your graphql operations.
 
-If you're using a client like `apollo-client` that does this automatically for your GraphQL operations, pass in the `--addTypename` option to `apollo-codegen` to make sure the generated Typescript and Flow types have the `__typename` field as well. This is required to ensure proper type generation support for `GraphQLUnionType` and `GraphQLInterfaceType` fields.
+If you're using a client like `apollo-client` that does this automatically for your GraphQL operations, pass in the `--add-typename` option to `apollo-codegen` to make sure the generated Typescript and Flow types have the `__typename` field as well. This is required to ensure proper type generation support for `GraphQLUnionType` and `GraphQLInterfaceType` fields.
 
 ### Why is the __typename field required?
 
diff --git a/package-lock.json b/package-lock.json
index 61c34830..24a4f8ca 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "apollo-codegen",
-  "version": "0.18.3",
+  "version": "0.19.1",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
@@ -97,9 +97,9 @@
       }
     },
     "@types/graphql": {
-      "version": "0.11.7",
-      "resolved": "https://registry.npmjs.org/@types/graphql/-/graphql-0.11.7.tgz",
-      "integrity": "sha512-+6UMNcBeLR/G/yMIFXVA6XJhfDlPO7x6cb7ooiyN12Q6GE1l3KbupZoWBMV2Uw3F2q+i+IiaHx9rIKwLADw+7A==",
+      "version": "0.12.4",
+      "resolved": "https://registry.npmjs.org/@types/graphql/-/graphql-0.12.4.tgz",
+      "integrity": "sha512-zICCZ+LEeqAx/mJ2gmMChlIHiUHhsMfy050DXQ5tSR8+GS4Os0Q0vjK9KT3HVV6bXrV60t02e/3dOmnHUcibYw==",
       "dev": true
     },
     "@types/inflected": {
@@ -114,11 +114,6 @@
       "integrity": "sha512-hQbL8aBM/g5S++sM1gb4yC73Dg+FK3uYE+Ioht1RPy629+LV/RmH6q+e+jbQEwKJdWAP/YE4s67CPO+ElkMivg==",
       "dev": true
     },
-    "@types/lodash": {
-      "version": "4.14.91",
-      "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.91.tgz",
-      "integrity": "sha512-k+nc3moSlAaXacyvz4/c6D9lnUeI6AKsLvkXFuNzUEEqMw7sjDnLW2GqlJ4nyFgMX/p+QzvVG6zRoDo4lJIV5g=="
-    },
     "@types/minimatch": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.1.tgz",
@@ -883,12 +878,19 @@
       }
     },
     "cross-fetch": {
-      "version": "0.0.8",
-      "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-0.0.8.tgz",
-      "integrity": "sha1-Ae2U3EB98sAPGAf95wCnz6SKIFw=",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.0.0.tgz",
+      "integrity": "sha512-gnx0GnDyW73iDq6DpqceL8i4GGn55PPKDzNwZkopJ3mKPcfJ0BUIXBsnYfJBVw+jFDB+hzIp2ELNRdqoxN6M3w==",
       "requires": {
-        "node-fetch": "1.7.3",
+        "node-fetch": "2.0.0",
         "whatwg-fetch": "2.0.3"
+      },
+      "dependencies": {
+        "node-fetch": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.0.0.tgz",
+          "integrity": "sha1-mCu6Q+zU8pIqKcwYamu7C7c/y6Y="
+        }
       }
     },
     "cross-spawn": {
@@ -2289,50 +2291,39 @@
       "dev": true
     },
     "graphql": {
-      "version": "0.12.3",
-      "resolved": "https://registry.npmjs.org/graphql/-/graphql-0.12.3.tgz",
-      "integrity": "sha512-Hn9rdu4zacplKXNrLCvR8YFiTGnbM4Zw/UH8FDmzBDsH7ou40lSNH4tIlsxcYnz2TGNVJCpu1WxCM23yd6kzhA==",
+      "version": "0.13.1",
+      "resolved": "https://registry.npmjs.org/graphql/-/graphql-0.13.1.tgz",
+      "integrity": "sha512-awNp3LTrQ7dJDSX3p3PBuxNDC+WFSOrWeV6+l4Xeh2PQJVOFyQ9SZPonXRz2WZc7aIxLZsf2nDZuuuc0qyEq/A==",
       "requires": {
-        "iterall": "1.1.3"
+        "iterall": "1.2.2"
       }
     },
     "graphql-config": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/graphql-config/-/graphql-config-1.1.1.tgz",
-      "integrity": "sha1-QPItSEXuYp0zRLMcTJ249pXdytU=",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/graphql-config/-/graphql-config-2.0.1.tgz",
+      "integrity": "sha512-eb4FzlODifHE/Q+91QptAmkGw39wL5ToinJ2556UUsGt2drPc4tzifL+HSnHSaxiIbH8EUhc/Fa6+neinF04qA==",
       "requires": {
-        "graphql": "0.12.3",
-        "graphql-import": "0.1.8",
-        "graphql-request": "1.4.0",
+        "graphql-import": "0.4.5",
+        "graphql-request": "1.5.1",
         "js-yaml": "3.10.0",
-        "minimatch": "3.0.4",
-        "rimraf": "2.6.2"
+        "lodash": "4.17.4",
+        "minimatch": "3.0.4"
       }
     },
     "graphql-import": {
-      "version": "0.1.8",
-      "resolved": "https://registry.npmjs.org/graphql-import/-/graphql-import-0.1.8.tgz",
-      "integrity": "sha1-QDufndg6IGqYCK4qtq+rQEDgNZ0=",
+      "version": "0.4.5",
+      "resolved": "https://registry.npmjs.org/graphql-import/-/graphql-import-0.4.5.tgz",
+      "integrity": "sha512-G/+I08Qp6/QGTb9qapknCm3yPHV0ZL7wbaalWFpxsfR8ZhZoTBe//LsbsCKlbALQpcMegchpJhpTSKiJjhaVqQ==",
       "requires": {
-        "@types/graphql": "0.11.7",
-        "@types/lodash": "4.14.91",
-        "graphql": "0.12.3",
         "lodash": "4.17.4"
-      },
-      "dependencies": {
-        "@types/graphql": {
-          "version": "0.11.7",
-          "resolved": "https://registry.npmjs.org/@types/graphql/-/graphql-0.11.7.tgz",
-          "integrity": "sha512-+6UMNcBeLR/G/yMIFXVA6XJhfDlPO7x6cb7ooiyN12Q6GE1l3KbupZoWBMV2Uw3F2q+i+IiaHx9rIKwLADw+7A=="
-        }
       }
     },
     "graphql-request": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-1.4.0.tgz",
-      "integrity": "sha512-lAAbaq2IbeN4sGcgQgx/OtxEZ9UimpWawIEUYAw8Dk0yNAYPwWH79/ASdGrH/5aTvYHz3U7CjgoQmaiUpLJ3qw==",
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-1.5.1.tgz",
+      "integrity": "sha512-p1f1q+D+5k1PMxsaZszestYW1BAEKjygliqTAhJI5nueRe74WRmwNQWAdrRBoCFRIpM0SZer98cbJF4PZHXaqg==",
       "requires": {
-        "cross-fetch": "0.0.8"
+        "cross-fetch": "2.0.0"
       }
     },
     "growly": {
@@ -2836,9 +2827,9 @@
       }
     },
     "iterall": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.1.3.tgz",
-      "integrity": "sha512-Cu/kb+4HiNSejAPhSaN1VukdNTTi/r4/e+yykqjlG/IW+1gZH5b4+Bq3whDX4tvbYugta3r8KTMUiqT3fIGxuQ=="
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.2.2.tgz",
+      "integrity": "sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA=="
     },
     "jest": {
       "version": "22.0.3",
diff --git a/package.json b/package.json
index 89c3b1a4..ace2921f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "apollo-codegen",
-  "version": "0.18.3",
+  "version": "0.19.1",
   "description": "Generate API code or type annotations based on a GraphQL schema and query documents",
   "main": "./lib/index.js",
   "bin": "./lib/cli.js",
@@ -28,7 +28,7 @@
     "@types/babylon": "^6.16.2",
     "@types/common-tags": "^1.4.0",
     "@types/glob": "^5.0.34",
-    "@types/graphql": "^0.11.7",
+    "@types/graphql": "^0.12.4",
     "@types/inflected": "^1.1.29",
     "@types/jest": "^21.1.8",
     "@types/node-fetch": "^1.6.7",
@@ -47,8 +47,8 @@
     "common-tags": "^1.5.1",
     "core-js": "^2.5.3",
     "glob": "^7.1.2",
-    "graphql": "^0.12.3",
-    "graphql-config": "^1.1.1",
+    "graphql": "^0.13.1",
+    "graphql-config": "^2.0.1",
     "inflected": "^2.0.3",
     "node-fetch": "^1.7.3",
     "rimraf": "^2.6.2",
diff --git a/src/compiler/index.ts b/src/compiler/index.ts
index 1ae98bd5..af190615 100644
--- a/src/compiler/index.ts
+++ b/src/compiler/index.ts
@@ -6,6 +6,7 @@ import {
   Kind,
   isCompositeType,
   GraphQLOutputType,
+  GraphQLInputType,
   GraphQLScalarType,
   GraphQLEnumType,
   GraphQLInputObjectType,
@@ -19,7 +20,6 @@ import {
   FragmentDefinitionNode,
   SelectionSetNode,
   SelectionNode,
-  ArgumentNode,
   isSpecifiedScalarType
 } from 'graphql';
 
@@ -49,15 +49,6 @@ export interface CompilerContext {
   options: CompilerOptions;
 }
 
-function argumentsFromAST(args: ArgumentNode[]): Argument[] {
-  return (
-    args &&
-    args.map(arg => {
-      return { name: arg.name.value, value: valueFromValueNode(arg.value) };
-    })
-  );
-}
-
 export interface Operation {
   operationId?: string;
   operationName: string;
@@ -88,6 +79,7 @@ export interface SelectionSet {
 export interface Argument {
   name: string;
   value: any;
+  type?: GraphQLInputType;
 }
 
 export type Selection = Field | TypeCondition | BooleanCondition | FragmentSpread;
@@ -164,14 +156,14 @@ export function compileToIR(
       fragmentSpread.selectionSet.possibleTypes.includes(type)
     );
 
-    fragmentSpread.isConditional = fragment.selectionSet.possibleTypes.some(type =>
-      !fragmentSpread.selectionSet.possibleTypes.includes(type)
+    fragmentSpread.isConditional = fragment.selectionSet.possibleTypes.some(
+      type => !fragmentSpread.selectionSet.possibleTypes.includes(type)
     );
 
     fragmentSpread.selectionSet = {
       possibleTypes,
       selections: fragment.selectionSet.selections
-    }
+    };
   }
 
   const typesUsed = compiler.typesUsed;
@@ -292,11 +284,6 @@ class Compiler {
         const name = selectionNode.name.value;
         const alias = selectionNode.alias ? selectionNode.alias.value : undefined;
 
-        const args =
-          selectionNode.arguments && selectionNode.arguments.length > 0
-            ? argumentsFromAST(selectionNode.arguments)
-            : undefined;
-
         const fieldDef = getFieldDef(this.schema, parentType, selectionNode);
         if (!fieldDef) {
           throw new GraphQLError(`Cannot query field "${name}" on type "${String(parentType)}"`, [
@@ -313,6 +300,19 @@ class Compiler {
 
         const responseKey = alias || name;
 
+        const args =
+          selectionNode.arguments && selectionNode.arguments.length > 0
+            ? selectionNode.arguments.map(arg => {
+                const name = arg.name.value;
+                const argDef = fieldDef.args.find(argDef => argDef.name === arg.name.value);
+                return {
+                  name,
+                  value: valueFromValueNode(arg.value),
+                  type: (argDef && argDef.type) || undefined
+                };
+              })
+            : undefined;
+
         let field: Field = {
           kind: 'Field',
           responseKey,
@@ -343,7 +343,7 @@ class Compiler {
       }
       case Kind.INLINE_FRAGMENT: {
         const typeNode = selectionNode.typeCondition;
-        const type = typeNode ? typeFromAST(this.schema, typeNode) as GraphQLCompositeType : parentType;
+        const type = typeNode ? (typeFromAST(this.schema, typeNode) as GraphQLCompositeType) : parentType;
         const possibleTypesForTypeCondition = this.possibleTypesForType(type).filter(type =>
           possibleTypes.includes(type)
         );
diff --git a/src/compiler/legacyIR.ts b/src/compiler/legacyIR.ts
index 166cd284..7cb6763e 100644
--- a/src/compiler/legacyIR.ts
+++ b/src/compiler/legacyIR.ts
@@ -1,4 +1,11 @@
-import { GraphQLSchema, GraphQLType, GraphQLObjectType, GraphQLCompositeType, DocumentNode } from 'graphql';
+import {
+  GraphQLSchema,
+  GraphQLType,
+  GraphQLObjectType,
+  GraphQLCompositeType,
+  GraphQLInputType,
+  DocumentNode
+} from 'graphql';
 
 import { compileToIR, CompilerContext, SelectionSet, Field, FragmentSpread } from './';
 
@@ -85,6 +92,7 @@ export interface BooleanCondition {
 export interface Argument {
   name: string;
   value: any;
+  type?: GraphQLInputType;
 }
 
 export function compileToLegacyIR(
@@ -156,7 +164,9 @@ class LegacyIRTransformer {
   transformSelectionSetToLegacyIR(selectionSet: SelectionSet) {
     const typeCase = typeCaseForSelectionSet(selectionSet, this.options.mergeInFieldsFromFragmentSpreads);
 
-    const fields: LegacyField[] = this.transformFieldsToLegacyIR(collectAndMergeFields(typeCase.default, false));
+    const fields: LegacyField[] = this.transformFieldsToLegacyIR(
+      collectAndMergeFields(typeCase.default, false)
+    );
 
     const inlineFragments: LegacyInlineFragment[] = typeCase.variants.flatMap(variant => {
       const fields = this.transformFieldsToLegacyIR(collectAndMergeFields(variant, false));
@@ -220,7 +230,7 @@ class LegacyIRTransformer {
         description,
         isDeprecated,
         deprecationReason,
-        ...selectionSet ? this.transformSelectionSetToLegacyIR(selectionSet) : {}
+        ...(selectionSet ? this.transformSelectionSetToLegacyIR(selectionSet) : {})
       } as LegacyField;
     });
   }
diff --git a/src/flow/types.js b/src/flow/types.js
index 21a92203..783607a8 100644
--- a/src/flow/types.js
+++ b/src/flow/types.js
@@ -36,7 +36,7 @@ export function typeNameFromGraphQLType(context, type, bareTypeName, nullable =
   if (type instanceof GraphQLList) {
     typeName = `Array< ${typeNameFromGraphQLType(context, type.ofType, bareTypeName)} >`;
   } else if (type instanceof GraphQLScalarType) {
-    typeName = builtInScalarMap[type.name] || (context.passthroughCustomScalars ? context.customScalarsPrefix + type.name : 'any');
+    typeName = builtInScalarMap[type.name] || (context.options.passthroughCustomScalars ? context.options.customScalarsPrefix + type.name : 'any');
   } else {
     typeName = bareTypeName || type.name;
   }
diff --git a/src/generate.ts b/src/generate.ts
index 017dfde4..81d9b184 100644
--- a/src/generate.ts
+++ b/src/generate.ts
@@ -103,7 +103,7 @@ export default function generate(
         output = generateFlowSource(context);
         break;
       case 'scala':
-        output = generateScalaSource(context, options);
+        output = generateScalaSource(context);
     }
 
     if (outputPath) {
diff --git a/src/javascript/flow/language.ts b/src/javascript/flow/language.ts
index d306dc65..8ffe92b0 100644
--- a/src/javascript/flow/language.ts
+++ b/src/javascript/flow/language.ts
@@ -104,7 +104,7 @@ export default class FlowGenerator {
         if (description) {
           objectTypeProperty.trailingComments = [{
             type: 'CommentLine',
-            value: ` ${description.replace('\n', ' ')}`
+            value: ` ${description.replace(new RegExp('\n', 'g'), ' ')}`
           } as t.CommentLine]
         }
 
diff --git a/src/javascript/typescript/language.ts b/src/javascript/typescript/language.ts
index 7197ea9c..fce3d652 100644
--- a/src/javascript/typescript/language.ts
+++ b/src/javascript/typescript/language.ts
@@ -56,7 +56,7 @@ export default class TypescriptGenerator {
     if (description) {
       typeAlias.leadingComments = [{
         type: 'CommentLine',
-        value: ` ${description.replace('\n', ' ')}`
+        value: ` ${description.replace(new RegExp('\n', 'g'), ' ')}`
       } as t.CommentLine];
     }
 
@@ -106,7 +106,7 @@ export default class TypescriptGenerator {
       if (description) {
         propertySignatureType.trailingComments = [{
           type: 'CommentLine',
-          value: ` ${description.replace('\n', ' ')}`
+          value: ` ${description.replace(new RegExp('\n', 'g'), ' ')}`
         } as t.CommentLine]
       }
 
diff --git a/src/printSchema.ts b/src/printSchema.ts
index d4b3c96d..b6403c02 100644
--- a/src/printSchema.ts
+++ b/src/printSchema.ts
@@ -3,8 +3,13 @@ import * as fs from 'fs';
 import { buildClientSchema, printSchema } from 'graphql';
 
 import { ToolError } from './errors'
+import { PrinterOptions } from 'graphql/utilities/schemaPrinter';
 
-export default async function printSchemaFromIntrospectionResult(schemaPath: string, outputPath: string) {
+export default async function printSchemaFromIntrospectionResult(
+  schemaPath: string,
+  outputPath: string,
+  options?: PrinterOptions
+) {
   if (!fs.existsSync(schemaPath)) {
     throw new ToolError(`Cannot find GraphQL schema file: ${schemaPath}`);
   }
@@ -16,7 +21,7 @@ export default async function printSchemaFromIntrospectionResult(schemaPath: str
   }
 
   const schema = buildClientSchema(schemaJSON.data);
-  const schemaIDL = printSchema(schema);
+  const schemaIDL = printSchema(schema, options);
 
   if (outputPath) {
     fs.writeFileSync(outputPath, schemaIDL);
diff --git a/src/scala/codeGeneration.js b/src/scala/codeGeneration.ts
similarity index 76%
rename from src/scala/codeGeneration.js
rename to src/scala/codeGeneration.ts
index 0dcc4803..a9dc0704 100644
--- a/src/scala/codeGeneration.js
+++ b/src/scala/codeGeneration.ts
@@ -2,13 +2,8 @@ import {
   GraphQLError,
   getNamedType,
   isCompositeType,
-  isAbstractType,
-  isEqualType,
-  GraphQLScalarType,
   GraphQLEnumType,
-  GraphQLList,
   GraphQLNonNull,
-  GraphQLID,
   GraphQLInputObjectType
 } from 'graphql'
 
@@ -16,15 +11,12 @@ import  { isTypeProperSuperTypeOf } from '../utilities/graphql'
 
 import {
   join,
-  wrap,
 } from '../utilities/printing';
 
 import {
   packageDeclaration,
   objectDeclaration,
   caseClassDeclaration,
-  propertyDeclaration,
-  propertyDeclarations,
   escapeIdentifierIfNeeded,
   comment
 } from './language';
@@ -35,16 +27,12 @@ import {
   caseClassNameForInlineFragment,
   operationClassName,
   enumCaseName,
-  propertiesFromSelectionSet,
-  propertyFromField,
-  propertyFromInlineFragment,
-  propertyFromFragmentSpread
+  propertyFromLegacyField,
+  propertyFromInputField,
 } from './naming';
 
 import {
-  escapedString,
   multilineString,
-  dictionaryLiteralForFieldArguments,
 } from './values';
 
 import {
@@ -53,15 +41,19 @@ import {
 } from './types';
 
 import CodeGenerator from '../utilities/CodeGenerator';
+import { LegacyCompilerContext, LegacyOperation, LegacyFragment, LegacyField, LegacyInlineFragment } from '../compiler/legacyIR';
+import { GraphQLType } from 'graphql';
+import { Property } from './language';
+import { GraphQLCompositeType } from 'graphql';
 
-export function generateSource(context, options) {
+export function generateSource(context: LegacyCompilerContext) {
   const generator = new CodeGenerator(context);
 
   generator.printOnNewline('//  This file was automatically generated and should not be edited.');
   generator.printNewline();
 
-  if (context.namespace) {
-    packageDeclaration(generator, context.namespace);
+  if (context.options.namespace) {
+    packageDeclaration(generator, context.options.namespace);
   }
 
   context.typesUsed.forEach(type => {
@@ -80,7 +72,7 @@ export function generateSource(context, options) {
 }
 
 export function classDeclarationForOperation(
-  generator,
+  generator: CodeGenerator<LegacyCompilerContext, any>,
   {
     operationName,
     operationType,
@@ -91,9 +83,8 @@ export function classDeclarationForOperation(
     fragmentSpreads,
     fragmentsReferenced,
     source,
-    sourceWithFragments,
     operationId
-  }
+  }: LegacyOperation
 ) {
   let objectName;
   let protocol;
@@ -113,8 +104,7 @@ export function classDeclarationForOperation(
 
   objectDeclaration(generator, {
     objectName,
-    modifiers: [],
-    superclass: protocol
+    superclass: protocol,
   }, () => {
     if (source) {
       generator.printOnNewline('val operationString =');
@@ -123,7 +113,9 @@ export function classDeclarationForOperation(
       });
     }
 
-    operationIdentifier(generator, { operationName, sourceWithFragments, operationId });
+    if (operationId) {
+      operationIdentifier(generator, operationId);
+    }
 
     if (fragmentsReferenced && fragmentsReferenced.length > 0) {
       generator.printNewlineIfNeeded();
@@ -144,7 +136,7 @@ export function classDeclarationForOperation(
       const properties = variables.map(({ name, type }) => {
         const propertyName = escapeIdentifierIfNeeded(name);
         const typeName = typeNameFromGraphQLType(generator.context, type);
-        const isOptional = !(type instanceof GraphQLNonNull || type.ofType instanceof GraphQLNonNull);
+        const isOptional = !(type instanceof GraphQLNonNull || type instanceof GraphQLNonNull);
         return { name, propertyName, type, typeName, isOptional };
       });
 
@@ -172,7 +164,7 @@ export function classDeclarationForOperation(
 }
 
 export function caseClassDeclarationForFragment(
-  generator,
+  generator: CodeGenerator<LegacyCompilerContext, any>,
   {
     fragmentName,
     typeCondition,
@@ -180,7 +172,7 @@ export function caseClassDeclarationForFragment(
     inlineFragments,
     fragmentSpreads,
     source
-  }
+  }: LegacyFragment
 ) {
   const caseClassName = caseClassNameForFragmentName(fragmentName);
 
@@ -190,7 +182,7 @@ export function caseClassDeclarationForFragment(
     fields,
     inlineFragments,
     fragmentSpreads
-  }, () => {}, () => {
+  }, () => {
     if (source) {
       generator.printOnNewline('val fragmentString =');
       generator.withIndent(() => {
@@ -201,7 +193,7 @@ export function caseClassDeclarationForFragment(
 }
 
 export function caseClassDeclarationForSelectionSet(
-  generator,
+  generator: CodeGenerator<LegacyCompilerContext, any>,
   {
     caseClassName,
     parentType,
@@ -209,17 +201,24 @@ export function caseClassDeclarationForSelectionSet(
     inlineFragments,
     fragmentSpreads,
     viewableAs
+  }: {
+    caseClassName: string,
+    parentType: GraphQLCompositeType,
+    fields: LegacyField[],
+    inlineFragments?: LegacyInlineFragment[],
+    fragmentSpreads?: string[],
+    viewableAs?: {
+      caseClassName: string,
+      properties: (LegacyField & Property)[]
+    }
   },
-  beforeClosure,
-  objectClosure,
+  objectClosure?: () => void,
 ) {
   const possibleTypes = parentType ? possibleTypesForType(generator.context, parentType) : null;
 
-  let properties;
-
   if (!possibleTypes || possibleTypes.length == 1) {
-    properties = fields
-      .map(field => propertyFromField(generator.context, field))
+    const properties = fields
+      .map(field => propertyFromLegacyField(generator.context, field, caseClassName))
       .filter(field => field.propertyName != "__typename");
 
     caseClassDeclaration(generator, { caseClassName, params: properties.map(p => {
@@ -231,7 +230,7 @@ export function caseClassDeclarationForSelectionSet(
   } else {
     generator.printNewlineIfNeeded();
     const properties = fields
-      .map(field => propertyFromField(generator.context, field))
+      .map(field => propertyFromLegacyField(generator.context, field, caseClassName))
       .filter(field => field.propertyName != "__typename");
 
     caseClassDeclaration(generator, { caseClassName, params: properties.map(p => {
@@ -239,14 +238,14 @@ export function caseClassDeclarationForSelectionSet(
         name: p.responseName,
         type: p.typeName,
       };
-    }), superclass: 'me.shadaj.slinky.core.WithRaw'}, () => {
+    }), superclass: 'slinky.readwrite.WithRaw'}, () => {
       if (inlineFragments && inlineFragments.length > 0) {
         inlineFragments.forEach((inlineFragment) => {
           const fragClass = caseClassNameForInlineFragment(inlineFragment);
           generator.printOnNewline(`def as${inlineFragment.typeCondition}`);
           generator.print(`: Option[${fragClass}] =`);
           generator.withinBlock(() => {
-            generator.printOnNewline(`if (${fragClass}.possibleTypes.contains(this.raw.__typename.asInstanceOf[String])) Some(implicitly[me.shadaj.slinky.core.Reader[${fragClass}]].read(this.raw)) else None`);
+            generator.printOnNewline(`if (${fragClass}.possibleTypes.contains(this.raw.__typename.asInstanceOf[String])) Some(implicitly[slinky.readwrite.Reader[${fragClass}]].read(this.raw)) else None`);
           });
         });
       }
@@ -259,7 +258,7 @@ export function caseClassDeclarationForSelectionSet(
             generator.printOnNewline(`def as${s}`);
             generator.print(`: Option[${s}] =`);
             generator.withinBlock(() => {
-              generator.printOnNewline(`if (${s}.possibleTypes.contains(this.raw.__typename.asInstanceOf[String])) Some(implicitly[me.shadaj.slinky.core.Reader[${s}]].read(this.raw)) else None`);
+              generator.printOnNewline(`if (${s}.possibleTypes.contains(this.raw.__typename.asInstanceOf[String])) Some(implicitly[slinky.readwrite.Reader[${s}]].read(this.raw)) else None`);
             });
           }
         })
@@ -275,7 +274,7 @@ export function caseClassDeclarationForSelectionSet(
             caseClassName: caseClassNameForInlineFragment(inlineFragment),
             parentType: inlineFragment.typeCondition,
             fields: inlineFragment.fields,
-            inlineFragments: inlineFragment.inlineFragments,
+            // inlineFragments: inlineFragment.inlineFragments,
             fragmentSpreads: inlineFragment.fragmentSpreads,
             viewableAs: {
               caseClassName,
@@ -309,27 +308,27 @@ export function caseClassDeclarationForSelectionSet(
       })
     }
 
+    fields.filter(field => isCompositeType(getNamedType(field.type))).forEach(field => {
+      caseClassDeclarationForSelectionSet(
+        generator,
+        {
+          caseClassName: caseClassNameForPropertyName(field.responseName),
+          parentType: getNamedType(field.type) as GraphQLCompositeType,
+          fields: field.fields || [],
+          inlineFragments: field.inlineFragments,
+          fragmentSpreads: field.fragmentSpreads
+        }
+      );
+    });
+
     if (objectClosure) {
       objectClosure();
     }
   });
-
-  fields.filter(field => isCompositeType(getNamedType(field.type))).forEach(field => {
-    caseClassDeclarationForSelectionSet(
-      generator,
-      {
-        caseClassName: caseClassNameForPropertyName(field.responseName),
-        parentType: getNamedType(field.type),
-        fields: field.fields,
-        inlineFragments: field.inlineFragments,
-        fragmentSpreads: field.fragmentSpreads
-      }
-    );
-  });
 }
 
-function operationIdentifier(generator,  { operationName, sourceWithFragments, operationId }) {
-  if (!generator.context.generateOperationIds) {
+function operationIdentifier(generator: CodeGenerator<LegacyCompilerContext, any>, operationId: string) {
+  if (!generator.context.options.generateOperationIds) {
     return
   }
 
@@ -337,7 +336,7 @@ function operationIdentifier(generator,  { operationName, sourceWithFragments, o
   generator.printOnNewline(`val operationIdentifier: String = "${operationId}"`);
 }
 
-export function typeDeclarationForGraphQLType(generator, type) {
+export function typeDeclarationForGraphQLType(generator: CodeGenerator<LegacyCompilerContext, any>, type: GraphQLType) {
   if (type instanceof GraphQLEnumType) {
     enumerationDeclaration(generator, type);
   } else if (type instanceof GraphQLInputObjectType) {
@@ -345,7 +344,7 @@ export function typeDeclarationForGraphQLType(generator, type) {
   }
 }
 
-function enumerationDeclaration(generator, type) {
+function enumerationDeclaration(generator: CodeGenerator<LegacyCompilerContext, any>, type: GraphQLEnumType) {
   const { name, description } = type;
   const values = type.getValues();
 
@@ -361,15 +360,16 @@ function enumerationDeclaration(generator, type) {
   generator.printNewline();
 }
 
-function caseClassDeclarationForInputObjectType(generator, type) {
+function caseClassDeclarationForInputObjectType(generator: CodeGenerator<LegacyCompilerContext, any>, type: GraphQLInputObjectType) {
   const { name: caseClassName, description } = type;
   const fields = Object.values(type.getFields());
-  const properties = fields.map(field => propertyFromField(generator.context, field));
+  const properties = fields.map(field => propertyFromInputField(generator.context, field, generator.context.options.namespace));
 
   caseClassDeclaration(generator, { caseClassName, description, params: properties.map(p => {
     return {
       name: p.propertyName,
-      type: p.typeName
+      type: p.typeName,
+      defaultValue: p.isOptional ? "scala.scalajs.js.undefined" : ""
     };
   })}, () => {});
 }
diff --git a/src/scala/index.js b/src/scala/index.ts
similarity index 100%
rename from src/scala/index.js
rename to src/scala/index.ts
diff --git a/src/scala/language.js b/src/scala/language.js
deleted file mode 100644
index 23fc67dc..00000000
--- a/src/scala/language.js
+++ /dev/null
@@ -1,66 +0,0 @@
-import {
-  join,
-  wrap,
-} from '../utilities/printing';
-
-export function comment(generator, comment) {
-  const split = comment ? comment.split('\n') : [];
-  if (split.length > 0) {
-    generator.printOnNewline('/**')
-    split.forEach(line => {
-      generator.printOnNewline(` * ${line.trim()}`);
-    });
-
-    generator.printOnNewline(' */');
-  }
-}
-
-export function packageDeclaration(generator, pkg) {
-  generator.printNewlineIfNeeded();
-  generator.printOnNewline(`package ${pkg}`);
-  generator.popScope();
-}
-
-export function objectDeclaration(generator, { objectName, superclass, properties }, closure) {
-  generator.printNewlineIfNeeded();
-  generator.printOnNewline(`object ${objectName}` + (superclass ? ` extends ${superclass}` : ''));
-  generator.pushScope({ typeName: objectName });
-  generator.withinBlock(closure);
-  generator.popScope();
-}
-
-export function caseClassDeclaration(generator, { caseClassName, description, superclass, params }, closure) {
-  generator.printNewlineIfNeeded();
-  comment(generator, description);
-  generator.printOnNewline(`case class ${caseClassName}(${(params || []).map(v => v.name + ": " + v.type).join(', ')})` + (superclass ? ` extends ${superclass}` : ''));
-  generator.pushScope({ typeName: caseClassName });
-  generator.withinBlock(closure);
-  generator.popScope();
-}
-
-export function propertyDeclaration(generator, { propertyName, typeName, description}, closure) {
-  comment(generator, description);
-  generator.printOnNewline(`val ${propertyName}: ${typeName} =`);
-  generator.withinBlock(closure);
-}
-
-export function propertyDeclarations(generator, declarations) {
-  declarations.forEach(o => {
-    propertyDeclaration(generator, o);
-  });
-}
-
-const reservedKeywords = new Set(
-  'case', 'catch', 'class', 'def', 'do', 'else',
-  'extends', 'false', 'final', 'for', 'if', 'match',
-  'new', 'null', 'throw', 'trait', 'true', 'try', 'until',
-  'val', 'var', 'while', 'with'
-);
-
-export function escapeIdentifierIfNeeded(identifier) {
-  if (reservedKeywords.has(identifier)) {
-    return '`' + identifier + '`';
-  } else {
-    return identifier;
-  }
-}
diff --git a/src/scala/language.ts b/src/scala/language.ts
new file mode 100644
index 00000000..eff9830a
--- /dev/null
+++ b/src/scala/language.ts
@@ -0,0 +1,123 @@
+import CodeGenerator from "../utilities/CodeGenerator";
+import { LegacyCompilerContext } from "../compiler/legacyIR";
+
+export interface Property {
+  propertyName: string;
+  typeName: string;
+  caseClassName?: string;
+  isOptional?: boolean;
+  isList?: boolean;
+  description?: string;
+}
+
+export function comment(generator: CodeGenerator<LegacyCompilerContext, any>, comment: string) {
+  const split = comment ? comment.split('\n') : [];
+  if (split.length > 0) {
+    generator.printOnNewline('/**')
+    split.forEach(line => {
+      generator.printOnNewline(` * ${line.trim()}`);
+    });
+
+    generator.printOnNewline(' */');
+  }
+}
+
+export function packageDeclaration(generator: CodeGenerator<LegacyCompilerContext, any>, pkg: string) {
+  generator.printNewlineIfNeeded();
+  generator.printOnNewline(`package ${pkg}`);
+  generator.popScope();
+}
+
+export function objectDeclaration(
+  generator: CodeGenerator<LegacyCompilerContext, any>,
+  { objectName, superclass }: {
+    objectName: string,
+    superclass?: string
+  },
+  closure?: () => void
+) {
+  generator.printNewlineIfNeeded();
+  generator.printOnNewline(`object ${objectName}` + (superclass ? ` extends ${superclass}` : ''));
+  generator.pushScope({ typeName: objectName });
+  if (closure) {
+    generator.withinBlock(closure);
+  }
+  generator.popScope();
+}
+
+export function caseClassDeclaration(
+  generator: CodeGenerator<LegacyCompilerContext, any>,
+  { caseClassName, description, superclass, params }: {
+    caseClassName: string,
+    description?: string,
+    superclass?: string,
+    params?: {
+      name: string,
+      type: string,
+      defaultValue?: string
+    }[],
+  },
+  closure?: () => void
+) {
+  generator.printNewlineIfNeeded();
+
+  if (description) {
+    comment(generator, description);
+  }
+
+  const paramsSection = (params || []).map(v => {
+    return v.name + ": " + v.type + (v.defaultValue ? ` = ${v.defaultValue}` : "");
+  }).join(', ');
+
+  generator.printOnNewline(`case class ${caseClassName}(${paramsSection})` + (superclass ? ` extends ${superclass}` : ''));
+  generator.pushScope({ typeName: caseClassName });
+  if (closure) {
+    generator.withinBlock(closure);
+  }
+  generator.popScope();
+}
+
+export function propertyDeclaration(
+  generator: CodeGenerator<LegacyCompilerContext, any>,
+  { propertyName, typeName, description}: {
+    propertyName: string,
+    typeName: string,
+    description: string
+  },
+  closure?: () => void
+) {
+  comment(generator, description);
+  generator.printOnNewline(`val ${propertyName}: ${typeName} =`);
+
+  if (closure) {
+    generator.withinBlock(closure);
+  }
+}
+
+export function propertyDeclarations(
+  generator: CodeGenerator<LegacyCompilerContext, any>,
+  declarations: {
+    propertyName: string,
+    typeName: string,
+    description: string
+  }[]
+) {
+  declarations.forEach(o => {
+    propertyDeclaration(generator, o);
+  });
+}
+
+const reservedKeywords = new Set([
+  'case', 'catch', 'class', 'def', 'do', 'else',
+  'extends', 'false', 'final', 'for', 'if', 'match',
+  'new', 'null', 'throw', 'trait', 'true', 'try', 'until',
+  'val', 'var', 'while', 'with'
+]);
+
+export function escapeIdentifierIfNeeded(identifier: string) {
+  if (reservedKeywords.has(identifier)) {
+    return '`' + identifier + '`';
+  } else {
+    return identifier;
+  }
+}
diff --git a/src/scala/naming.js b/src/scala/naming.js
deleted file mode 100644
index 6399c7a0..00000000
--- a/src/scala/naming.js
+++ /dev/null
@@ -1,87 +0,0 @@
-import { camelCase, pascalCase } from 'change-case';
-import * as Inflector from 'inflected';
-
-import {
-  join
-} from '../utilities/printing';
-
-import {
-  escapeIdentifierIfNeeded
-} from './language';
-
-import {
-  typeNameFromGraphQLType
-} from './types';
-
-import {
-  GraphQLError,
-  GraphQLList,
-  GraphQLNonNull,
-  getNamedType,
-  isCompositeType,
-} from 'graphql';
-
-export function enumCaseName(name) {
-  return camelCase(name);
-}
-
-export function operationClassName(name) {
-  return pascalCase(name);
-}
-
-export function caseClassNameForPropertyName(propertyName) {
-  return pascalCase(Inflector.singularize(propertyName));
-}
-
-export function caseClassNameForFragmentName(fragmentName) {
-  return pascalCase(fragmentName);
-}
-
-export function caseClassNameForInlineFragment(inlineFragment) {
-  return 'As' + pascalCase(String(inlineFragment.typeCondition));
-}
-
-export function propertyFromField(context, field, namespace) {
-  const name = field.name || field.responseName;
-  const unescapedPropertyName = isMetaFieldName(name) ? name : camelCase(name)
-  const propertyName = escapeIdentifierIfNeeded(unescapedPropertyName);
-
-  const type = field.type;
-  const isList = type instanceof GraphQLList || type.ofType instanceof GraphQLList
-  const isOptional = field.isConditional || !(type instanceof GraphQLNonNull);
-  const bareType = getNamedType(type);
-
-  if (isCompositeType(bareType)) {
-    const bareTypeName = join([
-      namespace,
-      escapeIdentifierIfNeeded(pascalCase(Inflector.singularize(name)))
-    ], '.');
-    const typeName = typeNameFromGraphQLType(context, type, bareTypeName, isOptional);
-    return { ...field, propertyName, typeName, bareTypeName, isOptional, isList, isComposite: true };
-  } else {
-    const typeName = typeNameFromGraphQLType(context, type, undefined, isOptional);
-    return { ...field, propertyName, typeName, isOptional, isList, isComposite: false };
-  }
-}
-
-export function propertyFromInlineFragment(context, inlineFragment) {
-  const structName = caseClassNameForInlineFragment(inlineFragment);
-  const propertyName = camelCase(structName);
-  const typeName = structName + '?'
-  return { propertyName, typeName, structName, isComposite: true, ...inlineFragment };
-}
-
-export function propertyFromFragmentSpread(context, fragmentSpread) {
-  const fragmentName = fragmentSpread;
-  const fragment = context.fragments[fragmentName];
-  if (!fragment) {
-    throw new GraphQLError(`Cannot find fragment "${fragmentName}"`);
-  }
-  const propertyName = camelCase(fragmentName);
-  const typeName = caseClassNameForFragmentName(fragmentName);
-  return { propertyName, typeName, fragment, isComposite: true };
-}
-
-function isMetaFieldName(name) {
-  return name.startsWith("__");
-}
\ No newline at end of file
diff --git a/src/scala/naming.ts b/src/scala/naming.ts
new file mode 100644
index 00000000..3576b0e2
--- /dev/null
+++ b/src/scala/naming.ts
@@ -0,0 +1,95 @@
+import { camelCase, pascalCase } from 'change-case';
+import * as Inflector from 'inflected';
+
+import {
+  join
+} from '../utilities/printing';
+
+import {
+  escapeIdentifierIfNeeded, Property
+} from './language';
+
+import {
+  typeNameFromGraphQLType
+} from './types';
+
+import {
+  GraphQLList,
+  GraphQLNonNull,
+  getNamedType,
+  isCompositeType,
+} from 'graphql';
+import { LegacyCompilerContext, LegacyField, LegacyInlineFragment } from '../compiler/legacyIR';
+import { GraphQLInputField } from 'graphql';
+
+export function enumCaseName(name: string) {
+  return camelCase(name);
+}
+
+export function operationClassName(name: string) {
+  return pascalCase(name);
+}
+
+export function caseClassNameForPropertyName(propertyName: string) {
+  return pascalCase(Inflector.singularize(propertyName));
+}
+
+export function caseClassNameForFragmentName(fragmentName: string) {
+  return pascalCase(fragmentName);
+}
+
+export function caseClassNameForInlineFragment(inlineFragment: LegacyInlineFragment) {
+  return 'As' + pascalCase(String(inlineFragment.typeCondition));
+}
+
+export function propertyFromInputField(context: LegacyCompilerContext, field: GraphQLInputField, namespace?: string, parentCaseClassName?: string): GraphQLInputField & Property {
+  const name = field.name;
+  const unescapedPropertyName = isMetaFieldName(name) ? name : camelCase(name)
+  const propertyName = escapeIdentifierIfNeeded(unescapedPropertyName);
+
+  const type = field.type;
+  const isList = type instanceof GraphQLList || type instanceof GraphQLList
+  const isOptional = !(type instanceof GraphQLNonNull);
+  const bareType = getNamedType(type);
+
+  if (isCompositeType(bareType)) {
+    const bareTypeName = join([
+      namespace,
+      parentCaseClassName,
+      escapeIdentifierIfNeeded(pascalCase(Inflector.singularize(name)))
+    ], '.');
+    const typeName = typeNameFromGraphQLType(context, type, bareTypeName, isOptional, true);
+    return { ...field, propertyName, typeName, isOptional, isList };
+  } else {
+    const typeName = typeNameFromGraphQLType(context, type, undefined, isOptional, true);
+    return { ...field, propertyName, typeName, isOptional, isList };
+  }
+}
+
+export function propertyFromLegacyField(context: LegacyCompilerContext, field: LegacyField, namespace?: string, parentCaseClassName?: string): LegacyField & Property {
+  const name = field.responseName;
+  const unescapedPropertyName = isMetaFieldName(name) ? name : camelCase(name)
+  const propertyName = escapeIdentifierIfNeeded(unescapedPropertyName);
+
+  const type = field.type;
+  const isList = type instanceof GraphQLList || type instanceof GraphQLList
+  const isOptional = field.isConditional || !(type instanceof GraphQLNonNull);
+  const bareType = getNamedType(type);
+
+  if (isCompositeType(bareType)) {
+    const bareTypeName = join([
+      namespace,
+      parentCaseClassName,
+      escapeIdentifierIfNeeded(pascalCase(Inflector.singularize(name)))
+    ], '.');
+    const typeName = typeNameFromGraphQLType(context, type, bareTypeName, isOptional);
+    return { ...field, propertyName, typeName, isOptional, isList };
+  } else {
+    const typeName = typeNameFromGraphQLType(context, type, undefined, isOptional);
+    return { ...field, propertyName, typeName, isOptional, isList };
+  }
+}
+
+function isMetaFieldName(name: string) {
+  return name.startsWith("__");
+}
diff --git a/src/scala/types.js b/src/scala/types.ts
similarity index 59%
rename from src/scala/types.js
rename to src/scala/types.ts
index ee182f85..70f9dc50 100644
--- a/src/scala/types.js
+++ b/src/scala/types.ts
@@ -1,12 +1,3 @@
-import {
-  join,
-  block,
-  wrap,
-  indent
-} from '../utilities/printing';
-
-import { camelCase } from 'change-case';
-
 import {
   GraphQLString,
   GraphQLInt,
@@ -17,9 +8,10 @@ import {
   GraphQLNonNull,
   GraphQLScalarType,
   GraphQLEnumType,
-  isCompositeType,
   isAbstractType
 } from 'graphql';
+import { LegacyCompilerContext } from '../compiler/legacyIR';
+import { GraphQLType } from 'graphql';
 
 const builtInScalarMap = {
   [GraphQLString.name]: 'String',
@@ -29,7 +21,7 @@ const builtInScalarMap = {
   [GraphQLID.name]: 'String',
 }
 
-export function possibleTypesForType(context, type) {
+export function possibleTypesForType(context: LegacyCompilerContext, type: GraphQLType) {
   if (isAbstractType(type)) {
     return context.schema.getPossibleTypes(type);
   } else {
@@ -37,7 +29,7 @@ export function possibleTypesForType(context, type) {
   }
 }
 
-export function typeNameFromGraphQLType(context, type, bareTypeName, isOptional) {
+export function typeNameFromGraphQLType(context: LegacyCompilerContext, type: GraphQLType, bareTypeName?: string, isOptional?: boolean, isInputObject?: boolean): string {
   if (type instanceof GraphQLNonNull) {
     return typeNameFromGraphQLType(context, type.ofType, bareTypeName, isOptional || false)
   } else if (isOptional === undefined) {
@@ -55,9 +47,9 @@ export function typeNameFromGraphQLType(context, type, bareTypeName, isOptional)
     typeName = bareTypeName || type.name;
   }
 
-  return isOptional ? `Option[${typeName}]` : typeName;
+  return isOptional ? (isInputObject ? `scala.scalajs.js.UndefOr[${typeName}]` : `Option[${typeName}]`) : typeName;
 }
 
-function typeNameForScalarType(context, type) {
-  return builtInScalarMap[type.name] || (context.passthroughCustomScalars ? context.customScalarsPrefix + type.name: GraphQLString)
+function typeNameForScalarType(context: LegacyCompilerContext, type: GraphQLScalarType): string {
+  return builtInScalarMap[type.name] || (context.options.passthroughCustomScalars ? context.options.customScalarsPrefix + type.name : GraphQLString.name)
 }
diff --git a/src/scala/values.js b/src/scala/values.js
deleted file mode 100644
index 0e24f9f4..00000000
--- a/src/scala/values.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import {
-  join,
-  wrap,
-} from '../utilities/printing';
-
-export function escapedString(string) {
-  return string.replace(/"/g, '\\"');
-}
-
-export function multilineString(context, string) {
-  const lines = string.split('\n');
-  lines.forEach((line, index) => {
-    const isLastLine = index != lines.length - 1;
-    context.printOnNewline(`"${escapedString(line)}"` + (isLastLine ? ' +' : ''));
-  });
-}
-
-export function dictionaryLiteralForFieldArguments(args) {
-  function expressionFromValue(value) {
-    if (value.kind === 'Variable') {
-      return `Variable("${value.variableName}")`;
-    } else if (Array.isArray(value)) {
-      return wrap('[', join(value.map(expressionFromValue), ', '), ']');
-    } else if (typeof value === 'object') {
-      return wrap('[', join(Object.entries(value).map(([key, value]) => {
-        return `"${key}": ${expressionFromValue(value)}`;
-      }), ', ') || ':', ']');
-    } else {
-      return JSON.stringify(value);
-    }
-  }
-
-  return wrap('[', join(args.map(arg => {
-    return `"${arg.name}": ${expressionFromValue(arg.value)}`;
-  }), ', ') || ':', ']');
-}
diff --git a/src/scala/values.ts b/src/scala/values.ts
new file mode 100644
index 00000000..fd69513a
--- /dev/null
+++ b/src/scala/values.ts
@@ -0,0 +1,14 @@
+import { LegacyCompilerContext } from '../compiler/legacyIR';
+import CodeGenerator from '../utilities/CodeGenerator';
+
+export function escapedString(string: string) {
+  return string.replace(/"/g, '\\"');
+}
+
+export function multilineString(generator: CodeGenerator<LegacyCompilerContext, any>, string: string) {
+  const lines = string.split('\n');
+  lines.forEach((line, index) => {
+    const isLastLine = index != lines.length - 1;
+    generator.printOnNewline(`"${escapedString(line)}"` + (isLastLine ? ' +' : ''));
+  });
+}
diff --git a/src/swift/codeGeneration.ts b/src/swift/codeGeneration.ts
index 86c76ef1..634cb539 100644
--- a/src/swift/codeGeneration.ts
+++ b/src/swift/codeGeneration.ts
@@ -148,7 +148,7 @@ export class SwiftAPIGenerator extends SwiftGenerator<CompilerContext> {
       },
       () => {
         if (source) {
-          this.printOnNewline('public static let operationString =');
+          this.printOnNewline('public let operationDefinition =');
           this.withIndent(() => {
             this.multilineString(source);
           });
@@ -163,14 +163,14 @@ export class SwiftAPIGenerator extends SwiftGenerator<CompilerContext> {
           const { operationId } = generateOperationId(operation, this.context.fragments, fragmentsReferenced);
           operation.operationId = operationId;
           this.printNewlineIfNeeded();
-          this.printOnNewline(`public static let operationIdentifier: String? = "${operationId}"`);
+          this.printOnNewline(`public let operationIdentifier: String? = "${operationId}"`);
         }
 
         if (fragmentsReferenced.size > 0) {
           this.printNewlineIfNeeded();
-          this.printOnNewline('public static var requestString: String { return operationString');
+          this.printOnNewline('public var queryDocument: String { return operationDefinition');
           fragmentsReferenced.forEach(fragmentName => {
-            this.print(`.appending(${this.helpers.structNameForFragmentName(fragmentName)}.fragmentString)`);
+            this.print(`.appending(${this.helpers.structNameForFragmentName(fragmentName)}.fragmentDefinition)`);
           });
           this.print(' }');
         }
@@ -226,7 +226,7 @@ export class SwiftAPIGenerator extends SwiftGenerator<CompilerContext> {
       },
       () => {
         if (source) {
-          this.printOnNewline('public static let fragmentString =');
+          this.printOnNewline('public static let fragmentDefinition =');
           this.withIndent(() => {
             this.multilineString(source);
           });
@@ -310,15 +310,12 @@ export class SwiftAPIGenerator extends SwiftGenerator<CompilerContext> {
 
       this.printNewlineIfNeeded();
 
-      this.propertyDeclaration({
-        propertyName: 'snapshot',
-        typeName: 'Snapshot'
-      });
+      this.printOnNewline(`public private(set) var resultMap: ResultMap`);
 
       this.printNewlineIfNeeded();
-      this.printOnNewline('public init(snapshot: Snapshot)');
+      this.printOnNewline('public init(unsafeResultMap: ResultMap)');
       this.withinBlock(() => {
-        this.printOnNewline(`self.snapshot = snapshot`);
+        this.printOnNewline(`self.resultMap = unsafeResultMap`);
       });
 
       if (typeCase) {
@@ -348,11 +345,11 @@ export class SwiftAPIGenerator extends SwiftGenerator<CompilerContext> {
         this.withinBlock(() => {
           this.printOnNewline('get');
           this.withinBlock(() => {
-            this.printOnNewline(`return Fragments(snapshot: snapshot)`);
+            this.printOnNewline(`return Fragments(unsafeResultMap: resultMap)`);
           });
           this.printOnNewline('set');
           this.withinBlock(() => {
-            this.printOnNewline(`snapshot += newValue.snapshot`);
+            this.printOnNewline(`resultMap += newValue.resultMap`);
           });
         });
 
@@ -361,9 +358,12 @@ export class SwiftAPIGenerator extends SwiftGenerator<CompilerContext> {
             structName: 'Fragments'
           },
           () => {
-            this.propertyDeclaration({
-              propertyName: 'snapshot',
-              typeName: 'Snapshot'
+            this.printOnNewline(`public private(set) var resultMap: ResultMap`);
+
+            this.printNewlineIfNeeded();
+            this.printOnNewline('public init(unsafeResultMap: ResultMap)');
+            this.withinBlock(() => {
+              this.printOnNewline(`self.resultMap = unsafeResultMap`);
             });
 
             for (const fragmentSpread of fragmentSpreads) {
@@ -376,18 +376,18 @@ export class SwiftAPIGenerator extends SwiftGenerator<CompilerContext> {
                 this.withinBlock(() => {
                   if (isConditional) {
                     this.printOnNewline(
-                      `if !${structName}.possibleTypes.contains(snapshot["__typename"]! as! String) { return nil }`
+                      `if !${structName}.possibleTypes.contains(resultMap["__typename"]! as! String) { return nil }`
                     );
                   }
-                  this.printOnNewline(`return ${structName}(snapshot: snapshot)`);
+                  this.printOnNewline(`return ${structName}(unsafeResultMap: resultMap)`);
                 });
                 this.printOnNewline('set');
                 this.withinBlock(() => {
                   if (isConditional) {
                     this.printOnNewline(`guard let newValue = newValue else { return }`);
-                    this.printOnNewline(`snapshot += newValue.snapshot`);
+                    this.printOnNewline(`resultMap += newValue.resultMap`);
                   } else {
-                    this.printOnNewline(`snapshot += newValue.snapshot`);
+                    this.printOnNewline(`resultMap += newValue.resultMap`);
                   }
                 });
               });
@@ -441,7 +441,7 @@ export class SwiftAPIGenerator extends SwiftGenerator<CompilerContext> {
       this.withinBlock(() => {
         this.printOnNewline(
           wrap(
-            `self.init(snapshot: [`,
+            `self.init(unsafeResultMap: [`,
             join(
               [
                 `"__typename": "${variant.possibleTypes[0]}"`,
@@ -477,7 +477,7 @@ export class SwiftAPIGenerator extends SwiftGenerator<CompilerContext> {
         this.withinBlock(() => {
           this.printOnNewline(
             wrap(
-              `return ${structName}(snapshot: [`,
+              `return ${structName}(unsafeResultMap: [`,
               join(
                 [`"__typename": "${possibleType}"`, ...properties.map(this.propertyAssignmentForField, this)],
                 ', '
@@ -490,21 +490,23 @@ export class SwiftAPIGenerator extends SwiftGenerator<CompilerContext> {
     }
   }
 
-  propertyAssignmentForField(field: Field & Property & Struct) {
-    const { responseKey, propertyName, type, structName } = field;
+  propertyAssignmentForField(field: { responseKey: string; propertyName: string; type: GraphQLType, isConditional?: boolean, structName?: string }) {
+    const { responseKey, propertyName, type, isConditional, structName } = field;
     const valueExpression = isCompositeType(getNamedType(type))
       ? this.helpers.mapExpressionForType(
           type,
-          identifier => `${identifier}.snapshot`,
+          isConditional,
+          expression => `${expression}.resultMap`,
           escapeIdentifierIfNeeded(propertyName),
-          structName
+          structName!,
+          'ResultMap'
         )
       : escapeIdentifierIfNeeded(propertyName);
     return `"${responseKey}": ${valueExpression}`;
   }
 
   propertyDeclarationForField(field: Field & Property) {
-    const { responseKey, propertyName, typeName, type, isOptional } = field;
+    const { responseKey, propertyName, typeName, type, isOptional, isConditional } = field;
 
     const unmodifiedFieldType = getNamedType(type);
 
@@ -521,65 +523,68 @@ export class SwiftAPIGenerator extends SwiftGenerator<CompilerContext> {
         if (isList(type)) {
           this.printOnNewline('get');
           this.withinBlock(() => {
-            const snapshotTypeName = this.helpers.typeNameFromGraphQLType(type, 'Snapshot', false);
-            let identifier;
+            const resultMapTypeName = this.helpers.typeNameFromGraphQLType(type, 'ResultMap', false);
+            let expression;
             if (isOptional) {
-              identifier = `(snapshot["${responseKey}"] as? ${snapshotTypeName})`;
+              expression = `(resultMap["${responseKey}"] as? ${resultMapTypeName})`;
             } else {
-              identifier = `(snapshot["${responseKey}"] as! ${snapshotTypeName})`;
+              expression = `(resultMap["${responseKey}"] as! ${resultMapTypeName})`;
             }
-            let getter = 'return ' + this.helpers.mapExpressionForType(
+            this.printOnNewline(`return ${this.helpers.mapExpressionForType(
               type,
-              identifier => `${structName}(snapshot: ${identifier})`,
-							identifier,
-							'Snapshot'
-            );
-            this.printOnNewline(getter);
+              isConditional,
+              expression => `${structName}(unsafeResultMap: ${expression})`,
+              expression,
+              'ResultMap',
+              structName
+            )}`);
           });
           this.printOnNewline('set');
           this.withinBlock(() => {
             let newValueExpression = this.helpers.mapExpressionForType(
               type,
-              identifier => `${identifier}.snapshot`,
+              isConditional,
+              expression => `${expression}.resultMap`,
               'newValue',
-              structName
+              structName,
+              'ResultMap'
             );
-            this.printOnNewline(`snapshot.updateValue(${newValueExpression}, forKey: "${responseKey}")`);
+            this.printOnNewline(`resultMap.updateValue(${newValueExpression}, forKey: "${responseKey}")`);
           });
         } else {
           this.printOnNewline('get');
           this.withinBlock(() => {
             if (isOptional) {
               this.printOnNewline(
-                `return (snapshot["${responseKey}"] as? Snapshot).flatMap { ${structName}(snapshot: $0) }`
+                `return (resultMap["${responseKey}"] as? ResultMap).flatMap { ${structName}(unsafeResultMap: $0) }`
               );
             } else {
-              this.printOnNewline(`return ${structName}(snapshot: snapshot["${responseKey}"]! as! Snapshot)`);
+              this.printOnNewline(`return ${structName}(unsafeResultMap: resultMap["${responseKey}"]! as! ResultMap)`);
             }
           });
           this.printOnNewline('set');
           this.withinBlock(() => {
             let newValueExpression;
             if (isOptional) {
-              newValueExpression = 'newValue?.snapshot';
+              newValueExpression = 'newValue?.resultMap';
             } else {
-              newValueExpression = 'newValue.snapshot';
+              newValueExpression = 'newValue.resultMap';
             }
-            this.printOnNewline(`snapshot.updateValue(${newValueExpression}, forKey: "${responseKey}")`);
+            this.printOnNewline(`resultMap.updateValue(${newValueExpression}, forKey: "${responseKey}")`);
           });
         }
       } else {
         this.printOnNewline('get');
         this.withinBlock(() => {
           if (isOptional) {
-            this.printOnNewline(`return snapshot["${responseKey}"] as? ${typeName.slice(0, -1)}`);
+            this.printOnNewline(`return resultMap["${responseKey}"] as? ${typeName.slice(0, -1)}`);
           } else {
-            this.printOnNewline(`return snapshot["${responseKey}"]! as! ${typeName}`);
+            this.printOnNewline(`return resultMap["${responseKey}"]! as! ${typeName}`);
           }
         });
         this.printOnNewline('set');
         this.withinBlock(() => {
-          this.printOnNewline(`snapshot.updateValue(newValue, forKey: "${responseKey}")`);
+          this.printOnNewline(`resultMap.updateValue(newValue, forKey: "${responseKey}")`);
         });
       }
     });
@@ -594,12 +599,12 @@ export class SwiftAPIGenerator extends SwiftGenerator<CompilerContext> {
       this.printOnNewline('get');
       this.withinBlock(() => {
         this.printOnNewline(`if !${structName}.possibleTypes.contains(__typename) { return nil }`);
-        this.printOnNewline(`return ${structName}(snapshot: snapshot)`);
+        this.printOnNewline(`return ${structName}(unsafeResultMap: resultMap)`);
       });
       this.printOnNewline('set');
       this.withinBlock(() => {
         this.printOnNewline(`guard let newValue = newValue else { return }`);
-        this.printOnNewline(`snapshot = newValue.snapshot`);
+        this.printOnNewline(`resultMap = newValue.resultMap`);
       });
     });
   }
@@ -753,7 +758,7 @@ export class SwiftAPIGenerator extends SwiftGenerator<CompilerContext> {
         );
       });
       this.comment('Auto generated constant for unknown enum values');
-      this.printOnNewline('case unknown(RawValue)');
+      this.printOnNewline('case __unknown(RawValue)');
 
       this.printNewlineIfNeeded();
       this.printOnNewline('public init?(rawValue: RawValue)');
@@ -765,7 +770,7 @@ export class SwiftAPIGenerator extends SwiftGenerator<CompilerContext> {
               `case "${value.value}": self = ${escapeIdentifierIfNeeded(this.helpers.enumDotCaseName(value.name))}`
             );
           });
-          this.printOnNewline(`default: self = .unknown(rawValue)`);
+          this.printOnNewline(`default: self = .__unknown(rawValue)`);
         });
       });
 
@@ -779,7 +784,7 @@ export class SwiftAPIGenerator extends SwiftGenerator<CompilerContext> {
               `case ${escapeIdentifierIfNeeded(this.helpers.enumDotCaseName(value.name))}: return "${value.value}"`
             );
           });
-          this.printOnNewline(`case .unknown(let value): return value`);
+          this.printOnNewline(`case .__unknown(let value): return value`);
         });
       });
 
@@ -795,7 +800,7 @@ export class SwiftAPIGenerator extends SwiftGenerator<CompilerContext> {
               `case ${tuple}: return true`
             );
           });
-          this.printOnNewline(`case (.unknown(let lhsValue), .unknown(let rhsValue)): return lhsValue == rhsValue`);
+          this.printOnNewline(`case (.__unknown(let lhsValue), .__unknown(let rhsValue)): return lhsValue == rhsValue`);
           this.printOnNewline(`default: return false`);
         });
       });
@@ -811,7 +816,7 @@ export class SwiftAPIGenerator extends SwiftGenerator<CompilerContext> {
 
     properties.forEach(property => {
       if (property.isOptional) {
-        property.typeName = `Optional<${property.typeName}>`;
+        property.typeName = `Swift.Optional<${property.typeName}>`;
       }
     });
 
@@ -841,18 +846,18 @@ export class SwiftAPIGenerator extends SwiftGenerator<CompilerContext> {
         );
       });
 
-      for (const { propertyName, typeName, description } of properties) {
+      for (const { name, propertyName, typeName, description } of properties) {
         this.printNewlineIfNeeded();
         this.comment(description);
         this.printOnNewline(`public var ${escapeIdentifierIfNeeded(propertyName)}: ${typeName}`);
         this.withinBlock(() => {
           this.printOnNewline('get');
           this.withinBlock(() => {
-            this.printOnNewline(`return graphQLMap["${propertyName}"] as! ${typeName}`);
+            this.printOnNewline(`return graphQLMap["${name}"] as! ${typeName}`);
           });
           this.printOnNewline('set');
           this.withinBlock(() => {
-            this.printOnNewline(`graphQLMap.updateValue(newValue, forKey: "${propertyName}")`);
+            this.printOnNewline(`graphQLMap.updateValue(newValue, forKey: "${name}")`);
           });
         });
       }
diff --git a/src/swift/helpers.ts b/src/swift/helpers.ts
index fb678098..ddd3bc3d 100644
--- a/src/swift/helpers.ts
+++ b/src/swift/helpers.ts
@@ -38,7 +38,7 @@ export class Helpers {
 
   // Types
 
-  typeNameFromGraphQLType(type: GraphQLType, unmodifiedTypeName?: string, isOptional?: boolean, isSingular: boolean = false): string {
+  typeNameFromGraphQLType(type: GraphQLType, unmodifiedTypeName?: string, isOptional?: boolean): string {
     if (type instanceof GraphQLNonNull) {
       return this.typeNameFromGraphQLType(type.ofType, unmodifiedTypeName, false);
     } else if (isOptional === undefined) {
@@ -47,11 +47,7 @@ export class Helpers {
 
     let typeName;
     if (type instanceof GraphQLList) {
-      if (isSingular) {
-      	typeName = this.typeNameFromGraphQLType(type.ofType, unmodifiedTypeName);
-      } else {
-      	typeName = '[' + this.typeNameFromGraphQLType(type.ofType, unmodifiedTypeName) + ']';
-      }
+      typeName = '[' + this.typeNameFromGraphQLType(type.ofType, unmodifiedTypeName) + ']';
     } else if (type instanceof GraphQLScalarType) {
       typeName = this.typeNameForScalarType(type);
     } else {
@@ -234,38 +230,67 @@ export class Helpers {
 
   mapExpressionForType(
     type: GraphQLType,
-    expression: (identifier: string) => string,
-    identifier: string = '',
-    subtypeName: string
+    isConditional: boolean = false,
+    makeExpression: (expression: string) => string,
+    expression: string,
+    inputTypeName: string,
+    outputTypeName: string
   ): string {
     let isOptional;
     if (type instanceof GraphQLNonNull) {
-      isOptional = false;
+      isOptional = !!isConditional;
       type = type.ofType;
     } else {
       isOptional = true;
     }
+
     if (type instanceof GraphQLList) {
+      const elementType = type.ofType;
       if (isOptional) {
-        const prologue = subtypeName === undefined ? '' : `(i: ${subtypeName}) in `
-        const subidentifier = subtypeName === undefined ? '$0' : 'i'
-        return `${identifier}?.map({ ${prologue}${this.mapExpressionForType(
-          type.ofType,
-          expression,
-          subidentifier,
-          this.typeNameFromGraphQLType(type.ofType, undefined, false, true)
-        )} })`;
+        return `${expression}.flatMap { ${makeClosureSignature(
+          this.typeNameFromGraphQLType(type, inputTypeName, false),
+          this.typeNameFromGraphQLType(type, outputTypeName, false)
+        )} value.map { ${makeClosureSignature(
+          this.typeNameFromGraphQLType(elementType, inputTypeName),
+          this.typeNameFromGraphQLType(elementType, outputTypeName)
+        )} ${this.mapExpressionForType(
+          elementType,
+          undefined,
+          makeExpression,
+          'value',
+          inputTypeName,
+          outputTypeName
+        )} } }`;
       } else {
-        const prologue = subtypeName === undefined ? '' : `(j: ${subtypeName}) in `
-        const subidentifier = subtypeName === undefined ? '$0' : 'j'
-        return `${identifier}.map { ${prologue}${this.mapExpressionForType(type.ofType, expression, subidentifier, this.typeNameFromGraphQLType(type, undefined, false, true))} }`;
+        return `${expression}.map { ${makeClosureSignature(
+          this.typeNameFromGraphQLType(elementType, inputTypeName),
+          this.typeNameFromGraphQLType(elementType, outputTypeName)
+        )} ${this.mapExpressionForType(
+          elementType,
+          undefined,
+          makeExpression,
+          'value',
+          inputTypeName,
+          outputTypeName
+        )} }`;
       }
     } else if (isOptional) {
-      const prologue = subtypeName === undefined ? '' : `(j: ${subtypeName}) in `
-      const subidentifier = subtypeName === undefined ? '$0' : 'j'
-      return `${identifier}.flatMap { ${prologue}${expression(subidentifier)} }`;
+      return `${expression}.flatMap { ${makeClosureSignature(
+        this.typeNameFromGraphQLType(type, inputTypeName, false),
+        this.typeNameFromGraphQLType(type, outputTypeName, false)
+      )} ${makeExpression('value')} }`;
     } else {
-      return expression(identifier);
+      return makeExpression(expression);
     }
   }
 }
+
+function makeClosureSignature(parameterTypeName: string, returnTypeName?: string) {
+  let closureSignature = `(value: ${parameterTypeName})`;
+
+  if (returnTypeName) {
+    closureSignature += ` -> ${returnTypeName}`;
+  }
+  closureSignature += ' in';
+  return closureSignature;
+}
diff --git a/src/typescript/codeGeneration.ts b/src/typescript/codeGeneration.ts
index afe02aef..b12bea4e 100644
--- a/src/typescript/codeGeneration.ts
+++ b/src/typescript/codeGeneration.ts
@@ -14,10 +14,6 @@ import {
   GraphQLObjectType
 } from 'graphql'
 
-import {
-  wrap
-} from '../utilities/printing';
-
 import {
   sortEnumValues
 } from '../utilities/graphql';
@@ -70,25 +66,11 @@ function enumerationDeclaration(generator: CodeGenerator, type: GraphQLEnumType)
   const values = type.getValues();
 
   generator.printNewlineIfNeeded();
-  if (description) {
-    description.split('\n')
-      .forEach(line => {
-        generator.printOnNewline(`// ${line.trim()}`);
-      })
-  }
+  printDocComment(generator, description);
   generator.printOnNewline(`export enum ${name} {`);
   sortEnumValues(values).forEach((value) => {
-    if (!value.description || value.description.indexOf('\n') === -1) {
-      generator.printOnNewline(`  ${value.value} = "${value.value}",${wrap(' // ', value.description)}`)
-    } else {
-      if (value.description) {
-        value.description.split('\n')
-          .forEach((line: string) => {
-            generator.printOnNewline(`  // ${line.trim()}`);
-          })
-      }
-      generator.printOnNewline(`  ${value.value} = "${value.value}",`)
-    }
+    printDocComment(generator, value.description, 1);
+    generator.printOnNewline(`  ${value.value} = "${value.value}",`)
   });
   generator.printOnNewline(`}`);
   generator.printNewline();
@@ -431,3 +413,18 @@ function getPossibleTypeNames(generator: CodeGenerator<LegacyCompilerContext>, p
 
   return [];
 }
+
+export function printDocComment(generator: CodeGenerator, description?: string, depth: number = 0): void {
+  if (!description) {
+    return;
+  }
+
+  const leadingSpace = ' '.repeat(2 * depth);
+
+  generator.printOnNewline(`${leadingSpace}/**`);
+  description.split('\n')
+    .forEach(line => {
+      generator.printOnNewline(`${leadingSpace} * ${line.trim()}`);
+    });
+  generator.printOnNewline(`${leadingSpace} */`);
+}
diff --git a/src/typescript/language.ts b/src/typescript/language.ts
index b82b8084..df381599 100644
--- a/src/typescript/language.ts
+++ b/src/typescript/language.ts
@@ -1,6 +1,6 @@
 import { LegacyInlineFragment } from '../compiler/legacyIR';
 
-import { propertyDeclarations } from './codeGeneration';
+import { propertyDeclarations, printDocComment } from './codeGeneration';
 import { typeNameFromGraphQLType } from './types';
 
 import CodeGenerator from "../utilities/CodeGenerator";
@@ -59,12 +59,7 @@ export function propertyDeclaration(generator: CodeGenerator, {
 }: Property, closure?: () => void) {
   const name = fieldName || propertyName;
 
-  if (description) {
-    description.split('\n')
-      .forEach(line => {
-        generator.printOnNewline(`// ${line.trim()}`);
-      })
-  }
+  printDocComment(generator, description);
 
   if (closure) {
     generator.printOnNewline(name);
@@ -111,12 +106,7 @@ export function propertySetsDeclaration(generator: CodeGenerator, property: Prop
   } = property;
   const name = fieldName || propertyName;
 
-  if (description) {
-    description.split('\n')
-      .forEach(line => {
-        generator.printOnNewline(`// ${line.trim()}`);
-      })
-  }
+  printDocComment(generator, description);
 
   if (!standalone) {
     generator.printOnNewline(`${name}: `);


Test patch:
diff --git a/test/__snapshots__/jsonOutput.ts.snap b/test/__snapshots__/jsonOutput.ts.snap
index 762482a1..46382794 100644
--- a/test/__snapshots__/jsonOutput.ts.snap
+++ b/test/__snapshots__/jsonOutput.ts.snap
@@ -30,14 +30,16 @@ exports[`JSON output should generate JSON output for a mutation with an enum and
 							\\"value\\": {
 								\\"kind\\": \\"Variable\\",
 								\\"variableName\\": \\"episode\\"
-							}
+							},
+							\\"type\\": \\"Episode\\"
 						},
 						{
 							\\"name\\": \\"review\\",
 							\\"value\\": {
 								\\"kind\\": \\"Variable\\",
 								\\"variableName\\": \\"review\\"
-							}
+							},
+							\\"type\\": \\"ReviewInput!\\"
 						}
 					],
 					\\"isConditional\\": false,
@@ -412,7 +414,8 @@ exports[`JSON output should generate JSON output for a query with an enum variab
 							\\"value\\": {
 								\\"kind\\": \\"Variable\\",
 								\\"variableName\\": \\"episode\\"
-							}
+							},
+							\\"type\\": \\"Episode\\"
 						}
 					],
 					\\"isConditional\\": false,
@@ -502,7 +505,8 @@ exports[`JSON output should generate JSON output for a subscription 1`] = `
 							\\"value\\": {
 								\\"kind\\": \\"Variable\\",
 								\\"variableName\\": \\"repoFullName\\"
-							}
+							},
+							\\"type\\": \\"String!\\"
 						}
 					],
 					\\"isConditional\\": false,
@@ -571,7 +575,8 @@ exports[`JSON output should generate JSON output for an input object type with d
 							\\"value\\": {
 								\\"kind\\": \\"Variable\\",
 								\\"variableName\\": \\"input\\"
-							}
+							},
+							\\"type\\": \\"ComplexInput!\\"
 						}
 					],
 					\\"isConditional\\": false,
diff --git a/test/compiler/legacyIR.js b/test/compiler/legacyIR.js
index 46894d49..ee91ebd3 100644
--- a/test/compiler/legacyIR.js
+++ b/test/compiler/legacyIR.js
@@ -159,7 +159,7 @@ describe('Compiling query documents to the legacy IR', () => {
     const { operations } = compileToLegacyIR(schema, document);
 
     expect(operations['HeroName'].fields[0].args)
-      .toEqual([{ name: "episode", value: "EMPIRE" }]);
+      .toEqual([{ name: "episode", value: "EMPIRE", type: schema.getType("Episode") }]);
   });
 
   it(`should include isConditional if a field has skip or include directives with variables`, () => {
diff --git a/test/compiler/visitors/typeCase.ts b/test/compiler/visitors/typeCase.ts
index 80957ec2..2333767a 100644
--- a/test/compiler/visitors/typeCase.ts
+++ b/test/compiler/visitors/typeCase.ts
@@ -22,12 +22,12 @@ export const animalSchema = buildSchema(`
     bodyTemperature: Int!
   }
 
-  type Cat implements Pet, WarmBlooded {
+  type Cat implements Pet & WarmBlooded {
     name: String!
     bodyTemperature: Int!
   }
 
-  type Bird implements Pet, WarmBlooded {
+  type Bird implements Pet & WarmBlooded {
     name: String!
     bodyTemperature: Int!
   }
diff --git a/test/fixtures/misc/schema.json b/test/fixtures/misc/schema.json
index 90e8d21d..109612af 100644
--- a/test/fixtures/misc/schema.json
+++ b/test/fixtures/misc/schema.json
@@ -191,7 +191,7 @@
             },
             {
               "name": "multiLine",
-              "description": "This is a multi-line\ncomment.",
+              "description": "This is a\nmulti-line\ncomment.",
               "args": [],
               "type": {
                 "kind": "SCALAR",
@@ -235,7 +235,7 @@
             },
             {
               "name": "second",
-              "description": "This is a multi-line\ncomment.",
+              "description": "This is a\nmulti-line\ncomment.",
               "isDeprecated": false,
               "deprecationReason": null
             }
@@ -1382,4 +1382,4 @@
       ]
     }
   }
-}
\ No newline at end of file
+}
diff --git a/test/flow/__snapshots__/codeGeneration.js.snap b/test/flow/__snapshots__/codeGeneration.js.snap
index 056cb715..657326c2 100644
--- a/test/flow/__snapshots__/codeGeneration.js.snap
+++ b/test/flow/__snapshots__/codeGeneration.js.snap
@@ -432,7 +432,8 @@ exports[`Flow code generation #generateSource() should handle comments in enums
 
 export type EnumCommentTestCase =
   \\"first\\" | // This is a single-line comment
-  // This is a multi-line
+  // This is a
+  // multi-line
   // comment.
   \\"second\\";
 
@@ -472,7 +473,8 @@ exports[`Flow code generation #generateSource() should handle multi-line comment
 export type CustomScalarQuery = {|
   commentTest: ? {|
     __typename: \\"CommentTest\\",
-    // This is a multi-line
+    // This is a
+    // multi-line
     // comment.
     multiLine: ?string,
   |},
diff --git a/test/scala/__snapshots__/codeGeneration.js.snap b/test/scala/__snapshots__/codeGeneration.js.snap
index 3c246851..072b70dd 100644
--- a/test/scala/__snapshots__/codeGeneration.js.snap
+++ b/test/scala/__snapshots__/codeGeneration.js.snap
@@ -1,7 +1,7 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
 exports[`Scala code generation #caseClassDeclarationForFragment() should generate a caseClass declaration for a fragment that includes a fragment spread 1`] = `
-"case class HeroDetails(name: String, appearsIn: Seq[Option[String]]) extends me.shadaj.slinky.core.WithRaw {
+"case class HeroDetails(name: String, appearsIn: Seq[Option[String]]) extends slinky.readwrite.WithRaw {
 }
 
 object HeroDetails {
@@ -30,11 +30,19 @@ object DroidDetails {
 `;
 
 exports[`Scala code generation #caseClassDeclarationForFragment() should generate a caseClass declaration for a fragment with a subselection 1`] = `
-"case class HeroDetails(name: String, friends: Option[Seq[Option[Friend]]]) extends me.shadaj.slinky.core.WithRaw {
+"case class HeroDetails(name: String, friends: Option[Seq[Option[HeroDetails.Friend]]]) extends slinky.readwrite.WithRaw {
 }
 
 object HeroDetails {
   val possibleTypes = scala.collection.Set(\\"Human\\", \\"Droid\\")
+
+
+  case class Friend(name: String) extends slinky.readwrite.WithRaw {
+  }
+
+  object Friend {
+    val possibleTypes = scala.collection.Set(\\"Human\\", \\"Droid\\")
+  }
   val fragmentString =
     \\"fragment HeroDetails on Character {\\" +
     \\"  name\\" +
@@ -42,19 +50,11 @@ object HeroDetails {
     \\"    name\\" +
     \\"  }\\" +
     \\"}\\"
-}
-
-
-case class Friend(name: String) extends me.shadaj.slinky.core.WithRaw {
-}
-
-object Friend {
-  val possibleTypes = scala.collection.Set(\\"Human\\", \\"Droid\\")
 }"
 `;
 
 exports[`Scala code generation #caseClassDeclarationForFragment() should generate a caseClass declaration for a fragment with an abstract type condition 1`] = `
-"case class HeroDetails(name: String, appearsIn: Seq[Option[String]]) extends me.shadaj.slinky.core.WithRaw {
+"case class HeroDetails(name: String, appearsIn: Seq[Option[String]]) extends slinky.readwrite.WithRaw {
 }
 
 object HeroDetails {
@@ -68,7 +68,7 @@ object HeroDetails {
 `;
 
 exports[`Scala code generation #caseClassDeclarationForSelectionSet() should escape reserved keywords in a caseClass declaration for a selection set 1`] = `
-"case class Hero(private: Option[String]) extends me.shadaj.slinky.core.WithRaw {
+"case class Hero(private: Option[String]) extends slinky.readwrite.WithRaw {
 }
 
 object Hero {
@@ -77,9 +77,9 @@ object Hero {
 `;
 
 exports[`Scala code generation #caseClassDeclarationForSelectionSet() should generate a caseClass declaration for a fragment spread nested in an inline fragment 1`] = `
-"case class Hero() extends me.shadaj.slinky.core.WithRaw {
+"case class Hero() extends slinky.readwrite.WithRaw {
   def asDroid: Option[AsDroid] = {
-    if (AsDroid.possibleTypes.contains(this.raw.__typename.asInstanceOf[String])) Some(implicitly[me.shadaj.slinky.core.Reader[AsDroid]].read(this.raw)) else None
+    if (AsDroid.possibleTypes.contains(this.raw.__typename.asInstanceOf[String])) Some(implicitly[slinky.readwrite.Reader[AsDroid]].read(this.raw)) else None
   }
 }
 
@@ -98,7 +98,7 @@ object Hero {
 `;
 
 exports[`Scala code generation #caseClassDeclarationForSelectionSet() should generate a caseClass declaration for a selection set 1`] = `
-"case class Hero(name: Option[String]) extends me.shadaj.slinky.core.WithRaw {
+"case class Hero(name: Option[String]) extends slinky.readwrite.WithRaw {
 }
 
 object Hero {
@@ -107,7 +107,7 @@ object Hero {
 `;
 
 exports[`Scala code generation #caseClassDeclarationForSelectionSet() should generate a caseClass declaration for a selection set with a fragment spread that matches the parent type 1`] = `
-"case class Hero(name: Option[String]) extends me.shadaj.slinky.core.WithRaw {
+"case class Hero(name: Option[String]) extends slinky.readwrite.WithRaw {
 }
 
 object Hero {
@@ -117,9 +117,9 @@ object Hero {
 `;
 
 exports[`Scala code generation #caseClassDeclarationForSelectionSet() should generate a caseClass declaration for a selection set with a fragment spread with a more specific type condition 1`] = `
-"case class Hero(name: Option[String]) extends me.shadaj.slinky.core.WithRaw {
+"case class Hero(name: Option[String]) extends slinky.readwrite.WithRaw {
   def asDroidDetails: Option[DroidDetails] = {
-    if (DroidDetails.possibleTypes.contains(this.raw.__typename.asInstanceOf[String])) Some(implicitly[me.shadaj.slinky.core.Reader[DroidDetails]].read(this.raw)) else None
+    if (DroidDetails.possibleTypes.contains(this.raw.__typename.asInstanceOf[String])) Some(implicitly[slinky.readwrite.Reader[DroidDetails]].read(this.raw)) else None
   }
 }
 
@@ -129,9 +129,9 @@ object Hero {
 `;
 
 exports[`Scala code generation #caseClassDeclarationForSelectionSet() should generate a caseClass declaration for a selection set with an inline fragment 1`] = `
-"case class Hero(name: String) extends me.shadaj.slinky.core.WithRaw {
+"case class Hero(name: String) extends slinky.readwrite.WithRaw {
   def asDroid: Option[AsDroid] = {
-    if (AsDroid.possibleTypes.contains(this.raw.__typename.asInstanceOf[String])) Some(implicitly[me.shadaj.slinky.core.Reader[AsDroid]].read(this.raw)) else None
+    if (AsDroid.possibleTypes.contains(this.raw.__typename.asInstanceOf[String])) Some(implicitly[slinky.readwrite.Reader[AsDroid]].read(this.raw)) else None
   }
 }
 
@@ -149,19 +149,19 @@ object Hero {
 `;
 
 exports[`Scala code generation #caseClassDeclarationForSelectionSet() should generate a nested caseClass declaration for a selection set with subselections 1`] = `
-"case class Hero(friends: Option[Seq[Option[Friend]]]) extends me.shadaj.slinky.core.WithRaw {
+"case class Hero(friends: Option[Seq[Option[Hero.Friend]]]) extends slinky.readwrite.WithRaw {
 }
 
 object Hero {
   val possibleTypes = scala.collection.Set(\\"Human\\", \\"Droid\\")
-}
 
 
-case class Friend(name: Option[String]) extends me.shadaj.slinky.core.WithRaw {
-}
+  case class Friend(name: Option[String]) extends slinky.readwrite.WithRaw {
+  }
 
-object Friend {
-  val possibleTypes = scala.collection.Set(\\"Human\\", \\"Droid\\")
+  object Friend {
+    val possibleTypes = scala.collection.Set(\\"Human\\", \\"Droid\\")
+  }
 }"
 `;
 
@@ -180,18 +180,18 @@ exports[`Scala code generation #classDeclarationForOperation() should generate a
   case class Variables(episode: Option[String]) {
   }
 
-  case class Data(createReview: Option[CreateReview]) {
+  case class Data(createReview: Option[Data.CreateReview]) {
   }
 
   object Data {
     val possibleTypes = scala.collection.Set(\\"Mutation\\")
-  }
 
-  case class CreateReview(stars: Int, commentary: Option[String]) {
-  }
+    case class CreateReview(stars: Int, commentary: Option[String]) {
+    }
 
-  object CreateReview {
-    val possibleTypes = scala.collection.Set(\\"Review\\")
+    object CreateReview {
+      val possibleTypes = scala.collection.Set(\\"Review\\")
+    }
   }
 }"
 `;
@@ -212,31 +212,31 @@ exports[`Scala code generation #classDeclarationForOperation() should generate a
 
   type Variables = Unit
 
-  case class Data(hero: Option[Hero]) {
+  case class Data(hero: Option[Data.Hero]) {
   }
 
   object Data {
     val possibleTypes = scala.collection.Set(\\"Query\\")
-  }
 
 
-  case class Hero() extends me.shadaj.slinky.core.WithRaw {
-    def asDroid: Option[AsDroid] = {
-      if (AsDroid.possibleTypes.contains(this.raw.__typename.asInstanceOf[String])) Some(implicitly[me.shadaj.slinky.core.Reader[AsDroid]].read(this.raw)) else None
+    case class Hero() extends slinky.readwrite.WithRaw {
+      def asDroid: Option[AsDroid] = {
+        if (AsDroid.possibleTypes.contains(this.raw.__typename.asInstanceOf[String])) Some(implicitly[slinky.readwrite.Reader[AsDroid]].read(this.raw)) else None
+      }
     }
-  }
 
-  case class AsDroid(name: String) {
-  }
+    case class AsDroid(name: String) {
+    }
 
-  object AsDroid {
-    val possibleTypes = scala.collection.Set(\\"Droid\\")
-    implicit def toHero(a: AsDroid): Hero = Hero()
-    implicit def toHeroDetails(a: AsDroid): HeroDetails = HeroDetails(a.name)
-  }
+    object AsDroid {
+      val possibleTypes = scala.collection.Set(\\"Droid\\")
+      implicit def toHero(a: AsDroid): Hero = Hero()
+      implicit def toHeroDetails(a: AsDroid): HeroDetails = HeroDetails(a.name)
+    }
 
-  object Hero {
-    val possibleTypes = scala.collection.Set(\\"Human\\", \\"Droid\\")
+    object Hero {
+      val possibleTypes = scala.collection.Set(\\"Human\\", \\"Droid\\")
+    }
   }
 }"
 `;
@@ -255,34 +255,34 @@ exports[`Scala code generation #classDeclarationForOperation() should generate a
 
   type Variables = Unit
 
-  case class Data(hero: Option[Hero]) {
+  case class Data(hero: Option[Data.Hero]) {
   }
 
   object Data {
     val possibleTypes = scala.collection.Set(\\"Query\\")
-  }
 
 
-  case class Hero() extends me.shadaj.slinky.core.WithRaw {
-    def asDroid: Option[AsDroid] = {
-      if (AsDroid.possibleTypes.contains(this.raw.__typename.asInstanceOf[String])) Some(implicitly[me.shadaj.slinky.core.Reader[AsDroid]].read(this.raw)) else None
-    }
-    def asDroidDetails: Option[DroidDetails] = {
-      if (DroidDetails.possibleTypes.contains(this.raw.__typename.asInstanceOf[String])) Some(implicitly[me.shadaj.slinky.core.Reader[DroidDetails]].read(this.raw)) else None
+    case class Hero() extends slinky.readwrite.WithRaw {
+      def asDroid: Option[AsDroid] = {
+        if (AsDroid.possibleTypes.contains(this.raw.__typename.asInstanceOf[String])) Some(implicitly[slinky.readwrite.Reader[AsDroid]].read(this.raw)) else None
+      }
+      def asDroidDetails: Option[DroidDetails] = {
+        if (DroidDetails.possibleTypes.contains(this.raw.__typename.asInstanceOf[String])) Some(implicitly[slinky.readwrite.Reader[DroidDetails]].read(this.raw)) else None
+      }
     }
-  }
 
-  case class AsDroid(primaryFunction: Option[String]) {
-  }
+    case class AsDroid(primaryFunction: Option[String]) {
+    }
 
-  object AsDroid {
-    val possibleTypes = scala.collection.Set(\\"Droid\\")
-    implicit def toHero(a: AsDroid): Hero = Hero()
-    implicit def toDroidDetails(a: AsDroid): DroidDetails = DroidDetails(a.primaryFunction)
-  }
+    object AsDroid {
+      val possibleTypes = scala.collection.Set(\\"Droid\\")
+      implicit def toHero(a: AsDroid): Hero = Hero()
+      implicit def toDroidDetails(a: AsDroid): DroidDetails = DroidDetails(a.primaryFunction)
+    }
 
-  object Hero {
-    val possibleTypes = scala.collection.Set(\\"Human\\", \\"Droid\\")
+    object Hero {
+      val possibleTypes = scala.collection.Set(\\"Human\\", \\"Droid\\")
+    }
   }
 }"
 `;
@@ -301,20 +301,20 @@ exports[`Scala code generation #classDeclarationForOperation() should generate a
 
   type Variables = Unit
 
-  case class Data(hero: Option[Hero]) {
+  case class Data(hero: Option[Data.Hero]) {
   }
 
   object Data {
     val possibleTypes = scala.collection.Set(\\"Query\\")
-  }
 
 
-  case class Hero(name: String) extends me.shadaj.slinky.core.WithRaw {
-  }
+    case class Hero(name: String) extends slinky.readwrite.WithRaw {
+    }
 
-  object Hero {
-    val possibleTypes = scala.collection.Set(\\"Human\\", \\"Droid\\")
-    implicit def toHeroDetails(a: Hero): HeroDetails = HeroDetails(a.name)
+    object Hero {
+      val possibleTypes = scala.collection.Set(\\"Human\\", \\"Droid\\")
+      implicit def toHeroDetails(a: Hero): HeroDetails = HeroDetails(a.name)
+    }
   }
 }"
 `;
@@ -333,19 +333,19 @@ exports[`Scala code generation #classDeclarationForOperation() should generate a
   case class Variables(episode: Option[String]) {
   }
 
-  case class Data(hero: Option[Hero]) {
+  case class Data(hero: Option[Data.Hero]) {
   }
 
   object Data {
     val possibleTypes = scala.collection.Set(\\"Query\\")
-  }
 
 
-  case class Hero(name: String) extends me.shadaj.slinky.core.WithRaw {
-  }
+    case class Hero(name: String) extends slinky.readwrite.WithRaw {
+    }
 
-  object Hero {
-    val possibleTypes = scala.collection.Set(\\"Human\\", \\"Droid\\")
+    object Hero {
+      val possibleTypes = scala.collection.Set(\\"Human\\", \\"Droid\\")
+    }
   }
 }"
 `;
@@ -366,20 +366,20 @@ exports[`Scala code generation #classDeclarationForOperation() when generateOper
 
   type Variables = Unit
 
-  case class Data(hero: Option[Hero]) {
+  case class Data(hero: Option[Data.Hero]) {
   }
 
   object Data {
     val possibleTypes = scala.collection.Set(\\"Query\\")
-  }
 
 
-  case class Hero(name: String) extends me.shadaj.slinky.core.WithRaw {
-  }
+    case class Hero(name: String) extends slinky.readwrite.WithRaw {
+    }
 
-  object Hero {
-    val possibleTypes = scala.collection.Set(\\"Human\\", \\"Droid\\")
-    implicit def toHeroDetails(a: Hero): HeroDetails = HeroDetails(a.name)
+    object Hero {
+      val possibleTypes = scala.collection.Set(\\"Human\\", \\"Droid\\")
+      implicit def toHeroDetails(a: Hero): HeroDetails = HeroDetails(a.name)
+    }
   }
 }"
 `;
@@ -399,6 +399,61 @@ fragment HeroName on Character {
 }"
 `;
 
+exports[`Scala code generation #generateSource() should emit a package declaration when the namespace option is specified 1`] = `
+"//  This file was automatically generated and should not be edited.
+
+
+package hello.world
+
+/**
+ * The episodes in the Star Wars trilogy
+ */
+object Episode {
+  /**
+   * Star Wars Episode IV: A New Hope, released in 1977.
+   */
+  val newhope = \\"NEWHOPE\\"
+  /**
+   * Star Wars Episode V: The Empire Strikes Back, released in 1980.
+   */
+  val empire = \\"EMPIRE\\"
+  /**
+   * Star Wars Episode VI: Return of the Jedi, released in 1983.
+   */
+  val jedi = \\"JEDI\\"
+}
+
+
+object HeroNameQuery extends com.apollographql.scalajs.GraphQLQuery {
+  val operationString =
+    \\"query HeroName($episode: Episode) {\\" +
+    \\"  hero(episode: $episode) {\\" +
+    \\"    name\\" +
+    \\"  }\\" +
+    \\"}\\"
+  val operation = com.apollographql.scalajs.gql(operationString)
+
+
+  case class Variables(episode: Option[String]) {
+  }
+
+  case class Data(hero: Option[Data.Hero]) {
+  }
+
+  object Data {
+    val possibleTypes = scala.collection.Set(\\"Query\\")
+
+
+    case class Hero(name: String) extends slinky.readwrite.WithRaw {
+    }
+
+    object Hero {
+      val possibleTypes = scala.collection.Set(\\"Human\\", \\"Droid\\")
+    }
+  }
+}"
+`;
+
 exports[`Scala code generation #typeDeclarationForGraphQLType() should escape identifiers in cases of enum declaration for a GraphQLEnumType 1`] = `
 "object AlbumPrivacies {
   val public = \\"PUBLIC\\"
@@ -411,7 +466,7 @@ exports[`Scala code generation #typeDeclarationForGraphQLType() should generate
 "/**
  * The input object sent when someone is creating a new review
  */
-case class ReviewInput(stars: Int, commentary: Option[String], favoriteColor: Option[ColorInput]) {
+case class ReviewInput(stars: Int, commentary: scala.scalajs.js.UndefOr[String] = scala.scalajs.js.undefined, favoriteColor: scala.scalajs.js.UndefOr[ColorInput] = scala.scalajs.js.undefined) {
 }"
 `;
 
diff --git a/test/scala/codeGeneration.js b/test/scala/codeGeneration.js
index 1a4d4216..65b8f30d 100644
--- a/test/scala/codeGeneration.js
+++ b/test/scala/codeGeneration.js
@@ -13,16 +13,13 @@ import {
 } from 'graphql';
 
 import {
+  generateSource,
   classDeclarationForOperation,
   caseClassDeclarationForFragment,
   caseClassDeclarationForSelectionSet,
   typeDeclarationForGraphQLType,
 } from '../../src/scala/codeGeneration';
 
-import {
-  dictionaryLiteralForFieldArguments,
-} from '../../src/scala/values';
-
 import { loadSchema } from '../../src/loading';
 const schema = loadSchema(require.resolve('../fixtures/starwars/schema.json'));
 
@@ -51,7 +48,8 @@ describe('Scala code generation', function() {
     compileFromSource = (source, options = { generateOperationIds: false }) => {
       const document = parse(source);
       let context = compileToLegacyIR(schema, document);
-      options.generateOperationIds && Object.assign(context, { generateOperationIds: true, operationIdsMap: {} });
+      options.generateOperationIds && Object.assign(context.options, { generateOperationIds: true, operationIdsMap: {} });
+      options.namespace && Object.assign(context.options, { namespace: options.namespace });
       generator.context = context;
       return context;
     };
@@ -63,6 +61,20 @@ describe('Scala code generation', function() {
     resetGenerator();
   });
 
+  describe('#generateSource()', function() {
+    test(`should emit a package declaration when the namespace option is specified`, function() {
+      const context = compileFromSource(`
+        query HeroName($episode: Episode) {
+          hero(episode: $episode) {
+            name
+          }
+        }
+      `, { namespace: "hello.world" });
+
+      expect(generateSource(context)).toMatchSnapshot();
+    });
+  });
+
   describe('#classDeclarationForOperation()', function() {
     test(`should generate a class declaration for a query with variables`, function() {
       const { operations, fragments } = compileFromSource(`
@@ -504,26 +516,9 @@ describe('Scala code generation', function() {
     });
   });
 
-  describe('#dictionaryLiteralForFieldArguments()', function() {
-    test('should include expressions for input objects with variables', function() {
-      const { operations } = compileFromSource(`
-        mutation FieldArgumentsWithInputObjects($commentary: String!, $red: Int!) {
-          createReview(episode: JEDI, review: { stars: 2, commentary: $commentary, favorite_color: { red: $red, blue: 100, green: 50 } }) {
-            commentary
-          }
-        }
-      `);
-
-      const fieldArguments = operations['FieldArgumentsWithInputObjects'].fields[0].args;
-      const dictionaryLiteral = dictionaryLiteralForFieldArguments(fieldArguments);
-
-      expect(dictionaryLiteral).toBe('["episode": "JEDI", "review": ["stars": 2, "commentary": Variable("commentary"), "favorite_color": ["red": Variable("red"), "blue": 100, "green": 50]]]');
-    });
-  });
-
   describe('#typeDeclarationForGraphQLType()', function() {
     test('should generate an enum declaration for a GraphQLEnumType', function() {
-      const generator = new CodeGenerator();
+      const generator = new CodeGenerator({options: {}});
 
       typeDeclarationForGraphQLType(generator, schema.getType('Episode'));
 
@@ -531,7 +526,7 @@ describe('Scala code generation', function() {
     });
 
     test('should escape identifiers in cases of enum declaration for a GraphQLEnumType', function() {
-      const generator = new CodeGenerator();
+      const generator = new CodeGenerator({options: {}});
 
       const albumPrivaciesEnum = new GraphQLEnumType({
         name: 'AlbumPrivacies',
@@ -544,7 +539,7 @@ describe('Scala code generation', function() {
     });
 
     test('should generate a caseClass declaration for a GraphQLInputObjectType', function() {
-      const generator = new CodeGenerator();
+      const generator = new CodeGenerator({options: {}});
 
       typeDeclarationForGraphQLType(generator, schema.getType('ReviewInput'));
 
diff --git a/test/scala/types.js b/test/scala/types.js
index 0139cfea..68ce1bb4 100644
--- a/test/scala/types.js
+++ b/test/scala/types.js
@@ -21,63 +21,63 @@ import { typeNameFromGraphQLType } from '../../src/scala/types'
 describe('Scala code generation: Types', function() {
   describe('#typeNameFromGraphQLType()', function() {
     test('should return Option[String] for GraphQLString', function() {
-      expect(typeNameFromGraphQLType({}, GraphQLString)).toBe('Option[String]');
+      expect(typeNameFromGraphQLType({options:{}}, GraphQLString)).toBe('Option[String]');
     });
 
     test('should return String for GraphQLNonNull(GraphQLString)', function() {
-      expect(typeNameFromGraphQLType({}, new GraphQLNonNull(GraphQLString))).toBe('String');
+      expect(typeNameFromGraphQLType({options:{}}, new GraphQLNonNull(GraphQLString))).toBe('String');
     });
 
     test('should return Option[Seq[Option[String]]] for GraphQLList(GraphQLString)', function() {
-      expect(typeNameFromGraphQLType({}, new GraphQLList(GraphQLString))).toBe('Option[Seq[Option[String]]]');
+      expect(typeNameFromGraphQLType({options:{}}, new GraphQLList(GraphQLString))).toBe('Option[Seq[Option[String]]]');
     });
 
     test('should return Seq[String] for GraphQLNonNull(GraphQLList(GraphQLString))', function() {
-      expect(typeNameFromGraphQLType({}, new GraphQLNonNull(new GraphQLList(GraphQLString)))).toBe('Seq[Option[String]]');
+      expect(typeNameFromGraphQLType({options:{}}, new GraphQLNonNull(new GraphQLList(GraphQLString)))).toBe('Seq[Option[String]]');
     });
 
     test('should return Option[Seq[String]] for GraphQLList(GraphQLNonNull(GraphQLString))', function() {
-      expect(typeNameFromGraphQLType({}, new GraphQLList(new GraphQLNonNull(GraphQLString)))).toBe('Option[Seq[String]]');
+      expect(typeNameFromGraphQLType({options:{}}, new GraphQLList(new GraphQLNonNull(GraphQLString)))).toBe('Option[Seq[String]]');
     });
 
     test('should return Seq[String] for GraphQLNonNull(GraphQLList(GraphQLNonNull(GraphQLString)))', function() {
-      expect(typeNameFromGraphQLType({}, new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString))))).toBe('Seq[String]');
+      expect(typeNameFromGraphQLType({options:{}}, new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString))))).toBe('Seq[String]');
     });
 
     test('should return Option[Seq[Option[Seq[Option[String]]]]] for GraphQLList(GraphQLList(GraphQLString))', function() {
-      expect(typeNameFromGraphQLType({}, new GraphQLList(new GraphQLList(GraphQLString)))).toBe('Option[Seq[Option[Seq[Option[String]]]]]');
+      expect(typeNameFromGraphQLType({options:{}}, new GraphQLList(new GraphQLList(GraphQLString)))).toBe('Option[Seq[Option[Seq[Option[String]]]]]');
     });
 
     test('should return Option[Seq[Seq[Option[String]]]] for GraphQLList(GraphQLNonNull(GraphQLList(GraphQLString)))', function() {
-      expect(typeNameFromGraphQLType({}, new GraphQLList(new GraphQLNonNull(new GraphQLList(GraphQLString))))).toBe('Option[Seq[Seq[Option[String]]]]');
+      expect(typeNameFromGraphQLType({options:{}}, new GraphQLList(new GraphQLNonNull(new GraphQLList(GraphQLString))))).toBe('Option[Seq[Seq[Option[String]]]]');
     });
 
     test('should return Option[Int] for GraphQLInt', function() {
-      expect(typeNameFromGraphQLType({}, GraphQLInt)).toBe('Option[Int]');
+      expect(typeNameFromGraphQLType({options:{}}, GraphQLInt)).toBe('Option[Int]');
     });
 
     test('should return Option[Double] for GraphQLFloat', function() {
-      expect(typeNameFromGraphQLType({}, GraphQLFloat)).toBe('Option[Double]');
+      expect(typeNameFromGraphQLType({options:{}}, GraphQLFloat)).toBe('Option[Double]');
     });
 
     test('should return Option[Boolean] for GraphQLBoolean', function() {
-      expect(typeNameFromGraphQLType({}, GraphQLBoolean)).toBe('Option[Boolean]');
+      expect(typeNameFromGraphQLType({options:{}}, GraphQLBoolean)).toBe('Option[Boolean]');
     });
 
     test('should return Option[String] for GraphQLID', function() {
-      expect(typeNameFromGraphQLType({}, GraphQLID)).toBe('Option[String]');
+      expect(typeNameFromGraphQLType({options:{}}, GraphQLID)).toBe('Option[String]');
     });
 
     test('should return Option[String] for a custom scalar type', function() {
-      expect(typeNameFromGraphQLType({}, new GraphQLScalarType({ name: 'CustomScalarType', serialize: String }))).toBe('Option[String]');
+      expect(typeNameFromGraphQLType({options:{}}, new GraphQLScalarType({ name: 'CustomScalarType', serialize: String }))).toBe('Option[String]');
     });
 
     test('should return a passed through custom scalar type with the passthroughCustomScalars option', function() {
-      expect(typeNameFromGraphQLType({ passthroughCustomScalars: true, customScalarsPrefix: '' }, new GraphQLScalarType({ name: 'CustomScalarType', serialize: String }))).toBe('Option[CustomScalarType]');
+      expect(typeNameFromGraphQLType({options: { passthroughCustomScalars: true, customScalarsPrefix: '' } }, new GraphQLScalarType({ name: 'CustomScalarType', serialize: String }))).toBe('Option[CustomScalarType]');
     });
 
     test('should return a passed through custom scalar type with a prefix with the customScalarsPrefix option', function() {
-      expect(typeNameFromGraphQLType({ passthroughCustomScalars: true, customScalarsPrefix: 'My' }, new GraphQLScalarType({ name: 'CustomScalarType', serialize: String }))).toBe('Option[MyCustomScalarType]');
+      expect(typeNameFromGraphQLType({options: { passthroughCustomScalars: true, customScalarsPrefix: 'My' } }, new GraphQLScalarType({ name: 'CustomScalarType', serialize: String }))).toBe('Option[MyCustomScalarType]');
     });
   });
 });
diff --git a/test/swift/__snapshots__/codeGeneration.ts.snap b/test/swift/__snapshots__/codeGeneration.ts.snap
index b98f63f7..cc7aa78c 100644
--- a/test/swift/__snapshots__/codeGeneration.ts.snap
+++ b/test/swift/__snapshots__/codeGeneration.ts.snap
@@ -2,7 +2,7 @@
 
 exports[`Swift code generation #classDeclarationForOperation() should generate a class declaration for a mutation with variables 1`] = `
 "public final class CreateReviewMutation: GraphQLMutation {
-  public static let operationString =
+  public let operationDefinition =
     \\"mutation CreateReview($episode: Episode) {\\\\n  createReview(episode: $episode, review: {stars: 5, commentary: \\\\\\"Wow!\\\\\\"}) {\\\\n    stars\\\\n    commentary\\\\n  }\\\\n}\\"
 
   public var episode: Episode?
@@ -22,22 +22,22 @@ exports[`Swift code generation #classDeclarationForOperation() should generate a
       GraphQLField(\\"createReview\\", arguments: [\\"episode\\": GraphQLVariable(\\"episode\\"), \\"review\\": [\\"stars\\": 5, \\"commentary\\": \\"Wow!\\"]], type: .object(CreateReview.selections)),
     ]
 
-    public var snapshot: Snapshot
+    public private(set) var resultMap: ResultMap
 
-    public init(snapshot: Snapshot) {
-      self.snapshot = snapshot
+    public init(unsafeResultMap: ResultMap) {
+      self.resultMap = unsafeResultMap
     }
 
     public init(createReview: CreateReview? = nil) {
-      self.init(snapshot: [\\"__typename\\": \\"Mutation\\", \\"createReview\\": createReview.flatMap { (j: CreateReview) in j.snapshot }])
+      self.init(unsafeResultMap: [\\"__typename\\": \\"Mutation\\", \\"createReview\\": createReview.flatMap { (value: CreateReview) -> ResultMap in value.resultMap }])
     }
 
     public var createReview: CreateReview? {
       get {
-        return (snapshot[\\"createReview\\"] as? Snapshot).flatMap { CreateReview(snapshot: $0) }
+        return (resultMap[\\"createReview\\"] as? ResultMap).flatMap { CreateReview(unsafeResultMap: $0) }
       }
       set {
-        snapshot.updateValue(newValue?.snapshot, forKey: \\"createReview\\")
+        resultMap.updateValue(newValue?.resultMap, forKey: \\"createReview\\")
       }
     }
 
@@ -49,33 +49,33 @@ exports[`Swift code generation #classDeclarationForOperation() should generate a
         GraphQLField(\\"commentary\\", type: .scalar(String.self)),
       ]
 
-      public var snapshot: Snapshot
+      public private(set) var resultMap: ResultMap
 
-      public init(snapshot: Snapshot) {
-        self.snapshot = snapshot
+      public init(unsafeResultMap: ResultMap) {
+        self.resultMap = unsafeResultMap
       }
 
       public init(stars: Int, commentary: String? = nil) {
-        self.init(snapshot: [\\"__typename\\": \\"Review\\", \\"stars\\": stars, \\"commentary\\": commentary])
+        self.init(unsafeResultMap: [\\"__typename\\": \\"Review\\", \\"stars\\": stars, \\"commentary\\": commentary])
       }
 
       /// The number of stars this review gave, 1-5
       public var stars: Int {
         get {
-          return snapshot[\\"stars\\"]! as! Int
+          return resultMap[\\"stars\\"]! as! Int
         }
         set {
-          snapshot.updateValue(newValue, forKey: \\"stars\\")
+          resultMap.updateValue(newValue, forKey: \\"stars\\")
         }
       }
 
       /// Comment about the movie
       public var commentary: String? {
         get {
-          return snapshot[\\"commentary\\"] as? String
+          return resultMap[\\"commentary\\"] as? String
         }
         set {
-          snapshot.updateValue(newValue, forKey: \\"commentary\\")
+          resultMap.updateValue(newValue, forKey: \\"commentary\\")
         }
       }
     }
@@ -85,10 +85,10 @@ exports[`Swift code generation #classDeclarationForOperation() should generate a
 
 exports[`Swift code generation #classDeclarationForOperation() should generate a class declaration for a query with a fragment spread nested in an inline fragment 1`] = `
 "public final class HeroQuery: GraphQLQuery {
-  public static let operationString =
+  public let operationDefinition =
     \\"query Hero {\\\\n  hero {\\\\n    ... on Droid {\\\\n      ...HeroDetails\\\\n    }\\\\n  }\\\\n}\\"
 
-  public static var requestString: String { return operationString.appending(HeroDetails.fragmentString) }
+  public var queryDocument: String { return operationDefinition.appending(HeroDetails.fragmentDefinition) }
 
   public init() {
   }
@@ -100,22 +100,22 @@ exports[`Swift code generation #classDeclarationForOperation() should generate a
       GraphQLField(\\"hero\\", type: .object(Hero.selections)),
     ]
 
-    public var snapshot: Snapshot
+    public private(set) var resultMap: ResultMap
 
-    public init(snapshot: Snapshot) {
-      self.snapshot = snapshot
+    public init(unsafeResultMap: ResultMap) {
+      self.resultMap = unsafeResultMap
     }
 
     public init(hero: Hero? = nil) {
-      self.init(snapshot: [\\"__typename\\": \\"Query\\", \\"hero\\": hero.flatMap { (j: Hero) in j.snapshot }])
+      self.init(unsafeResultMap: [\\"__typename\\": \\"Query\\", \\"hero\\": hero.flatMap { (value: Hero) -> ResultMap in value.resultMap }])
     }
 
     public var hero: Hero? {
       get {
-        return (snapshot[\\"hero\\"] as? Snapshot).flatMap { Hero(snapshot: $0) }
+        return (resultMap[\\"hero\\"] as? ResultMap).flatMap { Hero(unsafeResultMap: $0) }
       }
       set {
-        snapshot.updateValue(newValue?.snapshot, forKey: \\"hero\\")
+        resultMap.updateValue(newValue?.resultMap, forKey: \\"hero\\")
       }
     }
 
@@ -130,28 +130,28 @@ exports[`Swift code generation #classDeclarationForOperation() should generate a
         )
       ]
 
-      public var snapshot: Snapshot
+      public private(set) var resultMap: ResultMap
 
-      public init(snapshot: Snapshot) {
-        self.snapshot = snapshot
+      public init(unsafeResultMap: ResultMap) {
+        self.resultMap = unsafeResultMap
       }
 
       public static func makeHuman() -> Hero {
-        return Hero(snapshot: [\\"__typename\\": \\"Human\\"])
+        return Hero(unsafeResultMap: [\\"__typename\\": \\"Human\\"])
       }
 
       public static func makeDroid(name: String) -> Hero {
-        return Hero(snapshot: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
+        return Hero(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
       }
 
       public var asDroid: AsDroid? {
         get {
           if !AsDroid.possibleTypes.contains(__typename) { return nil }
-          return AsDroid(snapshot: snapshot)
+          return AsDroid(unsafeResultMap: resultMap)
         }
         set {
           guard let newValue = newValue else { return }
-          snapshot = newValue.snapshot
+          resultMap = newValue.resultMap
         }
       }
 
@@ -162,44 +162,48 @@ exports[`Swift code generation #classDeclarationForOperation() should generate a
           GraphQLField(\\"name\\", type: .nonNull(.scalar(String.self))),
         ]
 
-        public var snapshot: Snapshot
+        public private(set) var resultMap: ResultMap
 
-        public init(snapshot: Snapshot) {
-          self.snapshot = snapshot
+        public init(unsafeResultMap: ResultMap) {
+          self.resultMap = unsafeResultMap
         }
 
         public init(name: String) {
-          self.init(snapshot: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
+          self.init(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
         }
 
         /// What others call this droid
         public var name: String {
           get {
-            return snapshot[\\"name\\"]! as! String
+            return resultMap[\\"name\\"]! as! String
           }
           set {
-            snapshot.updateValue(newValue, forKey: \\"name\\")
+            resultMap.updateValue(newValue, forKey: \\"name\\")
           }
         }
 
         public var fragments: Fragments {
           get {
-            return Fragments(snapshot: snapshot)
+            return Fragments(unsafeResultMap: resultMap)
           }
           set {
-            snapshot += newValue.snapshot
+            resultMap += newValue.resultMap
           }
         }
 
         public struct Fragments {
-          public var snapshot: Snapshot
+          public private(set) var resultMap: ResultMap
+
+          public init(unsafeResultMap: ResultMap) {
+            self.resultMap = unsafeResultMap
+          }
 
           public var heroDetails: HeroDetails {
             get {
-              return HeroDetails(snapshot: snapshot)
+              return HeroDetails(unsafeResultMap: resultMap)
             }
             set {
-              snapshot += newValue.snapshot
+              resultMap += newValue.resultMap
             }
           }
         }
@@ -211,10 +215,10 @@ exports[`Swift code generation #classDeclarationForOperation() should generate a
 
 exports[`Swift code generation #classDeclarationForOperation() should generate a class declaration for a query with conditional fragment spreads 1`] = `
 "public final class HeroQuery: GraphQLQuery {
-  public static let operationString =
+  public let operationDefinition =
     \\"query Hero {\\\\n  hero {\\\\n    ...DroidDetails\\\\n  }\\\\n}\\"
 
-  public static var requestString: String { return operationString.appending(DroidDetails.fragmentString) }
+  public var queryDocument: String { return operationDefinition.appending(DroidDetails.fragmentDefinition) }
 
   public init() {
   }
@@ -226,22 +230,22 @@ exports[`Swift code generation #classDeclarationForOperation() should generate a
       GraphQLField(\\"hero\\", type: .object(Hero.selections)),
     ]
 
-    public var snapshot: Snapshot
+    public private(set) var resultMap: ResultMap
 
-    public init(snapshot: Snapshot) {
-      self.snapshot = snapshot
+    public init(unsafeResultMap: ResultMap) {
+      self.resultMap = unsafeResultMap
     }
 
     public init(hero: Hero? = nil) {
-      self.init(snapshot: [\\"__typename\\": \\"Query\\", \\"hero\\": hero.flatMap { (j: Hero) in j.snapshot }])
+      self.init(unsafeResultMap: [\\"__typename\\": \\"Query\\", \\"hero\\": hero.flatMap { (value: Hero) -> ResultMap in value.resultMap }])
     }
 
     public var hero: Hero? {
       get {
-        return (snapshot[\\"hero\\"] as? Snapshot).flatMap { Hero(snapshot: $0) }
+        return (resultMap[\\"hero\\"] as? ResultMap).flatMap { Hero(unsafeResultMap: $0) }
       }
       set {
-        snapshot.updateValue(newValue?.snapshot, forKey: \\"hero\\")
+        resultMap.updateValue(newValue?.resultMap, forKey: \\"hero\\")
       }
     }
 
@@ -256,40 +260,44 @@ exports[`Swift code generation #classDeclarationForOperation() should generate a
         )
       ]
 
-      public var snapshot: Snapshot
+      public private(set) var resultMap: ResultMap
 
-      public init(snapshot: Snapshot) {
-        self.snapshot = snapshot
+      public init(unsafeResultMap: ResultMap) {
+        self.resultMap = unsafeResultMap
       }
 
       public static func makeHuman() -> Hero {
-        return Hero(snapshot: [\\"__typename\\": \\"Human\\"])
+        return Hero(unsafeResultMap: [\\"__typename\\": \\"Human\\"])
       }
 
       public static func makeDroid(primaryFunction: String? = nil) -> Hero {
-        return Hero(snapshot: [\\"__typename\\": \\"Droid\\", \\"primaryFunction\\": primaryFunction])
+        return Hero(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"primaryFunction\\": primaryFunction])
       }
 
       public var fragments: Fragments {
         get {
-          return Fragments(snapshot: snapshot)
+          return Fragments(unsafeResultMap: resultMap)
         }
         set {
-          snapshot += newValue.snapshot
+          resultMap += newValue.resultMap
         }
       }
 
       public struct Fragments {
-        public var snapshot: Snapshot
+        public private(set) var resultMap: ResultMap
+
+        public init(unsafeResultMap: ResultMap) {
+          self.resultMap = unsafeResultMap
+        }
 
         public var droidDetails: DroidDetails? {
           get {
-            if !DroidDetails.possibleTypes.contains(snapshot[\\"__typename\\"]! as! String) { return nil }
-            return DroidDetails(snapshot: snapshot)
+            if !DroidDetails.possibleTypes.contains(resultMap[\\"__typename\\"]! as! String) { return nil }
+            return DroidDetails(unsafeResultMap: resultMap)
           }
           set {
             guard let newValue = newValue else { return }
-            snapshot += newValue.snapshot
+            resultMap += newValue.resultMap
           }
         }
       }
@@ -297,11 +305,11 @@ exports[`Swift code generation #classDeclarationForOperation() should generate a
       public var asDroid: AsDroid? {
         get {
           if !AsDroid.possibleTypes.contains(__typename) { return nil }
-          return AsDroid(snapshot: snapshot)
+          return AsDroid(unsafeResultMap: resultMap)
         }
         set {
           guard let newValue = newValue else { return }
-          snapshot = newValue.snapshot
+          resultMap = newValue.resultMap
         }
       }
 
@@ -312,44 +320,48 @@ exports[`Swift code generation #classDeclarationForOperation() should generate a
           GraphQLField(\\"primaryFunction\\", type: .scalar(String.self)),
         ]
 
-        public var snapshot: Snapshot
+        public private(set) var resultMap: ResultMap
 
-        public init(snapshot: Snapshot) {
-          self.snapshot = snapshot
+        public init(unsafeResultMap: ResultMap) {
+          self.resultMap = unsafeResultMap
         }
 
         public init(primaryFunction: String? = nil) {
-          self.init(snapshot: [\\"__typename\\": \\"Droid\\", \\"primaryFunction\\": primaryFunction])
+          self.init(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"primaryFunction\\": primaryFunction])
         }
 
         /// This droid's primary function
         public var primaryFunction: String? {
           get {
-            return snapshot[\\"primaryFunction\\"] as? String
+            return resultMap[\\"primaryFunction\\"] as? String
           }
           set {
-            snapshot.updateValue(newValue, forKey: \\"primaryFunction\\")
+            resultMap.updateValue(newValue, forKey: \\"primaryFunction\\")
           }
         }
 
         public var fragments: Fragments {
           get {
-            return Fragments(snapshot: snapshot)
+            return Fragments(unsafeResultMap: resultMap)
           }
           set {
-            snapshot += newValue.snapshot
+            resultMap += newValue.resultMap
           }
         }
 
         public struct Fragments {
-          public var snapshot: Snapshot
+          public private(set) var resultMap: ResultMap
+
+          public init(unsafeResultMap: ResultMap) {
+            self.resultMap = unsafeResultMap
+          }
 
           public var droidDetails: DroidDetails {
             get {
-              return DroidDetails(snapshot: snapshot)
+              return DroidDetails(unsafeResultMap: resultMap)
             }
             set {
-              snapshot += newValue.snapshot
+              resultMap += newValue.resultMap
             }
           }
         }
@@ -361,10 +373,10 @@ exports[`Swift code generation #classDeclarationForOperation() should generate a
 
 exports[`Swift code generation #classDeclarationForOperation() should generate a class declaration for a query with fragment spreads 1`] = `
 "public final class HeroQuery: GraphQLQuery {
-  public static let operationString =
+  public let operationDefinition =
     \\"query Hero {\\\\n  hero {\\\\n    ...HeroDetails\\\\n  }\\\\n}\\"
 
-  public static var requestString: String { return operationString.appending(HeroDetails.fragmentString) }
+  public var queryDocument: String { return operationDefinition.appending(HeroDetails.fragmentDefinition) }
 
   public init() {
   }
@@ -376,22 +388,22 @@ exports[`Swift code generation #classDeclarationForOperation() should generate a
       GraphQLField(\\"hero\\", type: .object(Hero.selections)),
     ]
 
-    public var snapshot: Snapshot
+    public private(set) var resultMap: ResultMap
 
-    public init(snapshot: Snapshot) {
-      self.snapshot = snapshot
+    public init(unsafeResultMap: ResultMap) {
+      self.resultMap = unsafeResultMap
     }
 
     public init(hero: Hero? = nil) {
-      self.init(snapshot: [\\"__typename\\": \\"Query\\", \\"hero\\": hero.flatMap { (j: Hero) in j.snapshot }])
+      self.init(unsafeResultMap: [\\"__typename\\": \\"Query\\", \\"hero\\": hero.flatMap { (value: Hero) -> ResultMap in value.resultMap }])
     }
 
     public var hero: Hero? {
       get {
-        return (snapshot[\\"hero\\"] as? Snapshot).flatMap { Hero(snapshot: $0) }
+        return (resultMap[\\"hero\\"] as? ResultMap).flatMap { Hero(unsafeResultMap: $0) }
       }
       set {
-        snapshot.updateValue(newValue?.snapshot, forKey: \\"hero\\")
+        resultMap.updateValue(newValue?.resultMap, forKey: \\"hero\\")
       }
     }
 
@@ -402,48 +414,52 @@ exports[`Swift code generation #classDeclarationForOperation() should generate a
         GraphQLField(\\"name\\", type: .nonNull(.scalar(String.self))),
       ]
 
-      public var snapshot: Snapshot
+      public private(set) var resultMap: ResultMap
 
-      public init(snapshot: Snapshot) {
-        self.snapshot = snapshot
+      public init(unsafeResultMap: ResultMap) {
+        self.resultMap = unsafeResultMap
       }
 
       public static func makeHuman(name: String) -> Hero {
-        return Hero(snapshot: [\\"__typename\\": \\"Human\\", \\"name\\": name])
+        return Hero(unsafeResultMap: [\\"__typename\\": \\"Human\\", \\"name\\": name])
       }
 
       public static func makeDroid(name: String) -> Hero {
-        return Hero(snapshot: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
+        return Hero(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
       }
 
       /// The name of the character
       public var name: String {
         get {
-          return snapshot[\\"name\\"]! as! String
+          return resultMap[\\"name\\"]! as! String
         }
         set {
-          snapshot.updateValue(newValue, forKey: \\"name\\")
+          resultMap.updateValue(newValue, forKey: \\"name\\")
         }
       }
 
       public var fragments: Fragments {
         get {
-          return Fragments(snapshot: snapshot)
+          return Fragments(unsafeResultMap: resultMap)
         }
         set {
-          snapshot += newValue.snapshot
+          resultMap += newValue.resultMap
         }
       }
 
       public struct Fragments {
-        public var snapshot: Snapshot
+        public private(set) var resultMap: ResultMap
+
+        public init(unsafeResultMap: ResultMap) {
+          self.resultMap = unsafeResultMap
+        }
 
         public var heroDetails: HeroDetails {
           get {
-            return HeroDetails(snapshot: snapshot)
+            return HeroDetails(unsafeResultMap: resultMap)
           }
           set {
-            snapshot += newValue.snapshot
+            resultMap += newValue.resultMap
           }
         }
       }
@@ -454,7 +470,7 @@ exports[`Swift code generation #classDeclarationForOperation() should generate a
 
 exports[`Swift code generation #classDeclarationForOperation() should generate a class declaration for a query with variables 1`] = `
 "public final class HeroNameQuery: GraphQLQuery {
-  public static let operationString =
+  public let operationDefinition =
     \\"query HeroName($episode: Episode) {\\\\n  hero(episode: $episode) {\\\\n    name\\\\n  }\\\\n}\\"
 
   public var episode: Episode?
@@ -474,22 +490,22 @@ exports[`Swift code generation #classDeclarationForOperation() should generate a
       GraphQLField(\\"hero\\", arguments: [\\"episode\\": GraphQLVariable(\\"episode\\")], type: .object(Hero.selections)),
     ]
 
-    public var snapshot: Snapshot
+    public private(set) var resultMap: ResultMap
 
-    public init(snapshot: Snapshot) {
-      self.snapshot = snapshot
+    public init(unsafeResultMap: ResultMap) {
+      self.resultMap = unsafeResultMap
     }
 
     public init(hero: Hero? = nil) {
-      self.init(snapshot: [\\"__typename\\": \\"Query\\", \\"hero\\": hero.flatMap { (j: Hero) in j.snapshot }])
+      self.init(unsafeResultMap: [\\"__typename\\": \\"Query\\", \\"hero\\": hero.flatMap { (value: Hero) -> ResultMap in value.resultMap }])
     }
 
     public var hero: Hero? {
       get {
-        return (snapshot[\\"hero\\"] as? Snapshot).flatMap { Hero(snapshot: $0) }
+        return (resultMap[\\"hero\\"] as? ResultMap).flatMap { Hero(unsafeResultMap: $0) }
       }
       set {
-        snapshot.updateValue(newValue?.snapshot, forKey: \\"hero\\")
+        resultMap.updateValue(newValue?.resultMap, forKey: \\"hero\\")
       }
     }
 
@@ -500,27 +516,27 @@ exports[`Swift code generation #classDeclarationForOperation() should generate a
         GraphQLField(\\"name\\", type: .nonNull(.scalar(String.self))),
       ]
 
-      public var snapshot: Snapshot
+      public private(set) var resultMap: ResultMap
 
-      public init(snapshot: Snapshot) {
-        self.snapshot = snapshot
+      public init(unsafeResultMap: ResultMap) {
+        self.resultMap = unsafeResultMap
       }
 
       public static func makeHuman(name: String) -> Hero {
-        return Hero(snapshot: [\\"__typename\\": \\"Human\\", \\"name\\": name])
+        return Hero(unsafeResultMap: [\\"__typename\\": \\"Human\\", \\"name\\": name])
       }
 
       public static func makeDroid(name: String) -> Hero {
-        return Hero(snapshot: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
+        return Hero(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
       }
 
       /// The name of the character
       public var name: String {
         get {
-          return snapshot[\\"name\\"]! as! String
+          return resultMap[\\"name\\"]! as! String
         }
         set {
-          snapshot.updateValue(newValue, forKey: \\"name\\")
+          resultMap.updateValue(newValue, forKey: \\"name\\")
         }
       }
     }
@@ -530,12 +546,12 @@ exports[`Swift code generation #classDeclarationForOperation() should generate a
 
 exports[`Swift code generation #classDeclarationForOperation() should generate a class declaration with an operationIdentifier property when generateOperationIds is specified 1`] = `
 "public final class HeroQuery: GraphQLQuery {
-  public static let operationString =
+  public let operationDefinition =
     \\"query Hero {\\\\n  hero {\\\\n    ...HeroDetails\\\\n  }\\\\n}\\"
 
-  public static let operationIdentifier: String? = \\"90d0d674eb6a7b33776f63200d6cec3d09f881247c360a2ac9a29037a02210c4\\"
+  public let operationIdentifier: String? = \\"90d0d674eb6a7b33776f63200d6cec3d09f881247c360a2ac9a29037a02210c4\\"
 
-  public static var requestString: String { return operationString.appending(HeroDetails.fragmentString) }
+  public var queryDocument: String { return operationDefinition.appending(HeroDetails.fragmentDefinition) }
 
   public init() {
   }
@@ -547,22 +563,22 @@ exports[`Swift code generation #classDeclarationForOperation() should generate a
       GraphQLField(\\"hero\\", type: .object(Hero.selections)),
     ]
 
-    public var snapshot: Snapshot
+    public private(set) var resultMap: ResultMap
 
-    public init(snapshot: Snapshot) {
-      self.snapshot = snapshot
+    public init(unsafeResultMap: ResultMap) {
+      self.resultMap = unsafeResultMap
     }
 
     public init(hero: Hero? = nil) {
-      self.init(snapshot: [\\"__typename\\": \\"Query\\", \\"hero\\": hero.flatMap { (j: Hero) in j.snapshot }])
+      self.init(unsafeResultMap: [\\"__typename\\": \\"Query\\", \\"hero\\": hero.flatMap { (value: Hero) -> ResultMap in value.resultMap }])
     }
 
     public var hero: Hero? {
       get {
-        return (snapshot[\\"hero\\"] as? Snapshot).flatMap { Hero(snapshot: $0) }
+        return (resultMap[\\"hero\\"] as? ResultMap).flatMap { Hero(unsafeResultMap: $0) }
       }
       set {
-        snapshot.updateValue(newValue?.snapshot, forKey: \\"hero\\")
+        resultMap.updateValue(newValue?.resultMap, forKey: \\"hero\\")
       }
     }
 
@@ -573,48 +589,52 @@ exports[`Swift code generation #classDeclarationForOperation() should generate a
         GraphQLField(\\"name\\", type: .nonNull(.scalar(String.self))),
       ]
 
-      public var snapshot: Snapshot
+      public private(set) var resultMap: ResultMap
 
-      public init(snapshot: Snapshot) {
-        self.snapshot = snapshot
+      public init(unsafeResultMap: ResultMap) {
+        self.resultMap = unsafeResultMap
       }
 
       public static func makeHuman(name: String) -> Hero {
-        return Hero(snapshot: [\\"__typename\\": \\"Human\\", \\"name\\": name])
+        return Hero(unsafeResultMap: [\\"__typename\\": \\"Human\\", \\"name\\": name])
       }
 
       public static func makeDroid(name: String) -> Hero {
-        return Hero(snapshot: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
+        return Hero(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
       }
 
       /// The name of the character
       public var name: String {
         get {
-          return snapshot[\\"name\\"]! as! String
+          return resultMap[\\"name\\"]! as! String
         }
         set {
-          snapshot.updateValue(newValue, forKey: \\"name\\")
+          resultMap.updateValue(newValue, forKey: \\"name\\")
         }
       }
 
       public var fragments: Fragments {
         get {
-          return Fragments(snapshot: snapshot)
+          return Fragments(unsafeResultMap: resultMap)
         }
         set {
-          snapshot += newValue.snapshot
+          resultMap += newValue.resultMap
         }
       }
 
       public struct Fragments {
-        public var snapshot: Snapshot
+        public private(set) var resultMap: ResultMap
+
+        public init(unsafeResultMap: ResultMap) {
+          self.resultMap = unsafeResultMap
+        }
 
         public var heroDetails: HeroDetails {
           get {
-            return HeroDetails(snapshot: snapshot)
+            return HeroDetails(unsafeResultMap: resultMap)
           }
           set {
-            snapshot += newValue.snapshot
+            resultMap += newValue.resultMap
           }
         }
       }
@@ -644,7 +664,7 @@ exports[`Swift code generation #initializerDeclarationForProperties() should gen
 
 exports[`Swift code generation #structDeclarationForFragment() should generate a struct declaration for a fragment that includes a fragment spread 1`] = `
 "public struct HeroDetails: GraphQLFragment {
-  public static let fragmentString =
+  public static let fragmentDefinition =
     \\"fragment HeroDetails on Character {\\\\n  name\\\\n  ...MoreHeroDetails\\\\n}\\"
 
   public static let possibleTypes = [\\"Human\\", \\"Droid\\"]
@@ -654,58 +674,62 @@ exports[`Swift code generation #structDeclarationForFragment() should generate a
     GraphQLField(\\"appearsIn\\", type: .nonNull(.list(.scalar(Episode.self)))),
   ]
 
-  public var snapshot: Snapshot
+  public private(set) var resultMap: ResultMap
 
-  public init(snapshot: Snapshot) {
-    self.snapshot = snapshot
+  public init(unsafeResultMap: ResultMap) {
+    self.resultMap = unsafeResultMap
   }
 
   public static func makeHuman(name: String, appearsIn: [Episode?]) -> HeroDetails {
-    return HeroDetails(snapshot: [\\"__typename\\": \\"Human\\", \\"name\\": name, \\"appearsIn\\": appearsIn])
+    return HeroDetails(unsafeResultMap: [\\"__typename\\": \\"Human\\", \\"name\\": name, \\"appearsIn\\": appearsIn])
   }
 
   public static func makeDroid(name: String, appearsIn: [Episode?]) -> HeroDetails {
-    return HeroDetails(snapshot: [\\"__typename\\": \\"Droid\\", \\"name\\": name, \\"appearsIn\\": appearsIn])
+    return HeroDetails(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"name\\": name, \\"appearsIn\\": appearsIn])
   }
 
   /// The name of the character
   public var name: String {
     get {
-      return snapshot[\\"name\\"]! as! String
+      return resultMap[\\"name\\"]! as! String
     }
     set {
-      snapshot.updateValue(newValue, forKey: \\"name\\")
+      resultMap.updateValue(newValue, forKey: \\"name\\")
     }
   }
 
   /// The movies this character appears in
   public var appearsIn: [Episode?] {
     get {
-      return snapshot[\\"appearsIn\\"]! as! [Episode?]
+      return resultMap[\\"appearsIn\\"]! as! [Episode?]
     }
     set {
-      snapshot.updateValue(newValue, forKey: \\"appearsIn\\")
+      resultMap.updateValue(newValue, forKey: \\"appearsIn\\")
     }
   }
 
   public var fragments: Fragments {
     get {
-      return Fragments(snapshot: snapshot)
+      return Fragments(unsafeResultMap: resultMap)
     }
     set {
-      snapshot += newValue.snapshot
+      resultMap += newValue.resultMap
     }
   }
 
   public struct Fragments {
-    public var snapshot: Snapshot
+    public private(set) var resultMap: ResultMap
+
+    public init(unsafeResultMap: ResultMap) {
+      self.resultMap = unsafeResultMap
+    }
 
     public var moreHeroDetails: MoreHeroDetails {
       get {
-        return MoreHeroDetails(snapshot: snapshot)
+        return MoreHeroDetails(unsafeResultMap: resultMap)
       }
       set {
-        snapshot += newValue.snapshot
+        resultMap += newValue.resultMap
       }
     }
   }
@@ -714,7 +738,7 @@ exports[`Swift code generation #structDeclarationForFragment() should generate a
 
 exports[`Swift code generation #structDeclarationForFragment() should generate a struct declaration for a fragment with a concrete type condition 1`] = `
 "public struct DroidDetails: GraphQLFragment {
-  public static let fragmentString =
+  public static let fragmentDefinition =
     \\"fragment DroidDetails on Droid {\\\\n  name\\\\n  primaryFunction\\\\n}\\"
 
   public static let possibleTypes = [\\"Droid\\"]
@@ -724,33 +748,33 @@ exports[`Swift code generation #structDeclarationForFragment() should generate a
     GraphQLField(\\"primaryFunction\\", type: .scalar(String.self)),
   ]
 
-  public var snapshot: Snapshot
+  public private(set) var resultMap: ResultMap
 
-  public init(snapshot: Snapshot) {
-    self.snapshot = snapshot
+  public init(unsafeResultMap: ResultMap) {
+    self.resultMap = unsafeResultMap
   }
 
   public init(name: String, primaryFunction: String? = nil) {
-    self.init(snapshot: [\\"__typename\\": \\"Droid\\", \\"name\\": name, \\"primaryFunction\\": primaryFunction])
+    self.init(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"name\\": name, \\"primaryFunction\\": primaryFunction])
   }
 
   /// What others call this droid
   public var name: String {
     get {
-      return snapshot[\\"name\\"]! as! String
+      return resultMap[\\"name\\"]! as! String
     }
     set {
-      snapshot.updateValue(newValue, forKey: \\"name\\")
+      resultMap.updateValue(newValue, forKey: \\"name\\")
     }
   }
 
   /// This droid's primary function
   public var primaryFunction: String? {
     get {
-      return snapshot[\\"primaryFunction\\"] as? String
+      return resultMap[\\"primaryFunction\\"] as? String
     }
     set {
-      snapshot.updateValue(newValue, forKey: \\"primaryFunction\\")
+      resultMap.updateValue(newValue, forKey: \\"primaryFunction\\")
     }
   }
 }"
@@ -758,7 +782,7 @@ exports[`Swift code generation #structDeclarationForFragment() should generate a
 
 exports[`Swift code generation #structDeclarationForFragment() should generate a struct declaration for a fragment with a subselection 1`] = `
 "public struct HeroDetails: GraphQLFragment {
-  public static let fragmentString =
+  public static let fragmentDefinition =
     \\"fragment HeroDetails on Character {\\\\n  name\\\\n  friends {\\\\n    name\\\\n  }\\\\n}\\"
 
   public static let possibleTypes = [\\"Human\\", \\"Droid\\"]
@@ -768,37 +792,37 @@ exports[`Swift code generation #structDeclarationForFragment() should generate a
     GraphQLField(\\"friends\\", type: .list(.object(Friend.selections))),
   ]
 
-  public var snapshot: Snapshot
+  public private(set) var resultMap: ResultMap
 
-  public init(snapshot: Snapshot) {
-    self.snapshot = snapshot
+  public init(unsafeResultMap: ResultMap) {
+    self.resultMap = unsafeResultMap
   }
 
   public static func makeHuman(name: String, friends: [Friend?]? = nil) -> HeroDetails {
-    return HeroDetails(snapshot: [\\"__typename\\": \\"Human\\", \\"name\\": name, \\"friends\\": friends?.map({ (i: Friend) in i.flatMap { (j: Character) in j.snapshot } })])
+    return HeroDetails(unsafeResultMap: [\\"__typename\\": \\"Human\\", \\"name\\": name, \\"friends\\": friends.flatMap { (value: [Friend?]) -> [ResultMap?] in value.map { (value: Friend?) -> ResultMap? in value.flatMap { (value: Friend) -> ResultMap in value.resultMap } } }])
   }
 
   public static func makeDroid(name: String, friends: [Friend?]? = nil) -> HeroDetails {
-    return HeroDetails(snapshot: [\\"__typename\\": \\"Droid\\", \\"name\\": name, \\"friends\\": friends?.map({ (i: Friend) in i.flatMap { (j: Character) in j.snapshot } })])
+    return HeroDetails(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"name\\": name, \\"friends\\": friends.flatMap { (value: [Friend?]) -> [ResultMap?] in value.map { (value: Friend?) -> ResultMap? in value.flatMap { (value: Friend) -> ResultMap in value.resultMap } } }])
   }
 
   /// The name of the character
   public var name: String {
     get {
-      return snapshot[\\"name\\"]! as! String
+      return resultMap[\\"name\\"]! as! String
     }
     set {
-      snapshot.updateValue(newValue, forKey: \\"name\\")
+      resultMap.updateValue(newValue, forKey: \\"name\\")
     }
   }
 
   /// The friends of the character, or an empty list if they have none
   public var friends: [Friend?]? {
     get {
-      return (snapshot[\\"friends\\"] as? [Snapshot?])?.map({ (i: Snapshot) in i.flatMap { (j: Character) in Friend(snapshot: j) } })
+      return (resultMap[\\"friends\\"] as? [ResultMap?]).flatMap { (value: [ResultMap?]) -> [Friend?] in value.map { (value: ResultMap?) -> Friend? in value.flatMap { (value: ResultMap) -> Friend in Friend(unsafeResultMap: value) } } }
     }
     set {
-      snapshot.updateValue(newValue?.map({ (i: Friend) in i.flatMap { (j: Character) in j.snapshot } }), forKey: \\"friends\\")
+      resultMap.updateValue(newValue.flatMap { (value: [Friend?]) -> [ResultMap?] in value.map { (value: Friend?) -> ResultMap? in value.flatMap { (value: Friend) -> ResultMap in value.resultMap } } }, forKey: \\"friends\\")
     }
   }
 
@@ -809,27 +833,27 @@ exports[`Swift code generation #structDeclarationForFragment() should generate a
       GraphQLField(\\"name\\", type: .nonNull(.scalar(String.self))),
     ]
 
-    public var snapshot: Snapshot
+    public private(set) var resultMap: ResultMap
 
-    public init(snapshot: Snapshot) {
-      self.snapshot = snapshot
+    public init(unsafeResultMap: ResultMap) {
+      self.resultMap = unsafeResultMap
     }
 
     public static func makeHuman(name: String) -> Friend {
-      return Friend(snapshot: [\\"__typename\\": \\"Human\\", \\"name\\": name])
+      return Friend(unsafeResultMap: [\\"__typename\\": \\"Human\\", \\"name\\": name])
     }
 
     public static func makeDroid(name: String) -> Friend {
-      return Friend(snapshot: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
+      return Friend(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
     }
 
     /// The name of the character
     public var name: String {
       get {
-        return snapshot[\\"name\\"]! as! String
+        return resultMap[\\"name\\"]! as! String
       }
       set {
-        snapshot.updateValue(newValue, forKey: \\"name\\")
+        resultMap.updateValue(newValue, forKey: \\"name\\")
       }
     }
   }
@@ -838,7 +862,7 @@ exports[`Swift code generation #structDeclarationForFragment() should generate a
 
 exports[`Swift code generation #structDeclarationForFragment() should generate a struct declaration for a fragment with an abstract type condition 1`] = `
 "public struct HeroDetails: GraphQLFragment {
-  public static let fragmentString =
+  public static let fragmentDefinition =
     \\"fragment HeroDetails on Character {\\\\n  name\\\\n  appearsIn\\\\n}\\"
 
   public static let possibleTypes = [\\"Human\\", \\"Droid\\"]
@@ -848,37 +872,37 @@ exports[`Swift code generation #structDeclarationForFragment() should generate a
     GraphQLField(\\"appearsIn\\", type: .nonNull(.list(.scalar(Episode.self)))),
   ]
 
-  public var snapshot: Snapshot
+  public private(set) var resultMap: ResultMap
 
-  public init(snapshot: Snapshot) {
-    self.snapshot = snapshot
+  public init(unsafeResultMap: ResultMap) {
+    self.resultMap = unsafeResultMap
   }
 
   public static func makeHuman(name: String, appearsIn: [Episode?]) -> HeroDetails {
-    return HeroDetails(snapshot: [\\"__typename\\": \\"Human\\", \\"name\\": name, \\"appearsIn\\": appearsIn])
+    return HeroDetails(unsafeResultMap: [\\"__typename\\": \\"Human\\", \\"name\\": name, \\"appearsIn\\": appearsIn])
   }
 
   public static func makeDroid(name: String, appearsIn: [Episode?]) -> HeroDetails {
-    return HeroDetails(snapshot: [\\"__typename\\": \\"Droid\\", \\"name\\": name, \\"appearsIn\\": appearsIn])
+    return HeroDetails(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"name\\": name, \\"appearsIn\\": appearsIn])
   }
 
   /// The name of the character
   public var name: String {
     get {
-      return snapshot[\\"name\\"]! as! String
+      return resultMap[\\"name\\"]! as! String
     }
     set {
-      snapshot.updateValue(newValue, forKey: \\"name\\")
+      resultMap.updateValue(newValue, forKey: \\"name\\")
     }
   }
 
   /// The movies this character appears in
   public var appearsIn: [Episode?] {
     get {
-      return snapshot[\\"appearsIn\\"]! as! [Episode?]
+      return resultMap[\\"appearsIn\\"]! as! [Episode?]
     }
     set {
-      snapshot.updateValue(newValue, forKey: \\"appearsIn\\")
+      resultMap.updateValue(newValue, forKey: \\"appearsIn\\")
     }
   }
 }"
@@ -892,27 +916,27 @@ exports[`Swift code generation #structDeclarationForSelectionSet() should escape
     GraphQLField(\\"name\\", alias: \\"private\\", type: .nonNull(.scalar(String.self))),
   ]
 
-  public var snapshot: Snapshot
+  public private(set) var resultMap: ResultMap
 
-  public init(snapshot: Snapshot) {
-    self.snapshot = snapshot
+  public init(unsafeResultMap: ResultMap) {
+    self.resultMap = unsafeResultMap
   }
 
   public static func makeHuman(\`private\`: String) -> Hero {
-    return Hero(snapshot: [\\"__typename\\": \\"Human\\", \\"private\\": \`private\`])
+    return Hero(unsafeResultMap: [\\"__typename\\": \\"Human\\", \\"private\\": \`private\`])
   }
 
   public static func makeDroid(\`private\`: String) -> Hero {
-    return Hero(snapshot: [\\"__typename\\": \\"Droid\\", \\"private\\": \`private\`])
+    return Hero(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"private\\": \`private\`])
   }
 
   /// The name of the character
   public var \`private\`: String {
     get {
-      return snapshot[\\"private\\"]! as! String
+      return resultMap[\\"private\\"]! as! String
     }
     set {
-      snapshot.updateValue(newValue, forKey: \\"private\\")
+      resultMap.updateValue(newValue, forKey: \\"private\\")
     }
   }
 }"
@@ -926,27 +950,27 @@ exports[`Swift code generation #structDeclarationForSelectionSet() should genera
     GraphQLField(\\"friends\\", type: .list(.object(Friend.selections))),
   ]
 
-  public var snapshot: Snapshot
+  public private(set) var resultMap: ResultMap
 
-  public init(snapshot: Snapshot) {
-    self.snapshot = snapshot
+  public init(unsafeResultMap: ResultMap) {
+    self.resultMap = unsafeResultMap
   }
 
   public static func makeHuman(friends: [Friend?]? = nil) -> Hero {
-    return Hero(snapshot: [\\"__typename\\": \\"Human\\", \\"friends\\": friends?.map({ (i: Friend) in i.flatMap { (j: Character) in j.snapshot } })])
+    return Hero(unsafeResultMap: [\\"__typename\\": \\"Human\\", \\"friends\\": friends.flatMap { (value: [Friend?]) -> [ResultMap?] in value.map { (value: Friend?) -> ResultMap? in value.flatMap { (value: Friend) -> ResultMap in value.resultMap } } }])
   }
 
   public static func makeDroid(friends: [Friend?]? = nil) -> Hero {
-    return Hero(snapshot: [\\"__typename\\": \\"Droid\\", \\"friends\\": friends?.map({ (i: Friend) in i.flatMap { (j: Character) in j.snapshot } })])
+    return Hero(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"friends\\": friends.flatMap { (value: [Friend?]) -> [ResultMap?] in value.map { (value: Friend?) -> ResultMap? in value.flatMap { (value: Friend) -> ResultMap in value.resultMap } } }])
   }
 
   /// The friends of the character, or an empty list if they have none
   public var friends: [Friend?]? {
     get {
-      return (snapshot[\\"friends\\"] as? [Snapshot?])?.map({ (i: Snapshot) in i.flatMap { (j: Character) in Friend(snapshot: j) } })
+      return (resultMap[\\"friends\\"] as? [ResultMap?]).flatMap { (value: [ResultMap?]) -> [Friend?] in value.map { (value: ResultMap?) -> Friend? in value.flatMap { (value: ResultMap) -> Friend in Friend(unsafeResultMap: value) } } }
     }
     set {
-      snapshot.updateValue(newValue?.map({ (i: Friend) in i.flatMap { (j: Character) in j.snapshot } }), forKey: \\"friends\\")
+      resultMap.updateValue(newValue.flatMap { (value: [Friend?]) -> [ResultMap?] in value.map { (value: Friend?) -> ResultMap? in value.flatMap { (value: Friend) -> ResultMap in value.resultMap } } }, forKey: \\"friends\\")
     }
   }
 
@@ -957,27 +981,27 @@ exports[`Swift code generation #structDeclarationForSelectionSet() should genera
       GraphQLField(\\"name\\", type: .nonNull(.scalar(String.self))),
     ]
 
-    public var snapshot: Snapshot
+    public private(set) var resultMap: ResultMap
 
-    public init(snapshot: Snapshot) {
-      self.snapshot = snapshot
+    public init(unsafeResultMap: ResultMap) {
+      self.resultMap = unsafeResultMap
     }
 
     public static func makeHuman(name: String) -> Friend {
-      return Friend(snapshot: [\\"__typename\\": \\"Human\\", \\"name\\": name])
+      return Friend(unsafeResultMap: [\\"__typename\\": \\"Human\\", \\"name\\": name])
     }
 
     public static func makeDroid(name: String) -> Friend {
-      return Friend(snapshot: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
+      return Friend(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
     }
 
     /// The name of the character
     public var name: String {
       get {
-        return snapshot[\\"name\\"]! as! String
+        return resultMap[\\"name\\"]! as! String
       }
       set {
-        snapshot.updateValue(newValue, forKey: \\"name\\")
+        resultMap.updateValue(newValue, forKey: \\"name\\")
       }
     }
   }
@@ -997,38 +1021,38 @@ exports[`Swift code generation #structDeclarationForSelectionSet() should genera
     )
   ]
 
-  public var snapshot: Snapshot
+  public private(set) var resultMap: ResultMap
 
-  public init(snapshot: Snapshot) {
-    self.snapshot = snapshot
+  public init(unsafeResultMap: ResultMap) {
+    self.resultMap = unsafeResultMap
   }
 
   public static func makeHuman(name: String) -> Hero {
-    return Hero(snapshot: [\\"__typename\\": \\"Human\\", \\"name\\": name])
+    return Hero(unsafeResultMap: [\\"__typename\\": \\"Human\\", \\"name\\": name])
   }
 
   public static func makeDroid(name: String) -> Hero {
-    return Hero(snapshot: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
+    return Hero(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
   }
 
   /// The name of the character
   public var name: String {
     get {
-      return snapshot[\\"name\\"]! as! String
+      return resultMap[\\"name\\"]! as! String
     }
     set {
-      snapshot.updateValue(newValue, forKey: \\"name\\")
+      resultMap.updateValue(newValue, forKey: \\"name\\")
     }
   }
 
   public var asDroid: AsDroid? {
     get {
       if !AsDroid.possibleTypes.contains(__typename) { return nil }
-      return AsDroid(snapshot: snapshot)
+      return AsDroid(unsafeResultMap: resultMap)
     }
     set {
       guard let newValue = newValue else { return }
-      snapshot = newValue.snapshot
+      resultMap = newValue.resultMap
     }
   }
 
@@ -1040,44 +1064,48 @@ exports[`Swift code generation #structDeclarationForSelectionSet() should genera
       GraphQLField(\\"name\\", type: .nonNull(.scalar(String.self))),
     ]
 
-    public var snapshot: Snapshot
+    public private(set) var resultMap: ResultMap
 
-    public init(snapshot: Snapshot) {
-      self.snapshot = snapshot
+    public init(unsafeResultMap: ResultMap) {
+      self.resultMap = unsafeResultMap
     }
 
     public init(name: String) {
-      self.init(snapshot: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
+      self.init(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
     }
 
     /// What others call this droid
     public var name: String {
       get {
-        return snapshot[\\"name\\"]! as! String
+        return resultMap[\\"name\\"]! as! String
       }
       set {
-        snapshot.updateValue(newValue, forKey: \\"name\\")
+        resultMap.updateValue(newValue, forKey: \\"name\\")
       }
     }
 
     public var fragments: Fragments {
       get {
-        return Fragments(snapshot: snapshot)
+        return Fragments(unsafeResultMap: resultMap)
       }
       set {
-        snapshot += newValue.snapshot
+        resultMap += newValue.resultMap
       }
     }
 
     public struct Fragments {
-      public var snapshot: Snapshot
+      public private(set) var resultMap: ResultMap
+
+      public init(unsafeResultMap: ResultMap) {
+        self.resultMap = unsafeResultMap
+      }
 
       public var heroDetails: HeroDetails {
         get {
-          return HeroDetails(snapshot: snapshot)
+          return HeroDetails(unsafeResultMap: resultMap)
         }
         set {
-          snapshot += newValue.snapshot
+          resultMap += newValue.resultMap
         }
       }
     }
@@ -1093,27 +1121,27 @@ exports[`Swift code generation #structDeclarationForSelectionSet() should genera
     GraphQLField(\\"name\\", type: .nonNull(.scalar(String.self))),
   ]
 
-  public var snapshot: Snapshot
+  public private(set) var resultMap: ResultMap
 
-  public init(snapshot: Snapshot) {
-    self.snapshot = snapshot
+  public init(unsafeResultMap: ResultMap) {
+    self.resultMap = unsafeResultMap
   }
 
   public static func makeHuman(name: String) -> Hero {
-    return Hero(snapshot: [\\"__typename\\": \\"Human\\", \\"name\\": name])
+    return Hero(unsafeResultMap: [\\"__typename\\": \\"Human\\", \\"name\\": name])
   }
 
   public static func makeDroid(name: String) -> Hero {
-    return Hero(snapshot: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
+    return Hero(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
   }
 
   /// The name of the character
   public var name: String {
     get {
-      return snapshot[\\"name\\"]! as! String
+      return resultMap[\\"name\\"]! as! String
     }
     set {
-      snapshot.updateValue(newValue, forKey: \\"name\\")
+      resultMap.updateValue(newValue, forKey: \\"name\\")
     }
   }
 }"
@@ -1129,27 +1157,27 @@ exports[`Swift code generation #structDeclarationForSelectionSet() should genera
     ]),
   ]
 
-  public var snapshot: Snapshot
+  public private(set) var resultMap: ResultMap
 
-  public init(snapshot: Snapshot) {
-    self.snapshot = snapshot
+  public init(unsafeResultMap: ResultMap) {
+    self.resultMap = unsafeResultMap
   }
 
   public static func makeHuman(name: String? = nil) -> Hero {
-    return Hero(snapshot: [\\"__typename\\": \\"Human\\", \\"name\\": name])
+    return Hero(unsafeResultMap: [\\"__typename\\": \\"Human\\", \\"name\\": name])
   }
 
   public static func makeDroid(name: String? = nil) -> Hero {
-    return Hero(snapshot: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
+    return Hero(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
   }
 
   /// The name of the character
   public var name: String? {
     get {
-      return snapshot[\\"name\\"] as? String
+      return resultMap[\\"name\\"] as? String
     }
     set {
-      snapshot.updateValue(newValue, forKey: \\"name\\")
+      resultMap.updateValue(newValue, forKey: \\"name\\")
     }
   }
 }"
@@ -1164,48 +1192,52 @@ exports[`Swift code generation #structDeclarationForSelectionSet() should genera
     GraphQLField(\\"name\\", type: .nonNull(.scalar(String.self))),
   ]
 
-  public var snapshot: Snapshot
+  public private(set) var resultMap: ResultMap
 
-  public init(snapshot: Snapshot) {
-    self.snapshot = snapshot
+  public init(unsafeResultMap: ResultMap) {
+    self.resultMap = unsafeResultMap
   }
 
   public static func makeHuman(name: String) -> Hero {
-    return Hero(snapshot: [\\"__typename\\": \\"Human\\", \\"name\\": name])
+    return Hero(unsafeResultMap: [\\"__typename\\": \\"Human\\", \\"name\\": name])
   }
 
   public static func makeDroid(name: String) -> Hero {
-    return Hero(snapshot: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
+    return Hero(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
   }
 
   /// The name of the character
   public var name: String {
     get {
-      return snapshot[\\"name\\"]! as! String
+      return resultMap[\\"name\\"]! as! String
     }
     set {
-      snapshot.updateValue(newValue, forKey: \\"name\\")
+      resultMap.updateValue(newValue, forKey: \\"name\\")
     }
   }
 
   public var fragments: Fragments {
     get {
-      return Fragments(snapshot: snapshot)
+      return Fragments(unsafeResultMap: resultMap)
     }
     set {
-      snapshot += newValue.snapshot
+      resultMap += newValue.resultMap
     }
   }
 
   public struct Fragments {
-    public var snapshot: Snapshot
+    public private(set) var resultMap: ResultMap
+
+    public init(unsafeResultMap: ResultMap) {
+      self.resultMap = unsafeResultMap
+    }
 
     public var heroDetails: HeroDetails {
       get {
-        return HeroDetails(snapshot: snapshot)
+        return HeroDetails(unsafeResultMap: resultMap)
       }
       set {
-        snapshot += newValue.snapshot
+        resultMap += newValue.resultMap
       }
     }
   }
@@ -1225,50 +1257,54 @@ exports[`Swift code generation #structDeclarationForSelectionSet() should genera
     )
   ]
 
-  public var snapshot: Snapshot
+  public private(set) var resultMap: ResultMap
 
-  public init(snapshot: Snapshot) {
-    self.snapshot = snapshot
+  public init(unsafeResultMap: ResultMap) {
+    self.resultMap = unsafeResultMap
   }
 
   public static func makeHuman(name: String) -> Hero {
-    return Hero(snapshot: [\\"__typename\\": \\"Human\\", \\"name\\": name])
+    return Hero(unsafeResultMap: [\\"__typename\\": \\"Human\\", \\"name\\": name])
   }
 
   public static func makeDroid(name: String) -> Hero {
-    return Hero(snapshot: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
+    return Hero(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
   }
 
   /// The name of the character
   public var name: String {
     get {
-      return snapshot[\\"name\\"]! as! String
+      return resultMap[\\"name\\"]! as! String
     }
     set {
-      snapshot.updateValue(newValue, forKey: \\"name\\")
+      resultMap.updateValue(newValue, forKey: \\"name\\")
     }
   }
 
   public var fragments: Fragments {
     get {
-      return Fragments(snapshot: snapshot)
+      return Fragments(unsafeResultMap: resultMap)
     }
     set {
-      snapshot += newValue.snapshot
+      resultMap += newValue.resultMap
     }
   }
 
   public struct Fragments {
-    public var snapshot: Snapshot
+    public private(set) var resultMap: ResultMap
+
+    public init(unsafeResultMap: ResultMap) {
+      self.resultMap = unsafeResultMap
+    }
 
     public var droidDetails: DroidDetails? {
       get {
-        if !DroidDetails.possibleTypes.contains(snapshot[\\"__typename\\"]! as! String) { return nil }
-        return DroidDetails(snapshot: snapshot)
+        if !DroidDetails.possibleTypes.contains(resultMap[\\"__typename\\"]! as! String) { return nil }
+        return DroidDetails(unsafeResultMap: resultMap)
       }
       set {
         guard let newValue = newValue else { return }
-        snapshot += newValue.snapshot
+        resultMap += newValue.resultMap
       }
     }
   }
@@ -1276,11 +1312,11 @@ exports[`Swift code generation #structDeclarationForSelectionSet() should genera
   public var asDroid: AsDroid? {
     get {
       if !AsDroid.possibleTypes.contains(__typename) { return nil }
-      return AsDroid(snapshot: snapshot)
+      return AsDroid(unsafeResultMap: resultMap)
     }
     set {
       guard let newValue = newValue else { return }
-      snapshot = newValue.snapshot
+      resultMap = newValue.resultMap
     }
   }
 
@@ -1292,44 +1328,48 @@ exports[`Swift code generation #structDeclarationForSelectionSet() should genera
       GraphQLField(\\"name\\", type: .nonNull(.scalar(String.self))),
     ]
 
-    public var snapshot: Snapshot
+    public private(set) var resultMap: ResultMap
 
-    public init(snapshot: Snapshot) {
-      self.snapshot = snapshot
+    public init(unsafeResultMap: ResultMap) {
+      self.resultMap = unsafeResultMap
     }
 
     public init(name: String) {
-      self.init(snapshot: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
+      self.init(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"name\\": name])
     }
 
     /// What others call this droid
     public var name: String {
       get {
-        return snapshot[\\"name\\"]! as! String
+        return resultMap[\\"name\\"]! as! String
       }
       set {
-        snapshot.updateValue(newValue, forKey: \\"name\\")
+        resultMap.updateValue(newValue, forKey: \\"name\\")
       }
     }
 
     public var fragments: Fragments {
       get {
-        return Fragments(snapshot: snapshot)
+        return Fragments(unsafeResultMap: resultMap)
       }
       set {
-        snapshot += newValue.snapshot
+        resultMap += newValue.resultMap
       }
     }
 
     public struct Fragments {
-      public var snapshot: Snapshot
+      public private(set) var resultMap: ResultMap
+
+      public init(unsafeResultMap: ResultMap) {
+        self.resultMap = unsafeResultMap
+      }
 
       public var droidDetails: DroidDetails {
         get {
-          return DroidDetails(snapshot: snapshot)
+          return DroidDetails(unsafeResultMap: resultMap)
         }
         set {
-          snapshot += newValue.snapshot
+          resultMap += newValue.resultMap
         }
       }
     }
@@ -1350,38 +1390,38 @@ exports[`Swift code generation #structDeclarationForSelectionSet() should genera
     )
   ]
 
-  public var snapshot: Snapshot
+  public private(set) var resultMap: ResultMap
 
-  public init(snapshot: Snapshot) {
-    self.snapshot = snapshot
+  public init(unsafeResultMap: ResultMap) {
+    self.resultMap = unsafeResultMap
   }
 
   public static func makeHuman(name: String) -> Hero {
-    return Hero(snapshot: [\\"__typename\\": \\"Human\\", \\"name\\": name])
+    return Hero(unsafeResultMap: [\\"__typename\\": \\"Human\\", \\"name\\": name])
   }
 
   public static func makeDroid(name: String, primaryFunction: String? = nil) -> Hero {
-    return Hero(snapshot: [\\"__typename\\": \\"Droid\\", \\"name\\": name, \\"primaryFunction\\": primaryFunction])
+    return Hero(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"name\\": name, \\"primaryFunction\\": primaryFunction])
   }
 
   /// The name of the character
   public var name: String {
     get {
-      return snapshot[\\"name\\"]! as! String
+      return resultMap[\\"name\\"]! as! String
     }
     set {
-      snapshot.updateValue(newValue, forKey: \\"name\\")
+      resultMap.updateValue(newValue, forKey: \\"name\\")
     }
   }
 
   public var asDroid: AsDroid? {
     get {
       if !AsDroid.possibleTypes.contains(__typename) { return nil }
-      return AsDroid(snapshot: snapshot)
+      return AsDroid(unsafeResultMap: resultMap)
     }
     set {
       guard let newValue = newValue else { return }
-      snapshot = newValue.snapshot
+      resultMap = newValue.resultMap
     }
   }
 
@@ -1393,33 +1433,33 @@ exports[`Swift code generation #structDeclarationForSelectionSet() should genera
       GraphQLField(\\"primaryFunction\\", type: .scalar(String.self)),
     ]
 
-    public var snapshot: Snapshot
+    public private(set) var resultMap: ResultMap
 
-    public init(snapshot: Snapshot) {
-      self.snapshot = snapshot
+    public init(unsafeResultMap: ResultMap) {
+      self.resultMap = unsafeResultMap
     }
 
     public init(name: String, primaryFunction: String? = nil) {
-      self.init(snapshot: [\\"__typename\\": \\"Droid\\", \\"name\\": name, \\"primaryFunction\\": primaryFunction])
+      self.init(unsafeResultMap: [\\"__typename\\": \\"Droid\\", \\"name\\": name, \\"primaryFunction\\": primaryFunction])
     }
 
     /// What others call this droid
     public var name: String {
       get {
-        return snapshot[\\"name\\"]! as! String
+        return resultMap[\\"name\\"]! as! String
       }
       set {
-        snapshot.updateValue(newValue, forKey: \\"name\\")
+        resultMap.updateValue(newValue, forKey: \\"name\\")
       }
     }
 
     /// This droid's primary function
     public var primaryFunction: String? {
       get {
-        return snapshot[\\"primaryFunction\\"] as? String
+        return resultMap[\\"primaryFunction\\"] as? String
       }
       set {
-        snapshot.updateValue(newValue, forKey: \\"primaryFunction\\")
+        resultMap.updateValue(newValue, forKey: \\"primaryFunction\\")
       }
     }
   }
@@ -1432,13 +1472,13 @@ exports[`Swift code generation #typeDeclarationForGraphQLType() should escape id
   case \`public\`
   case \`private\`
   /// Auto generated constant for unknown enum values
-  case unknown(RawValue)
+  case __unknown(RawValue)
 
   public init?(rawValue: RawValue) {
     switch rawValue {
       case \\"PUBLIC\\": self = .public
       case \\"PRIVATE\\": self = .private
-      default: self = .unknown(rawValue)
+      default: self = .__unknown(rawValue)
     }
   }
 
@@ -1446,7 +1486,7 @@ exports[`Swift code generation #typeDeclarationForGraphQLType() should escape id
     switch self {
       case .public: return \\"PUBLIC\\"
       case .private: return \\"PRIVATE\\"
-      case .unknown(let value): return value
+      case .__unknown(let value): return value
     }
   }
 
@@ -1454,7 +1494,7 @@ exports[`Swift code generation #typeDeclarationForGraphQLType() should escape id
     switch (lhs, rhs) {
       case (.public, .public): return true
       case (.private, .private): return true
-      case (.unknown(let lhsValue), .unknown(let rhsValue)): return lhsValue == rhsValue
+      case (.__unknown(let lhsValue), .__unknown(let rhsValue)): return lhsValue == rhsValue
       default: return false
     }
   }
@@ -1466,7 +1506,7 @@ exports[`Swift code generation #typeDeclarationForGraphQLType() should generate
 public struct ReviewInput: GraphQLMapConvertible {
   public var graphQLMap: GraphQLMap
 
-  public init(stars: Int, commentary: Optional<String?> = nil, favoriteColor: Optional<ColorInput?> = nil) {
+  public init(stars: Int, commentary: Swift.Optional<String?> = nil, favoriteColor: Swift.Optional<ColorInput?> = nil) {
     graphQLMap = [\\"stars\\": stars, \\"commentary\\": commentary, \\"favorite_color\\": favoriteColor]
   }
 
@@ -1481,9 +1521,9 @@ public struct ReviewInput: GraphQLMapConvertible {
   }
 
   /// Comment about the movie, optional
-  public var commentary: Optional<String?> {
+  public var commentary: Swift.Optional<String?> {
     get {
-      return graphQLMap[\\"commentary\\"] as! Optional<String?>
+      return graphQLMap[\\"commentary\\"] as! Swift.Optional<String?>
     }
     set {
       graphQLMap.updateValue(newValue, forKey: \\"commentary\\")
@@ -1491,12 +1531,12 @@ public struct ReviewInput: GraphQLMapConvertible {
   }
 
   /// Favorite color, optional
-  public var favoriteColor: Optional<ColorInput?> {
+  public var favoriteColor: Swift.Optional<ColorInput?> {
     get {
-      return graphQLMap[\\"favoriteColor\\"] as! Optional<ColorInput?>
+      return graphQLMap[\\"favorite_color\\"] as! Swift.Optional<ColorInput?>
     }
     set {
-      graphQLMap.updateValue(newValue, forKey: \\"favoriteColor\\")
+      graphQLMap.updateValue(newValue, forKey: \\"favorite_color\\")
     }
   }
 }"
@@ -1513,14 +1553,14 @@ public enum Episode: RawRepresentable, Equatable, Apollo.JSONDecodable, Apollo.J
   /// Star Wars Episode VI: Return of the Jedi, released in 1983.
   case jedi
   /// Auto generated constant for unknown enum values
-  case unknown(RawValue)
+  case __unknown(RawValue)
 
   public init?(rawValue: RawValue) {
     switch rawValue {
       case \\"NEWHOPE\\": self = .newhope
       case \\"EMPIRE\\": self = .empire
       case \\"JEDI\\": self = .jedi
-      default: self = .unknown(rawValue)
+      default: self = .__unknown(rawValue)
     }
   }
 
@@ -1529,7 +1569,7 @@ public enum Episode: RawRepresentable, Equatable, Apollo.JSONDecodable, Apollo.J
       case .newhope: return \\"NEWHOPE\\"
       case .empire: return \\"EMPIRE\\"
       case .jedi: return \\"JEDI\\"
-      case .unknown(let value): return value
+      case .__unknown(let value): return value
     }
   }
 
@@ -1538,7 +1578,7 @@ public enum Episode: RawRepresentable, Equatable, Apollo.JSONDecodable, Apollo.J
       case (.newhope, .newhope): return true
       case (.empire, .empire): return true
       case (.jedi, .jedi): return true
-      case (.unknown(let lhsValue), .unknown(let rhsValue)): return lhsValue == rhsValue
+      case (.__unknown(let lhsValue), .__unknown(let rhsValue)): return lhsValue == rhsValue
       default: return false
     }
   }
diff --git a/test/swift/codeGeneration.ts b/test/swift/codeGeneration.ts
index 0041f8f9..9854378c 100644
--- a/test/swift/codeGeneration.ts
+++ b/test/swift/codeGeneration.ts
@@ -231,7 +231,7 @@ describe('Swift code generation', () => {
           propertyName: 'propertyName',
           type: schema.getType('Droid')
         })
-      ).toBe('"response_key": propertyName.flatMap { $0.snapshot }');
+      ).toBe('"response_key": propertyName.flatMap { (value: Droid) -> ResultMap in value.resultMap }');
     });
 
     it('should generate expression for non-null composite', () => {
@@ -241,7 +241,7 @@ describe('Swift code generation', () => {
           propertyName: 'propertyName',
           type: new GraphQLNonNull(schema.getType('Droid'))
         })
-      ).toBe('"response_key": propertyName.snapshot');
+      ).toBe('"response_key": propertyName.resultMap');
     });
 
     it('should generate expression for nullable list of nullable composites', () => {
@@ -251,7 +251,7 @@ describe('Swift code generation', () => {
           propertyName: 'propertyName',
           type: new GraphQLList(schema.getType('Droid'))
         })
-      ).toBe('"response_key": propertyName?.map({ $0.flatMap { (j: Droid) in j.snapshot } })');
+      ).toBe('"response_key": propertyName.flatMap { (value: [Droid?]) -> [ResultMap?] in value.map { (value: Droid?) -> ResultMap? in value.flatMap { (value: Droid) -> ResultMap in value.resultMap } } }');
     });
 
     it('should generate expression for nullable list of non-null composites', () => {
@@ -261,7 +261,7 @@ describe('Swift code generation', () => {
           propertyName: 'propertyName',
           type: new GraphQLList(new GraphQLNonNull(schema.getType('Droid')))
         })
-      ).toBe('"response_key": propertyName?.map({ $0.snapshot })');
+      ).toBe('"response_key": propertyName.flatMap { (value: [Droid]) -> [ResultMap] in value.map { (value: Droid) -> ResultMap in value.resultMap } }');
     });
 
     it('should generate expression for non-null list of nullable composites', () => {
@@ -271,7 +271,7 @@ describe('Swift code generation', () => {
           propertyName: 'propertyName',
           type: new GraphQLNonNull(new GraphQLList(schema.getType('Droid')))
         })
-      ).toBe('"response_key": propertyName.map { $0.flatMap { (j: Droid?) in j.snapshot } }');
+      ).toBe('"response_key": propertyName.map { (value: Droid?) -> ResultMap? in value.flatMap { (value: Droid) -> ResultMap in value.resultMap } }');
     });
 
     it('should generate expression for non-null list of non-null composites', () => {
@@ -281,7 +281,7 @@ describe('Swift code generation', () => {
           propertyName: 'propertyName',
           type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(schema.getType('Droid')))
         })
-      ).toBe('"response_key": propertyName.map { $0.snapshot }');
+      ).toBe('"response_key": propertyName.map { (value: Droid) -> ResultMap in value.resultMap }');
     });
   });
 
diff --git a/test/typescript/__snapshots__/codeGeneration.js.snap b/test/typescript/__snapshots__/codeGeneration.js.snap
index 935f3814..99ede263 100644
--- a/test/typescript/__snapshots__/codeGeneration.js.snap
+++ b/test/typescript/__snapshots__/codeGeneration.js.snap
@@ -4,11 +4,22 @@ exports[`TypeScript code generation #generateSource() should generate correct li
 "/* tslint:disable */
 //  This file was automatically generated and should not be edited.
 
-// The episodes in the Star Wars trilogy
+/**
+ * The episodes in the Star Wars trilogy
+ */
 export enum Episode {
-  EMPIRE = \\"EMPIRE\\", // Star Wars Episode V: The Empire Strikes Back, released in 1980.
-  JEDI = \\"JEDI\\", // Star Wars Episode VI: Return of the Jedi, released in 1983.
-  NEWHOPE = \\"NEWHOPE\\", // Star Wars Episode IV: A New Hope, released in 1977.
+  /**
+   * Star Wars Episode V: The Empire Strikes Back, released in 1980.
+   */
+  EMPIRE = \\"EMPIRE\\",
+  /**
+   * Star Wars Episode VI: Return of the Jedi, released in 1983.
+   */
+  JEDI = \\"JEDI\\",
+  /**
+   * Star Wars Episode IV: A New Hope, released in 1977.
+   */
+  NEWHOPE = \\"NEWHOPE\\",
 }
 
 
@@ -19,31 +30,47 @@ export interface HeroAndFriendsNamesQueryVariables {
 export interface HeroAndFriendsNamesQuery {
   hero: ( {
       __typename: \\"Human\\",
-      // The name of the character
+      /**
+       * The name of the character
+       */
       name: string,
-      // The friends of the character, or an empty list if they have none
+      /**
+       * The friends of the character, or an empty list if they have none
+       */
       friends:  Array<( {
           __typename: \\"Human\\",
-          // The name of the character
+          /**
+           * The name of the character
+           */
           name: string,
         } | {
           __typename: \\"Droid\\",
-          // The name of the character
+          /**
+           * The name of the character
+           */
           name: string,
         }
       ) | null > | null,
     } | {
       __typename: \\"Droid\\",
-      // The name of the character
+      /**
+       * The name of the character
+       */
       name: string,
-      // The friends of the character, or an empty list if they have none
+      /**
+       * The friends of the character, or an empty list if they have none
+       */
       friends:  Array<( {
           __typename: \\"Human\\",
-          // The name of the character
+          /**
+           * The name of the character
+           */
           name: string,
         } | {
           __typename: \\"Droid\\",
-          // The name of the character
+          /**
+           * The name of the character
+           */
           name: string,
         }
       ) | null > | null,
@@ -53,11 +80,15 @@ export interface HeroAndFriendsNamesQuery {
 
 export type FriendFragment = ( {
       __typename: \\"Human\\",
-      // The name of the character
+      /**
+       * The name of the character
+       */
       name: string,
     } | {
       __typename: \\"Droid\\",
-      // The name of the character
+      /**
+       * The name of the character
+       */
       name: string,
     }
   );
@@ -71,31 +102,47 @@ exports[`TypeScript code generation #generateSource() should generate fragmented
 export interface HeroAndFriendsNamesQuery {
   hero: ( {
       __typename: \\"Human\\",
-      // The name of the character
+      /**
+       * The name of the character
+       */
       name: string,
-      // The friends of the character, or an empty list if they have none
+      /**
+       * The friends of the character, or an empty list if they have none
+       */
       friends:  Array<( {
           __typename: \\"Human\\",
-          // The name of the character
+          /**
+           * The name of the character
+           */
           name: string,
         } | {
           __typename: \\"Droid\\",
-          // The name of the character
+          /**
+           * The name of the character
+           */
           name: string,
         }
       ) | null > | null,
     } | {
       __typename: \\"Droid\\",
-      // The name of the character
+      /**
+       * The name of the character
+       */
       name: string,
-      // The friends of the character, or an empty list if they have none
+      /**
+       * The friends of the character, or an empty list if they have none
+       */
       friends:  Array<( {
           __typename: \\"Human\\",
-          // The name of the character
+          /**
+           * The name of the character
+           */
           name: string,
         } | {
           __typename: \\"Droid\\",
-          // The name of the character
+          /**
+           * The name of the character
+           */
           name: string,
         }
       ) | null > | null,
@@ -105,27 +152,39 @@ export interface HeroAndFriendsNamesQuery {
 
 export type heroFriendsFragment = ( {
       __typename: \\"Human\\",
-      // The friends of the character, or an empty list if they have none
+      /**
+       * The friends of the character, or an empty list if they have none
+       */
       friends:  Array<( {
           __typename: \\"Human\\",
-          // The name of the character
+          /**
+           * The name of the character
+           */
           name: string,
         } | {
           __typename: \\"Droid\\",
-          // The name of the character
+          /**
+           * The name of the character
+           */
           name: string,
         }
       ) | null > | null,
     } | {
       __typename: \\"Droid\\",
-      // The friends of the character, or an empty list if they have none
+      /**
+       * The friends of the character, or an empty list if they have none
+       */
       friends:  Array<( {
           __typename: \\"Human\\",
-          // The name of the character
+          /**
+           * The name of the character
+           */
           name: string,
         } | {
           __typename: \\"Droid\\",
-          // The name of the character
+          /**
+           * The name of the character
+           */
           name: string,
         }
       ) | null > | null,
@@ -138,20 +197,37 @@ exports[`TypeScript code generation #generateSource() should generate mutation o
 "/* tslint:disable */
 //  This file was automatically generated and should not be edited.
 
-// The episodes in the Star Wars trilogy
+/**
+ * The episodes in the Star Wars trilogy
+ */
 export enum Episode {
-  EMPIRE = \\"EMPIRE\\", // Star Wars Episode V: The Empire Strikes Back, released in 1980.
-  JEDI = \\"JEDI\\", // Star Wars Episode VI: Return of the Jedi, released in 1983.
-  NEWHOPE = \\"NEWHOPE\\", // Star Wars Episode IV: A New Hope, released in 1977.
+  /**
+   * Star Wars Episode V: The Empire Strikes Back, released in 1980.
+   */
+  EMPIRE = \\"EMPIRE\\",
+  /**
+   * Star Wars Episode VI: Return of the Jedi, released in 1983.
+   */
+  JEDI = \\"JEDI\\",
+  /**
+   * Star Wars Episode IV: A New Hope, released in 1977.
+   */
+  NEWHOPE = \\"NEWHOPE\\",
 }
 
 
 export interface ReviewInput {
-  // 0-5 stars
+  /**
+   * 0-5 stars
+   */
   stars: number,
-  // Comment about the movie, optional
+  /**
+   * Comment about the movie, optional
+   */
   commentary?: string | null,
-  // Favorite color, optional
+  /**
+   * Favorite color, optional
+   */
   favorite_color?: ColorInput | null,
 };
 
@@ -169,9 +245,13 @@ export interface ReviewMovieMutationVariables {
 export interface ReviewMovieMutation {
   createReview:  {
     __typename: \\"Review\\",
-    // The number of stars this review gave, 1-5
+    /**
+     * The number of stars this review gave, 1-5
+     */
     stars: number,
-    // Comment about the movie
+    /**
+     * Comment about the movie
+     */
     commentary: string | null,
   } | null,
 };
@@ -185,15 +265,23 @@ exports[`TypeScript code generation #generateSource() should generate query oper
 export interface HeroAndDetailsQuery {
   hero: ( {
       __typename: \\"Human\\",
-      // What this human calls themselves
+      /**
+       * What this human calls themselves
+       */
       name: string,
-      // Height in the preferred unit, default is meters
+      /**
+       * Height in the preferred unit, default is meters
+       */
       height: number | null,
     } | {
       __typename: \\"Droid\\",
-      // What others call this droid
+      /**
+       * What others call this droid
+       */
       name: string,
-      // This droid's primary function
+      /**
+       * This droid's primary function
+       */
       primaryFunction: string | null,
     }
   ) | null,
@@ -201,11 +289,15 @@ export interface HeroAndDetailsQuery {
 
 export type HeroDetailsFragment = ( {
       __typename: \\"Human\\",
-      // Height in the preferred unit, default is meters
+      /**
+       * Height in the preferred unit, default is meters
+       */
       height: number | null,
     } | {
       __typename: \\"Droid\\",
-      // This droid's primary function
+      /**
+       * This droid's primary function
+       */
       primaryFunction: string | null,
     }
   );
@@ -216,11 +308,22 @@ exports[`TypeScript code generation #generateSource() should generate simple nes
 "/* tslint:disable */
 //  This file was automatically generated and should not be edited.
 
-// The episodes in the Star Wars trilogy
+/**
+ * The episodes in the Star Wars trilogy
+ */
 export enum Episode {
-  EMPIRE = \\"EMPIRE\\", // Star Wars Episode V: The Empire Strikes Back, released in 1980.
-  JEDI = \\"JEDI\\", // Star Wars Episode VI: Return of the Jedi, released in 1983.
-  NEWHOPE = \\"NEWHOPE\\", // Star Wars Episode IV: A New Hope, released in 1977.
+  /**
+   * Star Wars Episode V: The Empire Strikes Back, released in 1980.
+   */
+  EMPIRE = \\"EMPIRE\\",
+  /**
+   * Star Wars Episode VI: Return of the Jedi, released in 1983.
+   */
+  JEDI = \\"JEDI\\",
+  /**
+   * Star Wars Episode IV: A New Hope, released in 1977.
+   */
+  NEWHOPE = \\"NEWHOPE\\",
 }
 
 
@@ -231,31 +334,47 @@ export interface HeroAndFriendsNamesQueryVariables {
 export interface HeroAndFriendsNamesQuery {
   hero: ( {
       __typename: \\"Human\\",
-      // The name of the character
+      /**
+       * The name of the character
+       */
       name: string,
-      // The friends of the character, or an empty list if they have none
+      /**
+       * The friends of the character, or an empty list if they have none
+       */
       friends:  Array<( {
           __typename: \\"Human\\",
-          // The name of the character
+          /**
+           * The name of the character
+           */
           name: string,
         } | {
           __typename: \\"Droid\\",
-          // The name of the character
+          /**
+           * The name of the character
+           */
           name: string,
         }
       ) | null > | null,
     } | {
       __typename: \\"Droid\\",
-      // The name of the character
+      /**
+       * The name of the character
+       */
       name: string,
-      // The friends of the character, or an empty list if they have none
+      /**
+       * The friends of the character, or an empty list if they have none
+       */
       friends:  Array<( {
           __typename: \\"Human\\",
-          // The name of the character
+          /**
+           * The name of the character
+           */
           name: string,
         } | {
           __typename: \\"Droid\\",
-          // The name of the character
+          /**
+           * The name of the character
+           */
           name: string,
         }
       ) | null > | null,
@@ -285,11 +404,15 @@ exports[`TypeScript code generation #generateSource() should generate simple que
 export interface HeroNameQuery {
   hero: ( {
       __typename: \\"Human\\",
-      // The name of the character
+      /**
+       * The name of the character
+       */
       name: string,
     } | {
       __typename: \\"Droid\\",
-      // The name of the character
+      /**
+       * The name of the character
+       */
       name: string,
     }
   ) | null,
@@ -301,11 +424,22 @@ exports[`TypeScript code generation #generateSource() should generate simple que
 "/* tslint:disable */
 //  This file was automatically generated and should not be edited.
 
-// The episodes in the Star Wars trilogy
+/**
+ * The episodes in the Star Wars trilogy
+ */
 export enum Episode {
-  EMPIRE = \\"EMPIRE\\", // Star Wars Episode V: The Empire Strikes Back, released in 1980.
-  JEDI = \\"JEDI\\", // Star Wars Episode VI: Return of the Jedi, released in 1983.
-  NEWHOPE = \\"NEWHOPE\\", // Star Wars Episode IV: A New Hope, released in 1977.
+  /**
+   * Star Wars Episode V: The Empire Strikes Back, released in 1980.
+   */
+  EMPIRE = \\"EMPIRE\\",
+  /**
+   * Star Wars Episode VI: Return of the Jedi, released in 1983.
+   */
+  JEDI = \\"JEDI\\",
+  /**
+   * Star Wars Episode IV: A New Hope, released in 1977.
+   */
+  NEWHOPE = \\"NEWHOPE\\",
 }
 
 
@@ -316,11 +450,15 @@ export interface HeroNameQueryVariables {
 export interface HeroNameQuery {
   hero: ( {
       __typename: \\"Human\\",
-      // The name of the character
+      /**
+       * The name of the character
+       */
       name: string,
     } | {
       __typename: \\"Droid\\",
-      // The name of the character
+      /**
+       * The name of the character
+       */
       name: string,
     }
   ) | null,
@@ -333,9 +471,15 @@ exports[`TypeScript code generation #generateSource() should handle comments in
 //  This file was automatically generated and should not be edited.
 
 export enum EnumCommentTestCase {
-  first = \\"first\\", // This is a single-line comment
-  // This is a multi-line
-  // comment.
+  /**
+   * This is a single-line comment
+   */
+  first = \\"first\\",
+  /**
+   * This is a
+   * multi-line
+   * comment.
+   */
   second = \\"second\\",
 }
 
@@ -375,8 +519,11 @@ exports[`TypeScript code generation #generateSource() should handle multi-line c
 export interface CustomScalarQuery {
   commentTest:  {
     __typename: \\"CommentTest\\",
-    // This is a multi-line
-    // comment.
+    /**
+     * This is a
+     * multi-line
+     * comment.
+     */
     multiLine: string | null,
   } | null,
 };
@@ -390,7 +537,9 @@ exports[`TypeScript code generation #generateSource() should handle single line
 export interface CustomScalarQuery {
   commentTest:  {
     __typename: \\"CommentTest\\",
-    // This is a single-line comment
+    /**
+     * This is a single-line comment
+     */
     singleLine: string | null,
   } | null,
 };
@@ -421,47 +570,71 @@ exports[`TypeScript code generation #generateSource() should have __typename val
 export interface HeroNameQuery {
   hero: ( {
       __typename: \\"Human\\",
-      // The friends of the human exposed as a connection with edges
+      /**
+       * The friends of the human exposed as a connection with edges
+       */
       friendsConnection:  {
         __typename: \\"FriendsConnection\\",
-        // The edges for each of the character's friends.
+        /**
+         * The edges for each of the character's friends.
+         */
         edges:  Array< {
           __typename: \\"FriendsEdge\\",
-          // The character represented by this friendship edge
+          /**
+           * The character represented by this friendship edge
+           */
           node: ( {
               __typename: \\"Human\\",
-              // The name of the character
+              /**
+               * The name of the character
+               */
               name: string,
             } | {
               __typename: \\"Droid\\",
-              // The name of the character
+              /**
+               * The name of the character
+               */
               name: string,
             }
           ) | null,
         } | null > | null,
       },
-      // A list of starships this person has piloted, or an empty list if none
+      /**
+       * A list of starships this person has piloted, or an empty list if none
+       */
       starships:  Array< {
         __typename: \\"Starship\\",
-        // The name of the starship
+        /**
+         * The name of the starship
+         */
         name: string,
       } | null > | null,
     } | {
       __typename: \\"Droid\\",
-      // The friends of the character exposed as a connection with edges
+      /**
+       * The friends of the character exposed as a connection with edges
+       */
       friendsConnection:  {
         __typename: \\"FriendsConnection\\",
-        // The edges for each of the character's friends.
+        /**
+         * The edges for each of the character's friends.
+         */
         edges:  Array< {
           __typename: \\"FriendsEdge\\",
-          // The character represented by this friendship edge
+          /**
+           * The character represented by this friendship edge
+           */
           node: ( {
               __typename: \\"Human\\",
-              // The name of the character
+              /**
+               * The name of the character
+               */
               name: string,
             } | {
               __typename: \\"Droid\\",
-              // The name of the character
+              /**
+               * The name of the character
+               */
               name: string,
             }
           ) | null,
@@ -480,11 +653,15 @@ exports[`TypeScript code generation #generateSource() should have __typename val
 export interface HeroNameQuery {
   hero: ( {
       __typename: \\"Human\\",
-      // The name of the character
+      /**
+       * The name of the character
+       */
       name: string,
     } | {
       __typename: \\"Droid\\",
-      // The name of the character
+      /**
+       * The name of the character
+       */
       name: string,
     }
   ) | null,
@@ -492,11 +669,15 @@ export interface HeroNameQuery {
 
 export type HeroWithNameFragment = ( {
       __typename: \\"Human\\",
-      // The name of the character
+      /**
+       * The name of the character
+       */
       name: string,
     } | {
       __typename: \\"Droid\\",
-      // The name of the character
+      /**
+       * The name of the character
+       */
       name: string,
     }
   );
@@ -510,14 +691,18 @@ exports[`TypeScript code generation #generateSource() should have __typename val
 export interface DroidNameQuery {
   droid:  {
     __typename: \\"Droid\\",
-    // What others call this droid
+    /**
+     * What others call this droid
+     */
     name: string,
   } | null,
 };
 
 export interface DroidWithNameFragment {
   __typename: \\"Droid\\",
-  // What others call this droid
+  /**
+   * What others call this droid
+   */
   name: string,
 };
 "