Move codegen types to syn-codegen crate
diff --git a/Cargo.toml b/Cargo.toml
index e206f8d..adea8f3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -52,4 +52,4 @@
 travis-ci = { repository = "dtolnay/syn" }
 
 [workspace]
-members = ["dev"]
+members = ["dev", "json"]
diff --git a/codegen/Cargo.toml b/codegen/Cargo.toml
index 1f0ff42..3cff380 100644
--- a/codegen/Cargo.toml
+++ b/codegen/Cargo.toml
@@ -1,5 +1,5 @@
 [package]
-name = "syn_codegen"
+name = "syn-internal-codegen"
 version = "0.0.0"
 authors = ["Nika Layzell <nika@thelayzells.com>"]
 edition = "2018"
@@ -18,6 +18,7 @@
 serde_json = "1.0.38"
 toml = "0.4.10"
 semver = { version = "0.9", features = ["serde"] }
+syn-codegen = { path = "../json" }
 
 [workspace]
 # Prefer that `cargo clean` in syn's directory does not require a rebuild of
diff --git a/codegen/src/gen.rs b/codegen/src/gen.rs
index 3daf75a..d92249c 100644
--- a/codegen/src/gen.rs
+++ b/codegen/src/gen.rs
@@ -10,10 +10,10 @@
 //!    - only submodules located in the same directory.
 //! 3. The path to `syn` is hardcoded.
 
-use crate::types;
 use proc_macro2::TokenStream;
 use quote::quote;
 use rustfmt_nightly as rustfmt;
+use syn_codegen as types;
 
 use std::fs::File;
 use std::io::Write;
@@ -23,11 +23,11 @@
 const VISIT_MUT_SRC: &str = "../src/gen/visit_mut.rs";
 
 mod codegen {
-    use crate::types;
     use inflections::Inflect;
     use proc_macro2::{Span, TokenStream};
     use quote::{quote, TokenStreamExt};
     use syn::*;
+    use syn_codegen as types;
 
     #[derive(Default)]
     pub struct State {
diff --git a/codegen/src/json.rs b/codegen/src/json.rs
index 63764b6..8e45308 100644
--- a/codegen/src/json.rs
+++ b/codegen/src/json.rs
@@ -1,4 +1,4 @@
-use crate::types::Definitions;
+use syn_codegen::Definitions;
 
 use std::fs;
 use std::path::Path;
diff --git a/codegen/src/main.rs b/codegen/src/main.rs
index d5d3262..98dd59c 100644
--- a/codegen/src/main.rs
+++ b/codegen/src/main.rs
@@ -16,7 +16,6 @@
 mod gen;
 mod json;
 mod parse;
-mod types;
 mod version;
 
 fn main() {
diff --git a/codegen/src/parse.rs b/codegen/src/parse.rs
index c8c2a03..c6335b7 100644
--- a/codegen/src/parse.rs
+++ b/codegen/src/parse.rs
@@ -1,8 +1,10 @@
-use crate::{types, version};
+use crate::version;
 
 use indexmap::IndexMap;
 use quote::quote;
+use syn::parse::Parser;
 use syn::{parse_quote, Data, DataStruct, DeriveInput, Ident, Item};
+use syn_codegen as types;
 
 use std::collections::BTreeMap;
 use std::fs::File;
@@ -192,7 +194,7 @@
             continue;
         }
 
-        let features: types::Features = syn::parse2(attr.tts.clone()).unwrap();
+        let features = parsing::parse_features.parse2(attr.tts.clone()).unwrap();
 
         if ret.any.is_empty() {
             ret = features;
@@ -250,13 +252,13 @@
 
 mod parsing {
     use super::{AstItem, TokenLookup};
-    use crate::types;
 
     use proc_macro2::TokenStream;
     use quote::quote;
     use syn;
     use syn::parse::{Parse, ParseStream, Result};
     use syn::*;
+    use syn_codegen as types;
 
     use std::collections::{BTreeMap, BTreeSet};
 
@@ -453,39 +455,37 @@
         Ok(s.value())
     }
 
-    impl Parse for types::Features {
-        fn parse(input: ParseStream) -> Result<Self> {
-            let mut features = BTreeSet::new();
+    pub fn parse_features(input: ParseStream) -> Result<types::Features> {
+        let mut features = BTreeSet::new();
 
-            let level_1;
-            parenthesized!(level_1 in input);
+        let level_1;
+        parenthesized!(level_1 in input);
 
-            let i: syn::Ident = level_1.fork().parse()?;
+        let i: syn::Ident = level_1.fork().parse()?;
 
-            if i == "any" {
-                level_1.parse::<syn::Ident>()?;
+        if i == "any" {
+            level_1.parse::<syn::Ident>()?;
 
-                let level_2;
-                parenthesized!(level_2 in level_1);
+            let level_2;
+            parenthesized!(level_2 in level_1);
 
-                while !level_2.is_empty() {
-                    features.insert(parse_feature(&level_2)?);
+            while !level_2.is_empty() {
+                features.insert(parse_feature(&level_2)?);
 
-                    if !level_2.is_empty() {
-                        level_2.parse::<Token![,]>()?;
-                    }
+                if !level_2.is_empty() {
+                    level_2.parse::<Token![,]>()?;
                 }
-            } else if i == "feature" {
-                features.insert(parse_feature(&level_1)?);
-                assert!(level_1.is_empty());
-            } else {
-                panic!("{:?}", i);
             }
-
-            assert!(input.is_empty());
-
-            Ok(types::Features { any: features })
+        } else if i == "feature" {
+            features.insert(parse_feature(&level_1)?);
+            assert!(level_1.is_empty());
+        } else {
+            panic!("{:?}", i);
         }
+
+        assert!(input.is_empty());
+
+        Ok(types::Features { any: features })
     }
 }
 
diff --git a/json/Cargo.toml b/json/Cargo.toml
new file mode 100644
index 0000000..c4c17c1
--- /dev/null
+++ b/json/Cargo.toml
@@ -0,0 +1,15 @@
+[package]
+name = "syn-codegen"
+version = "0.0.0"
+authors = ["David Tolnay <dtolnay@gmail.com>"]
+edition = "2018"
+license = "MIT OR Apache-2.0"
+description = "Syntax tree describing Syn's syntax tree"
+repository = "https://github.com/dtolnay/syn"
+documentation = "https://docs.rs/syn-codegen"
+categories = ["development-tools::procedural-macro-helpers"]
+
+[dependencies]
+indexmap = { version = "1.0", features = ["serde-1"] }
+semver = { version = "0.9", features = ["serde"] }
+serde = { version = "1.0.88", features = ["derive"] }
diff --git a/codegen/src/types.rs b/json/src/lib.rs
similarity index 100%
rename from codegen/src/types.rs
rename to json/src/lib.rs