private void PropogateTypeReference(IExpression inner, IExpression outer) { Contract.Requires(inner != null); Contract.Requires(outer != null); if (ReferencedTypes.ContainsKey(inner)) { AddTypeReference(ReferencedTypes[inner], outer); } }
private void AddTypeReference(ITypeReference type, IExpression expr) { Contract.Requires(type != null); Contract.Requires(expr != null); Contract.Ensures(ReferencedTypes.ContainsKey(expr)); Contract.Ensures(ReferencedTypes[expr] == type); if (!ReferencedTypes.ContainsKey(expr)) { ReferencedTypes.Add(expr, type); } else { Contract.Assume(ReferencedTypes[expr] == type); } }
/// <summary> /// Recursively "unwrap" the generic type or array. If type is not generic and not an array /// then do nothing. /// </summary> /// <param name="parentType"></param> /// <param name="type"></param> public void UnwrapType(Type parentType, Type type) { if (ReferencedTypes.ContainsKey(type)) { if (parentType == null) { return; } ReferencedTypes[type].ReferencesIn.Add(parentType); ReferencedTypes[parentType].ReferencesOut.Add(type); return; } // Some types could be wrapped in generic types that should not be checked var checkType = CheckType(type); if (type.IsConstructedGenericType) // List<int> { UnwrapType(parentType, type.GetGenericTypeDefinition()); if (!(type.GenericTypeArguments?.Length > 0)) { return; } foreach (var argType in type.GenericTypeArguments) { UnwrapType(parentType, argType); } } else if (type.IsGenericParameter) // void Method<T>() <-- T in generic class { return; } else if (type.IsGenericTypeDefinition) // List<> { if (checkType) { AddTypeToCheckProps(parentType, type); } } else if (type.IsGenericType) // List<int> { if (type.ContainsGenericParameters) { foreach (var argType in type.GenericTypeArguments) { UnwrapType(parentType, argType); } } return; } else if (type.IsArray || type.IsByRef) // SomeType[] or ref SomeType { UnwrapType(parentType, type.GetElementType()); } else { if (checkType) { AddTypeToCheckProps(parentType, type); } } }