瀏覽代碼

Schema2 to code generation tool cleaned up

Vicente Penades 6 年之前
父節點
當前提交
9abc96a529

+ 4 - 1
src/glTF2Sharp.CodeGen/CodeEmitUtils.cs → src/glTF2Sharp.CodeGen/CodeGen/CodeEmitUtils.cs

@@ -2,8 +2,11 @@
 using System.Collections.Generic;
 using System.Text;
 
-namespace Epsylon.glTF2Toolkit.CodeGen
+namespace glTF2Sharp.CodeGen
 {
+    /// <summary>
+    /// Text processing extensions to facilitate source code emission.
+    /// </summary>
     static class CodeEmitUtils
     {
         public static string Indent(this string text, int indent)

+ 85 - 63
src/glTF2Sharp.CodeGen/PersistentSchema.EmitCSharp.cs → src/glTF2Sharp.CodeGen/CodeGen/EmitCSharp.cs

@@ -6,8 +6,14 @@ using System.Text;
 
 using static System.FormattableString;
 
-namespace Epsylon.glTF2Toolkit.CodeGen
+namespace glTF2Sharp.CodeGen
 {
+    using SchemaReflection;
+
+    /// <summary>
+    /// Takes a <see cref="SchemaReflection.SchemaType.Context"/> and emits
+    /// all its enums and classes as c# source code
+    /// </summary>
     class CSharpEmitter
     {
         #region runtime names
@@ -173,11 +179,10 @@ namespace Epsylon.glTF2Toolkit.CodeGen
                 DeclareEnum(etype);
             }
         }
-        
 
-           
+        internal string _GetRuntimeName(SchemaType type) { return _GetRuntimeName(type, null); }
 
-        private string _GetRuntimeName(SchemaType type, _RuntimeField extra = null)
+        private string _GetRuntimeName(SchemaType type, _RuntimeField extra)
         {
             if (type is ObjectType anyType) return typeof(Object).Name;
             if (type is StringType strType) return typeof(String).Name;            
@@ -382,32 +387,7 @@ namespace Epsylon.glTF2Toolkit.CodeGen
                 HasBaseClass = type.BaseClass != null
             };
 
-            foreach (var f in type.Fields)
-            {
-                var trname = _GetRuntimeName(f.FieldType);
-                var frname = GetFieldRuntimeName(f);
-
-                xclass.AddFields(_GetClassField(f));
-
-                if (f.FieldType is EnumType etype)
-                {
-                    // emit serializer
-                    var smethod = etype.UseIntegers ? "SerializePropertyEnumValue" : "SerializePropertyEnumSymbol";
-                    smethod = $"{smethod}<{trname}>(writer,\"{f.PersistentName}\",{frname}";
-                    if (f.DefaultValue != null) smethod += $", {frname}Default";
-                    smethod += ");";
-                    xclass.AddFieldSerializerCase(smethod);
-
-                    // emit deserializer
-                    xclass.AddFieldDeserializerCase(f.PersistentName, $"{frname} = DeserializeValue<{_GetRuntimeName(etype)}>(reader);");
-
-                    continue;
-                }
-
-
-                xclass.AddFieldSerializerCase(_GetJSonSerializerMethod(f));
-                xclass.AddFieldDeserializerCase(f.PersistentName, _GetJSonDeserializerMethod(f));
-            }
+            xclass.AddFields(type);            
 
             return String.Join("\r\n",xclass.EmitCode().Indent(1));            
         }
@@ -422,7 +402,7 @@ namespace Epsylon.glTF2Toolkit.CodeGen
             return classDecl;
         }
 
