Browse Source

Support CSComponent descendants other than direct subclasses

Matt Benic 9 years ago
parent
commit
be974c2fff

+ 161 - 136
Script/AtomicNET/AtomicNETService/AssemblyInspector.cs

@@ -17,210 +17,235 @@ using File = System.IO.File;
 namespace AtomicTools
 {
 
-	class AssemblyInspector
-	{
+    class AssemblyInspector
+    {
 
-		Dictionary<string, InspectorEnum> InspectorEnums = new Dictionary<string, InspectorEnum> ();
-		Dictionary<string, InspectorComponent> InspectorComponents = new Dictionary<string, InspectorComponent> ();
+        Dictionary<string, InspectorEnum> InspectorEnums = new Dictionary<string, InspectorEnum>();
+        Dictionary<string, InspectorComponent> InspectorComponents = new Dictionary<string, InspectorComponent>();
 
-		PEReader peFile;
-		MetadataReader metaReader;
+        PEReader peFile;
+        MetadataReader metaReader;
 
-		public AssemblyInspector ()
-		{
+        public AssemblyInspector()
+        {
 
-		}
+        }
 
-		public string DumpToJSON ()
-		{
-			var dict = new Dictionary<string, object> ();
+        public string DumpToJSON()
+        {
+            var dict = new Dictionary<string, object>();
 
-			var enumList = new List<object> ();
-			var componentList = new List<object> ();
+            var enumList = new List<object>();
+            var componentList = new List<object>();
 
-			foreach (var entry in InspectorEnums) {
-				enumList.Add (entry.Value.GetJSONDict ());
-			}
+            foreach (var entry in InspectorEnums)
+            {
+                enumList.Add(entry.Value.GetJSONDict());
+            }
 
-			foreach (var entry in InspectorComponents) {
-				componentList.Add (entry.Value.GetJSONDict ());
-			}
+            foreach (var entry in InspectorComponents)
+            {
+                componentList.Add(entry.Value.GetJSONDict());
+            }
 
-			dict ["enums"] = enumList;
-			dict ["components"] = componentList;
+            dict["enums"] = enumList;
+            dict["components"] = componentList;
 
-			return MiniJSON.Json.Serialize (dict);
+            return MiniJSON.Json.Serialize(dict);
 
-		}
+        }
 
-		public void Inspect (String pathToAssembly)
-		{
+        public void Inspect(String pathToAssembly)
+        {
 
-			using (var stream = File.OpenRead (pathToAssembly))
-			using (peFile = new PEReader (stream)) {
+            using (var stream = File.OpenRead(pathToAssembly))
+            using (peFile = new PEReader(stream))
+            {
 
-				metaReader = peFile.GetMetadataReader ();
+                metaReader = peFile.GetMetadataReader();
 
-				ParseEnums ();
-				ParseComponents ();
-			}
+                ParseEnums();
+                ParseComponents();
+            }
 
-		}
+        }
 
-		void ParseComponents ()
-		{
+        void ParseComponents()
+        {
 
-			foreach (var handle in metaReader.TypeDefinitions) {
+            foreach (var handle in metaReader.TypeDefinitions)
+            {
 
-				var typeDef = metaReader.GetTypeDefinition (handle);
+                var typeDef = metaReader.GetTypeDefinition(handle);
 
-				var baseTypeHandle = typeDef.BaseType;
+                var parentName = metaReader.GetString(typeDef.Name);
 
-				if (baseTypeHandle.Kind == HandleKind.TypeReference) {
+                var baseTypeHandle = typeDef.BaseType;
 
-					var typeRef = metaReader.GetTypeReference ((TypeReferenceHandle)baseTypeHandle);
+                // Work up to base reference (ie defined outside this assembly)
+                while (baseTypeHandle.Kind == HandleKind.TypeDefinition)
+                {
+                    var baseTypeDef = metaReader.GetTypeDefinition((TypeDefinitionHandle)baseTypeHandle);
+                    // No way to predetermine if .BaseType is valid
+                    try
+                    {
+                        baseTypeHandle = baseTypeDef.BaseType;
+                    }
+                    catch (Exception) { break; }
+                }
 
-                    var name = metaReader.GetString (typeRef.Name); 
+                if (baseTypeHandle.Kind == HandleKind.TypeReference)
+                {
 
-					if (name != "CSComponent")
-						continue;
+                    var typeRef = metaReader.GetTypeReference((TypeReferenceHandle)baseTypeHandle);
 
-					var inspector = new CSComponentInspector (typeDef, peFile, metaReader);
+                    var name = metaReader.GetString(typeRef.Name);
 
-					var icomponent = inspector.Inspect ();
+                    if (name != "CSComponent")
+                        continue;
 
-					if (icomponent != null)
-						InspectorComponents [icomponent.Name] = icomponent;
-				}
-			}
-		}
+                    var inspector = new CSComponentInspector(typeDef, peFile, metaReader);
 
+                    var icomponent = inspector.Inspect();
 
-		void ParseEnums ()
-		{
-			foreach (var handle in metaReader.TypeDefinitions) {
+                    if (icomponent != null)
+                        InspectorComponents[icomponent.Name] = icomponent;
+                }
+            }
+        }
 
-				var typeDef = metaReader.GetTypeDefinition (handle);
 
-				var baseTypeHandle = typeDef.BaseType;
+        void ParseEnums()
+        {
+            foreach (var handle in metaReader.TypeDefinitions)
+            {
 
-				if (baseTypeHandle.Kind == HandleKind.TypeReference) {
-					var typeRef = metaReader.GetTypeReference ((TypeReferenceHandle)baseTypeHandle);
+                var typeDef = metaReader.GetTypeDefinition(handle);
 
-					if (metaReader.GetString (typeRef.Name) == "Enum") {
-						ParseEnum (typeDef);
-					}
-				}
-			}
-		}
+                var baseTypeHandle = typeDef.BaseType;
 
-		void ParseEnum (TypeDefinition enumTypeDef)
-		{
+                if (baseTypeHandle.Kind == HandleKind.TypeReference)
+                {
+                    var typeRef = metaReader.GetTypeReference((TypeReferenceHandle)baseTypeHandle);
 
-			// TODO: verify that int32 is the enums storage type for constant read below
+                    if (metaReader.GetString(typeRef.Name) == "Enum")
+                    {
+                        ParseEnum(typeDef);
+                    }
+                }
+            }
+        }
 
-			InspectorEnum ienum = new InspectorEnum ();
+        void ParseEnum(TypeDefinition enumTypeDef)
+        {
 
-			ienum.Name = metaReader.GetString (enumTypeDef.Name);
+            // TODO: verify that int32 is the enums storage type for constant read below
 
-			InspectorEnums [ienum.Name] = ienum;
+            InspectorEnum ienum = new InspectorEnum();
 
-			var fields = enumTypeDef.GetFields ();
+            ienum.Name = metaReader.GetString(enumTypeDef.Name);
 
-			foreach (var fieldHandle in fields) {
+            InspectorEnums[ienum.Name] = ienum;
 
-				var inspectorField = new InspectorField ();
+            var fields = enumTypeDef.GetFields();
 
-				var fieldDef = metaReader.GetFieldDefinition (fieldHandle);
+            foreach (var fieldHandle in fields)
+            {
 
-				if ((fieldDef.Attributes & FieldAttributes.HasDefault) != 0) {
+                var inspectorField = new InspectorField();
 
-					var constantHandle = fieldDef.GetDefaultValue ();
-					var constant = metaReader.GetConstant (constantHandle);
+                var fieldDef = metaReader.GetFieldDefinition(fieldHandle);
 
-					BlobReader constantReader = metaReader.GetBlobReader (constant.Value);
+                if ((fieldDef.Attributes & FieldAttributes.HasDefault) != 0)
+                {
 
-					ienum.Values [metaReader.GetString (fieldDef.Name)] = constantReader.ReadInt32 ();
+                    var constantHandle = fieldDef.GetDefaultValue();
+                    var constant = metaReader.GetConstant(constantHandle);
 
-				}
-			}
+                    BlobReader constantReader = metaReader.GetBlobReader(constant.Value);
 
-			return;
+                    ienum.Values[metaReader.GetString(fieldDef.Name)] = constantReader.ReadInt32();
 
-		}
-	}
+                }
+            }
 
-	internal class InspectorEnum
-	{
-		public String Name;
-		public Dictionary<string, int> Values = new Dictionary<string, int> ();
+            return;
 
-		public Dictionary<string, object> GetJSONDict ()
-		{
-			var dict = new Dictionary<string,object> ();
-			dict ["name"] = Name;
-			dict ["values"] = Values;
-			return dict;
-		}
-	}
+        }
+    }
 
-	internal class InspectorComponent
-	{
-		public String Name;
-		public String Namespace;
-		public Dictionary<string, InspectorField> Fields = new Dictionary<string, InspectorField> ();
+    internal class InspectorEnum
+    {
+        public String Name;
+        public Dictionary<string, int> Values = new Dictionary<string, int>();
 
-		public Dictionary<string, object> GetJSONDict ()
-		{
-			var dict = new Dictionary<string,object> ();
+        public Dictionary<string, object> GetJSONDict()
+        {
+            var dict = new Dictionary<string, object>();
+            dict["name"] = Name;
+            dict["values"] = Values;
+            return dict;
+        }
+    }
 
-			dict ["name"] = Name;
-			dict ["namespace"] = Namespace;
+    internal class InspectorComponent
+    {
+        public String Name;
+        public String Namespace;
+        public Dictionary<string, InspectorField> Fields = new Dictionary<string, InspectorField>();
 
-			var fieldList = new List<object> ();
+        public Dictionary<string, object> GetJSONDict()
+        {
+            var dict = new Dictionary<string, object>();
 
-			foreach (var entry in Fields) {
-				fieldList.Add (entry.Value.GetJSONDict ());
-			}
+            dict["name"] = Name;
+            dict["namespace"] = Namespace;
 
-			dict ["fields"] = fieldList;
+            var fieldList = new List<object>();
 
-			return dict;
-		}
-	}
+            foreach (var entry in Fields)
+            {
+                fieldList.Add(entry.Value.GetJSONDict());
+            }
 
-	internal class InspectorField
-	{
+            dict["fields"] = fieldList;
 
-		public Dictionary<string, object> GetJSONDict ()
-		{
+            return dict;
+        }
+    }
 
-			var dict = new Dictionary<string,object> ();
+    internal class InspectorField
+    {
 
-			dict ["isEnum"] = IsEnum;
-			dict ["typeName"] = TypeName;
-			dict ["name"] = Name;
-			dict ["defaultValue"] = DefaultValue;
+        public Dictionary<string, object> GetJSONDict()
+        {
 
-			dict ["caPos"] = CustomAttrPositionalArgs;
-			dict ["caNamed"] = CustomAttrNamedArgs;
+            var dict = new Dictionary<string, object>();
 
-			return dict;
+            dict["isEnum"] = IsEnum;
+            dict["typeName"] = TypeName;
+            dict["name"] = Name;
+            dict["defaultValue"] = DefaultValue;
 
-		}
+            dict["caPos"] = CustomAttrPositionalArgs;
+            dict["caNamed"] = CustomAttrNamedArgs;
 
-		public bool IsEnum = false;
+            return dict;
 
-		public string TypeName;
+        }
 
-		// the Name of the InspectorField
-		public string Name;
-		// The DefaultValue if supplied
-		public string DefaultValue;
+        public bool IsEnum = false;
 
-		// custom attributes, positional and named
-		public List<string> CustomAttrPositionalArgs = new List<string> ();
-		public Dictionary<string, string> CustomAttrNamedArgs = new Dictionary<string, string> ();
-	}
+        public string TypeName;
+
+        // the Name of the InspectorField
+        public string Name;
+        // The DefaultValue if supplied
+        public string DefaultValue;
+
+        // custom attributes, positional and named
+        public List<string> CustomAttrPositionalArgs = new List<string>();
+        public Dictionary<string, string> CustomAttrNamedArgs = new Dictionary<string, string>();
+    }
 
 }

