internal static FuncDecl GetOrAddMemberAccessFunction(Context context, Environment environment, MemberInfo memberInfo) { FuncDecl memberFunc; if (!environment.Members.TryGetValue(memberInfo, out memberFunc)) { Sort memberTypeSort; if (!environment.Types.TryGetValue(memberInfo.DeclaringType, out memberTypeSort)) { throw new KeyNotFoundException(memberInfo.DeclaringType + " could not be found at environment.Types"); } Sort memberReturnTypeEnumSort; var propertyType = ((PropertyInfo)memberInfo).PropertyType; if (propertyType == typeof(bool)) memberReturnTypeEnumSort = context.MkBoolSort(); else if (propertyType == typeof(int)) memberReturnTypeEnumSort = context.MkIntSort(); else if (propertyType == typeof(long)) memberReturnTypeEnumSort = context.MkRealSort(); else if (propertyType == typeof(string)) memberReturnTypeEnumSort = environment.PossibleStringValues; else { if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) { var listItemType = propertyType.GenericTypeArguments[0]; var listSort = context.MkSetSort(environment.Types[listItemType]); memberReturnTypeEnumSort = listSort; // TODO: add TryGetValue environment.Types.Add(propertyType, listSort); } else if (propertyType.IsEnum) { EnumSort enumSort = context.MkEnumSort(propertyType.Name, Enum.GetNames(propertyType)); memberReturnTypeEnumSort = enumSort; // TODO: add TryGetValue environment.Types.Add(propertyType, enumSort); } else { // TODO throw exception if type is not supported memberReturnTypeEnumSort = environment.Types[propertyType]; } } memberFunc = context.MkFuncDecl(memberInfo.Name, memberTypeSort, memberReturnTypeEnumSort); environment.Members.Add(memberInfo, memberFunc); } return memberFunc; }