-        private IEnumerable<string> _GetClassField(FieldInfo f)
+        internal IEnumerable<string> _GetClassField(FieldInfo f)
         {            
             var tdecl = _GetRuntimeName(f.FieldType, _UseField(f));
             var fname = GetFieldRuntimeName(f);
@@ -470,18 +450,80 @@ namespace Epsylon.glTF2Toolkit.CodeGen
 
             yield return string.IsNullOrEmpty(defval) ? $"private {tdecl} {fname};" : $"private {tdecl} {fname} = {defval};";
 
-            yield return string.Empty;                
-            
+            yield return string.Empty;
+        }            
+
+        #endregion
+    }
+
+    /// <summary>
+    /// Utility class to emit a <see cref="SchemaReflection.ClassType"/>
+    /// as c# source code
+    /// </summary>
+    class CSharpClassEmitter
+    {
+        #region constructor
+
+        public CSharpClassEmitter(CSharpEmitter emitter)
+        {
+            _Emitter = emitter;            
+        }
+
+        #endregion
+
+        #region data
+
+        private readonly CSharpEmitter _Emitter;
+
+        private readonly List<string> _Fields = new List<string>();
+        private readonly List<string> _SerializerBody = new List<string>();
+        private readonly List<string> _DeserializerSwitchBody = new List<string>();
+
+        public string ClassDeclaration { get; set; }
+
+        public bool HasBaseClass { get; set; }
+
+        #endregion
+
+        #region API
+
+        public void AddFields(ClassType type)
+        {
+            foreach (var f in type.Fields)
+            {
+                var trname = _Emitter._GetRuntimeName(f.FieldType);
+                var frname = _Emitter.GetFieldRuntimeName(f);
+
+                _Fields.AddRange(_Emitter._GetClassField(f));
+
+                if (f.FieldType is EnumType etype)
+                {
+                    // emit serializer
+                    var smethod = etype.UseIntegers ? "SerializePropertyEnumValue" : "SerializePropertyEnumSymbol";
+                    smethod = $"{smethod}<{trname}>(writer,\"{f.PersistentName}\",{frname}";
+                    if (f.DefaultValue != null) smethod += $", {frname}Default";
+                    smethod += ");";
+                    this.AddFieldSerializerCase(smethod);
+
+                    // emit deserializer
+                    this.AddFieldDeserializerCase(f.PersistentName, $"{frname} = DeserializeValue<{_Emitter._GetRuntimeName(etype)}>(reader);");
+
+                    continue;
+                }
+
+                this.AddFieldSerializerCase(_GetJSonSerializerMethod(f));
+                this.AddFieldDeserializerCase(f.PersistentName, _GetJSonDeserializerMethod(f));
+            }
         }
-        
+
         private string _GetJSonSerializerMethod(FieldInfo f)
         {
             var pname = f.PersistentName;
-            var fname = GetFieldRuntimeName(f);
+            var fname = _Emitter.GetFieldRuntimeName(f);
 
             if (f.FieldType is ClassType ctype)
             {
-                return $"SerializePropertyObject(writer,\"{pname}\",{fname});";                
+                return $"SerializePropertyObject(writer,\"{pname}\",{fname});";
             }
 
             if (f.FieldType is ArrayType atype)
@@ -498,44 +540,22 @@ namespace Epsylon.glTF2Toolkit.CodeGen
 
         private string _GetJSonDeserializerMethod(FieldInfo f)
         {
-            var fname = GetFieldRuntimeName(f);
+            var fname = _Emitter.GetFieldRuntimeName(f);
 
             if (f.FieldType is ArrayType atype)
             {
-                var titem = _GetRuntimeName(atype.ItemType);
+                var titem = _Emitter._GetRuntimeName(atype.ItemType);
                 return $"DeserializeList<{titem}>(reader,{fname});";
             }
             else if (f.FieldType is DictionaryType dtype)
             {
-                var titem = _GetRuntimeName(dtype.ValueType);
+                var titem = _Emitter._GetRuntimeName(dtype.ValueType);
                 return $"DeserializeDictionary<{titem}>(reader,{fname});";
-            }            
+            }
 
-            return $"{fname} = DeserializeValue<{_GetRuntimeName(f.FieldType)}>(reader);";            
+            return $"{fname} = DeserializeValue<{_Emitter._GetRuntimeName(f.FieldType)}>(reader);";
         }        
 
-        #endregion
-    }
-
-    class CSharpClassEmitter
-    {
-        public CSharpClassEmitter(CSharpEmitter emitter)
-        {
-            _Emitter = emitter;            
-        }
-
-        private readonly CSharpEmitter _Emitter;
-
-        private readonly List<string> _Fields = new List<string>();
-        private readonly List<string> _SerializerBody = new List<string>();
-        private readonly List<string> _DeserializerSwitchBody = new List<string>();
-
-        public string ClassDeclaration { get; set; }
-
-        public bool HasBaseClass { get; set; }
-
-        public void AddFields(IEnumerable<string> lines) { _Fields.AddRange(lines); }
-
         public void AddFieldSerializerCase(string line) { _SerializerBody.Add(line); }
 
         public void AddFieldDeserializerCase(string persistentName, string line)
@@ -578,5 +598,7 @@ namespace Epsylon.glTF2Toolkit.CodeGen
 
             yield return "}";
         }