File diff suppressed because it is too large
+ 702 - 627
Script/AtomicNET/AtomicNETService/CSComponentInspector.cs


+ 3 - 3
Source/ToolCore/JSBind/CSharp/CSFunctionWriter.cpp

@@ -624,9 +624,9 @@ void CSFunctionWriter::WriteManagedConstructor(String& source)
 
     source += IndentLine(ToString("var classType = typeof(%s);\n", klass->GetName().CString()));
     source += IndentLine("var thisType = this.GetType();\n");
-    source += IndentLine("var nativeThisType = NativeCore.IsNativeType(thisType);\n");    
-    source += IndentLine("var nativeBaseType = NativeCore.IsNativeType(thisType.BaseType);\n");
-    source += IndentLine("if ( (nativeThisType && (thisType == classType)) || (!nativeThisType && (nativeBaseType && (thisType.BaseType == classType))))\n");
+    source += IndentLine("var thisTypeIsNative = NativeCore.IsNativeType(thisType);\n");    
+    source += IndentLine("var nativeAncsestorType = NativeCore.GetNativeAncestorType(thisType);\n");
+    source += IndentLine("if ( (thisTypeIsNative && (thisType == classType)) || (!thisTypeIsNative && (nativeAncsestorType == classType)))\n");
     source += IndentLine("{\n");
 
     Indent();

Some files were not shown because too many files changed in this diff