protected static void CheckCanBeAssigned(GroboIL il, Type to, ESType from) { if (!CanBeAssigned(to, from, il.VerificationKind)) { ThrowError(il, $"Unable to set a value of type '{@from}' to an instance of type '{Formatter.Format(to)}'"); } }
private static bool EqualESTypes(ESType first, ESType second) { if ((first is SimpleESType) ^ (second is SimpleESType)) { return(false); } if (first.ToType() != second.ToType()) { return(false); } if (first is SimpleESType) { return(true); } var firstInterfaces = new HashSet <Type>(((ComplexESType)first).Interfaces); var secondInterfaces = ((ComplexESType)second).Interfaces; foreach (var type in secondInterfaces) { if (!firstInterfaces.Contains(type)) { return(false); } firstInterfaces.Remove(type); } return(firstInterfaces.Count == 0); }
protected static void CheckNotStruct(GroboIL il, ESType type) { if (ToCLIType(type) == CLIType.Struct) { ThrowError(il, $"Struct of type '{type}' is not valid at this point"); } }
protected static void CheckNotStruct(GroboIL il, ESType type) { if (ToCLIType(type) == CLIType.Struct) { ThrowError(il, string.Format("Struct of type '{0}' is not valid at this point", type)); } }
private static bool CanBeAssigned(Type to, ESType esFrom) { var cliTo = ToCLIType(to); var cliFrom = ToCLIType(esFrom); var from = esFrom.ToType(); switch (cliTo) { case CLIType.Int32: return(cliFrom == CLIType.Int32 || cliFrom == CLIType.NativeInt || cliFrom == CLIType.Zero); case CLIType.NativeInt: return(cliFrom == CLIType.Int32 || cliFrom == CLIType.NativeInt || cliFrom == CLIType.Zero); case CLIType.Int64: return(cliFrom == CLIType.Int64 || cliFrom == CLIType.Zero); case CLIType.Float: return(cliFrom == CLIType.Float || cliFrom == CLIType.Zero); case CLIType.Struct: return(ReflectionExtensions.Equal(to, from)); case CLIType.Pointer: if (cliFrom == CLIType.Zero || ReflectionExtensions.Equal(to, from)) { return(true); } if (cliFrom != CLIType.Pointer) { return(false); } to = to.GetElementType(); from = from.GetElementType(); return(to.IsValueType && from.IsValueType); case CLIType.Object: if (cliFrom == CLIType.Zero || ReflectionExtensions.Equal(to, from)) { return(true); } if (cliFrom != CLIType.Object) { return(false); } var simpleESFrom = esFrom as SimpleESType; if (simpleESFrom != null) { return(ReflectionExtensions.IsAssignableFrom(to, from)); } var complexESFrom = (ComplexESType)esFrom; return(ReflectionExtensions.IsAssignableFrom(to, complexESFrom.BaseType) || complexESFrom.Interfaces.Any(interfaCe => ReflectionExtensions.IsAssignableFrom(to, interfaCe))); case CLIType.Zero: return(true); default: throw new InvalidOperationException(string.Format("CLI type '{0}' is not valid at this point", cliTo)); } }
protected static void CheckCanBeAssigned(GroboIL il, Type to, ESType from) { if (!CanBeAssigned(to, from)) { ThrowError(il, string.Format("Unable to set a value of type '{0}' to an instance of type '{1}'", from, Formatter.Format(to))); } }
protected static void CheckIsAPointer(GroboIL il, ESType type) { var cliType = ToCLIType(type); if (cliType != CLIType.Pointer && cliType != CLIType.NativeInt) { ThrowError(il, $"A pointer type expected but was '{type}'"); } }
private static CLIType ToLowLevelCLIType(ESType esType) { if (esType == null) { return(CLIType.NativeInt); } var simpleESType = esType as SimpleESType; return(simpleESType == null ? CLIType.NativeInt : ToLowLevelCLIType(simpleESType.Type)); // ComplexESType is always an object }
protected static CLIType ToCLIType(ESType esType) { if (esType == null) { return(CLIType.Zero); } var simpleESType = esType as SimpleESType; return(simpleESType == null ? CLIType.Object : ToCLIType(simpleESType.Type)); // ComplexESType is always an object }
private static StacksComparisonResult CompareStacks(ESType[] first, ESType[] second, out ESType[] merged) { merged = null; if (first.Length != second.Length) { return(StacksComparisonResult.Inconsistent); } ESType[] result = null; for (var i = 0; i < first.Length; ++i) { var firstCLIType = ToCLIType(first[i]); var secondCLIType = ToCLIType(second[i]); if (firstCLIType != CLIType.Zero && secondCLIType != CLIType.Zero && firstCLIType != secondCLIType) { return(StacksComparisonResult.Inconsistent); } if (!EqualESTypes(first[i], second[i])) { var common = FindCommonType(firstCLIType, first[i], second[i]); if (common == null) { return(StacksComparisonResult.Inconsistent); } if (result == null) { result = new ESType[first.Length]; for (var j = 0; j < i; ++j) { result[j] = first[j]; } } result[i] = common; } else if (result != null) { result[i] = first[i]; } } if (result == null) { return(StacksComparisonResult.Equal); } merged = result; return(StacksComparisonResult.Equivalent); }
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"); } }
private static bool CanBeAssigned(Type to, ESType esFrom, TypesAssignabilityVerificationKind verificationKind) { if (verificationKind == TypesAssignabilityVerificationKind.None) { return(true); } var cliTo = verificationKind == TypesAssignabilityVerificationKind.HighLevel ? ToCLIType(to) : ToLowLevelCLIType(to); var cliFrom = verificationKind == TypesAssignabilityVerificationKind.HighLevel ? ToCLIType(esFrom) : ToLowLevelCLIType(esFrom); var from = esFrom.ToType(); switch (cliTo) { case CLIType.Int32: return(cliFrom == CLIType.Int32 || cliFrom == CLIType.NativeInt || cliFrom == CLIType.Zero); case CLIType.NativeInt: return(cliFrom == CLIType.Int32 || cliFrom == CLIType.NativeInt || cliFrom == CLIType.Zero); case CLIType.Int64: return(cliFrom == CLIType.Int64 || cliFrom == CLIType.Zero); case CLIType.Float: return(cliFrom == CLIType.Float || cliFrom == CLIType.Zero); case CLIType.Struct: return(ReflectionExtensions.Equal(to, from)); case CLIType.Pointer: if (cliFrom == CLIType.Zero || ReflectionExtensions.Equal(to, from)) { return(true); } if (cliFrom != CLIType.Pointer) { return(false); } to = to.GetElementType(); from = from.GetElementType(); return(to.IsValueType && from.IsValueType); case CLIType.Object: if (cliFrom == CLIType.Zero || ReflectionExtensions.Equal(to, from)) { return(true); } if (cliFrom != CLIType.Object) { return(false); } var simpleESFrom = esFrom as SimpleESType; if (simpleESFrom != null) { return(ReflectionExtensions.IsAssignableFrom(to, from)); } var complexESFrom = (ComplexESType)esFrom; return(ReflectionExtensions.IsAssignableFrom(to, complexESFrom.BaseType) || complexESFrom.Interfaces.Any(interfaCe => ReflectionExtensions.IsAssignableFrom(to, interfaCe))); case CLIType.Zero: return(true); default: throw new InvalidOperationException($"CLI type '{cliTo}' is not valid at this point"); } }
protected static Type Canonize(ESType esType) { return(Canonize(esType.ToType())); }