+
+        #endregion
     }
 }

+ 1 - 1
src/glTF2Sharp.CodeGen/Constants.cs

@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 using System.Text;
 
-namespace Epsylon.glTF2Toolkit.CodeGen
+namespace glTF2Sharp
 {
     static class Constants
     {

+ 5 - 11
src/glTF2Sharp.CodeGen/Program.cs

@@ -6,11 +6,10 @@ using System.Text;
 using System.Threading.Tasks;
 using NJsonSchema.References;
 
-namespace Epsylon.glTF2Toolkit.CodeGen
+namespace glTF2Sharp
 {
-    // https://github.com/RSuter/NJsonSchema
-    // https://github.com/RSuter/NJsonSchema/issues/378
-    // https://github.com/RSuter/NJsonSchema/issues/377        
+    using CodeGen;
+    using SchemaReflection;    
 
     class Program
     {
@@ -237,7 +236,7 @@ namespace Epsylon.glTF2Toolkit.CodeGen
             var ctypes = new NJsonSchema.CodeGeneration.CSharp.CSharpTypeResolver(settings);
             ctypes.Resolve(schema, false, null);
 
-            return PersistentSchema.Generate(ctypes);
+            return SchemaTypesReader.Generate(ctypes);
         }
 
         static NJsonSchema.JsonSchema4 LoadSchema(string filePath)
@@ -278,10 +277,5 @@ namespace Epsylon.glTF2Toolkit.CodeGen
         }
 
         #endregion
-    }
-
-
-
-
-    
+    }    
 }

+ 4 - 1
src/glTF2Sharp.CodeGen/SchemaDownload.cs

@@ -2,8 +2,11 @@
 using System.Collections.Generic;
 using System.Text;
 
