protected void Allow(CLIType left, params CLIType[] right) { foreach (var r in right) { allowedTypes[(int)left, (int)r] = true; } }
private bool IsAllowed(CLIType left, CLIType right) { return(allowedTypes[(int)left, (int)right]); }
private static ESType FindCommonType(CLIType cliType, ESType first, ESType second) { if (first.ToType() == null) { return(second); } if (second.ToType() == null) { return(first); } switch (cliType) { case CLIType.Int32: return(new SimpleESType(typeof(int))); case CLIType.Int64: return(new SimpleESType(typeof(long))); case CLIType.Float: return(new SimpleESType(typeof(double))); case CLIType.NativeInt: { if (((SimpleESType)first).Type.IsPointer && ((SimpleESType)second).Type.IsPointer) { return(new SimpleESType(typeof(void).MakePointerType())); } return(new SimpleESType(typeof(IntPtr))); } case CLIType.Pointer: { var firstElementType = ((SimpleESType)first).Type.GetElementType(); var secondElementType = ((SimpleESType)second).Type.GetElementType(); if (!firstElementType.IsValueType || !secondElementType.IsValueType) { return(null); } return(Marshal.SizeOf(firstElementType) <= Marshal.SizeOf(secondElementType) ? first : second); } case CLIType.Struct: return(null); case CLIType.Object: { var baseType = first.ToType().FindBaseClassWith(second.ToType()); var firstInterfaces = new HashSet <Type>(new ReflectionExtensions.TypesComparer()); if (first is SimpleESType) { ((SimpleESType)first).Type.GetInterfacesCollectionStupid(firstInterfaces); } else { ((ComplexESType)first).BaseType.GetInterfacesCollectionStupid(firstInterfaces); foreach (var interfaCe in ((ComplexESType)first).Interfaces) { firstInterfaces.Add(interfaCe); } } var secondInterfaces = new HashSet <Type>(new ReflectionExtensions.TypesComparer()); if (second is SimpleESType) { ((SimpleESType)second).Type.GetInterfacesCollectionStupid(secondInterfaces); } else { ((ComplexESType)second).BaseType.GetInterfacesCollectionStupid(secondInterfaces); foreach (var interfaCe in ((ComplexESType)second).Interfaces) { secondInterfaces.Add(interfaCe); } } HashSet <Type> intersected; if (firstInterfaces.Count > secondInterfaces.Count) { firstInterfaces.IntersectWith(secondInterfaces); intersected = firstInterfaces; } else { secondInterfaces.IntersectWith(firstInterfaces); intersected = secondInterfaces; } intersected.Add(baseType); //var firstInterfaces = ((first is SimpleESType) // ? ((SimpleESType)first).Type.GetTypesArray() // : ((ComplexESType)first).BaseType.GetTypesArray().Concat(((ComplexESType)first).Interfaces)).Where(t => t.IsInterface).ToArray(); //var secondInterfaces = ((second is SimpleESType) // ? ((SimpleESType)second).Type.GetTypesArray() // : ((ComplexESType)second).BaseType.GetTypesArray().Concat(((ComplexESType)second).Interfaces)).Where(t => t.IsInterface).ToArray(); //var hashSet = new HashSet<Type>(firstInterfaces.Intersect(secondInterfaces).Concat(new[] {baseType}), new ReflectionExtensions.TypesComparer()); while (true) { var end = true; foreach (var type in intersected.ToArray()) { var children = ReflectionExtensions.GetInterfaces(type); foreach (var child in children) { if (intersected.Contains(child)) { end = false; intersected.Remove(child); } } } if (end) { break; } } intersected.Remove(baseType); if (intersected.Count == 0) { return(new SimpleESType(baseType)); } return(new ComplexESType(baseType, intersected.ToArray())); } default: throw new InvalidOperationException($"CLI type '{cliType}' is not valid at this point"); } }