-namespace Epsylon.glTF2Toolkit.CodeGen
+namespace glTF2Sharp
 {
+    /// <summary>
+    /// Utility class to download the gltf2 schema from github
+    /// </summary>
     static class SchemaDownload
     {
         public static void Syncronize(string remoteUrl, string localDirectory)

+ 108 - 118
src/glTF2Sharp.CodeGen/PersistentSchema.Types.cs → src/glTF2Sharp.CodeGen/SchemaReflection/SchemaTypes.cs

@@ -4,147 +4,76 @@ using System.Linq;
 using System.Reflection;
 using System.Text;
 
-namespace Epsylon.glTF2Toolkit.CodeGen
+namespace glTF2Sharp.SchemaReflection
 {
-    // this is a mechanism to define serializable types, pretty much like Type and TypeInfo,
-    // but the types can be defined as "Virtual Types" because they don't actually exist.
-    // .
-    // this is useful to emit source code from schemas, since the types to emit don't exist prior emission.
-    // .
-    // Alternatives:
-    // 1. Type and TypeInfo inherit from MemberInfo and IReflect ... but in the end, you must implement a lot of code
-    // 2. Roslyn has a mechanism to define types, but it's missing the "emit serialization" part.
-
-
-
-    // In here we define a schema intended only for serialization
-    
-
-    public abstract class SchemaType
+    /// <summary>
+    /// Base class for all schema Types
+    /// </summary>
+    public abstract partial class SchemaType
     {
-        protected SchemaType(Context ctx) { _Owner = ctx; }
-
-        internal readonly Context _Owner;
-
-        protected Context Owner => _Owner;
-
-        public abstract string PersistentName { get; }
-
-        public sealed class Context
-        {
-            #region data
-
-            private readonly Dictionary<string, SchemaType> _Types = new Dictionary<string, SchemaType>();
-
-            private TypeInfo _RefType;
-
-            #endregion
-
-            #region properties
-
-            public IEnumerable<EnumType> Enumerations => _Types.Values.OfType<EnumType>();
-
-            public IEnumerable<ClassType> Classes => _Types.Values.OfType<ClassType>();
-
-            #endregion
-
-            #region API
-
-            private SchemaType _UseOrCreate(SchemaType item)
-            {
-                if (_Types.TryGetValue(item.PersistentName, out SchemaType value)) return value;
-
-                _Types[item.PersistentName] = item;
-
-                return item;
-            }
-
-            public ObjectType UseAnyType()
-            {
-                var item = new ObjectType(this);
-                return (ObjectType)_UseOrCreate(item);
-            }
-
-            public StringType UseString()
-            {
-                var item = new StringType(this);
-                return (StringType)_UseOrCreate(item);
-            }
+        #region constructor
 
-            public BlittableType UseBlittable(TypeInfo t, bool isNullable = false)
-            {
-                if (t == null || !t.IsValueType) throw new ArgumentException(nameof(t));
-
-                var item = new BlittableType(this, t, isNullable);
-                return (BlittableType)_UseOrCreate(item);
-            }
+        protected SchemaType(Context ctx) { _Owner = ctx; }
 
-            public EnumType UseEnum(string name, bool isNullable = false)
-            {
-                var item = new EnumType(this, name, isNullable);
-                return (EnumType)_UseOrCreate(item);
-            }
+        #endregion
 
-            public EnumType GetEnum(string name)
-            {
-                return _Types.TryGetValue(name, out SchemaType etype) ? etype as EnumType : null;
-            }            
+        #region data
 
-            public ArrayType UseArray(SchemaType elementType)
-            {
-                var item = new ArrayType(this,elementType);
-                return (ArrayType)_UseOrCreate(item);                
-            }            
+        /// <summary>
+        /// context where this type is stored
+        /// </summary>
+        private readonly Context _Owner;        
 
-            public DictionaryType UseDictionary(SchemaType key, SchemaType val)
-            {
-                var item = new DictionaryType(this, key,val);
-                return (DictionaryType)_UseOrCreate(item);
-            }
+        /// <summary>
+        /// identifier used for serialization and deserialization
+        /// </summary>
+        public abstract string PersistentName { get; }
 
-            public ClassType UseClass(string name)
-            {
-                var item = new ClassType(this, name);
-                return (ClassType)_UseOrCreate(item);
-            }
+        #endregion
 
-            public void Remove(SchemaType type) { _Types.Remove(type.PersistentName); }
+        #region properties
 
-            public void Remove(string persistentName)
-            {
-                _Types.Remove(persistentName);
-            }
+        public Context Owner => _Owner;
 
-            #endregion
-        }        
+        #endregion
     }
 
     [System.Diagnostics.DebuggerDisplay("{PersistentName}")]
     public sealed class StringType : SchemaType
     {
-        // https://en.wikipedia.org/wiki/Blittable_types        
+        #region constructor
 
         internal StringType(Context ctx) : base(ctx) { }
 
-        public override string PersistentName => typeof(String).Name;        
+        #endregion
+
+        #region properties
+
+        public override string PersistentName => typeof(String).Name;
+
+        #endregion
     }
 
     [System.Diagnostics.DebuggerDisplay("{PersistentName}")]
     public sealed class ObjectType : SchemaType
     {
-        // https://en.wikipedia.org/wiki/Blittable_types        
+        #region constructor
 
         internal ObjectType(Context ctx) : base(ctx) { }
 
+        #endregion
+
+        #region properties
+
         public override string PersistentName => typeof(Object).Name;
 
-        
+        #endregion
     }
 
     [System.Diagnostics.DebuggerDisplay("{PersistentName}")]
-    public sealed class BlittableType : SchemaType // blittable
+    public sealed class BlittableType : SchemaType
     {
-        // https://en.wikipedia.org/wiki/Blittable_types        
+        #region constructor        
 
         internal BlittableType(Context ctx, TypeInfo t, bool isNullable) : base(ctx)
         {
@@ -152,35 +81,56 @@ namespace Epsylon.glTF2Toolkit.CodeGen
 
             _Type = t;
             _IsNullable = isNullable;
-        }        
+        }
+
+        #endregion
+
+        #region data
+
+        // https://en.wikipedia.org/wiki/Blittable_types
 
         private readonly TypeInfo _Type;
         private readonly Boolean _IsNullable;
 
+        #endregion
+
+        #region properties
+
         public TypeInfo DataType => _Type;
 
         public bool IsNullable => _IsNullable;
 
-        public override string PersistentName => _IsNullable ? $"{_Type.Name}?" : _Type.Name;        
-    }
+        public override string PersistentName => _IsNullable ? $"{_Type.Name}?" : _Type.Name;
 
-    
+        #endregion
+    }    
 
     [System.Diagnostics.DebuggerDisplay("enum {PersistentName}")]
     public sealed class EnumType : SchemaType
     {
+        #region constructor
+
         internal EnumType(Context ctx, string name, bool isNullable) : base(ctx)
         {
             _PersistentName = name;
             _IsNullable = isNullable;
         }
 
+        #endregion
+
+        #region data
+
         private readonly String _PersistentName;
         private readonly Boolean _IsNullable;
 
         private bool _UseIntegers;
+
         private readonly Dictionary<string, int> _Values = new Dictionary<string, int>();
 
+        #endregion
+
+        #region properties
+
         public bool IsNullable => _IsNullable;
 
         public override string PersistentName => _PersistentName;
@@ -191,22 +141,40 @@ namespace Epsylon.glTF2Toolkit.CodeGen
 
         public IEnumerable<KeyValuePair<string, int>> Values => _Values;
 
-        public void SetValue(string key, int val) { _Values[key] = val; }        
+        #endregion
+
+        #region API
+
+        public void SetValue(string key, int val) { _Values[key] = val; }
+
+        #endregion
     }
 
     [System.Diagnostics.DebuggerDisplay("{PersistentName}")]
     public sealed class ArrayType : SchemaType
     {
+        #region constructor
+
         internal ArrayType(Context ctx, SchemaType element) : base(ctx)
         {
             _ItemType = element;
         }
 
+        #endregion
+
+        #region data
+
         private readonly SchemaType _ItemType;
 
         public SchemaType ItemType => _ItemType;
 
-        public override string PersistentName => $"{_ItemType.PersistentName}[]";        
+        #endregion
+
+        #region properties
+
+        public override string PersistentName => $"{_ItemType.PersistentName}[]";
+
+        #endregion
     }    
 
     [System.Diagnostics.DebuggerDisplay("{PersistentName}")]
@@ -291,7 +259,7 @@ namespace Epsylon.glTF2Toolkit.CodeGen
 
         public FieldInfo SetDataType(Type type, bool isNullable)
         {
-            _FieldType = _Owner._Owner.UseBlittable(type.GetTypeInfo(), isNullable);
+            _FieldType = DeclaringClass.Owner.UseBlittable(type.GetTypeInfo(), isNullable);
             return this;
         }
 
@@ -330,11 +298,17 @@ namespace Epsylon.glTF2Toolkit.CodeGen
     [System.Diagnostics.DebuggerDisplay("class {PersistentName} : {BaseClass.PersistentName}")]
     public sealed class ClassType : SchemaType
     {
+        #region constructor
+
         internal ClassType(Context ctx, string name) : base(ctx)
         {
             _PersistentName = name;            
         }
 
+        #endregion
+
+        #region data
+
         private readonly String _PersistentName;        
 
         private readonly HashSet<FieldInfo> _Fields = new HashSet<FieldInfo>(FieldInfo.Comparer);
@@ -347,6 +321,10 @@ namespace Epsylon.glTF2Toolkit.CodeGen
 
         public IEnumerable<FieldInfo> Fields => _Fields;
 
+        #endregion
+
+        #region API
+
         public FieldInfo UseField(string name)
         {
             var f = new FieldInfo(this, name);
@@ -354,23 +332,35 @@ namespace Epsylon.glTF2Toolkit.CodeGen
             _Fields.Add(f);
 
             return _Fields.FirstOrDefault(item => item.PersistentName == name);
-        }        
+        }
+
+        #endregion
     }
 
-    
+    /// <summary>
+    /// not used
+    /// </summary>
     public sealed class ReferenceType : SchemaType
     {
+        #region constructor
+
         internal ReferenceType(Context ctx, SchemaType refType) : base(ctx)
         {
             _ReferencedType = refType;
         }
 
+        #endregion
+
+        #region data
+
         // In code it has the representation List<Node>();
         // In serialization, it has the representation List<int>();
 
         private readonly SchemaType _ReferencedType;
 
-        public override string PersistentName => throw new NotImplementedException();        
+        public override string PersistentName => throw new NotImplementedException();
+
+        #endregion
     }
 
         

+ 91 - 0
src/glTF2Sharp.CodeGen/SchemaReflection/SchemaTypesContext.cs

@@ -0,0 +1,91 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+
+namespace glTF2Sharp.SchemaReflection
+{
+    public partial class SchemaType
+    {
+        /// <summary>
+        /// Collection class that contains all the types found in a json schema.
+        /// </summary>
+        public sealed class Context
+        {
+            #region data
+
+            private readonly Dictionary<string, SchemaType> _Types = new Dictionary<string, SchemaType>();            
+
+            #endregion
+
+            #region properties
+
+            /// <summary>
+            /// returns all the <see cref="enum"/> types.
+            /// </summary>
+            public IEnumerable<EnumType> Enumerations => _Types.Values.OfType<EnumType>();
+
+            /// <summary>
+            /// returns all the <see cref="class"/> types.
+            /// </summary>
+            public IEnumerable<ClassType> Classes => _Types.Values.OfType<ClassType>();
+
+            #endregion
+
+            #region API
+
+            /// <summary>
+            /// Creates a new type or uses an existing one if it already exists.
+            /// </summary>
+            /// <param name="item">a newly created type</param>
+            /// <returns>A stored type if it already exist, or the newly created type</returns>
+            private SchemaType _UseOrCreate(SchemaType item)
+            {
+                if (_Types.TryGetValue(item.PersistentName, out SchemaType value)) return value;
+
+                _Types[item.PersistentName] = item;
+
+                return item;
+            }
+
+            public ObjectType UseAnyType() { return (ObjectType)_UseOrCreate( new ObjectType(this) ); }
+
+            public StringType UseString() { return (StringType)_UseOrCreate( new StringType(this) ); }
+
+            public ArrayType UseArray(SchemaType elementType) { return (ArrayType)_UseOrCreate( new ArrayType(this, elementType) ); }
+
+            public ClassType UseClass(string name) { return (ClassType)_UseOrCreate(new ClassType(this, name)); }
+
+            public BlittableType UseBlittable(TypeInfo t, bool isNullable = false)
+            {
+                if (t == null || !t.IsValueType) throw new ArgumentException(nameof(t));
+
+                var item = new BlittableType(this, t, isNullable);
+                return (BlittableType)_UseOrCreate(item);
+            }
+
+            public EnumType UseEnum(string name, bool isNullable = false)
+            {
+                var item = new EnumType(this, name, isNullable);
+                return (EnumType)_UseOrCreate(item);
+            }
+
+            public EnumType GetEnum(string name)
+            {
+                return _Types.TryGetValue(name, out SchemaType etype) ? etype as EnumType : null;
+            }            
+
+            public DictionaryType UseDictionary(SchemaType key, SchemaType val)
+            {                
+                return (DictionaryType)_UseOrCreate( new DictionaryType(this, key, val) );
+            }            
+
+            public void Remove(SchemaType type) { _Types.Remove(type.PersistentName); }
+
+            public void Remove(string persistentName) { _Types.Remove(persistentName); }
+
+            #endregion
+        }
+    }
+}

+ 26 - 9
src/glTF2Sharp.CodeGen/PersistentSchema.Builder.cs → src/glTF2Sharp.CodeGen/SchemaReflection/SchemaTypesReader.cs

@@ -4,23 +4,38 @@ using System.Linq;
 using System.Reflection;
 using System.Text;
 
-namespace Epsylon.glTF2Toolkit.CodeGen
+namespace glTF2Sharp.SchemaReflection
 {
-    static class PersistentSchema
+    /// <summary>
+    /// Utility class that reads a json schema and creates a <see cref="SchemaType.Context"/>
+    /// Which is a collection of Schema Types resembling <see cref="System.Type"/>
+    /// </summary>
+    static class SchemaTypesReader
     {
+        // issues related to gltf2 schema parsing:
+        // https://github.com/RSuter/NJsonSchema
+        // https://github.com/RSuter/NJsonSchema/issues/378
+        // https://github.com/RSuter/NJsonSchema/issues/377
+
+        #region API
+
         public static SchemaType.Context Generate(NJsonSchema.CodeGeneration.CSharp.CSharpTypeResolver types)
         {
             var context = new SchemaType.Context();
 
             foreach(var t in types.Types.Keys)
             {
-                context.UseType(t);
+                context._UseType(t);
             }
 
             return context;
         }
 
-        public static SchemaType UseType(this SchemaType.Context ctx, NJsonSchema.JsonSchema4 schema, bool isRequired = true)
+        #endregion
+
+        #region core
+
+        private static SchemaType _UseType(this SchemaType.Context ctx, NJsonSchema.JsonSchema4 schema, bool isRequired = true)
         {
             if (ctx == null) throw new ArgumentNullException(nameof(ctx));
             if (schema == null) throw new ArgumentNullException(nameof(schema));
@@ -50,11 +65,11 @@ namespace Epsylon.glTF2Toolkit.CodeGen
                 throw new NotImplementedException();
             }            
 
-            if (schema.HasReference) return ctx.UseType(schema.ActualTypeSchema, isRequired); // we could have our own ref
+            if (schema.HasReference) return ctx._UseType(schema.ActualTypeSchema, isRequired); // we could have our own ref
 
             if (schema.IsArray)
             {
-                return ctx.UseArray(ctx.UseType(schema.Item.ActualSchema));
+                return ctx.UseArray(ctx._UseType(schema.Item.ActualSchema));
             }
 
             if (_IsEnumeration(schema))
@@ -99,7 +114,7 @@ namespace Epsylon.glTF2Toolkit.CodeGen
             if (_IsDictionary(schema))
             {
                 var key = ctx.UseString();
-                var val = ctx.UseType(_GetDictionaryValue(schema));
+                var val = ctx._UseType(_GetDictionaryValue(schema));
 
                 return ctx.UseDictionary(key, val);
             }
@@ -110,7 +125,7 @@ namespace Epsylon.glTF2Toolkit.CodeGen
 
                 // process base class                
 
-                if (schema.InheritedSchema != null) classDecl.BaseClass = ctx.UseType(schema.InheritedSchema) as ClassType;
+                if (schema.InheritedSchema != null) classDecl.BaseClass = ctx._UseType(schema.InheritedSchema) as ClassType;
 
                 // filter declared properties
 
@@ -132,7 +147,7 @@ namespace Epsylon.glTF2Toolkit.CodeGen
                 foreach(var p in props)
                 {
                     var field = classDecl.UseField(p.Name);
-                    field.FieldType = ctx.UseType(p, required.Contains(p.Name));
+                    field.FieldType = ctx._UseType(p, required.Contains(p.Name));
 
                     field.MinimumValue = p.Minimum;
                     field.MaximumValue = p.Maximum;
@@ -232,5 +247,7 @@ namespace Epsylon.glTF2Toolkit.CodeGen
                 .Concat(_GetProperyNames(schema.InheritedSchema))
                 .ToArray();
         }
+
+        #endregion
     }
 }

+ 1 - 0
src/glTF2Sharp.CodeGen/glTF2Sharp.CodeGen.csproj

@@ -3,6 +3,7 @@
   <PropertyGroup>
     <OutputType>Exe</OutputType>
     <TargetFramework>netcoreapp2.1</TargetFramework>
+    <RootNamespace>glTF2Sharp</RootNamespace>
   </PropertyGroup>
 
   <ItemGroup>