From 8fcc2958f3d23ab303e55ffc1c347a0cdea6514a Mon Sep 17 00:00:00 2001 From: Olmo del Corral Cano Date: Fri, 4 Jan 2019 17:26:59 +0100 Subject: [PATCH 01/25] initial NotNull reference types --- Signum.Utilities/ConsoleSwitch.cs | 8 +- Signum.Utilities/Csv.cs | 76 +++++++++---------- .../DataStructures/DirectedEdgedGraph.cs | 2 +- .../DataStructures/LambdaComparer.cs | 12 +-- .../Extensions/DictionaryExtensions.cs | 4 +- .../Extensions/StringExtensions.cs | 50 ++++++------ Signum.Utilities/Signum.Utilities.csproj | 4 +- Signum.Utilities/StringDistance.cs | 26 +++---- Signum.Utilities/Synchronization/ResetLazy.cs | 14 ++-- Signum.Utilities/Tsv.cs | 34 ++++----- 10 files changed, 118 insertions(+), 112 deletions(-) diff --git a/Signum.Utilities/ConsoleSwitch.cs b/Signum.Utilities/ConsoleSwitch.cs index 221033eb15..9187b68573 100644 --- a/Signum.Utilities/ConsoleSwitch.cs +++ b/Signum.Utilities/ConsoleSwitch.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.ComponentModel; @@ -274,21 +274,21 @@ static string DefaultDescription(object value) public static class ConsoleSwitchExtensions { - public static T ChooseConsole(this IEnumerable collection, Func getString = null, string message = null) where T : class { + public static T ChooseConsole(this IEnumerable collection, Func? getString = null, string? message = null) where T : class { var cs = new ConsoleSwitch(message ?? ConsoleMessage.SelectOneOfTheFollowingOptions.NiceToString()); cs.Load(collection.ToList(), getString); return cs.Choose(); } - public static T[] ChooseConsoleMultiple(this IEnumerable collection, Func getString = null, string message = null) where T : class + public static T[] ChooseConsoleMultiple(this IEnumerable collection, Func? getString = null, string? message = null) where T : class { var cs = new ConsoleSwitch(message ?? ConsoleMessage.SelectOneOfTheFollowingOptions.NiceToString()); cs.Load(collection.ToList(), getString); return cs.ChooseMultiple(); } - public static ConsoleSwitch Load(this ConsoleSwitch cs, List collection, Func getString = null) where T : class + public static ConsoleSwitch Load(this ConsoleSwitch cs, List collection, Func? getString = null) where T : class { for (int i = 0; i < collection.Count; i++) { diff --git a/Signum.Utilities/Csv.cs b/Signum.Utilities/Csv.cs index debae5de99..0d5df85240 100644 --- a/Signum.Utilities/Csv.cs +++ b/Signum.Utilities/Csv.cs @@ -20,8 +20,8 @@ public static class Csv public static CultureInfo DefaultCulture = null; - public static string ToCsvFile(this IEnumerable collection, string fileName, Encoding encoding = null, CultureInfo culture = null, bool writeHeaders = true, bool autoFlush = false, bool append = false, - Func, CultureInfo, Func> toStringFactory = null) + public static string ToCsvFile(this IEnumerable collection, string fileName, Encoding? encoding = null, CultureInfo? culture = null, bool writeHeaders = true, bool autoFlush = false, bool append = false, + Func, CultureInfo, Func>? toStringFactory = null) { using (FileStream fs = append ? new FileStream(fileName, FileMode.Append, FileAccess.Write) : File.Create(fileName)) ToCsv(collection, fs, encoding, culture, writeHeaders, autoFlush, toStringFactory); @@ -29,8 +29,8 @@ public static string ToCsvFile(this IEnumerable collection, string fileNam return fileName; } - public static byte[] ToCsvBytes(this IEnumerable collection, Encoding encoding = null, CultureInfo culture = null, bool writeHeaders = true, bool autoFlush = false, - Func, CultureInfo, Func> toStringFactory = null) + public static byte[] ToCsvBytes(this IEnumerable collection, Encoding? encoding = null, CultureInfo? culture = null, bool writeHeaders = true, bool autoFlush = false, + Func, CultureInfo, Func>? toStringFactory = null) { using (MemoryStream ms = new MemoryStream()) { @@ -39,32 +39,33 @@ public static byte[] ToCsvBytes(this IEnumerable collection, Encoding enco } } - public static void ToCsv(this IEnumerable collection, Stream stream, Encoding encoding = null, CultureInfo culture = null, bool writeHeaders = true, bool autoFlush = false, - Func, CultureInfo, Func> toStringFactory = null) + public static void ToCsv(this IEnumerable collection, Stream stream, Encoding? encoding = null, CultureInfo? culture = null, bool writeHeaders = true, bool autoFlush = false, + Func, CultureInfo, Func>? toStringFactory = null) { - encoding = encoding ?? DefaultEncoding; - culture = culture ?? DefaultCulture ?? CultureInfo.CurrentCulture; + var defEncoding = encoding ?? DefaultEncoding; + var defCulture = culture ?? DefaultCulture ?? CultureInfo.CurrentCulture; - string separator = culture.TextInfo.ListSeparator; + string separator = defCulture.TextInfo.ListSeparator; if (typeof(IList).IsAssignableFrom(typeof(T))) { - using (StreamWriter sw = new StreamWriter(stream, encoding) { AutoFlush = autoFlush }) + using (StreamWriter sw = new StreamWriter(stream, defEncoding) { AutoFlush = autoFlush }) { - foreach (IList row in collection) + foreach (IList? row in collection) { - for (int i = 0; i < row.Count; i++) + for (int i = 0; i < row!.Count; i++) { - var obj = row[i]; + var obj = row![i]; - var str = EncodeCsv(ConvertToString(obj, null, culture), culture); + var str = EncodeCsv(ConvertToString(obj, null, defCulture), defCulture); sw.Write(str); - if (i < row.Count - 1) + if (i < row!.Count - 1) sw.Write(separator); else sw.WriteLine(); } + } } } @@ -72,7 +73,7 @@ public static void ToCsv(this IEnumerable collection, Stream stream, Encod { var columns = ColumnInfoCache.Columns; var members = columns.Select(c => c.MemberEntry).ToList(); - var toString = columns.Select(c => GetToString(culture, c, toStringFactory)).ToList(); + var toString = columns.Select(c => GetToString(defCulture, c, toStringFactory)).ToList(); using (StreamWriter sw = new StreamWriter(stream, encoding) { AutoFlush = autoFlush }) { @@ -85,7 +86,7 @@ public static void ToCsv(this IEnumerable collection, Stream stream, Encod { var obj = members[i].Getter(item); - var str = EncodeCsv(toString[i](obj), culture); + var str = EncodeCsv(toString[i](obj), defCulture); sw.Write(str); if (i < members.Count - 1) @@ -99,7 +100,7 @@ public static void ToCsv(this IEnumerable collection, Stream stream, Encod } - static string EncodeCsv(string p, CultureInfo culture) + static string? EncodeCsv(string p, CultureInfo culture) { if (p == null) return null; @@ -113,7 +114,7 @@ static string EncodeCsv(string p, CultureInfo culture) return p; } - private static Func GetToString(CultureInfo culture, CsvColumnInfo column, Func, CultureInfo, Func> toStringFactory) + private static Func GetToString(CultureInfo culture, CsvColumnInfo column, Func, CultureInfo, Func>? toStringFactory) { if (toStringFactory != null) { @@ -126,15 +127,15 @@ private static Func GetToString(CultureInfo culture, CsvColum return obj => ConvertToString(obj, column.Format, culture); } - static string ConvertToString(object obj, string format, CultureInfo culture) + static string ConvertToString(object obj, string? format, CultureInfo culture) { if (obj == null) return ""; if (obj is IFormattable f) - return f.ToString(null, culture); + return f.ToString(format, culture); else - return obj.ToString(); + return obj!.ToString(); } static string HandleSpaces(string p) @@ -142,7 +143,7 @@ static string HandleSpaces(string p) return p.Replace("__", "^").Replace("_", " ").Replace("^", "_"); } - public static List ReadFile(string fileName, Encoding encoding = null, CultureInfo culture = null, int skipLines = 1, CsvReadOptions options = null) where T : class, new() + public static List ReadFile(string fileName, Encoding? encoding = null, CultureInfo? culture = null, int skipLines = 1, CsvReadOptions? options = null) where T : class, new() { encoding = encoding ?? DefaultEncoding; culture = culture ?? DefaultCulture ?? CultureInfo.CurrentCulture; @@ -151,26 +152,25 @@ static string HandleSpaces(string p) return ReadStream(fs, encoding, culture, skipLines, options).ToList(); } - public static List ReadBytes(byte[] data, Encoding encoding = null, CultureInfo culture = null, int skipLines = 1, CsvReadOptions options = null) where T : class, new() + public static List ReadBytes(byte[] data, Encoding? encoding = null, CultureInfo? culture = null, int skipLines = 1, CsvReadOptions? options = null) where T : class, new() { using (MemoryStream ms = new MemoryStream(data)) return ReadStream(ms, encoding, culture, skipLines, options).ToList(); } - public static IEnumerable ReadStream(Stream stream, Encoding encoding = null, CultureInfo culture = null, int skipLines = 1, CsvReadOptions options = null) where T : class, new() + public static IEnumerable ReadStream(Stream stream, Encoding? encoding = null, CultureInfo? culture = null, int skipLines = 1, CsvReadOptions? options = null) where T : class, new() { encoding = encoding ?? DefaultEncoding; - culture = culture ?? DefaultCulture ?? CultureInfo.CurrentCulture; - if (options == null) - options = new CsvReadOptions(); + var defCulture = culture ?? DefaultCulture ?? CultureInfo.CurrentCulture; + var defOptions = options ?? new CsvReadOptions(); var columns = ColumnInfoCache.Columns; var members = columns.Select(c => c.MemberEntry).ToList(); - var parsers = columns.Select(c => GetParser(culture, c, options.ParserFactory)).ToList(); + var parsers = columns.Select(c => GetParser(defCulture, c, defOptions.ParserFactory)).ToList(); - Regex regex = GetRegex(culture, options.RegexTimeout); + Regex regex = GetRegex(defCulture, defOptions.RegexTimeout); - if (options.AsumeSingleLine) + if (defOptions.AsumeSingleLine) { using (StreamReader sr = new StreamReader(stream, encoding)) { @@ -185,8 +185,8 @@ static string HandleSpaces(string p) if (csvLine == null) yield break; - Match m = null; - T t = null; + Match? m = null; + T? t = null; try { m = regex.Match(csvLine); @@ -199,7 +199,7 @@ static string HandleSpaces(string p) { e.Data["row"] = line; - if (options.SkipError == null || !options.SkipError(e, m)) + if (defOptions.SkipError == null || !defOptions.SkipError(e, m)) throw new ParseCsvException(e); } @@ -224,7 +224,7 @@ static string HandleSpaces(string p) { if (m.Length > 0) { - T t = null; + T? t = null; try { t = ReadObject(m, members, parsers); @@ -233,7 +233,7 @@ static string HandleSpaces(string p) { e.Data["row"] = line; - if (options.SkipError == null || !options.SkipError(e, m)) + if (defOptions.SkipError == null || !defOptions.SkipError(e, m)) throw new ParseCsvException(e); } if (t != null) @@ -245,7 +245,7 @@ static string HandleSpaces(string p) } } - public static T ReadLine(string csvLine, CultureInfo culture = null, CsvReadOptions options = null) + public static T ReadLine(string csvLine, CultureInfo? culture = null, CsvReadOptions options = null) where T : class, new() { if (options == null) @@ -264,7 +264,7 @@ public static T ReadLine(string csvLine, CultureInfo culture = null, CsvReadO columns.Select(c => GetParser(culture, c, options.ParserFactory)).ToList()); } - private static Func GetParser(CultureInfo culture, CsvColumnInfo column, Func, CultureInfo, Func> parserFactory) + private static Func GetParser(CultureInfo culture, CsvColumnInfo column, Func, CultureInfo, Func>? parserFactory) { if (parserFactory != null) { diff --git a/Signum.Utilities/DataStructures/DirectedEdgedGraph.cs b/Signum.Utilities/DataStructures/DirectedEdgedGraph.cs index 3796f3f343..2502f1956b 100644 --- a/Signum.Utilities/DataStructures/DirectedEdgedGraph.cs +++ b/Signum.Utilities/DataStructures/DirectedEdgedGraph.cs @@ -388,7 +388,7 @@ public XDocument ToDGML() e => e.ToString() ?? "[null]"); } - public XDocument ToDGML(Func getNodeLabel, Func getColor, Func getEdgeLabel = null) + public XDocument ToDGML(Func getNodeLabel, Func getColor, Func? getEdgeLabel = null) { return ToDGML(n => new[] { diff --git a/Signum.Utilities/DataStructures/LambdaComparer.cs b/Signum.Utilities/DataStructures/LambdaComparer.cs index 21b77e1173..751f63fb70 100644 --- a/Signum.Utilities/DataStructures/LambdaComparer.cs +++ b/Signum.Utilities/DataStructures/LambdaComparer.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Collections; @@ -7,8 +7,8 @@ namespace Signum.Utilities.DataStructures public class LambdaComparer : IComparer, IEqualityComparer, IComparer, IEqualityComparer { readonly Func func; - readonly IComparer comparer = null; - readonly IEqualityComparer equalityComparer = null; + readonly IComparer comparer; + readonly IEqualityComparer equalityComparer; int descending = 1; public bool Descending @@ -17,7 +17,7 @@ public bool Descending set { descending = value ? -1 : 1; } } - public LambdaComparer(Func func, IEqualityComparer equalityComparer = null, IComparer comparer = null) + public LambdaComparer(Func func, IEqualityComparer? equalityComparer = null, IComparer? comparer = null) { if (func == null) throw new ArgumentNullException("func"); @@ -60,12 +60,12 @@ bool IEqualityComparer.Equals(object x, object y) public static class LambdaComparer { - public static LambdaComparer By(Func func, IEqualityComparer equalityComparer = null, IComparer comparer = null) + public static LambdaComparer By(Func func, IEqualityComparer? equalityComparer = null, IComparer? comparer = null) { return new LambdaComparer(func, equalityComparer, comparer); } - public static LambdaComparer ByDescending(Func func, IEqualityComparer equalityComparer = null, IComparer comparer = null) + public static LambdaComparer ByDescending(Func func, IEqualityComparer? equalityComparer = null, IComparer? comparer = null) { return new LambdaComparer(func, equalityComparer, comparer) { Descending = true }; } diff --git a/Signum.Utilities/Extensions/DictionaryExtensions.cs b/Signum.Utilities/Extensions/DictionaryExtensions.cs index 5f496e3bfb..2e0759a7cd 100644 --- a/Signum.Utilities/Extensions/DictionaryExtensions.cs +++ b/Signum.Utilities/Extensions/DictionaryExtensions.cs @@ -1,4 +1,4 @@ -using Signum.Utilities.ExpressionTrees; +using Signum.Utilities.ExpressionTrees; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -16,7 +16,7 @@ public static V TryGet(this IReadOnlyDictionary dictionary, K key, V return defaultValue; } - public static V TryGetC(this IReadOnlyDictionary dictionary, K key) where V : class + public static V? TryGetC(this IReadOnlyDictionary dictionary, K key) where V : class { if (dictionary.TryGetValue(key, out V result)) return result; diff --git a/Signum.Utilities/Extensions/StringExtensions.cs b/Signum.Utilities/Extensions/StringExtensions.cs index 3176f5805d..3a448a1a02 100644 --- a/Signum.Utilities/Extensions/StringExtensions.cs +++ b/Signum.Utilities/Extensions/StringExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.IO; @@ -147,7 +147,7 @@ public static string After(this string str, string separator) /// /// /// the substring before the first occurence of the separator or null if not found - public static string TryBefore(this string str, char separator) + public static string? TryBefore(this string? str, char separator) { if (str == null) return null; @@ -166,7 +166,7 @@ public static string TryBefore(this string str, char separator) /// /// /// the substring before the first occurence of the separator or null if not found - public static string TryBefore(this string str, string separator) + public static string? TryBefore(this string? str, string separator) { if (str == null) return null; @@ -184,7 +184,7 @@ public static string TryBefore(this string str, string separator) /// /// /// the substring after the first occurence of the separator or null if not found - public static string TryAfter(this string str, char separator) + public static string? TryAfter(this string? str, char separator) { if (str == null) return null; @@ -202,7 +202,7 @@ public static string TryAfter(this string str, char separator) /// /// /// the substring after the first occurence of the separator or null if not found - public static string TryAfter(this string str, string separator) + public static string? TryAfter(this string? str, string separator) { if (str == null) return null; @@ -288,7 +288,7 @@ public static string AfterLast(this string str, string separator) /// /// /// the substring before the last occurence of the separator or null if not found - public static string TryBeforeLast(this string str, char separator) + public static string? TryBeforeLast(this string? str, char separator) { if (str == null) return null; @@ -307,7 +307,7 @@ public static string TryBeforeLast(this string str, char separator) /// /// /// the substring before the last occurence of the separator or null if not found - public static string TryBeforeLast(this string str, string separator) + public static string? TryBeforeLast(this string? str, string separator) { if (str == null) return null; @@ -325,7 +325,7 @@ public static string TryBeforeLast(this string str, string separator) /// /// /// the substring after the last occurence of the separator or null if not found - public static string TryAfterLast(this string str, char separator) + public static string? TryAfterLast(this string? str, char separator) { if (str == null) return null; @@ -343,7 +343,7 @@ public static string TryAfterLast(this string str, char separator) /// /// /// the substring after the last occurence of the separator or null if not found - public static string TryAfterLast(this string str, string separator) + public static string? TryAfterLast(this string? str, string separator) { if (str == null) return null; @@ -355,7 +355,7 @@ public static string TryAfterLast(this string str, string separator) return str.Substring(index + separator.Length); } - public static string Between(this string str, string firstSeparator, string secondSeparator = null) + public static string Between(this string str, string firstSeparator, string? secondSeparator = null) { if (secondSeparator == null) secondSeparator = firstSeparator; @@ -391,10 +391,10 @@ public static string Between(this string str, char firstSeparator, char secondSe return str.Substring(start, end - start); } - public static string TryBetween(this string str, string firstSeparator, string secondSeparator = null) + public static string? TryBetween(this string? str, string firstSeparator, string? secondSeparator = null) { - if (secondSeparator == null) - secondSeparator = firstSeparator; + if (str == null) + return null; int start = str.IndexOf(firstSeparator); if (start == -1) @@ -402,17 +402,17 @@ public static string TryBetween(this string str, string firstSeparator, string s start = start + 1; - int end = str.IndexOf(secondSeparator, start); + int end = str.IndexOf(secondSeparator ?? firstSeparator, start); if (start == -1) return null; return str.Substring(start, end - start); } - public static string TryBetween(this string str, char firstSeparator, char secondSeparator = (char)0) + public static string? TryBetween(this string? str, char firstSeparator, char? secondSeparator = null) { - if (secondSeparator == 0) - secondSeparator = firstSeparator; + if (str == null) + return null; int start = str.IndexOf(firstSeparator); if (start == -1) @@ -420,7 +420,7 @@ public static string TryBetween(this string str, char firstSeparator, char secon start = start + 1; - int end = str.IndexOf(secondSeparator, start); + int end = str.IndexOf(secondSeparator ?? firstSeparator, start); if (start == -1) return null; @@ -435,7 +435,7 @@ public static string Start(this string str, int numChars) return str.Substring(0, numChars); } - public static string TryStart(this string str, int numChars) + public static string? TryStart(this string? str, int numChars) { if (str == null) return null; @@ -454,7 +454,7 @@ public static string End(this string str, int numChars) return str.Substring(str.Length - numChars, numChars); } - public static string TryEnd(this string str, int numChars) + public static string? TryEnd(this string? str, int numChars) { if (str == null) return null; @@ -530,7 +530,7 @@ public static string PadChopLeft(this string str, int length) return str.Length > length ? str.Substring(str.Length - length, length) : str.PadLeft(length); } - public static string FirstNonEmptyLine(this string str) + public static string? FirstNonEmptyLine(this string? str) { if (str == null) return null; @@ -598,7 +598,7 @@ public static string RemoveChars(this string str, params char[] chars) return sb.ToString(); } - public static string FormatWith(this string format, object arg0) + public static string FormatWith(this string format, object? arg0) { return string.Format(format, arg0); } @@ -630,7 +630,7 @@ public static string Replace(this string str, Dictionary replace public static string Replace(this string str, Dictionary replacements) { - StringBuilder sb = null; + StringBuilder? sb = null; for (int i = 0; i < str.Length; i++) { char c = str[i]; @@ -763,7 +763,7 @@ public static string ToComputerSize(this long value, bool useAbbreviations) public static string Combine(this string separator, params object[] elements) { - StringBuilder sb = null; + StringBuilder? sb = null; foreach (var item in elements) { if (item != null) @@ -782,7 +782,7 @@ public static string Combine(this string separator, params object[] elements) public static string CombineIfNotEmpty(this string separator, params object[] elements) { - StringBuilder sb = null; + StringBuilder? sb = null; foreach (var item in elements) { string str; diff --git a/Signum.Utilities/Signum.Utilities.csproj b/Signum.Utilities/Signum.Utilities.csproj index efcfd4d0f5..9bdbe60fcb 100644 --- a/Signum.Utilities/Signum.Utilities.csproj +++ b/Signum.Utilities/Signum.Utilities.csproj @@ -2,8 +2,10 @@ netcoreapp2.2 - latest + 8.0 true + true + true x64 diff --git a/Signum.Utilities/StringDistance.cs b/Signum.Utilities/StringDistance.cs index 7434340cea..cb20bce014 100644 --- a/Signum.Utilities/StringDistance.cs +++ b/Signum.Utilities/StringDistance.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; @@ -10,12 +10,12 @@ public class StringDistance { int[,] num; - public int LevenshteinDistance(string strOld, string strNew, IEqualityComparer comparer = null, Func, int> weight = null, bool allowTransposition = false) + public int LevenshteinDistance(string strOld, string strNew, IEqualityComparer comparer = null, Func, int>? weight = null, bool allowTransposition = false) { return LevenshteinDistance(strOld.ToCharArray(), strNew.ToCharArray(), comparer, weight, allowTransposition); } - public int LevenshteinDistance(T[] strOld, T[] strNew, IEqualityComparer comparer = null, Func, int> weight = null, bool allowTransposition = false) + public int LevenshteinDistance(T[] strOld, T[] strNew, IEqualityComparer comparer = null, Func, int>? weight = null, bool allowTransposition = false) { int M1 = strOld.Length + 1; int M2 = strNew.Length + 1; @@ -68,16 +68,16 @@ public enum ChoiceType Transpose, } - public struct Choice + public struct Choice where T: object { public readonly ChoiceType Type; - public readonly T Removed; - public readonly T Added; + public readonly T? Removed; + public readonly T? Added; public bool HasRemoved { get { return Type != ChoiceType.Add; } } public bool HasAdded { get { return Type != ChoiceType.Remove; } } - internal Choice( ChoiceType type, T removed, T added) + internal Choice( ChoiceType type, T? removed, T? added) { this.Type = type; this.Removed = removed; @@ -110,7 +110,7 @@ internal static Choice Transpose(T remove, T add) } - public override string ToString() + public override string? ToString() { switch (Type) { @@ -221,7 +221,7 @@ public int LongestCommonSubstring(string str1, string str2, out int startPos1, o return LongestCommonSubstring(str1.ToCharArray(), str2.ToCharArray(), out startPos1, out startPos2); } - public int LongestCommonSubstring(T[] str1, T[] str2, out int startPos1, out int startPos2, IEqualityComparer comparer = null) + public int LongestCommonSubstring(T[] str1, T[] str2, out int startPos1, out int startPos2, IEqualityComparer? comparer = null) { if (str1 == null) throw new ArgumentNullException("str1"); @@ -233,7 +233,7 @@ public int LongestCommonSubstring(T[] str1, T[] str2, out int startPos1, out } //http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Longest_common_substring - public int LongestCommonSubstring(Slice str1, Slice str2, out int startPos1, out int startPos2, IEqualityComparer comparer = null) + public int LongestCommonSubstring(Slice str1, Slice str2, out int startPos1, out int startPos2, IEqualityComparer? comparer = null) { startPos1 = 0; startPos2 = 0; @@ -429,14 +429,14 @@ public List> DiffWords(string strOld, string strNew) return Diff(wordsOld, wordsNew); } - public List> Diff(T[] strOld, T[] strNew, IEqualityComparer comparer = null) + public List> Diff(T[] strOld, T[] strNew, IEqualityComparer? comparer = null) { var result = new List>(); DiffPrivate(new Slice(strOld), new Slice(strNew), comparer, result); return result; } - void DiffPrivate(Slice sliceOld, Slice sliceNew, IEqualityComparer comparer, List> result) + void DiffPrivate(Slice sliceOld, Slice sliceNew, IEqualityComparer? comparer, List> result) { int length = LongestCommonSubstring(sliceOld, sliceNew, out int posOld, out int posNew, comparer); @@ -461,7 +461,7 @@ static void AddResults(List> list, Slice slice, DiffAction act list.Add(new DiffPair(action, slice[i])); } - void TryDiff(Slice sliceOld, Slice sliceNew, IEqualityComparer comparer, List> result) + void TryDiff(Slice sliceOld, Slice sliceNew, IEqualityComparer? comparer, List> result) { if (sliceOld.Length > 0 && sliceOld.Length > 0) { diff --git a/Signum.Utilities/Synchronization/ResetLazy.cs b/Signum.Utilities/Synchronization/ResetLazy.cs index 27e68d4497..ab5de3b2a6 100644 --- a/Signum.Utilities/Synchronization/ResetLazy.cs +++ b/Signum.Utilities/Synchronization/ResetLazy.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; using System.Threading; using System.Diagnostics; @@ -15,6 +15,11 @@ public interface IResetLazy public class ResetLazyStats { + public ResetLazyStats(Type type) + { + this.Type = type; + } + public Type Type; public int Loads; public int Invalidations; @@ -36,7 +41,7 @@ public Box(T value) public readonly T Value; } - public ResetLazy(Func valueFactory, LazyThreadSafetyMode mode = LazyThreadSafetyMode.PublicationOnly, Type declaringType = null) + public ResetLazy(Func valueFactory, LazyThreadSafetyMode mode = LazyThreadSafetyMode.PublicationOnly, Type? declaringType = null) { if (valueFactory == null) throw new ArgumentNullException("valueFactory"); @@ -56,7 +61,7 @@ public ResetLazy(Func valueFactory, LazyThreadSafetyMode mode = LazyThreadSaf object syncLock = new object(); - Box box; + Box? box; Type declaringType; public Type DeclaringType @@ -155,13 +160,12 @@ public void Reset() ResetLazyStats IResetLazy.Stats() { - return new ResetLazyStats + return new ResetLazyStats(typeof(T)) { SumLoadTime = this.SumLoadtime, Hits = this.Hits, Loads = this.Loads, Invalidations = this.Invalidations, - Type = typeof(T) }; } diff --git a/Signum.Utilities/Tsv.cs b/Signum.Utilities/Tsv.cs index 321641e29b..9a5d8a46d8 100644 --- a/Signum.Utilities/Tsv.cs +++ b/Signum.Utilities/Tsv.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -15,8 +15,8 @@ public static class Tsv public static Encoding DefaultEncoding = Encoding.GetEncoding(1252); public static CultureInfo Culture = CultureInfo.InvariantCulture; - public static string ToTsvFile(T[,] collection, string fileName, Encoding encoding = null, bool autoFlush = false, bool append = false, - Func, Func> toStringFactory = null) + public static string ToTsvFile(T[,] collection, string fileName, Encoding? encoding = null, bool autoFlush = false, bool append = false, + Func, Func>? toStringFactory = null) { encoding = encoding ?? DefaultEncoding; @@ -40,8 +40,8 @@ public static string ToTsvFile(T[,] collection, string fileName, Encoding enc return fileName; } - public static string ToTsvFile(this IEnumerable collection, string fileName, Encoding encoding = null, bool writeHeaders = true, bool autoFlush = false, bool append = false, - Func, Func> toStringFactory = null) + public static string ToTsvFile(this IEnumerable collection, string fileName, Encoding? encoding = null, bool writeHeaders = true, bool autoFlush = false, bool append = false, + Func, Func>? toStringFactory = null) { using (FileStream fs = append ? new FileStream(fileName, FileMode.Append, FileAccess.Write) : File.Create(fileName)) ToTsv(collection, fs, encoding, writeHeaders, autoFlush, toStringFactory); @@ -49,8 +49,8 @@ public static string ToTsvFile(this IEnumerable collection, string fileNam return fileName; } - public static byte[] ToTsvBytes(this IEnumerable collection, Encoding encoding = null, bool writeHeaders = true, bool autoFlush = false, - Func, Func> toStringFactory = null) + public static byte[] ToTsvBytes(this IEnumerable collection, Encoding? encoding = null, bool writeHeaders = true, bool autoFlush = false, + Func, Func>? toStringFactory = null) { using (MemoryStream ms = new MemoryStream()) { @@ -61,8 +61,8 @@ public static byte[] ToTsvBytes(this IEnumerable collection, Encoding enco private const string tab = "\t"; - public static void ToTsv(this IEnumerable collection, Stream stream, Encoding encoding = null, bool writeHeaders = true, bool autoFlush = false, - Func, Func> toStringFactory = null) + public static void ToTsv(this IEnumerable collection, Stream stream, Encoding? encoding = null, bool writeHeaders = true, bool autoFlush = false, + Func, Func>? toStringFactory = null) { encoding = encoding ?? DefaultEncoding; @@ -117,7 +117,7 @@ public static void ToTsv(this IEnumerable collection, Stream stream, Encod } } - private static Func GetToString(TsvColumnInfo column, Func, Func> toStringFactory) + private static Func GetToString(TsvColumnInfo column, Func, Func>? toStringFactory) { if (toStringFactory != null) { @@ -244,7 +244,7 @@ private static Func GetParser(TsvColumnInfo column, Func .Select((me, i) => new TsvColumnInfo(i, me, me.MemberInfo.GetCustomAttribute()?.Format)).ToList(); } - static object ConvertTo(string s, Type type, string format) + static object? ConvertTo(string s, Type type, string format) { Type baseType = Nullable.GetUnderlyingType(type); if (baseType != null) @@ -296,8 +296,8 @@ static object ConvertTo(string s, Type type, string format) public class TsvReadOptions where T : class { - public Func, Func> ParserFactory; - public Func SkipError; + public Func, Func>? ParserFactory; + public Func? SkipError; } @@ -325,8 +325,8 @@ internal TsvColumnInfo(int index, MemberEntry memberEntry, string format) public class ParseTsvException : Exception { public int? Row { get; set; } - public string Member { get; set; } - public string Value { get; set; } + public string? Member { get; set; } + public string? Value { get; set; } public ParseTsvException() { } public ParseTsvException(Exception inner) : base(inner.Message, inner) @@ -349,4 +349,4 @@ public override string Message } } } -} \ No newline at end of file +} From 94a026e2a204612dc93b5d3b30cbd2b3171650d0 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Mon, 7 Jan 2019 08:24:50 +0100 Subject: [PATCH 02/25] more on not nullable --- Signum.Utilities/Extensions/Extensions.cs | 16 ++-- .../Reflection/MemberEntryFactory.cs | 18 ++-- .../Reflection/ReflectionTools.cs | 85 +++++++++---------- Signum.Utilities/Tsv.cs | 41 +++++---- 4 files changed, 74 insertions(+), 86 deletions(-) diff --git a/Signum.Utilities/Extensions/Extensions.cs b/Signum.Utilities/Extensions/Extensions.cs index 023cf3f39e..9bf50b1551 100644 --- a/Signum.Utilities/Extensions/Extensions.cs +++ b/Signum.Utilities/Extensions/Extensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; @@ -13,7 +13,7 @@ namespace Signum.Utilities public static class Extensions { #region Parse Number - public static int? ToInt(this string str, NumberStyles ns = NumberStyles.Integer, CultureInfo ci = null) + public static int? ToInt(this string str, NumberStyles ns = NumberStyles.Integer, CultureInfo? ci = null) { if (int.TryParse(str, ns, ci ?? CultureInfo.CurrentCulture, out int result)) return result; @@ -21,7 +21,7 @@ public static class Extensions return null; } - public static long? ToLong(this string str, NumberStyles ns = NumberStyles.Integer, CultureInfo ci = null) + public static long? ToLong(this string str, NumberStyles ns = NumberStyles.Integer, CultureInfo? ci = null) { if (long.TryParse(str, ns, ci ?? CultureInfo.CurrentCulture, out long result)) return result; @@ -29,7 +29,7 @@ public static class Extensions return null; } - public static short? ToShort(this string str, NumberStyles ns = NumberStyles.Integer, CultureInfo ci = null) + public static short? ToShort(this string str, NumberStyles ns = NumberStyles.Integer, CultureInfo? ci = null) { if (short.TryParse(str, ns, ci ?? CultureInfo.CurrentCulture, out short result)) return result; @@ -37,7 +37,7 @@ public static class Extensions return null; } - public static float? ToFloat(this string str, NumberStyles ns = NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo ci = null) + public static float? ToFloat(this string str, NumberStyles ns = NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo? ci = null) { if (float.TryParse(str, ns, ci ?? CultureInfo.CurrentCulture, out float result)) return result; @@ -45,7 +45,7 @@ public static class Extensions return null; } - public static double? ToDouble(this string str, NumberStyles ns = NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo ci = null) + public static double? ToDouble(this string str, NumberStyles ns = NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo? ci = null) { if (double.TryParse(str, ns, ci ?? CultureInfo.CurrentCulture, out double result)) return result; @@ -53,7 +53,7 @@ public static class Extensions return null; } - public static decimal? ToDecimal(this string str, NumberStyles ns = NumberStyles.Number, CultureInfo ci = null) + public static decimal? ToDecimal(this string str, NumberStyles ns = NumberStyles.Number, CultureInfo? ci = null) { if (decimal.TryParse(str, ns, ci ?? CultureInfo.CurrentCulture, out decimal result)) return result; @@ -225,7 +225,7 @@ public static long DivCeiling(this int a, long b) #region DateTime - public static DateTime? ToDateTimeExact(this string date, string format, IFormatProvider formatProvider = null, + public static DateTime? ToDateTimeExact(this string date, string format, IFormatProvider? formatProvider = null, DateTimeStyles? styles = null) { if (DateTime.TryParseExact(date, format, diff --git a/Signum.Utilities/Reflection/MemberEntryFactory.cs b/Signum.Utilities/Reflection/MemberEntryFactory.cs index 838a2e3750..40c46ee0c7 100644 --- a/Signum.Utilities/Reflection/MemberEntryFactory.cs +++ b/Signum.Utilities/Reflection/MemberEntryFactory.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -77,19 +77,19 @@ public class MemberEntry : IMemberEntry { public string Name {get; private set;} public MemberInfo MemberInfo { get; private set; } - public Func Getter { get; private set; } - public Func UntypedGetter { get; private set; } - public Action Setter { get; private set; } - public Action UntypedSetter { get; private set; } + public Func? Getter { get; private set; } + public Func? UntypedGetter { get; private set; } + public Action? Setter { get; private set; } + public Action? UntypedSetter { get; private set; } - public MemberEntry(string name, MemberInfo memberInfo, Func getter, Func untypedGetter,Action setter, Action untypedSetter) + public MemberEntry(string name, MemberInfo memberInfo, Func? getter, Func? untypedGetter, Action? setter, Action? untypedSetter) { this.Name = name; this.MemberInfo = memberInfo; this.Getter = getter; this.UntypedGetter = untypedGetter; - + this.Setter = setter; this.UntypedSetter = untypedSetter; } @@ -99,8 +99,8 @@ public interface IMemberEntry { string Name { get; } MemberInfo MemberInfo { get; } - Func UntypedGetter { get; } - Action UntypedSetter { get; } + Func? UntypedGetter { get; } + Action? UntypedSetter { get; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = true)] diff --git a/Signum.Utilities/Reflection/ReflectionTools.cs b/Signum.Utilities/Reflection/ReflectionTools.cs index 98258dd863..41fa4da332 100644 --- a/Signum.Utilities/Reflection/ReflectionTools.cs +++ b/Signum.Utilities/Reflection/ReflectionTools.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Reflection; using System.Linq.Expressions; @@ -41,13 +41,11 @@ public static bool MemeberEquals(MemberInfo m1, MemberInfo m2) if (m1.MetadataToken != m2.MetadataToken || m1.Module != m2.Module) return false; - if (m1 is MethodInfo) + if (m1 is MethodInfo lhsMethod) { - MethodInfo lhsMethod = m1 as MethodInfo; - if (lhsMethod.IsGenericMethod) { - MethodInfo rhsMethod = m2 as MethodInfo; + MethodInfo rhsMethod = (MethodInfo)m2; Type[] lhsGenArgs = lhsMethod.GetGenericArguments(); Type[] rhsGenArgs = rhsMethod.GetGenericArguments(); @@ -81,13 +79,11 @@ public static PropertyInfo BasePropertyInfo(LambdaExpression property) Expression body = property.Body; if (body.NodeType == ExpressionType.Convert) body = ((UnaryExpression)body).Operand; - - MemberExpression ex = body as MemberExpression; - if (ex == null) + + if (!(body is MemberExpression ex)) throw new ArgumentException("The lambda 'property' should be an expression accessing a property"); - - PropertyInfo pi = ex.Member as PropertyInfo; - if (pi == null) + + if (!(ex.Member is PropertyInfo pi)) throw new ArgumentException("The lambda 'property' should be an expression accessing a property"); return pi; @@ -107,7 +103,7 @@ public static ConstructorInfo BaseConstuctorInfo(LambdaExpression constuctor) if (body.NodeType == ExpressionType.Convert) body = ((UnaryExpression)body).Operand; - NewExpression ex = body as NewExpression; + NewExpression? ex = body as NewExpression; if (ex == null) throw new ArgumentException("The lambda 'constuctor' should be an expression constructing an object"); @@ -133,16 +129,14 @@ public static FieldInfo BaseFieldInfo(LambdaExpression field) Expression body = field.Body; if (body.NodeType == ExpressionType.Convert) body = ((UnaryExpression)body).Operand; - - MemberExpression ex = body as MemberExpression; - if (ex == null) + + if (!(body is MemberExpression ex)) throw new ArgumentException("The lambda 'field' should be an expression accessing a field"); - FieldInfo pi = ex.Member as FieldInfo; - if (pi == null) + if (!(ex.Member is FieldInfo fi)) throw new ArgumentException("The lambda 'field' should be an expression accessing a field"); - return pi; + return fi; } @@ -165,11 +159,10 @@ public static MemberInfo BaseMemberInfo(LambdaExpression member) if (body.NodeType == ExpressionType.Convert) body = ((UnaryExpression)body).Operand; - MemberExpression ex = body as MemberExpression; - if (ex == null) + if (!(body is MemberExpression me)) throw new ArgumentException("The lambda 'member' should be an expression accessing a member"); - return ex.Member; + return me.Member; } @@ -202,14 +195,12 @@ public static MethodInfo BaseMethodInfo(LambdaExpression method) if (body.NodeType == ExpressionType.Convert) body = ((UnaryExpression)body).Operand; - MethodCallExpression ex = body as MethodCallExpression; - if (ex == null) + if (!(body is MethodCallExpression ex)) throw new ArgumentException("The lambda 'method' should be an expression calling a method"); return ex.Method; } - public static ConstructorInfo GetGenericConstructorDefinition(this ConstructorInfo ci) { return ci.DeclaringType.GetGenericTypeDefinition().GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).SingleEx(a => a.MetadataToken == ci.MetadataToken); @@ -230,7 +221,7 @@ public static Type GetReceiverType(Expression> lambda) return ((MemberExpression)body).Expression.Type; } - public static Func CreateGetter(MemberInfo m) + public static Func? CreateGetter(MemberInfo m) { if ((m as PropertyInfo)?.Let(a => !a.CanRead) ?? false) return null; @@ -240,7 +231,7 @@ public static Func CreateGetter(MemberInfo m) return (Func)exp.Compile(); } - public static Func CreateGetter(MemberInfo m) + public static Func? CreateGetter(MemberInfo m) { using (HeavyProfiler.LogNoStackTrace("CreateGetter")) { @@ -250,11 +241,11 @@ public static Func CreateGetter(MemberInfo m) ParameterExpression p = Expression.Parameter(typeof(T), "p"); Type lambdaType = typeof(Func<,>).MakeGenericType(typeof(T), typeof(object)); var exp = Expression.Lambda(lambdaType, Expression.Convert(Expression.MakeMemberAccess(p, m), typeof(object)), p); - return (Func)exp.Compile(); + return (Func)exp.Compile(); } } - public static Func CreateGetterUntyped(Type type, MemberInfo m) + public static Func? CreateGetterUntyped(Type type, MemberInfo m) { using (HeavyProfiler.LogNoStackTrace("CreateGetterUntyped")) { @@ -264,11 +255,11 @@ public static Func CreateGetterUntyped(Type type, MemberInfo m) ParameterExpression p = Expression.Parameter(typeof(object), "p"); Type lambdaType = typeof(Func<,>).MakeGenericType(typeof(object), typeof(object)); var exp = Expression.Lambda(lambdaType, Expression.Convert(Expression.MakeMemberAccess(Expression.Convert(p, type), m), typeof(object)), p); - return (Func)exp.Compile(); + return (Func)exp.Compile(); } } - public static Action CreateSetter(MemberInfo m) + public static Action? CreateSetter(MemberInfo m) { using (HeavyProfiler.LogNoStackTrace("CreateSetter")) { @@ -283,7 +274,7 @@ public static Action CreateSetter(MemberInfo m) } } - public static Action CreateSetter(MemberInfo m) + public static Action? CreateSetter(MemberInfo m) { using (HeavyProfiler.LogNoStackTrace("CreateSetter")) { @@ -294,13 +285,13 @@ public static Action CreateSetter(MemberInfo m) ParameterExpression p = Expression.Parameter(typeof(object), "p"); var exp = Expression.Lambda(typeof(Action), Expression.Assign(Expression.MakeMemberAccess(t, m), Expression.Convert(p, m.ReturningType())), t, p); - return (Action)exp.Compile(); + return (Action)exp.Compile(); } } static Module module = ((Expression>)(() => 2)).Compile().Method.Module; - public static Action CreateSetterUntyped(Type type, MemberInfo m) + public static Action? CreateSetterUntyped(Type type, MemberInfo m) { using (HeavyProfiler.LogNoStackTrace("CreateSetterUntyped")) { @@ -311,7 +302,7 @@ public static Action CreateSetterUntyped(Type type, MemberInfo m ParameterExpression p = Expression.Parameter(typeof(object), "p"); var exp = Expression.Lambda(typeof(Action), Expression.Assign(Expression.MakeMemberAccess(Expression.Convert(t, type), m), Expression.Convert(p, m.ReturningType())), t, p); - return (Action)exp.Compile(); + return (Action)exp.Compile(); } } @@ -383,7 +374,7 @@ public static bool IsPercentage(string formatString, CultureInfo culture) return formatString.HasText() && formatString.StartsWith("p", StringComparison.InvariantCultureIgnoreCase); } - public static object ParsePercentage(string value, Type targetType, CultureInfo culture) + public static object? ParsePercentage(string value, Type targetType, CultureInfo culture) { value = value.Trim(culture.NumberFormat.PercentSymbol.ToCharArray()); @@ -415,7 +406,7 @@ public static T Parse(string value) return (T)(object)value; if (value == null || value == "") - return (T)(object)null; + return (T)(object?)null; Type utype = typeof(T).UnNullify(); if (utype.IsEnum) @@ -426,13 +417,13 @@ public static T Parse(string value) return (T)Convert.ChangeType(value, utype); } - public static object Parse(string value, Type type) + public static object? Parse(string value, Type type) { if (type == typeof(string)) return (object)value; if (value == null || value == "" || value == " ") - return (object)null; + return (object?)null; Type utype = type.UnNullify(); if (utype.IsEnum) @@ -461,7 +452,7 @@ public static T Parse(string value, CultureInfo culture) return (T)(object)value; if (value == null || value == "") - return (T)(object)null; + return (T)(object?)null; Type utype = typeof(T).UnNullify(); if (utype.IsEnum) @@ -478,7 +469,7 @@ public static object Parse(string value, Type type, CultureInfo culture) return (object)value; if (value == null || value == "") - return (object)null; + return (object?)null; Type utype = type.UnNullify(); if (utype.IsEnum) @@ -491,7 +482,7 @@ public static object Parse(string value, Type type, CultureInfo culture) public static bool TryParse(string value, out T result) { - if (TryParse(value, typeof(T), CultureInfo.CurrentCulture, out object objResult)) + if (TryParse(value, typeof(T), CultureInfo.CurrentCulture, out object? objResult)) { result = (T)objResult; return true; @@ -505,7 +496,7 @@ public static bool TryParse(string value, out T result) public static bool TryParse(string value, CultureInfo ci, out T result) { - if (TryParse(value, typeof(T), ci, out object objResult)) + if (TryParse(value, typeof(T), ci, out object? objResult)) { result = (T)objResult; return true; @@ -517,12 +508,12 @@ public static bool TryParse(string value, CultureInfo ci, out T result) } } - public static bool TryParse(string value, Type type, out object result) + public static bool TryParse(string value, Type type, out object? result) { return TryParse(value, type, CultureInfo.CurrentCulture, out result); } - public static bool TryParse(string value, Type type, CultureInfo ci, out object result) + public static bool TryParse(string value, Type type, CultureInfo ci, out object? result) { if (type == typeof(string)) { @@ -713,7 +704,7 @@ public static bool TryParse(string value, Type type, CultureInfo ci, out object public static T ChangeType(object value) { if (value == null) - return (T)(object)null; + return (T)(object?)null; if (value.GetType() == typeof(T)) return (T)value; @@ -736,7 +727,7 @@ public static T ChangeType(object value) } } - public static object ChangeType(object value, Type type) + public static object? ChangeType(object value, Type type) { if (value == null) return null; @@ -770,7 +761,7 @@ public static object ChangeType(object value, Type type) { var colType = type.IsInstantiationOf(typeof(IEnumerable<>)) ? typeof(List<>).MakeGenericType(type.GetGenericArguments()) : type; IList col = (IList)Activator.CreateInstance(colType); - foreach (var item in value as IEnumerable) + foreach (var item in (IEnumerable)value) { col.Add(item); } diff --git a/Signum.Utilities/Tsv.cs b/Signum.Utilities/Tsv.cs index 9a5d8a46d8..c41f1fabcd 100644 --- a/Signum.Utilities/Tsv.cs +++ b/Signum.Utilities/Tsv.cs @@ -70,16 +70,16 @@ public static void ToTsv(this IEnumerable collection, Stream stream, Encod { using (StreamWriter sw = new StreamWriter(stream, encoding) { AutoFlush = autoFlush }) { - foreach (IList row in collection) + foreach (IList? row in collection) { - for (int i = 0; i < row.Count; i++) + for (int i = 0; i < row!.Count; i++) { - var obj = row[i]; + var obj = row![i]; var str = ConvertToString(obj); sw.Write(str); - if (i < row.Count - 1) + if (i < row!.Count - 1) sw.Write(tab); else sw.WriteLine(); @@ -130,7 +130,7 @@ private static Func GetToString(TsvColumnInfo column, Func return ConvertToString; } - static string ConvertToString(object obj) + static string ConvertToString(object? obj) { if (obj == null) return ""; @@ -139,7 +139,7 @@ static string ConvertToString(object obj) return f.ToString(null, Culture); else { - var p = obj.ToString(); + var p = obj!.ToString(); if (p != null && p.Contains(tab)) throw new InvalidDataException("TSV fields can't contain the tab character, found one in value: " + p); return p; @@ -151,7 +151,7 @@ static string HandleSpaces(string p) return p.Replace("__", "^").Replace("_", " ").Replace("^", "_"); } - public static List ReadFile(string fileName, Encoding encoding = null, int skipLines = 1, TsvReadOptions options = null) where T : class, new() + public static List ReadFile(string fileName, Encoding? encoding = null, int skipLines = 1, TsvReadOptions? options = null) where T : class, new() { encoding = encoding ?? DefaultEncoding; @@ -159,21 +159,20 @@ static string HandleSpaces(string p) return ReadStream(fs, encoding, skipLines, options).ToList(); } - public static List ReadBytes(byte[] data, Encoding encoding = null, int skipLines = 1, TsvReadOptions options = null) where T : class, new() + public static List ReadBytes(byte[] data, Encoding? encoding = null, int skipLines = 1, TsvReadOptions? options = null) where T : class, new() { using (MemoryStream ms = new MemoryStream(data)) return ReadStream(ms, encoding, skipLines, options).ToList(); } - public static IEnumerable ReadStream(Stream stream, Encoding encoding = null, int skipLines = 1, TsvReadOptions options = null) where T : class, new() + public static IEnumerable ReadStream(Stream stream, Encoding? encoding = null, int skipLines = 1, TsvReadOptions? options = null) where T : class, new() { encoding = encoding ?? DefaultEncoding; - if (options == null) - options = new TsvReadOptions(); + var defOptions = options ?? new TsvReadOptions(); var columns = ColumnInfoCache.Columns; var members = columns.Select(c => c.MemberEntry).ToList(); - var parsers = columns.Select(c => GetParser(c, options.ParserFactory)).ToList(); + var parsers = columns.Select(c => GetParser(c, defOptions.ParserFactory)).ToList(); using (StreamReader sr = new StreamReader(stream, encoding)) @@ -189,7 +188,7 @@ static string HandleSpaces(string p) if (tsvLine == null) yield break; - T t = null; + T? t = null; try { t = ReadObject(tsvLine, members, parsers); @@ -198,7 +197,7 @@ static string HandleSpaces(string p) { e.Data["row"] = line; - if (options.SkipError == null || !options.SkipError(e, tsvLine)) + if (defOptions.SkipError == null || !options.SkipError(e, tsvLine)) throw new ParseCsvException(e); } @@ -208,20 +207,19 @@ static string HandleSpaces(string p) } } - public static T ReadLine(string tsvLine, TsvReadOptions options = null) + public static T ReadLine(string tsvLine, TsvReadOptions? options = null) where T : class, new() { - if (options == null) - options = new TsvReadOptions(); + var defOptions = options ?? new TsvReadOptions(); var columns = ColumnInfoCache.Columns; return ReadObject(tsvLine, columns.Select(c => c.MemberEntry).ToList(), - columns.Select(c => GetParser(c, options.ParserFactory)).ToList()); + columns.Select(c => GetParser(c, defOptions.ParserFactory)).ToList()); } - private static Func GetParser(TsvColumnInfo column, Func, Func> parserFactory) + private static Func GetParser(TsvColumnInfo column, Func, Func>? parserFactory) { if (parserFactory != null) { @@ -234,7 +232,7 @@ private static Func GetParser(TsvColumnInfo column, Func ConvertTo(str, column.MemberInfo.ReturningType(), column.Format); } - static T ReadObject(string line, List> members, List> parsers) where T : new() + static T ReadObject(string line, List> members, List> parsers) where T : new() { var vals = line.Split(new[] { tab }, StringSplitOptions.None).ToList(); @@ -248,7 +246,7 @@ private static Func GetParser(TsvColumnInfo column, Func where T : class public Func? SkipError; } - public class TsvColumnInfo { public readonly int Index; From 0c3c53fe54c6b7fd0eab1e573c6be0a439afac94 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Cano Date: Mon, 7 Jan 2019 08:32:37 +0100 Subject: [PATCH 03/25] more on not nullable --- .../Extensions/StringExtensions.cs | 8 ++-- Signum.Utilities/StringDistance.cs | 45 +++++++++++-------- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/Signum.Utilities/Extensions/StringExtensions.cs b/Signum.Utilities/Extensions/StringExtensions.cs index 3a448a1a02..22f5c20ac9 100644 --- a/Signum.Utilities/Extensions/StringExtensions.cs +++ b/Signum.Utilities/Extensions/StringExtensions.cs @@ -603,22 +603,22 @@ public static string FormatWith(this string format, object? arg0) return string.Format(format, arg0); } - public static string FormatWith(this string format, object arg0, object arg1) + public static string FormatWith(this string format, object? arg0, object? arg1) { return string.Format(format, arg0, arg1); } - public static string FormatWith(this string format, object arg0, object arg1, object arg2) + public static string FormatWith(this string format, object? arg0, object? arg1, object? arg2) { return string.Format(format, arg0, arg1, arg2); } - public static string FormatWith(this string pattern, params object[] parameters) + public static string FormatWith(this string pattern, params object?[] parameters) { return string.Format(pattern, parameters); } - public static string FormatWith(this string format, IFormatProvider provider, params object[] args) + public static string FormatWith(this string format, IFormatProvider provider, params object?[] args) { return string.Format(provider, format, args); } diff --git a/Signum.Utilities/StringDistance.cs b/Signum.Utilities/StringDistance.cs index cb20bce014..ed354281e4 100644 --- a/Signum.Utilities/StringDistance.cs +++ b/Signum.Utilities/StringDistance.cs @@ -8,14 +8,14 @@ namespace Signum.Utilities { public class StringDistance { - int[,] num; + int[,]? _cachedNum; - public int LevenshteinDistance(string strOld, string strNew, IEqualityComparer comparer = null, Func, int>? weight = null, bool allowTransposition = false) + public int LevenshteinDistance(string strOld, string strNew, IEqualityComparer? comparer = null, Func, int>? weight = null, bool allowTransposition = false) { return LevenshteinDistance(strOld.ToCharArray(), strNew.ToCharArray(), comparer, weight, allowTransposition); } - public int LevenshteinDistance(T[] strOld, T[] strNew, IEqualityComparer comparer = null, Func, int>? weight = null, bool allowTransposition = false) + public int LevenshteinDistance(T[] strOld, T[] strNew, IEqualityComparer? comparer = null, Func, int>? weight = null, bool allowTransposition = false) { int M1 = strOld.Length + 1; int M2 = strNew.Length + 1; @@ -26,7 +26,7 @@ public int LevenshteinDistance(T[] strOld, T[] strNew, IEqualityComparer c if (weight == null) weight = c => 1; - ResizeArray(M1, M2); + var num = ResizeArray(M1, M2); num[0, 0] = 0; @@ -68,16 +68,16 @@ public enum ChoiceType Transpose, } - public struct Choice where T: object + public struct Choice { public readonly ChoiceType Type; - public readonly T? Removed; - public readonly T? Added; + public readonly T Removed; + public readonly T Added; public bool HasRemoved { get { return Type != ChoiceType.Add; } } public bool HasAdded { get { return Type != ChoiceType.Remove; } } - internal Choice( ChoiceType type, T? removed, T? added) + internal Choice( ChoiceType type, T removed, T added) { this.Type = type; this.Removed = removed; @@ -86,12 +86,12 @@ internal Choice( ChoiceType type, T? removed, T? added) public static Choice Add(T value) { - return new Choice(ChoiceType.Add, default(T), value); + return new Choice(ChoiceType.Add, default(T)!, value); } public static Choice Remove(T value) { - return new Choice(ChoiceType.Remove, value, default(T)); + return new Choice(ChoiceType.Remove, value, default(T)!); } public static Choice Equal(T value) @@ -125,12 +125,12 @@ internal static Choice Transpose(T remove, T add) } - public List> LevenshteinChoices(string strOld, string strNew, IEqualityComparer comparer = null, Func, int> weight = null) + public List> LevenshteinChoices(string strOld, string strNew, IEqualityComparer? comparer = null, Func, int>? weight = null) { return LevenshteinChoices(strOld.ToCharArray(), strNew.ToCharArray(), comparer, weight); } - public List> LevenshteinChoices(T[] strOld, T[] strNew, IEqualityComparer comparer = null, Func, int> weight = null) + public List> LevenshteinChoices(T[] strOld, T[] strNew, IEqualityComparer? comparer = null, Func, int>? weight = null) { if (comparer == null) comparer = EqualityComparer.Default; @@ -159,6 +159,8 @@ public List> LevenshteinChoices(T[] strOld, T[] strNew, IEqualityCo var cAdd = Choice.Add(strNew[j - 1]); var cSubstitute = Choice.Substitute(strOld[i - 1], strNew[j - 1]); + var num = _cachedNum!; + var remove = num[i - 1, j] + weight(cRemove); var add = num[i, j - 1] + weight(cAdd); var substitute = num[i - 1, j - 1] + weight(cSubstitute); @@ -244,7 +246,7 @@ public int LongestCommonSubstring(Slice str1, Slice str2, out int start if (comparer == null) comparer = EqualityComparer.Default; - ResizeArray(str1.Length, str2.Length); + var num = ResizeArray(str1.Length, str2.Length); int maxlen = 0; @@ -275,7 +277,10 @@ public int LongestCommonSubstring(Slice str1, Slice str2, out int start string DebugTable() { - return num.SelectArray(a => a.ToString()).FormatTable(); + if (_cachedNum == null) + throw new InvalidOperationException("Not initialized"); + + return _cachedNum.SelectArray(a => a.ToString()).FormatTable(); } public int LongestCommonSubsequence(string str1, string str2) @@ -290,7 +295,7 @@ public int LongestCommonSubsequence(string str1, string str2) /// /// ACE is a subsequence of ABCDE /// - public int LongestCommonSubsequence(T[] str1, T[] str2, IEqualityComparer comparer = null) + public int LongestCommonSubsequence(T[] str1, T[] str2, IEqualityComparer? comparer = null) { if (str1 == null) throw new ArgumentNullException("str1"); @@ -307,7 +312,7 @@ public int LongestCommonSubsequence(T[] str1, T[] str2, IEqualityComparer int M1 = str1.Length + 1; int M2 = str2.Length + 1; - ResizeArray(M1, M2); + var num = ResizeArray(M1, M2); for (int i = 0; i < M1; i++) num[i, 0] = 0; @@ -333,12 +338,14 @@ public int LongestCommonSubsequence(T[] str1, T[] str2, IEqualityComparer return num[str1.Length, str2.Length]; } - private void ResizeArray(int M1, int M2) + private int [,] ResizeArray(int M1, int M2) { - if (num == null || M1 > num.GetLength(0) || M2 > num.GetLength(1)) + if (_cachedNum == null || M1 > _cachedNum.GetLength(0) || M2 > _cachedNum.GetLength(1)) { - num = new int[M1, M2]; + _cachedNum = new int[M1, M2]; } + + return _cachedNum; } From 19f34c7f1b34a0e62c24b43087c09e8e4bf7c09e Mon Sep 17 00:00:00 2001 From: Olmo del Corral Cano Date: Mon, 7 Jan 2019 09:53:12 +0100 Subject: [PATCH 04/25] more in not nullable --- Signum.Utilities/ConsoleSwitch.cs | 27 +-- Signum.Utilities/Csv.cs | 31 ++- .../DataStructures/ImmutableStack.cs | 18 +- .../DataStructures/ScopedDictionary.cs | 18 +- .../ExpandableQueryProvider.cs | 2 +- .../ExpressionTrees/ExpressionComparer.cs | 10 +- .../Extensions/DictionaryExtensions.cs | 40 ++-- .../Extensions/EnumerableExtensions.cs | 201 ++++++++++-------- Signum.Utilities/Extensions/Extensions.cs | 4 +- .../Extensions/StreamExtensions.cs | 4 +- .../Extensions/StringExtensions.cs | 14 +- .../NaturalLanguage/NaturalLanguageTools.cs | 26 +-- Signum.Utilities/Polymorphic.cs | 69 +++--- Signum.Utilities/Profiler/HeavyProfiler.cs | 30 +-- Signum.Utilities/SafeConsole.cs | 18 +- Signum.Utilities/Signum.Utilities.csproj | 4 + Signum.Utilities/Statics.cs | 41 ++-- 17 files changed, 296 insertions(+), 261 deletions(-) diff --git a/Signum.Utilities/ConsoleSwitch.cs b/Signum.Utilities/ConsoleSwitch.cs index 9187b68573..6d7d7c58eb 100644 --- a/Signum.Utilities/ConsoleSwitch.cs +++ b/Signum.Utilities/ConsoleSwitch.cs @@ -5,7 +5,9 @@ namespace Signum.Utilities { - public class ConsoleSwitch : IEnumerable>> where V : class + public class ConsoleSwitch : IEnumerable>> + where K : object + where V : class { Dictionary> dictionary = new Dictionary>(StringComparer.InvariantCultureIgnoreCase); Dictionary separators = new Dictionary(); @@ -37,7 +39,7 @@ public void Add(K key, V value, string description) dictionary.AddOrThrow(key.ToString(), new WithDescription(value, description), "Key {0} already in ConsoleSwitch"); } - public V Choose(int? numberOfOptions = null) + public V? Choose(int? numberOfOptions = null) { var tuple = ChooseTuple(numberOfOptions); @@ -47,7 +49,7 @@ public V Choose(int? numberOfOptions = null) return tuple.Value; } - public WithDescription ChooseTuple(int? numberOfOptions = null) + public WithDescription? ChooseTuple(int? numberOfOptions = null) { Console.WriteLine(welcomeMessage); var noOfOptsPerScreen = numberOfOptions ?? dictionary.Count; @@ -89,7 +91,7 @@ void PrintOptions(int skip, int take) { var key = keys[i]; - string value = separators.TryGetC(i); + string? value = separators.TryGetC(i); if (value.HasText()) { Console.WriteLine(); @@ -105,13 +107,13 @@ void PrintOptions(int skip, int take) Console.WriteLine(" - " + ConsoleMessage.More.NiceToString()); } - public V[] ChooseMultiple(string[] args = null) + public V[]? ChooseMultiple(string[]? args = null) { return ChooseMultiple(ConsoleMessage.EnterYoutSelectionsSeparatedByComma.NiceToString(), args); } - public V[] ChooseMultiple(string endMessage, string[] args = null) + public V[]? ChooseMultiple(string endMessage, string[]? args = null) { var array = ChooseMultipleWithDescription(endMessage, args); @@ -122,12 +124,12 @@ public V[] ChooseMultiple(string endMessage, string[] args = null) } - public WithDescription[] ChooseMultipleWithDescription(string[] args = null) + public WithDescription[]? ChooseMultipleWithDescription(string[]? args = null) { return ChooseMultipleWithDescription(ConsoleMessage.EnterYoutSelectionsSeparatedByComma.NiceToString(), args); } - public WithDescription[] ChooseMultipleWithDescription(string endMessage, string[] args = null) + public WithDescription[]? ChooseMultipleWithDescription(string endMessage, string[]? args = null) { if (args != null) return args.ToString(" ").SplitNoEmpty(',').SelectMany(GetValuesRange).ToArray(); @@ -191,7 +193,7 @@ int GetIndex(string value) return index; } - WithDescription TryGetValue(string input) + WithDescription? TryGetValue(string input) { var exact = dictionary.TryGetC(input); if (exact != null) @@ -242,7 +244,8 @@ public enum ConsoleMessage More } - public class WithDescription + public class WithDescription + where T : class { public T Value { get; private set; } @@ -274,14 +277,14 @@ static string DefaultDescription(object value) public static class ConsoleSwitchExtensions { - public static T ChooseConsole(this IEnumerable collection, Func? getString = null, string? message = null) where T : class { + public static T? ChooseConsole(this IEnumerable collection, Func? getString = null, string? message = null) where T : class { var cs = new ConsoleSwitch(message ?? ConsoleMessage.SelectOneOfTheFollowingOptions.NiceToString()); cs.Load(collection.ToList(), getString); return cs.Choose(); } - public static T[] ChooseConsoleMultiple(this IEnumerable collection, Func? getString = null, string? message = null) where T : class + public static T[]? ChooseConsoleMultiple(this IEnumerable collection, Func? getString = null, string? message = null) where T : class { var cs = new ConsoleSwitch(message ?? ConsoleMessage.SelectOneOfTheFollowingOptions.NiceToString()); cs.Load(collection.ToList(), getString); diff --git a/Signum.Utilities/Csv.cs b/Signum.Utilities/Csv.cs index 0d5df85240..4d135b1f1b 100644 --- a/Signum.Utilities/Csv.cs +++ b/Signum.Utilities/Csv.cs @@ -84,7 +84,7 @@ public static void ToCsv(this IEnumerable collection, Stream stream, Encod { for (int i = 0; i < members.Count; i++) { - var obj = members[i].Getter(item); + var obj = members[i].Getter!(item); var str = EncodeCsv(toString[i](obj), defCulture); @@ -245,15 +245,14 @@ static string HandleSpaces(string p) } } - public static T ReadLine(string csvLine, CultureInfo? culture = null, CsvReadOptions options = null) + public static T ReadLine(string csvLine, CultureInfo? culture = null, CsvReadOptions? options = null) where T : class, new() { - if (options == null) - options = new CsvReadOptions(); + var defOptions = options ?? new CsvReadOptions(); - culture = culture ?? DefaultCulture ?? CultureInfo.CurrentCulture; + var defCulture = culture ?? DefaultCulture ?? CultureInfo.CurrentCulture; - Regex regex = GetRegex(culture, options.RegexTimeout); + Regex regex = GetRegex(defCulture, defOptions.RegexTimeout); Match m = regex.Match(csvLine); @@ -261,10 +260,10 @@ public static T ReadLine(string csvLine, CultureInfo? culture = null, CsvRead return ReadObject(m, columns.Select(c => c.MemberEntry).ToList(), - columns.Select(c => GetParser(culture, c, options.ParserFactory)).ToList()); + columns.Select(c => GetParser(defCulture, c, defOptions.ParserFactory)).ToList()); } - private static Func GetParser(CultureInfo culture, CsvColumnInfo column, Func, CultureInfo, Func>? parserFactory) + private static Func GetParser(CultureInfo culture, CsvColumnInfo column, Func, CultureInfo, Func>? parserFactory) { if (parserFactory != null) { @@ -277,7 +276,7 @@ private static Func GetParser(CultureInfo culture, CsvColumnI return str => ConvertTo(str, column.MemberInfo.ReturningType(), culture, column.Format); } - static T ReadObject(Match m, List> members, List> parsers) where T : new() + static T ReadObject(Match m, List> members, List> parsers) where T : new() { var vals = m.Groups["val"].Captures; @@ -287,14 +286,14 @@ private static Func GetParser(CultureInfo culture, CsvColumnI T t = new T(); for (int i = 0; i < members.Count; i++) { - string str = null; + string? str = null; try { str = DecodeCsv(vals[i].Value); - object val = parsers[i](str); + object? val = parsers[i](str); - members[i].Setter(t, val); + members[i].Setter!(t, val); } catch (Exception e) { @@ -336,7 +335,7 @@ static string DecodeCsv(string s) return s; } - static object ConvertTo(string s, Type type, CultureInfo culture, string format) + static object? ConvertTo(string s, Type type, CultureInfo culture, string format) { Type baseType = Nullable.GetUnderlyingType(type); if (baseType != null) @@ -362,9 +361,9 @@ static object ConvertTo(string s, Type type, CultureInfo culture, string format) public class CsvReadOptions where T: class { - public Func, CultureInfo, Func> ParserFactory; + public Func, CultureInfo, Func>? ParserFactory; public bool AsumeSingleLine = false; - public Func SkipError; + public Func? SkipError; public TimeSpan RegexTimeout = Regex.InfiniteMatchTimeout; } @@ -395,7 +394,7 @@ public class ParseCsvException : Exception public int? Row { get; set; } public string Member { get; set; } public string Value { get; set; } - + public ParseCsvException() { } public ParseCsvException(Exception inner) : base(inner.Message, inner) { diff --git a/Signum.Utilities/DataStructures/ImmutableStack.cs b/Signum.Utilities/DataStructures/ImmutableStack.cs index 64a1ac323e..5341af2f76 100644 --- a/Signum.Utilities/DataStructures/ImmutableStack.cs +++ b/Signum.Utilities/DataStructures/ImmutableStack.cs @@ -1,18 +1,21 @@ -using System; +using System; using System.Collections.Generic; using System.Collections; using System.Threading; namespace Signum.Utilities.DataStructures { - public class ImmutableStack:IEnumerable + + + public class ImmutableStack : IEnumerable + where T : object { - private class ImmutableFullStack : ImmutableStack + class ImmutableFullStack : ImmutableStack { readonly T head; readonly ImmutableStack tail; - public ImmutableFullStack(T head, ImmutableStack tail) + internal ImmutableFullStack(T head, ImmutableStack tail) { this.head = head; this.tail = tail; @@ -33,12 +36,11 @@ public override string ToString() { return "[" + this.ToString(", ") + "]"; } - } public static readonly ImmutableStack Empty = new ImmutableStack(); - private ImmutableStack(){} + internal ImmutableStack() { } public virtual bool IsEmpty { get { return true; } } public virtual T Peek() { throw new InvalidOperationException("Empty Stack"); } @@ -52,12 +54,12 @@ private ImmutableStack(){} public static class ImmutableStackExtensions { - public static ImmutableStack Reverse(this ImmutableStack stack) + public static ImmutableStack Reverse(this ImmutableStack stack) where T : object { return Reverse(stack, ImmutableStack.Empty); } - public static ImmutableStack Reverse(this ImmutableStack stack, ImmutableStack initial) + public static ImmutableStack Reverse(this ImmutableStack stack, ImmutableStack initial) where T : object { ImmutableStack r = initial; for (ImmutableStack f = stack; !f.IsEmpty; f = f.Pop()) diff --git a/Signum.Utilities/DataStructures/ScopedDictionary.cs b/Signum.Utilities/DataStructures/ScopedDictionary.cs index d61919a840..6e8a2ceac8 100644 --- a/Signum.Utilities/DataStructures/ScopedDictionary.cs +++ b/Signum.Utilities/DataStructures/ScopedDictionary.cs @@ -5,20 +5,20 @@ namespace Signum.Utilities.DataStructures { public class ScopedDictionary : IEnumerable> { - ScopedDictionary previous; + ScopedDictionary? previous; Dictionary map; public IEqualityComparer Comparer { get { return map.Comparer; } } - public ScopedDictionary Previous { get { return previous; } } + public ScopedDictionary? Previous { get { return previous; } } - public ScopedDictionary(ScopedDictionary previous) + public ScopedDictionary(ScopedDictionary? previous) :this(previous, EqualityComparer.Default) { this.previous = previous; this.map = new Dictionary(); } - public ScopedDictionary(ScopedDictionary previous, IEqualityComparer comparer) + public ScopedDictionary(ScopedDictionary? previous, IEqualityComparer comparer) { this.previous = previous; this.map = new Dictionary(comparer); @@ -31,18 +31,18 @@ public void Add(TKey key, TValue value) public bool TryGetValue(TKey key, out TValue value) { - for (ScopedDictionary scope = this; scope != null; scope = scope.previous) + for (ScopedDictionary? scope = this; scope != null; scope = scope.previous) { if (scope.map.TryGetValue(key, out value)) return true; } - value = default(TValue); + value = default(TValue)!; return false; } public bool ContainsKey(TKey key) { - for (ScopedDictionary scope = this; scope != null; scope = scope.previous) + for (ScopedDictionary? scope = this; scope != null; scope = scope.previous) { if (scope.map.ContainsKey(key)) return true; @@ -52,7 +52,7 @@ public bool ContainsKey(TKey key) public override string ToString() { - var str = map.ToString(kvp => kvp.Key.ToString() + " -> " + kvp.Value.ToString(), "\r\n"); + var str = map.ToString(kvp => kvp.Key + " -> " + kvp.Value, "\r\n"); if (this.previous == null) return str; @@ -83,7 +83,7 @@ public TValue GetOrCreate(TKey key, Func valueFactory) public IEnumerator> GetEnumerator() { - for (var sd = this; sd != null; sd = sd.previous) + for (ScopedDictionary? sd = this; sd != null; sd = sd.previous) { foreach (var item in sd.map) { diff --git a/Signum.Utilities/ExpressionTrees/ExpandableQueryProvider.cs b/Signum.Utilities/ExpressionTrees/ExpandableQueryProvider.cs index f8a3926056..63675c30b9 100644 --- a/Signum.Utilities/ExpressionTrees/ExpandableQueryProvider.cs +++ b/Signum.Utilities/ExpressionTrees/ExpandableQueryProvider.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; diff --git a/Signum.Utilities/ExpressionTrees/ExpressionComparer.cs b/Signum.Utilities/ExpressionTrees/ExpressionComparer.cs index d381f76832..88f261fd2a 100644 --- a/Signum.Utilities/ExpressionTrees/ExpressionComparer.cs +++ b/Signum.Utilities/ExpressionTrees/ExpressionComparer.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -10,7 +10,7 @@ namespace Signum.Utilities.ExpressionTrees { public class ExpressionComparer { - internal ScopedDictionary parameterScope; + internal ScopedDictionary? parameterScope; bool checkParameterNames = false; protected IDisposable ParameterScope() @@ -20,13 +20,13 @@ protected IDisposable ParameterScope() return new Disposable(() => parameterScope = saved); } - protected ExpressionComparer(ScopedDictionary parameterScope, bool checkParameterNames) + protected ExpressionComparer(ScopedDictionary? parameterScope, bool checkParameterNames) { this.parameterScope = parameterScope; this.checkParameterNames = checkParameterNames; } - public static bool AreEqual( Expression a, Expression b, ScopedDictionary parameterScope = null, bool checkParameterNames = false) + public static bool AreEqual( Expression a, Expression b, ScopedDictionary? parameterScope = null, bool checkParameterNames = false) { return new ExpressionComparer(parameterScope, checkParameterNames).Compare(a, b); } @@ -187,7 +187,7 @@ protected virtual bool CompareLambda(LambdaExpression a, LambdaExpression b) using (ParameterScope()) { for (int i = 0; i < n; i++) - parameterScope.Add(a.Parameters[i], b.Parameters[i]); + parameterScope!.Add(a.Parameters[i], b.Parameters[i]); return Compare(a.Body, b.Body); } diff --git a/Signum.Utilities/Extensions/DictionaryExtensions.cs b/Signum.Utilities/Extensions/DictionaryExtensions.cs index 2e0759a7cd..2c102d9b36 100644 --- a/Signum.Utilities/Extensions/DictionaryExtensions.cs +++ b/Signum.Utilities/Extensions/DictionaryExtensions.cs @@ -89,21 +89,21 @@ public static V GetOrThrow(this IDictionary dictionary, K key, Func< return result; } - public static V GetOrThrow(this IDictionary dictionary, K key, string messageWithFormat) + public static V GetOrThrow(this IDictionary dictionary, K key, string messageWithFormat) where K : object { if (!dictionary.TryGetValue(key, out V result)) throw new KeyNotFoundException(messageWithFormat.FormatWith(key)); return result; } - public static V GetOrThrow(this IDictionary dictionary, K key) + public static V GetOrThrow(this IDictionary dictionary, K key) where K : object { if (!dictionary.TryGetValue(key, out V result)) throw new KeyNotFoundException("Key '{0}' ({1}) not found on {2}".FormatWith(key, key.GetType().TypeName(), dictionary.GetType().TypeName())); return result; } - public static void AddOrThrow(this IDictionary dictionary, K key, V value, string messageWithFormat) + public static void AddOrThrow(this IDictionary dictionary, K key, V value, string messageWithFormat) where K : object { if (dictionary.ContainsKey(key)) throw new ArgumentException(messageWithFormat.FormatWith(key)); @@ -133,7 +133,7 @@ public static Dictionary ToDictionary(this IEnumerable ToDictionaryEx(this IEnumerable> collection, string errorContext = null) + public static Dictionary ToDictionaryEx(this IEnumerable> collection, string? errorContext = null) { var result = new Dictionary(); result.AddRange(collection, errorContext ?? typeof(K).TypeName()); @@ -147,7 +147,7 @@ public static Dictionary ToDictionary(this IEnumerable ToDictionaryEx(this IEnumerable> collection, IEqualityComparer comparer, string errorContext = null) + public static Dictionary ToDictionaryEx(this IEnumerable> collection, IEqualityComparer comparer, string? errorContext = null) { var result = new Dictionary(comparer); result.AddRange(collection, errorContext ?? typeof(K).TypeName()); @@ -155,28 +155,28 @@ public static Dictionary ToDictionaryEx(this IEnumerable ToDictionaryEx(this IEnumerable source, Func keySelector, string errorContext = null) + public static Dictionary ToDictionaryEx(this IEnumerable source, Func keySelector, string? errorContext = null) { Dictionary result = new Dictionary(); result.AddRange(source, keySelector, v => v, errorContext ?? typeof(K).TypeName()); return result; } - public static Dictionary ToDictionaryEx(this IEnumerable source, Func keySelector, Func elementSelector, string errorContext = null) + public static Dictionary ToDictionaryEx(this IEnumerable source, Func keySelector, Func elementSelector, string? errorContext = null) { Dictionary result = new Dictionary(); result.AddRange(source, keySelector, elementSelector, errorContext ?? typeof(K).TypeName()); return result; } - public static Dictionary ToDictionaryEx(this IEnumerable source, Func keySelector, IEqualityComparer comparer, string errorContext = null) + public static Dictionary ToDictionaryEx(this IEnumerable source, Func keySelector, IEqualityComparer comparer, string? errorContext = null) { Dictionary result = new Dictionary(comparer); result.AddRange(source, keySelector, v => v, errorContext ?? typeof(K).TypeName()); return result; } - public static Dictionary ToDictionaryEx(this IEnumerable source, Func keySelector, Func elementSelector, IEqualityComparer comparer, string errorContext = null) + public static Dictionary ToDictionaryEx(this IEnumerable source, Func keySelector, Func elementSelector, IEqualityComparer comparer, string? errorContext = null) { Dictionary result = new Dictionary(comparer); result.AddRange(source, keySelector, elementSelector, errorContext ?? typeof(K).TypeName()); @@ -252,7 +252,7 @@ public static void JoinDictionaryForeachStrict( } } - public static Dictionary OuterJoinDictionaryCC(this IReadOnlyDictionary dic1, IReadOnlyDictionary dic2, Func mixer) + public static Dictionary OuterJoinDictionaryCC(this IReadOnlyDictionary dic1, IReadOnlyDictionary dic2, Func mixer) where V1 : class where V2 : class { @@ -263,7 +263,7 @@ public static Dictionary OuterJoinDictionaryCC(this IReadOnl return set.ToDictionaryEx(k => k, k => mixer(k, dic1.TryGetC(k), dic2.TryGetC(k))); } - public static Dictionary OuterJoinDictionarySC(this IReadOnlyDictionary dic1, IReadOnlyDictionary dic2, Func mixer) + public static Dictionary OuterJoinDictionarySC(this IReadOnlyDictionary dic1, IReadOnlyDictionary dic2, Func mixer) where V1 : struct where V2 : class { @@ -274,7 +274,7 @@ public static Dictionary OuterJoinDictionarySC(this IReadOnl return set.ToDictionaryEx(k => k, k => mixer(k, dic1.TryGetS(k), dic2.TryGetC(k))); } - public static Dictionary OuterJoinDictionarySC(this IReadOnlyDictionary dic1, IReadOnlyDictionary dic2, Func mixer) + public static Dictionary OuterJoinDictionarySC(this IReadOnlyDictionary dic1, IReadOnlyDictionary dic2, Func mixer) where V1 : struct where V2 : class { @@ -285,7 +285,7 @@ public static Dictionary OuterJoinDictionarySC(this IReadO return set.ToDictionaryEx(k => k, k => mixer(k, dic1.TryGetS(k), dic2.TryGetC(k))); } - public static Dictionary OuterJoinDictionaryCS(this IReadOnlyDictionary dic1, IReadOnlyDictionary dic2, Func mixer) + public static Dictionary OuterJoinDictionaryCS(this IReadOnlyDictionary dic1, IReadOnlyDictionary dic2, Func mixer) where V1 : class where V2 : struct { @@ -296,7 +296,7 @@ public static Dictionary OuterJoinDictionaryCS(this IReadOnl return set.ToDictionaryEx(k => k, k => mixer(k, dic1.TryGetC(k), dic2.TryGetS(k))); } - public static Dictionary OuterJoinDictionaryCS(this IReadOnlyDictionary dic1, IReadOnlyDictionary dic2, Func mixer) + public static Dictionary OuterJoinDictionaryCS(this IReadOnlyDictionary dic1, IReadOnlyDictionary dic2, Func mixer) where V1 : class where V2 : struct { @@ -462,14 +462,14 @@ public static Dictionary Extract(this IDictionary dictionary, } - public static V Extract(this IDictionary dictionary, K key) + public static V Extract(this IDictionary dictionary, K key) where K : object { V value = dictionary.GetOrThrow(key); dictionary.Remove(key); return value; } - public static V Extract(this IDictionary dictionary, K key, string messageWithFormat) + public static V Extract(this IDictionary dictionary, K key, string messageWithFormat) where K : object { V value = dictionary.GetOrThrow(key, messageWithFormat); dictionary.Remove(key); @@ -524,17 +524,17 @@ public static void Increment(this IDictionary dic, K key) dic[key] = count + 1; } - public static NameValueCollection ToNameValueCollection(this IDictionary dic) + public static NameValueCollection ToNameValueCollection(this IDictionary dic) { var collection = new NameValueCollection(); foreach (var kvp in dic) { - string value = null; + string? value = null; if (kvp.Value != null) - value = kvp.Value.ToString(); + value = kvp.Value!.ToString(); - collection.Add(kvp.Key.ToString(), value); + collection.Add(kvp.Key!.ToString(), value); } return collection; diff --git a/Signum.Utilities/Extensions/EnumerableExtensions.cs b/Signum.Utilities/Extensions/EnumerableExtensions.cs index 99e50569ea..21ac730b4a 100644 --- a/Signum.Utilities/Extensions/EnumerableExtensions.cs +++ b/Signum.Utilities/Extensions/EnumerableExtensions.cs @@ -52,7 +52,7 @@ public static T SingleEx(this IEnumerable collection, Func predic if (predicate == null) throw new ArgumentNullException("predicate"); - T result = default(T); + T result = default(T)!; bool found = false; foreach (T item in collection) { @@ -165,7 +165,7 @@ public static T SingleOrDefaultEx(this IEnumerable collection, Func(this IEnumerable collection) using (IEnumerator enumerator = collection.GetEnumerator()) { if (!enumerator.MoveNext()) - return default(T); + return default(T)!; T current = enumerator.Current; @@ -215,7 +215,7 @@ public static T SingleOrDefaultEx(this IEnumerable collection, Func enumerator = collection.GetEnumerator()) { if (!enumerator.MoveNext()) - return default(T); + return default(T)!; T current = enumerator.Current; @@ -303,7 +303,7 @@ public static T SingleOrManyEx(this IEnumerable collection) T current = enumerator.Current; if (enumerator.MoveNext()) - return default(T); + return default(T)!; return current; } @@ -322,7 +322,7 @@ public static T SingleOrManyEx(this IEnumerable collection, Func e T current = enumerator.Current; if (enumerator.MoveNext()) - return default(T); + return default(T)!; return current; } @@ -342,7 +342,7 @@ public static T SingleOrMany(this IEnumerable collection) T current = enumerator.Current; if (enumerator.MoveNext()) - return default(T); + return default(T)!; return current; } @@ -357,12 +357,12 @@ public static T Only(this IEnumerable collection) using (IEnumerator enumerator = collection.GetEnumerator()) { if (!enumerator.MoveNext()) - return default(T); + return default(T)!; T current = enumerator.Current; if (enumerator.MoveNext()) - return default(T); + return default(T)!; return current; } @@ -482,7 +482,7 @@ public static IEnumerable Shuffle(this IEnumerable collection, Random r public static string ToString(this IEnumerable source, string separator) { - StringBuilder sb = null; + StringBuilder? sb = null; foreach (var item in source) { if (sb == null) @@ -490,7 +490,7 @@ public static string ToString(this IEnumerable source, string separator) else sb.Append(separator); - sb.Append(item.ToString()); + sb.Append(item!.ToString()); } if (sb == null) @@ -501,7 +501,7 @@ public static string ToString(this IEnumerable source, string separator) public static string ToString(this IEnumerable source, Func toString, string separator) { - StringBuilder sb = null; + StringBuilder? sb = null; foreach (var item in source) { if (sb == null) @@ -525,7 +525,7 @@ public static string ToString(this IQueryable source, Expression(this IEnumerable collection) { - return CommaString(collection.Select(a => a.ToString()).ToArray(), CollectionMessage.And.NiceToString()); + return CommaString(collection.Select(a => a!.ToString()).ToArray(), CollectionMessage.And.NiceToString()); } public static string CommaAnd(this IEnumerable collection, Func toString) @@ -535,7 +535,7 @@ public static string CommaAnd(this IEnumerable collection, Func public static string CommaOr(this IEnumerable collection) { - return CommaString(collection.Select(a => a.ToString()).ToArray(), CollectionMessage.Or.NiceToString()); + return CommaString(collection.Select(a => a!.ToString()).ToArray(), CollectionMessage.Or.NiceToString()); } public static string CommaOr(this IEnumerable collection, Func toString) @@ -545,7 +545,7 @@ public static string CommaOr(this IEnumerable collection, Func public static string Comma(this IEnumerable collection, string lastSeparator) { - return CommaString(collection.Select(a => a.ToString()).ToArray(), lastSeparator); + return CommaString(collection.Select(a => a!.ToString()).ToArray(), lastSeparator); } public static string Comma(this IEnumerable collection, Func toString, string lastSeparator) @@ -578,7 +578,7 @@ static string CommaString(this string[] values, string lastSeparator) public static void ToConsole(this IEnumerable collection) { - ToConsole(collection, a => a.ToString()); + ToConsole(collection, a => a!.ToString()); } public static void ToConsole(this IEnumerable collection, Func toString) @@ -614,7 +614,7 @@ public static DataTable ToDataTable(this IEnumerable collection, bool with table.Columns.Add(name, type); } foreach (var e in collection) - table.Rows.Add(members.Select(m => m.Getter(e)).ToArray()); + table.Rows.Add(members.Select(m => m.Getter!(e)).ToArray()); return table; } @@ -663,7 +663,7 @@ static Type BetsCommonType(List list) foreach (var item in collection) { for (int i = 0; i < members.Count; i++) - result[i, j] = members[i].Getter(item)?.ToString() ?? ""; + result[i, j] = members[i].Getter!(item)?.ToString() ?? ""; j++; } @@ -699,21 +699,21 @@ public static string FormatTable(this string[,] table, bool longHeaders = true, return 0.To(height).Select(j => 0.To(width).ToString(i => table[i, j].PadChopRight(lengths[i]), separator)).ToString("\r\n"); } - public static void WriteFormattedStringTable(this IEnumerable collection, TextWriter textWriter, string title, bool longHeaders) + public static void WriteFormattedStringTable(this IEnumerable collection, TextWriter textWriter, string? title, bool longHeaders) { textWriter.WriteLine(); if (title.HasText()) - textWriter.WriteLine(title); + textWriter.WriteLine(title!); textWriter.WriteLine(collection.ToStringTable().FormatTable(longHeaders)); textWriter.WriteLine(); } - public static void ToConsoleTable(this IEnumerable collection, string title = null, bool longHeader = false) + public static void ToConsoleTable(this IEnumerable collection, string? title = null, bool longHeader = false) { collection.WriteFormattedStringTable(Console.Out, title, longHeader); } - public static string ToFormattedTable(this IEnumerable collection, string title = null, bool longHeader = false) + public static string ToFormattedTable(this IEnumerable collection, string? title = null, bool longHeader = false) { StringBuilder sb = new StringBuilder(); using (StringWriter sw = new StringWriter(sb)) @@ -726,9 +726,9 @@ public static string ToFormattedTable(this IEnumerable collection, string public static T WithMin(this IEnumerable collection, Func valueSelector) where V : IComparable { - T result = default(T); + T result = default(T)!; bool hasMin = false; - V min = default(V); + V min = default(V)!; foreach (var item in collection) { V val = valueSelector(item); @@ -746,9 +746,9 @@ public static T WithMin(this IEnumerable collection, Func valueSe public static T WithMax(this IEnumerable collection, Func valueSelector) where V : IComparable { - T result = default(T); + T result = default(T)!; bool hasMax = false; - V max = default(V); + V max = default(V)!; foreach (var item in collection) { @@ -767,18 +767,18 @@ public static List WithMinList(this IEnumerable collection, Func { List result = new List(); - V max = default(V); + V min = default(V)!; foreach (var item in collection) { V val = valueSelector(item); int comp = 0; - if (result.Count == 0 || (comp = val.CompareTo(max)) <= 0) + if (result.Count == 0 || (comp = val.CompareTo(min)) <= 0) { if (comp < 0) result.Clear(); result.Add(item); - max = val; + min = val; } } return result; @@ -788,7 +788,7 @@ public static List WithMaxList(this IEnumerable collection, Func { List result = new List(); - V max = default(V); + V max = default(V)!; foreach (var item in collection) { @@ -808,9 +808,9 @@ public static List WithMaxList(this IEnumerable collection, Func WithMinMaxPair(this IEnumerable collection, Func valueSelector) where V : IComparable { - T withMin = default(T), withMax = default(T); + T withMin = default(T)!, withMax = default(T)!; bool hasMin = false, hasMax = false; - V min = default(V), max = default(V); + V min = default(V)!, max = default(V)!; foreach (var item in collection) { V val = valueSelector(item); @@ -897,12 +897,37 @@ public static IEnumerable Concat(params IEnumerable[] collections) } } - public static IEnumerable BiSelect(this IEnumerable collection, Func func) + public static IEnumerable BiSelectC(this IEnumerable collection, Func func, BiSelectOptions options = BiSelectOptions.None) + where T : class { - return BiSelect(collection, func, BiSelectOptions.None); + using (IEnumerator enumerator = collection.GetEnumerator()) + { + if (!enumerator.MoveNext()) + yield break; + + + T firstItem = enumerator.Current; + if (options == BiSelectOptions.Initial || options == BiSelectOptions.InitialAndFinal) + yield return func(null, firstItem); + + T lastItem = firstItem; + while (enumerator.MoveNext()) + { + T item = enumerator.Current; + yield return func(lastItem, item); + lastItem = item; + } + + if (options == BiSelectOptions.Final || options == BiSelectOptions.InitialAndFinal) + yield return func(lastItem, null); + + if (options == BiSelectOptions.Circular) + yield return func(lastItem, firstItem); + } } - public static IEnumerable BiSelect(this IEnumerable collection, Func func, BiSelectOptions options) + public static IEnumerable BiSelectS(this IEnumerable collection, Func func, BiSelectOptions options = BiSelectOptions.None) + where T : struct { using (IEnumerator enumerator = collection.GetEnumerator()) { @@ -912,7 +937,7 @@ public static IEnumerable BiSelect(this IEnumerable collection, Func T firstItem = enumerator.Current; if (options == BiSelectOptions.Initial || options == BiSelectOptions.InitialAndFinal) - yield return func(default(T), firstItem); + yield return func(null, firstItem); T lastItem = firstItem; while (enumerator.MoveNext()) @@ -923,7 +948,7 @@ public static IEnumerable BiSelect(this IEnumerable collection, Func } if (options == BiSelectOptions.Final || options == BiSelectOptions.InitialAndFinal) - yield return func(lastItem, default(T)); + yield return func(lastItem, null); if (options == BiSelectOptions.Circular) yield return func(lastItem, firstItem); @@ -942,6 +967,7 @@ public static IEnumerable SelectAggregate(this IEnumerable collectio } public static IEnumerable> CartesianProduct(this IEnumerable> sequences) + where T : object { IEnumerable> emptyProduct = new[] { ImmutableStack.Empty }; var result = sequences.Aggregate( @@ -1005,8 +1031,8 @@ public static IEnumerable ZipOrDefault(this IEnumerable colA, IEn while (okA & (okA = enumA.MoveNext()) | okB & (okB = enumB.MoveNext())) { yield return resultSelector( - okA ? enumA.Current : default(A), - okB ? enumB.Current : default(B)); + okA ? enumA.Current : default(A)!, + okB ? enumB.Current : default(B)!); } } } @@ -1020,8 +1046,8 @@ public static IEnumerable ZipOrDefault(this IEnumerable colA, IEn { while ((okA &= enumA.MoveNext()) || (okB &= enumB.MoveNext())) { - var first = okA ? enumA.Current : default(A); - var second = okB ? enumB.Current : default(B); + var first = okA ? enumA.Current : default(A)!; + var second = okB ? enumB.Current : default(B)!; yield return (first, second); } @@ -1125,11 +1151,10 @@ static EmptyReadOnlyDictionary() } } - public static ObservableCollection ToObservableCollection(this IEnumerable collection) + public static ObservableCollection? ToObservableCollection(this IEnumerable? collection) { return collection == null ? null : - collection as ObservableCollection ?? - new ObservableCollection(collection); + collection as ObservableCollection ?? new ObservableCollection(collection); } public static IEnumerable AsThreadSafe(this IEnumerable source) @@ -1188,7 +1213,7 @@ public static IEnumerable JoinStrict( var extra = currentDictionary.Keys.Where(k => !shouldDictionary.ContainsKey(k)).ToList(); var missing = shouldDictionary.Keys.Where(k => !currentDictionary.ContainsKey(k)).ToList(); - string differences = GetDifferences(extra, missing); + string? differences = GetDifferences(extra, missing); if (differences != null) { throw new InvalidOperationException($@"Mismatches {action}: @@ -1212,7 +1237,7 @@ public static IEnumerable JoinRelaxed( var extra = currentDictionary.Keys.Where(k => !shouldDictionary.ContainsKey(k)).ToList(); var missing = shouldDictionary.Keys.Where(k => !currentDictionary.ContainsKey(k)).ToList(); - string differences = GetDifferences(extra, missing); + string? differences = GetDifferences(extra, missing); if (differences != null) { try @@ -1235,7 +1260,7 @@ public static IEnumerable JoinRelaxed( return commonKeys.Select(k => resultSelector(currentDictionary[k], shouldDictionary[k])); } - private static string GetDifferences(List extra, List missing) + private static string? GetDifferences(List extra, List missing) { if (extra.Count != 0) { @@ -1296,7 +1321,7 @@ public static IEnumerable> Iterate(this IEnumerable collectio } } - public static List Duplicates(this IEnumerable source, Func selector, IEqualityComparer comparer) + public static List Duplicates(this IEnumerable source, Func selector, IEqualityComparer? comparer) { var hash = new HashSet(comparer); return source.Where(item => !hash.Add(selector(item))).ToList(); @@ -1443,46 +1468,46 @@ public static class StandartDeviationExtensions public static double? StdDev(this IEnumerable source, Func selector) => source.Select(selector).StdDev(); - public static decimal? StdDev(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); + public static decimal? StdDev(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); - public static double? StdDev(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); + public static double? StdDev(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); - public static double? StdDev(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); + public static double? StdDev(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); - public static double? StdDev(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); + public static double? StdDev(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); - public static decimal? StdDev(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); + public static decimal? StdDev(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); - public static double? StdDev(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); + public static double? StdDev(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); - public static double? StdDev(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); + public static double? StdDev(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); - public static double? StdDev(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); + public static double? StdDev(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); - public static float? StdDev(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); + public static float? StdDev(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); - public static float? StdDev(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); + public static float? StdDev(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); - public static decimal? StdDev(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); + public static decimal? StdDev(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); - public static double? StdDev(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); + public static double? StdDev(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); - public static double? StdDev(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); + public static double? StdDev(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); - public static double? StdDev(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); + public static double? StdDev(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); - public static decimal? StdDev(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); + public static decimal? StdDev(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); - public static double? StdDev(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); + public static double? StdDev(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); - public static double? StdDev(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); + public static double? StdDev(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); - public static double? StdDev(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); + public static double? StdDev(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); - public static float? StdDev(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); + public static float? StdDev(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); - public static float? StdDev(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); + public static float? StdDev(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); } /// @@ -1558,45 +1583,45 @@ public static class StandartDeviationPopulationExtensions public static double? StdDevP(this IEnumerable source, Func selector) => source.Select(selector).StdDevP(); - public static decimal? StdDevP(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); + public static decimal? StdDevP(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); - public static double? StdDevP(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); + public static double? StdDevP(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); - public static double? StdDevP(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); + public static double? StdDevP(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); - public static double? StdDevP(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); + public static double? StdDevP(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); - public static decimal? StdDevP(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); + public static decimal? StdDevP(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); - public static double? StdDevP(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); + public static double? StdDevP(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); - public static double? StdDevP(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); + public static double? StdDevP(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); - public static double? StdDevP(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); + public static double? StdDevP(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); - public static float? StdDevP(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); + public static float? StdDevP(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); - public static float? StdDevP(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); + public static float? StdDevP(this IQueryable source) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression)); - public static decimal? StdDevP(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); + public static decimal? StdDevP(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); - public static double? StdDevP(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); + public static double? StdDevP(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); - public static double? StdDevP(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); + public static double? StdDevP(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); - public static double? StdDevP(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); + public static double? StdDevP(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); - public static decimal? StdDevP(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); + public static decimal? StdDevP(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); - public static double? StdDevP(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); + public static double? StdDevP(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); - public static double? StdDevP(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); + public static double? StdDevP(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); - public static double? StdDevP(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); + public static double? StdDevP(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); - public static float? StdDevP(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); + public static float? StdDevP(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); - public static float? StdDevP(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); + public static float? StdDevP(this IQueryable source, Expression> selector) => source.Provider.Execute(Expression.Call((Expression?)null, (MethodInfo)MethodInfo.GetCurrentMethod(), source.Expression, Expression.Quote(selector))); } } diff --git a/Signum.Utilities/Extensions/Extensions.cs b/Signum.Utilities/Extensions/Extensions.cs index 9bf50b1551..df9b9c7ba4 100644 --- a/Signum.Utilities/Extensions/Extensions.cs +++ b/Signum.Utilities/Extensions/Extensions.cs @@ -350,9 +350,9 @@ public static IEnumerable For(this T start, Func condition, Func< public delegate R FuncCC(T input) where T : class where R : class; - public static IEnumerable Follow(this T start, FuncCC next) where T : class + public static IEnumerable Follow(this T start, FuncCC next) where T : class { - for (T i = start; i != null; i = next(i)) + for (T? i = start; i != null; i = next(i)) yield return i; } diff --git a/Signum.Utilities/Extensions/StreamExtensions.cs b/Signum.Utilities/Extensions/StreamExtensions.cs index 82ea54be73..6f2fb6c76b 100644 --- a/Signum.Utilities/Extensions/StreamExtensions.cs +++ b/Signum.Utilities/Extensions/StreamExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text; using System.IO; using System.Resources; @@ -36,7 +36,7 @@ public static void WriteAllBytes(this Stream str, byte[] data) str.Write(data, 0, data.Length); } - public static string ReadResourceStream(this Assembly assembly, string name, Encoding encoding = null) + public static string ReadResourceStream(this Assembly assembly, string name, Encoding? encoding = null) { using (Stream stream = assembly.GetManifestResourceStream(name)) { diff --git a/Signum.Utilities/Extensions/StringExtensions.cs b/Signum.Utilities/Extensions/StringExtensions.cs index 22f5c20ac9..691f92f8db 100644 --- a/Signum.Utilities/Extensions/StringExtensions.cs +++ b/Signum.Utilities/Extensions/StringExtensions.cs @@ -13,25 +13,25 @@ public static class StringExtensions { static readonly Expression> HasTextExpression = str => (str ?? "").Length > 0; [ExpressionField("HasTextExpression")] - public static bool HasText(this string str) + public static bool HasText(this string? str) { return !string.IsNullOrEmpty(str); } static readonly Expression> DefaultTextExpression = (a, b) => ((a ?? "").Length > 0) ? a : b; [ExpressionField("DefaultTextExpression")] - public static string DefaultText(this string str, string defaultText) + public static string DefaultText(this string? str, string defaultText) { if (str.HasText()) - return str; + return str!; else return defaultText; } - public static string AssertHasText(this string str, string errorMessage) + public static string AssertHasText(this string? str, string errorMessage) { if (str.HasText()) - return str; + return str!; else throw new ArgumentException(errorMessage); } @@ -41,7 +41,7 @@ public static bool Contains(this string source, string toCheck, StringComparison return source.IndexOf(toCheck, comp) >= 0; } - public static string Add(this string str, string separator, string part) + public static string? Add(this string? str, string separator, string? part) { if (str.HasText()) { @@ -54,7 +54,7 @@ public static string Add(this string str, string separator, string part) return part; } - public static string AddLine(this string str, string part) + public static string? AddLine(this string? str, string part) { return Add(str, "\r\n", part); } diff --git a/Signum.Utilities/NaturalLanguage/NaturalLanguageTools.cs b/Signum.Utilities/NaturalLanguage/NaturalLanguageTools.cs index ad4c3d5b4d..b40e5148b9 100644 --- a/Signum.Utilities/NaturalLanguage/NaturalLanguageTools.cs +++ b/Signum.Utilities/NaturalLanguage/NaturalLanguageTools.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using System.Text; using System.Globalization; @@ -28,12 +28,11 @@ public static class NaturalLanguageTools {"es", new SpanishNumberWriter()}, }; - public static char? GetGender(string name, CultureInfo culture = null) + public static char? GetGender(string name, CultureInfo? culture = null) { - if (culture == null) - culture = CultureInfo.CurrentUICulture; + var defCulture = culture ?? CultureInfo.CurrentUICulture; - IGenderDetector detector = GenderDetectors.TryGetC(culture.TwoLetterISOLanguageName); + var detector = GenderDetectors.TryGetC(defCulture.TwoLetterISOLanguageName); if (detector == null) return null; @@ -43,7 +42,7 @@ public static class NaturalLanguageTools public static bool HasGenders(CultureInfo cultureInfo) { - IGenderDetector detector = GenderDetectors.TryGetC(cultureInfo.TwoLetterISOLanguageName); + var detector = GenderDetectors.TryGetC(cultureInfo.TwoLetterISOLanguageName); if (detector == null) return false; @@ -51,12 +50,12 @@ public static bool HasGenders(CultureInfo cultureInfo) return !detector.Pronoms.IsNullOrEmpty(); } - public static string GetPronom(char gender, bool plural, CultureInfo culture = null) + public static string? GetPronom(char gender, bool plural, CultureInfo? culture = null) { if (culture == null) culture = CultureInfo.CurrentUICulture; - IGenderDetector detector = GenderDetectors.TryGetC(culture.TwoLetterISOLanguageName); + var detector = GenderDetectors.TryGetC(culture.TwoLetterISOLanguageName); if (detector == null) return null; @@ -68,12 +67,12 @@ public static string GetPronom(char gender, bool plural, CultureInfo culture = n return plural ? pro.Plural : pro.Singular; } - public static string Pluralize(string singularName, CultureInfo culture = null) + public static string Pluralize(string singularName, CultureInfo? culture = null) { if (culture == null) culture = CultureInfo.CurrentUICulture; - IPluralizer pluralizer = Pluralizers.TryGetC(culture.TwoLetterISOLanguageName); + var pluralizer = Pluralizers.TryGetC(culture.TwoLetterISOLanguageName); if (pluralizer == null) return singularName; @@ -88,10 +87,9 @@ public static string NiceName(this string memberName) memberName.SpacePascal(); } - public static string SpacePascal(this string pascalStr, CultureInfo culture = null) + public static string SpacePascal(this string pascalStr, CultureInfo? culture = null) { - if (culture == null) - culture = CultureInfo.CurrentUICulture; + var defCulture = culture ?? CultureInfo.CurrentUICulture; return SpacePascal(pascalStr, false); } @@ -271,7 +269,9 @@ public class PronomInfo public string Singular { get; private set; } public string Plural { get; private set; } +#pragma warning disable CS8618 // Non-nullable field is uninitialized. public PronomInfo() { } +#pragma warning restore CS8618 // Non-nullable field is uninitialized. public PronomInfo(char gender, string singular, string plural) { diff --git a/Signum.Utilities/Polymorphic.cs b/Signum.Utilities/Polymorphic.cs index 506a645e44..68315a3424 100644 --- a/Signum.Utilities/Polymorphic.cs +++ b/Signum.Utilities/Polymorphic.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Collections.Concurrent; @@ -9,12 +9,12 @@ namespace Signum.Utilities { public static class PolymorphicMerger { - public static T Inheritance(KeyValuePair currentValue, KeyValuePair baseValue, List> newInterfacesValues) where T : class + public static T? Inheritance(KeyValuePair currentValue, KeyValuePair baseValue, List> newInterfacesValues) where T : class { return currentValue.Value ?? baseValue.Value; } - public static T InheritanceAndInterfaces(KeyValuePair currentValue, KeyValuePair baseValue, List> newInterfacesValues) where T : class + public static T? InheritanceAndInterfaces(KeyValuePair currentValue, KeyValuePair baseValue, List> newInterfacesValues) where T : class { var result = currentValue.Value ?? baseValue.Value; @@ -29,7 +29,7 @@ public static T InheritanceAndInterfaces(KeyValuePair currentValue, return conflicts.Select(a => a.Value).SingleOrDefaultEx(); } - public static Dictionary InheritDictionary(KeyValuePair> currentValue, KeyValuePair> baseValue, List>> newInterfacesValues) + public static Dictionary? InheritDictionary(KeyValuePair?> currentValue, KeyValuePair?> baseValue, List?>> newInterfacesValues) { if (currentValue.Value == null && baseValue.Value == null) return null; @@ -37,15 +37,16 @@ public static Dictionary InheritDictionary(KeyValuePair newDictionary = new Dictionary(); if (baseValue.Value != null) - newDictionary.AddRange(baseValue.Value); + newDictionary.AddRange(baseValue.Value!); if (currentValue.Value != null) - newDictionary.SetRange(currentValue.Value); + newDictionary.SetRange(currentValue.Value!); return newDictionary; } - public static Dictionary InheritDictionaryInterfaces(KeyValuePair> currentValue, KeyValuePair> baseValue, List>> newInterfacesValues) + public static Dictionary? InheritDictionaryInterfaces(KeyValuePair?> currentValue, KeyValuePair?> baseValue, List?>> newInterfacesValues) + where K : Object { if (currentValue.Value == null && baseValue.Value == null && newInterfacesValues.All(a => a.Value == null)) return null; @@ -53,22 +54,22 @@ public static Dictionary InheritDictionaryInterfaces(KeyValuePair newDictionary = new Dictionary(); if (baseValue.Value != null) - newDictionary.AddRange(baseValue.Value); + newDictionary.AddRange(baseValue.Value!); if (currentValue.Value != null) - newDictionary.SetRange(currentValue.Value); + newDictionary.SetRange(currentValue.Value!); - var interfaces = newInterfacesValues.Where(a => a.Value != null); + var interfaces = newInterfacesValues.Where(a => a.Value != null) as IEnumerable>>; var keys = interfaces.SelectMany(inter => inter.Value.Keys).Distinct().Except(newDictionary.Keys); foreach (var item in keys) { - var types = interfaces.Where(a => a.Value.ContainsKey(item)).Select(a => new { a.Key, Value = a.Value[item] }).ToList(); + var types = interfaces.Where(a => a.Value!.ContainsKey(item)).Select(a => new { a.Key, Value = a.Value![item] }).ToList(); var groups = types.GroupBy(t => t.Value); if (groups.Count() > 1) - throw new InvalidOperationException("Ambiguity for key {0} in type {0} between interfaces {1}".FormatWith(item, currentValue.Key.Name, types.CommaAnd(t => t.Key.Name))); + throw new InvalidOperationException("Ambiguity for key {0} in type {0} between interfaces {1}".FormatWith(item, currentValue.Key.Name, types.CommaAnd(t => t.Key!.Name))); newDictionary[item] = groups.Single().Key; } @@ -77,15 +78,15 @@ public static Dictionary InheritDictionaryInterfaces(KeyValuePair(KeyValuePair currentValue, KeyValuePair baseValue, List> newInterfacesValues) where T : class; + public delegate T? PolymorphicMerger(KeyValuePair currentValue, KeyValuePair baseValue, List> newInterfacesValues) where T : class; public class Polymorphic where T : class { Dictionary definitions = new Dictionary(); - ConcurrentDictionary cached = new ConcurrentDictionary(); + ConcurrentDictionary cached = new ConcurrentDictionary(); PolymorphicMerger merger; - Type minimumType; + Type? minimumType; public bool ContainsKey(Type type) @@ -102,16 +103,16 @@ bool IsAllowed(Type type) void AssertAllowed(Type type) { if (!IsAllowed(type)) - throw new InvalidOperationException("{0} is not a {1}".FormatWith(type.Name, minimumType.Name)); + throw new InvalidOperationException("{0} is not a {1}".FormatWith(type.Name, minimumType!.Name)); } - public Polymorphic(PolymorphicMerger merger = null, Type minimumType = null) + public Polymorphic(PolymorphicMerger? merger = null, Type? minimumType = null) { this.merger = merger ?? PolymorphicMerger.Inheritance; this.minimumType = minimumType ?? GetDefaultType(typeof(T)); } - private static Type GetDefaultType(Type type) + private static Type? GetDefaultType(Type type) { if (!typeof(Delegate).IsAssignableFrom(type)) return null; @@ -136,23 +137,23 @@ public T GetValue(Type type) return result; } - public T TryGetValue(Type type) + public T? TryGetValue(Type type) { AssertAllowed(type); return cached.GetOrAdd(type, TryGetValueInternal); } - public T GetDefinition(Type type) + public T? GetDefinition(Type type) { AssertAllowed(type); return definitions.TryGetC(type); } - T TryGetValueInternal(Type type) + T? TryGetValueInternal(Type type) { - if (cached.TryGetValue(type, out T result)) + if (cached.TryGetValue(type, out T? result)) return result; var baseValue = type.BaseType == null || !IsAllowed(type.BaseType) ? null : TryGetValue(type.BaseType); @@ -160,7 +161,7 @@ T TryGetValueInternal(Type type) var currentValue = definitions.TryGetC(type); if (minimumType != null && !minimumType.IsInterface) - return merger(KVP.Create(type, currentValue), KVP.Create(type.BaseType, baseValue), null); + return merger(KVP.Create(type, currentValue), KVP.Create(type.BaseType, baseValue), new List>()); IEnumerable interfaces = type.GetInterfaces().Where(IsAllowed); @@ -211,7 +212,7 @@ public static class PolymorphicExtensions { public static T GetOrAddDefinition(this Polymorphic polymorphic, Type type) where T : class, new() { - T value = polymorphic.GetDefinition(type); + T? value = polymorphic.GetDefinition(type); if (value != null) return value; @@ -276,31 +277,31 @@ public static void Register(this Polymorphic(this Polymorphic> polymorphic, T instance) + public static void Invoke(this Polymorphic> polymorphic, T instance) where T : object { var action = polymorphic.GetValue(instance.GetType()); action(instance); } - public static void Invoke(this Polymorphic> polymorphic, T instance, P0 p0) + public static void Invoke(this Polymorphic> polymorphic, T instance, P0 p0) where T : object { var action = polymorphic.GetValue(instance.GetType()); action(instance, p0); } - public static void Invoke(this Polymorphic> polymorphic, T instance, P0 p0, P1 p1) + public static void Invoke(this Polymorphic> polymorphic, T instance, P0 p0, P1 p1) where T : object { var action = polymorphic.GetValue(instance.GetType()); action(instance, p0, p1); } - public static void Invoke(this Polymorphic> polymorphic, T instance, P0 p0, P1 p1, P2 p2) + public static void Invoke(this Polymorphic> polymorphic, T instance, P0 p0, P1 p1, P2 p2) where T : object { var action = polymorphic.GetValue(instance.GetType()); action(instance, p0, p1, p2); } - public static void Invoke(this Polymorphic> polymorphic, T instance, P0 p0, P1 p1, P2 p2, P3 p3) + public static void Invoke(this Polymorphic> polymorphic, T instance, P0 p0, P1 p1, P2 p2, P3 p3) where T : object { var action = polymorphic.GetValue(instance.GetType()); action(instance, p0, p1, p2, p3); @@ -308,31 +309,31 @@ public static void Invoke(this Polymorphic(this Polymorphic> polymorphic, T instance) + public static R Invoke(this Polymorphic> polymorphic, T instance) where T : object { var func = polymorphic.GetValue(instance.GetType()); return func(instance); } - public static R Invoke(this Polymorphic> polymorphic, T instance, P0 p0) + public static R Invoke(this Polymorphic> polymorphic, T instance, P0 p0) where T : object { var func = polymorphic.GetValue(instance.GetType()); return func(instance, p0); } - public static R Invoke(this Polymorphic> polymorphic, T instance, P0 p0, P1 p1) + public static R Invoke(this Polymorphic> polymorphic, T instance, P0 p0, P1 p1) where T : object { var func = polymorphic.GetValue(instance.GetType()); return func(instance, p0, p1); } - public static R Invoke(this Polymorphic> polymorphic, T instance, P0 p0, P1 p1, P2 p2) + public static R Invoke(this Polymorphic> polymorphic, T instance, P0 p0, P1 p1, P2 p2) where T : object { var func = polymorphic.GetValue(instance.GetType()); return func(instance, p0, p1, p2); } - public static R Invoke(this Polymorphic> polymorphic, T instance, P0 p0, P1 p1, P2 p2, P3 p3) + public static R Invoke(this Polymorphic> polymorphic, T instance, P0 p0, P1 p1, P2 p2, P3 p3) where T : object { var func = polymorphic.GetValue(instance.GetType()); return func(instance, p0, p1, p2, p3); diff --git a/Signum.Utilities/Profiler/HeavyProfiler.cs b/Signum.Utilities/Profiler/HeavyProfiler.cs index b8a3dfdf84..318656564b 100644 --- a/Signum.Utilities/Profiler/HeavyProfiler.cs +++ b/Signum.Utilities/Profiler/HeavyProfiler.cs @@ -47,7 +47,7 @@ public static void Clean() } } - public static Tracer Log(string role) + public static Tracer? Log(string role) { if (!enabled) return null; @@ -57,7 +57,7 @@ public static Tracer Log(string role) return tracer; } - public static Tracer Log(string role, Func additionalData) + public static Tracer? Log(string role, Func additionalData) { if (!enabled) return null; @@ -67,7 +67,7 @@ public static Tracer Log(string role, Func additionalData) return tracer; } - public static Tracer LogNoStackTrace(string role) + public static Tracer? LogNoStackTrace(string role) { if (!enabled) return null; @@ -77,7 +77,7 @@ public static Tracer LogNoStackTrace(string role) return tracer; } - public static Tracer LogNoStackTrace(string role, Func additionalData) + public static Tracer? LogNoStackTrace(string role, Func additionalData) { if (!enabled) return null; @@ -109,7 +109,7 @@ public static T LogValueNoStackTrace(string role, Func valueFactory) } } - private static Tracer CreateNewEntry(string role, Func additionalData, bool stackTrace) + private static Tracer? CreateNewEntry(string role, Func? additionalData, bool stackTrace) { long beforeStart = PerfCounter.Ticks; @@ -161,8 +161,8 @@ private static Tracer CreateNewEntry(string role, Func additionalData, b public class Tracer : IDisposable { - internal HeavyProfilerEntry newCurrent; - + internal HeavyProfilerEntry? newCurrent; + public void Dispose() { if (newCurrent == null) //After a Switch sequence disabled in the middle @@ -180,7 +180,7 @@ public void Dispose() } } - public static void Switch(this Tracer tracer, string role, Func additionalData = null) + public static void Switch(this Tracer tracer, string role, Func? additionalData = null) { if (tracer == null) return; @@ -279,7 +279,7 @@ public static HeavyProfilerEntry Find(string fullIndex) { var array = fullIndex.Split('-').Select(a => int.Parse(a)).ToArray(); - HeavyProfilerEntry entry = null; + HeavyProfilerEntry? entry = null; List currentList = Signum.Utilities.HeavyProfiler.Entries; @@ -295,7 +295,7 @@ public static HeavyProfilerEntry Find(string fullIndex) currentList = entry.Entries; } - return entry; + return entry!; } } @@ -303,7 +303,7 @@ public static HeavyProfilerEntry Find(string fullIndex) public class HeavyProfilerEntry { public List Entries; - public HeavyProfilerEntry Parent; + public HeavyProfilerEntry? Parent; public string Role; public int Index; @@ -315,7 +315,7 @@ public string FullIndex() return this.Follow(a => a.Parent).Reverse().ToString(a => a.Index.ToString(), "-"); } - public string AdditionalData; + public string? AdditionalData; public string AdditionalDataPreview() { if (string.IsNullOrEmpty(AdditionalData)) @@ -329,8 +329,8 @@ public string AdditionalDataPreview() public long? End; public long EndOrNow => End ?? PerfCounter.Ticks; - public StackTrace StackTrace; - public List ExternalStackTrace; + public StackTrace? StackTrace; + public List? ExternalStackTrace; public TimeSpan Elapsed { @@ -445,7 +445,7 @@ public void CleanStackTrace() item.CleanStackTrace(); } - internal static HeavyProfilerEntry ImportXml(XElement xLog, HeavyProfilerEntry parent) + internal static HeavyProfilerEntry ImportXml(XElement xLog, HeavyProfilerEntry? parent = null) { var result = new HeavyProfilerEntry { diff --git a/Signum.Utilities/SafeConsole.cs b/Signum.Utilities/SafeConsole.cs index f22f2451cf..f29af664a0 100644 --- a/Signum.Utilities/SafeConsole.cs +++ b/Signum.Utilities/SafeConsole.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; @@ -22,7 +22,7 @@ public static void WriteSameLine(string str) if (needToClear) str = str.PadChopRight(Console.BufferWidth - 1); else - str = str.TryStart(Console.BufferWidth - 1); + str = str.TryStart(Console.BufferWidth - 1)!; Console.WriteLine(str); @@ -78,14 +78,14 @@ public static void WriteSameLineColor(ConsoleColor color, string str) Console.ForegroundColor = old; } - public static string AskString(string question, Func stringValidator = null) + public static string AskString(string question, Func? stringValidator = null) { Console.Write(question); do { var userAnswer = Console.ReadLine(); - string error = stringValidator == null ? null : stringValidator(userAnswer); + string? error = stringValidator == null ? null : stringValidator(userAnswer); if (error == null) return userAnswer; @@ -112,7 +112,7 @@ public static string Ask(string question, params string[] answers) } while (true); } - public static string AskMultiLine(string question, params string[] answers) + public static string? AskMultiLine(string question, params string[] answers) { Console.WriteLine(question); @@ -147,7 +147,7 @@ public static bool Ask(ref bool? rememberedAnswer, string question) if (rememberedAnswer != null) return rememberedAnswer.Value; - string answerString = null; + string? answerString = null; string result = Ask(ref answerString, question, "yes", "no"); @@ -157,7 +157,7 @@ public static bool Ask(ref bool? rememberedAnswer, string question) return result == "yes"; } - public static string Ask(ref string rememberedAnswer, string question, params string[] answers) + public static string Ask(ref string? rememberedAnswer, string question, params string[] answers) { if (rememberedAnswer != null) return rememberedAnswer; @@ -186,7 +186,7 @@ public static string Ask(ref string rememberedAnswer, string question, params st } } - public static string AskSwitch(string question, List options) + public static string? AskSwitch(string question, List options) { var cs = new ConsoleSwitch(question); @@ -215,7 +215,7 @@ public static int WaitRows(string startingText, Func updateOrDelete) public static T WaitQuery(string startingText, Func query) { - T result = default(T); + T result = default(T)!; SafeConsole.WriteColor(ConsoleColor.Yellow, startingText); WaitExecute(() => { result = query(); Console.WriteLine(); }); return result; diff --git a/Signum.Utilities/Signum.Utilities.csproj b/Signum.Utilities/Signum.Utilities.csproj index 9bdbe60fcb..eadfd1b5af 100644 --- a/Signum.Utilities/Signum.Utilities.csproj +++ b/Signum.Utilities/Signum.Utilities.csproj @@ -9,6 +9,10 @@ x64 + + 1701;1702;8618 + + PreserveNewest diff --git a/Signum.Utilities/Statics.cs b/Signum.Utilities/Statics.cs index 8a06333418..10d2eb62bf 100644 --- a/Signum.Utilities/Statics.cs +++ b/Signum.Utilities/Statics.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -17,7 +17,7 @@ public static ThreadVariable ThreadVariable(string name, bool avoidExportI return variable; } - public static Dictionary ExportThreadContext(bool force = false) + public static Dictionary ExportThreadContext(bool force = false) { return threadVariables.Where(t => !t.Value.IsClean && (!t.Value.AvoidExportImport || force)).ToDictionaryEx(kvp => kvp.Key, kvp => kvp.Value.UntypedValue); } @@ -82,7 +82,7 @@ public static ISessionFactory SessionFactory public interface IUntypedVariable { string Name { get; } - object UntypedValue { get; set; } + object? UntypedValue { get; set; } bool IsClean {get;} void Clean(); } @@ -98,7 +98,7 @@ public Variable(string name) public abstract T Value { get; set; } - public object UntypedValue + public object? UntypedValue { get { return Value; } set { Value = (T)value; } @@ -152,13 +152,13 @@ public override T Value public override void Clean() { - Value = default(T); + Value = default(T)!; } } public abstract class SessionVariable: Variable { - public abstract Func ValueFactory { get; set; } + public abstract Func? ValueFactory { get; set; } protected internal SessionVariable(string name) : base(name) @@ -168,7 +168,7 @@ protected internal SessionVariable(string name) public T GetDefaulValue() { if (ValueFactory == null) - return default(T); + return default(T)!; Value = ValueFactory(); @@ -191,15 +191,16 @@ public SessionVariable CreateVariable(string name) class VoidVariable : SessionVariable { - public override Func ValueFactory { get; set; } + public override Func? ValueFactory { get; set; } public VoidVariable(string name) : base(name) - { } + { + } public override T Value { - get { return default(T); } + get { return default(T)!; } set { throw new InvalidOperationException("No session found to set '{0}'".FormatWith(this.Name)); ; } } @@ -211,9 +212,9 @@ public override void Clean() public class SingletonSessionFactory : ISessionFactory { - public static Dictionary singletonSession = new Dictionary(); + public static Dictionary singletonSession = new Dictionary(); - public static Dictionary SingletonSession + public static Dictionary SingletonSession { get { return singletonSession; } set { singletonSession = value; } @@ -226,8 +227,8 @@ public SessionVariable CreateVariable(string name) class SingletonVariable : SessionVariable { - public override Func ValueFactory { get; set; } - + public override Func? ValueFactory { get; set; } + public SingletonVariable(string name) : base(name) { } @@ -236,7 +237,7 @@ public override T Value { get { - if (singletonSession.TryGetValue(Name, out object result)) + if (singletonSession.TryGetValue(Name, out object? result)) return (T)result; return GetDefaulValue(); @@ -255,7 +256,7 @@ public class ScopeSessionFactory : ISessionFactory { public ISessionFactory Factory; - static readonly ThreadVariable> overridenSession = Statics.ThreadVariable>("overridenSession"); + static readonly ThreadVariable> overridenSession = Statics.ThreadVariable>("overridenSession"); public static bool IsOverriden { @@ -269,10 +270,10 @@ public ScopeSessionFactory(ISessionFactory factory) public static IDisposable OverrideSession() { - return OverrideSession(new Dictionary()); + return OverrideSession(new Dictionary()); } - public static IDisposable OverrideSession(Dictionary sessionDictionary) + public static IDisposable OverrideSession(Dictionary sessionDictionary) { if (!(Statics.SessionFactory is ScopeSessionFactory)) throw new InvalidOperationException("Impossible to OverrideSession because Statics.SessionFactory is not a ScopeSessionFactory"); @@ -296,7 +297,7 @@ public OverrideableVariable(SessionVariable variable) this.variable = variable; } - public override Func ValueFactory + public override Func? ValueFactory { get { return variable.ValueFactory; } set { variable.ValueFactory = value; } @@ -310,7 +311,7 @@ public override T Value if (dic != null) { - if (dic.TryGetValue(Name, out object result)) + if (dic.TryGetValue(Name, out object? result)) return (T)result; return GetDefaulValue(); From 766882852e41814b9cfd13909770e4af750cda53 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Tue, 8 Jan 2019 08:06:25 +0100 Subject: [PATCH 05/25] not nullable entities --- Signum.Entities/DynamicQuery/ResultTable.cs | 56 ++++++++--------- .../DynamicQuery/Tokens/QueryToken.cs | 4 +- Signum.Entities/Entity.cs | 18 +++--- Signum.Entities/FieldAttributes.cs | 26 ++++---- Signum.Entities/ModifiableEntity.cs | 62 +++++++++---------- Signum.Entities/Patterns/ImmutableEntity.cs | 8 +-- Signum.Entities/Signum.Entities.csproj | 4 +- .../Extensions/StringExtensions.cs | 6 +- 8 files changed, 90 insertions(+), 94 deletions(-) diff --git a/Signum.Entities/DynamicQuery/ResultTable.cs b/Signum.Entities/DynamicQuery/ResultTable.cs index dbdaa06082..890d29c83e 100644 --- a/Signum.Entities/DynamicQuery/ResultTable.cs +++ b/Signum.Entities/DynamicQuery/ResultTable.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -36,6 +36,7 @@ public ResultColumn(Column column, IList values) } +#pragma warning disable CS8618 // Non-nullable field is uninitialized. ResultColumn(SerializationInfo info, StreamingContext context) { foreach (SerializationEntry entry in info) @@ -48,6 +49,7 @@ public ResultColumn(Column column, IList values) } } } +#pragma warning restore CS8618 // Non-nullable field is uninitialized. GenericInvoker> listBuilder = new GenericInvoker>(num => new List(num)); @@ -73,7 +75,7 @@ public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("column", column); - Func serializer = GetValueSerializer(); + Func? serializer = GetValueSerializer(); if (serializer == null) info.AddValue("valuesList", values); @@ -138,7 +140,7 @@ Func GetValueDeserializer() throw new InvalidOperationException("Impossible to deserialize a ResultColumn of {0}".FormatWith(column.Type)); } - Func GetValueSerializer() + Func? GetValueSerializer() { if (column.Type.IsLite()) { @@ -217,7 +219,7 @@ static object DeserializeLite(string str, Type defaultEntityType) public class ResultTable { internal ResultColumn entityColumn; - public ColumnDescription EntityColumn + public ColumnDescription? EntityColumn { get { return entityColumn == null ? null : ((ColumnToken)entityColumn.Column.Token).Column; } } @@ -239,7 +241,10 @@ public ResultTable(ResultColumn[] columns, int? totalElements, Pagination pagina this.entityColumn = columns.Where(c => c.Column is _EntityColumn).SingleOrDefaultEx(); this.columns = columns.Where(c => !(c.Column is _EntityColumn) && c.Column.Token.IsAllowed() == null).ToArray(); - CreateIndices(columns); + int rowCount = columns.Select(a => a.Values.Count).Distinct().SingleEx(() => "Count"); + for (int i = 0; i < Columns.Length; i++) + Columns[i].Index = i; + this.rows = 0.To(rowCount).Select(i => new ResultRow(i, this)).ToArray(); this.totalElements = totalElements; this.pagination = pagination; @@ -251,34 +256,23 @@ public ResultTable(ResultColumn[] columns, int? totalElements, Pagination pagina // CreateIndices(columns); //} - void CreateIndices(ResultColumn[] columns) - { - int rows = columns.Select(a => a.Values.Count).Distinct().SingleEx(() => "Count"); - - for (int i = 0; i < Columns.Length; i++) - Columns[i].Index = i; - - this.rows = 0.To(rows).Select(i => new ResultRow(i, this)).ToArray(); - } - - public DataTable ToDataTable(DataTableValueConverter converter = null) + + public DataTable ToDataTable(DataTableValueConverter? converter = null) { - if (converter == null) - converter = new InvariantDataTableValueConverter(); + var defConverter = converter ?? new InvariantDataTableValueConverter(); DataTable dt = new DataTable("Table"); - dt.Columns.AddRange(Columns.Select(c => new DataColumn(c.Column.Name, converter.ConvertType(c.Column))).ToArray()); + dt.Columns.AddRange(Columns.Select(c => new DataColumn(c.Column.Name, defConverter.ConvertType(c.Column))).ToArray()); foreach (var row in Rows) { - dt.Rows.Add(Columns.Select((c, i) => converter.ConvertValue(row[i], c.Column)).ToArray()); + dt.Rows.Add(Columns.Select((c, i) => defConverter.ConvertValue(row[i], c.Column)).ToArray()); } return dt; } - public DataTable ToDataTablePivot(int rowColumnIndex, int columnColumnIndex, int valueIndex, DataTableValueConverter converter = null) + public DataTable ToDataTablePivot(int rowColumnIndex, int columnColumnIndex, int valueIndex, DataTableValueConverter? converter = null) { - if (converter != null) - converter = new InvariantDataTableValueConverter(); + var defConverter = converter ?? new InvariantDataTableValueConverter(); string Null = "- NULL -"; @@ -297,15 +291,15 @@ public DataTable ToDataTablePivot(int rowColumnIndex, int columnColumnIndex, int var valueColumn = this.Columns[valueIndex]; var result = new DataTable(); - result.Columns.Add(new DataColumn( rowColumn.Column.DisplayName, converter.ConvertType(rowColumn.Column))); + result.Columns.Add(new DataColumn( rowColumn.Column.DisplayName, defConverter.ConvertType(rowColumn.Column))); foreach (var item in allColumns) - result.Columns.Add(new DataColumn(item.ToString(), converter.ConvertType(valueColumn.Column))); + result.Columns.Add(new DataColumn(item.ToString(), defConverter.ConvertType(valueColumn.Column))); foreach (var kvp in dictionary) { result.Rows.Add( - allColumns.Select(val => converter.ConvertValue(kvp.Value.TryGetC(val), valueColumn.Column)) - .PreAnd(converter.ConvertValue(kvp.Key, rowColumn.Column)) + allColumns.Select(val => defConverter.ConvertValue(kvp.Value.TryGetC(val), valueColumn.Column)) + .PreAnd(defConverter.ConvertValue(kvp.Key, rowColumn.Column)) .ToArray()); } @@ -339,7 +333,7 @@ public int? EndElementIndex public abstract class DataTableValueConverter { public abstract Type ConvertType(Column column); - public abstract object ConvertValue(object value, Column column); + public abstract object? ConvertValue(object? value, Column column); } public class NiceDataTableValueConverter : DataTableValueConverter @@ -360,7 +354,7 @@ public override Type ConvertType(Column column) return type.UnNullify(); } - public override object ConvertValue(object value, Column column) + public override object? ConvertValue(object? value, Column column) { if (value is Lite) return ((Lite)value).ToString(); @@ -391,7 +385,7 @@ public override Type ConvertType(Column column) return type.UnNullify(); } - public override object ConvertValue(object value, Column column) + public override object? ConvertValue(object? value, Column column) { var type = column.Token.Type; @@ -444,7 +438,7 @@ public Lite Entity get { return (Lite)Table.entityColumn.Values[Index]; } } - public Lite TryEntity + public Lite? TryEntity { get { return Table.entityColumn == null ? null : (Lite)Table.entityColumn.Values[Index]; } } diff --git a/Signum.Entities/DynamicQuery/Tokens/QueryToken.cs b/Signum.Entities/DynamicQuery/Tokens/QueryToken.cs index d66bae65e3..73d2a71564 100644 --- a/Signum.Entities/DynamicQuery/Tokens/QueryToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/QueryToken.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Signum.Utilities.Reflection; @@ -92,7 +92,7 @@ public Expression BuildExpression(BuildExpressionContext context) public abstract PropertyRoute GetPropertyRoute(); - internal PropertyRoute AddPropertyRoute(PropertyInfo pi) + internal PropertyRoute? AddPropertyRoute(PropertyInfo pi) { if (typeof(ModelEntity).IsAssignableFrom(Type)) return PropertyRoute.Root(Type).Add(pi); diff --git a/Signum.Entities/Entity.cs b/Signum.Entities/Entity.cs index b91277c795..70dcc207c4 100644 --- a/Signum.Entities/Entity.cs +++ b/Signum.Entities/Entity.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Signum.Utilities; @@ -22,7 +22,7 @@ public abstract class Entity : ModifiableEntity, IEntity [Ignore, DebuggerBrowsable(DebuggerBrowsableState.Never)] - protected internal string toStr; //for queries and lites on entities with non-expression ToString + protected internal string? toStr; //for queries and lites on entities with non-expression ToString [HiddenProperty, Description("Id")] public PrimaryKey Id @@ -60,7 +60,7 @@ public long Ticks set { ticks = value; } } - protected bool SetIfNew(ref T field, T value, [CallerMemberNameAttribute]string automaticPropertyName = null) + protected bool SetIfNew(ref T field, T value, [CallerMemberName]string? automaticPropertyName = null) { if (EqualityComparer.Default.Equals(field, value)) return false; @@ -70,7 +70,7 @@ protected bool SetIfNew(ref T field, T value, [CallerMemberNameAttribute]stri throw new InvalidOperationException("Attempt to modify '{0}' when the entity is not new".FormatWith(automaticPropertyName)); } - return base.Set(ref field, value, automaticPropertyName); + return base.Set(ref field, value, automaticPropertyName!); } public override string ToString() @@ -135,7 +135,7 @@ public M Mixin() where M : MixinEntity .FormatWith(typeof(M).TypeName(), GetType().TypeName())); } - public M TryMixin() where M : MixinEntity + public M? TryMixin() where M : MixinEntity { var current = mixin; while (current != null) @@ -256,7 +256,7 @@ static class ReadonlySetterCache where T : ModifiableEntity internal static Action Setter(PropertyInfo pi) { - return (Action)cache.GetOrAdd(pi.Name, s => ReflectionTools.CreateSetter(Reflector.FindFieldInfo(typeof(T), pi))); + return (Action)cache.GetOrAdd(pi.Name, s => ReflectionTools.CreateSetter(Reflector.FindFieldInfo(typeof(T), pi))!); } } @@ -271,9 +271,9 @@ public static T SetIsNew(this T entity, bool isNew = true) public static T SetNotModified(this T mod) where T : Modifiable { - if (mod is Entity e) - e.IsNew = false; - mod.Modified = ModifiedState.Clean; + if (mod is Entity) + ((Entity)(Modifiable)mod).IsNew = false; + mod.Modified = ModifiedState.Clean; /*Compiler bug*/ return mod; } diff --git a/Signum.Entities/FieldAttributes.cs b/Signum.Entities/FieldAttributes.cs index e412c3f573..887b436b7a 100644 --- a/Signum.Entities/FieldAttributes.cs +++ b/Signum.Entities/FieldAttributes.cs @@ -26,7 +26,7 @@ public sealed class AttachToUniqueIndexesAttribute : Attribute [Serializable] public struct Implementations : IEquatable, ISerializable { - object arrayOrType; + object? arrayOrType; public bool IsByAll { get { return arrayOrType == null; } } public IEnumerable Types @@ -46,11 +46,13 @@ private IEnumerable Enumerate() { yield return t; } - else + else if (arrayOrType is Type[] ts) { - foreach (var item in ((Type[])arrayOrType)) + foreach (var item in ts) yield return item; } + else + throw new InvalidOperationException("IsByAll"); } public static Implementations? TryFromAttributes(Type t, PropertyRoute route, ImplementedByAttribute ib, ImplementedByAllAttribute iba) @@ -121,7 +123,7 @@ public static Implementations By(params Type[] types) return new Implementations { arrayOrType = types.OrderBy(a => a.FullName).ToArray() }; } - static string Error(Type type) + static string? Error(Type type) { if (type.IsInterface) return "{0} is an interface".FormatWith(type.Name); @@ -183,8 +185,8 @@ public override int GetHashCode() public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("arrayOrType", arrayOrType == null ? "ALL" : - arrayOrType is Type ? ((Type)arrayOrType).AssemblyQualifiedName : - arrayOrType is Type[] ? ((Type[])arrayOrType).ToString(a => a.AssemblyQualifiedName, "|") : null); + arrayOrType is Type t ? t.AssemblyQualifiedName : + arrayOrType is Type[] ts ? ts.ToString(a => a.AssemblyQualifiedName, "|") : null); } } @@ -279,11 +281,11 @@ public bool HasScale get { return scale.HasValue; } } - public string UserDefinedTypeName { get; set; } + public string? UserDefinedTypeName { get; set; } - public string Default { get; set; } + public string? Default { get; set; } - public string Collation { get; set; } + public string? Collation { get; set; } public const string NewId = "NEWID()"; public const string NewSequentialId = "NEWSEQUENTIALID()"; @@ -371,9 +373,9 @@ public sealed class TicksColumnAttribute : SqlDbTypeAttribute { public bool HasTicks { get; private set; } - public string Name { get; set; } + public string? Name { get; set; } - public Type Type { get; set; } + public Type? Type { get; set; } public TicksColumnAttribute(bool hasTicks = true) { @@ -387,7 +389,7 @@ public TicksColumnAttribute(bool hasTicks = true) [AttributeUsage(AttributeTargets.Class | AttributeTargets.Field | AttributeTargets.Property /*MList fields*/, Inherited = true, AllowMultiple = false)] public sealed class SystemVersionedAttribute : Attribute { - public string TemporalTableName { get; set; } + public string? TemporalTableName { get; set; } public string StartDateColumnName { get; set; } = "SysStartDate"; public string EndDateColumnName { get; set; } = "SysEndDate"; } diff --git a/Signum.Entities/ModifiableEntity.cs b/Signum.Entities/ModifiableEntity.cs index f175fb6556..c4d1a6235c 100644 --- a/Signum.Entities/ModifiableEntity.cs +++ b/Signum.Entities/ModifiableEntity.cs @@ -33,18 +33,18 @@ internal static void SetIsRetrievingFunc(Func isRetrievingFunc) protected internal const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; - protected virtual T Get(T fieldValue, [CallerMemberName]string automaticPropertyName = null) + protected virtual T Get(T fieldValue, [CallerMemberName]string? automaticPropertyName = null) { return fieldValue; } - protected virtual bool Set(ref T field, T value, [CallerMemberName]string automaticPropertyName = null) + protected virtual bool Set(ref T field, T value, [CallerMemberName]string? automaticPropertyName = null) { if (EqualityComparer.Default.Equals(field, value)) return false; - PropertyInfo pi = GetPropertyInfo(automaticPropertyName); + PropertyInfo pi = GetPropertyInfo(automaticPropertyName!); if (pi == null) throw new ArgumentException("No PropertyInfo with name {0} found in {1} or any implemented interface".FormatWith(automaticPropertyName, this.GetType().TypeName())); @@ -52,41 +52,39 @@ protected virtual bool Set(ref T field, T value, [CallerMemberName]string aut if (value is IMListPrivate && !((IMListPrivate)value).IsNew && !object.ReferenceEquals(value, field)) throw new InvalidOperationException("Only MList with IsNew = true can be assigned to an entity"); - if (field is INotifyCollectionChanged col) + if (field is INotifyCollectionChanged colb) { if (AttributeManager.FieldContainsAttribute(GetType(), pi)) - col.CollectionChanged -= ChildCollectionChanged; + colb.CollectionChanged -= ChildCollectionChanged; if (AttributeManager.FieldContainsAttribute(GetType(), pi)) - foreach (ModifiableEntity item in (IEnumerable)col) + foreach (ModifiableEntity item in (IEnumerable)colb) item.SetParentEntity(null); } - if ((object)field is ModifiableEntity mod) + if (field is ModifiableEntity modb) { if (AttributeManager.FieldContainsAttribute(GetType(), pi)) - mod.SetParentEntity(null); + modb.SetParentEntity(null); } SetSelfModified(); field = value; - - col = field as INotifyCollectionChanged; - if (col != null) + + if (field is INotifyCollectionChanged cola) { if (AttributeManager.FieldContainsAttribute(GetType(), pi)) - col.CollectionChanged += ChildCollectionChanged; + cola.CollectionChanged += ChildCollectionChanged; if (AttributeManager.FieldContainsAttribute(GetType(), pi)) - foreach (ModifiableEntity item in (IEnumerable)col) + foreach (ModifiableEntity item in (IEnumerable)cola) item.SetParentEntity(this); } - - mod = field as ModifiableEntity; - if (mod != null) + + if (field is ModifiableEntity moda) { if (AttributeManager.FieldContainsAttribute(GetType(), pi)) - mod.SetParentEntity(this); + moda.SetParentEntity(this); } NotifyPrivate(pi.Name); @@ -153,7 +151,7 @@ protected virtual void RebindEvents() notify.CollectionChanged += ChildCollectionChanged; } - foreach (object field in AttributeManager.FieldsWithAttribute(this)) + foreach (object? field in AttributeManager.FieldsWithAttribute(this)) { if (field == null) continue; @@ -162,7 +160,7 @@ protected virtual void RebindEvents() entity.SetParentEntity(this); else { - foreach (ModifiableEntity item in (IEnumerable)field) + foreach (ModifiableEntity item in (IEnumerable)field!) item.SetParentEntity(this); } } @@ -201,7 +199,7 @@ protected virtual void ChildPropertyChanged(object sender, PropertyChangedEventA } - protected virtual string ChildPropertyValidation(ModifiableEntity sender, PropertyInfo pi) + protected virtual string? ChildPropertyValidation(ModifiableEntity sender, PropertyInfo pi) { return null; } @@ -211,14 +209,14 @@ protected virtual string ChildPropertyValidation(ModifiableEntity sender, Proper public event PropertyChangedEventHandler PropertyChanged; [NonSerialized, Ignore] - ModifiableEntity parentEntity; + ModifiableEntity? parentEntity; - public ModifiableEntity GetParentEntity() + public ModifiableEntity? GetParentEntity() { return parentEntity; } - private void SetParentEntity(ModifiableEntity p) + private void SetParentEntity(ModifiableEntity? p) { if (p != null && this.parentEntity != null && this.parentEntity != p) throw new InvalidOperationException($"'{nameof(parentEntity)}' is still connected to '{parentEntity}'"); @@ -226,7 +224,7 @@ private void SetParentEntity(ModifiableEntity p) this.parentEntity = p; } - internal string OnParentChildPropertyValidation(PropertyInfo pi) + internal string? OnParentChildPropertyValidation(PropertyInfo pi) { if (parentEntity == null) return null; @@ -277,18 +275,18 @@ public override int GetHashCode() #region IDataErrorInfo Members [HiddenProperty] - public string Error + public string? Error { get { return IntegrityCheck()?.Errors.Values.ToString("\r\n"); } } - public IntegrityCheck IntegrityCheck() + public IntegrityCheck? IntegrityCheck() { using (var log = HeavyProfiler.LogNoStackTrace("IntegrityCheck")) { var validators = Validator.GetPropertyValidators(GetType()); - Dictionary dic = null; + Dictionary? dic = null; foreach (var pv in validators.Values) { @@ -311,7 +309,7 @@ public IntegrityCheck IntegrityCheck() //override for per-property checks [HiddenProperty] - string IDataErrorInfo.this[string columnName] + string? IDataErrorInfo.this[string columnName] { get { @@ -322,12 +320,12 @@ string IDataErrorInfo.this[string columnName] } } - public string PropertyCheck(Expression> property) + public string? PropertyCheck(Expression> property) { return PropertyCheck(ReflectionTools.GetPropertyInfo(property).Name); } - public string PropertyCheck(string propertyName) + public string? PropertyCheck(string propertyName) { IPropertyValidator pp = Validator.TryGetPropertyValidator(GetType(), propertyName); @@ -337,7 +335,7 @@ public string PropertyCheck(string propertyName) return pp.PropertyCheck(this); } - protected internal virtual string PropertyValidation(PropertyInfo pi) + protected internal virtual string? PropertyValidation(PropertyInfo pi) { return null; } @@ -384,7 +382,7 @@ object ICloneable.Clone() [Ignore] - internal Dictionary temporalErrors; + internal Dictionary? temporalErrors; internal void SetTemporalErrors(Dictionary errors) { NotifyTemporalErrors(); diff --git a/Signum.Entities/Patterns/ImmutableEntity.cs b/Signum.Entities/Patterns/ImmutableEntity.cs index d8c49acdd0..8d8829f4ef 100644 --- a/Signum.Entities/Patterns/ImmutableEntity.cs +++ b/Signum.Entities/Patterns/ImmutableEntity.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.CompilerServices; using Signum.Utilities; @@ -16,12 +16,12 @@ public bool AllowChange set { allowTemporaly = value; Notify(() => AllowChange); } } - protected override bool Set(ref T variable, T value, [CallerMemberNameAttribute]string automaticPropertyName = null) + protected override bool Set(ref T variable, T value, [CallerMemberName]string? automaticPropertyName = null) { if (AllowChange) - return base.Set(ref variable, value, automaticPropertyName); + return base.Set(ref variable, value, automaticPropertyName!); else - return base.SetIfNew(ref variable, value, automaticPropertyName); + return base.SetIfNew(ref variable, value, automaticPropertyName!); } protected internal override void PreSaving(PreSavingContext ctx) diff --git a/Signum.Entities/Signum.Entities.csproj b/Signum.Entities/Signum.Entities.csproj index 8ae9ce348e..715a252080 100644 --- a/Signum.Entities/Signum.Entities.csproj +++ b/Signum.Entities/Signum.Entities.csproj @@ -2,8 +2,10 @@ netcoreapp2.2 - latest + 8.0 true + true + true x64 diff --git a/Signum.Utilities/Extensions/StringExtensions.cs b/Signum.Utilities/Extensions/StringExtensions.cs index 3a448a1a02..e61cd499ae 100644 --- a/Signum.Utilities/Extensions/StringExtensions.cs +++ b/Signum.Utilities/Extensions/StringExtensions.cs @@ -13,7 +13,7 @@ public static class StringExtensions { static readonly Expression> HasTextExpression = str => (str ?? "").Length > 0; [ExpressionField("HasTextExpression")] - public static bool HasText(this string str) + public static bool HasText(this string? str) { return !string.IsNullOrEmpty(str); } @@ -603,7 +603,7 @@ public static string FormatWith(this string format, object? arg0) return string.Format(format, arg0); } - public static string FormatWith(this string format, object arg0, object arg1) + public static string FormatWith(this string format, object? arg0, object arg1) { return string.Format(format, arg0, arg1); } @@ -780,7 +780,7 @@ public static string Combine(this string separator, params object[] elements) return sb == null ? "" : sb.ToString(); // Remove at the end is faster } - public static string CombineIfNotEmpty(this string separator, params object[] elements) + public static string CombineIfNotEmpty(this string separator, params object?[] elements) { StringBuilder? sb = null; foreach (var item in elements) From 91a248b24744456cc7bba7debed0520f38324c3d Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Thu, 10 Jan 2019 07:57:48 +0100 Subject: [PATCH 06/25] not nullable in entities --- .../DynamicQuery/ExpressionContainer.cs | 15 +-- Signum.Entities/Basics/Operation.cs | 52 ++++---- Signum.Entities/DynamicQuery/Column.cs | 6 +- Signum.Entities/DynamicQuery/Meta.cs | 8 +- Signum.Entities/DynamicQuery/QueryUtils.cs | 23 ++-- .../DynamicQuery/Tokens/AggregateToken.cs | 70 +++++----- .../DynamicQuery/Tokens/AsTypeToken.cs | 35 +++-- .../Tokens/CollectionAnyAllToken.cs | 33 ++--- .../Tokens/CollectionElementToken.cs | 44 ++++--- .../DynamicQuery/Tokens/ColumnToken.cs | 41 +++--- .../DynamicQuery/Tokens/CountToken.cs | 24 ++-- .../Tokens/DateTimeSpecialTokens.cs | 24 ++-- .../DynamicQuery/Tokens/DateToken.cs | 23 ++-- .../Tokens/DecimalSpecialTokens.cs | 123 ++++++++++-------- .../Tokens/EntityPropertyToken.cs | 47 ++++--- .../Tokens/EntityToStringToken.cs | 32 ++--- .../Tokens/ExtensionDictionaryToken.cs | 43 +++--- .../DynamicQuery/Tokens/ExtensionToken.cs | 47 ++++--- .../DynamicQuery/Tokens/HasValueToken.cs | 25 ++-- .../DynamicQuery/Tokens/NetPropertyToken.cs | 38 +++--- .../DynamicQuery/Tokens/QueryToken.cs | 39 +++--- .../DynamicQuery/Tokens/SystemTimeToken.cs | 19 +-- Signum.Entities/Entity.cs | 6 +- Signum.Entities/EnumEntity.cs | 8 +- Signum.Entities/Lite.cs | 52 ++++---- Signum.Entities/MList.cs | 12 +- Signum.Entities/MixinEntity.cs | 10 +- Signum.Entities/ModelEntity.cs | 6 +- Signum.Entities/ModifiableEntity.cs | 2 +- Signum.Entities/ObjectDumper.cs | 54 ++++---- Signum.Entities/Patterns/LockeableEntity.cs | 6 +- Signum.Entities/PropertyRoute.cs | 122 ++++++++--------- Signum.Entities/Reflection/GraphExplorer.cs | 16 +-- Signum.Entities/Reflection/ModifyInspector.cs | 10 +- Signum.Entities/Signum.Entities.csproj | 2 +- .../Extensions/DictionaryExtensions.cs | 24 ++-- .../Extensions/EnumerableExtensions.cs | 2 +- Signum.Utilities/Extensions/Extensions.cs | 4 +- .../Extensions/StringExtensions.cs | 8 +- 39 files changed, 563 insertions(+), 592 deletions(-) diff --git a/Signum.Engine/DynamicQuery/ExpressionContainer.cs b/Signum.Engine/DynamicQuery/ExpressionContainer.cs index c789382db5..cf5d378562 100644 --- a/Signum.Engine/DynamicQuery/ExpressionContainer.cs +++ b/Signum.Engine/DynamicQuery/ExpressionContainer.cs @@ -225,10 +225,9 @@ public IEnumerable GetAllTokens(QueryToken parent) unit: info.Unit, format: info.Format, implementations: info.Implementations, - propertyRoute: info.PropertyRoute) - { - Lambda = t => ValueSelector.Evaluate(CollectionSelector.Evaluate(t).SingleOrDefaultEx(kvp => KeySelector.Evaluate(kvp).Equals(key))), - }); + propertyRoute: info.PropertyRoute, + lambda: t => ValueSelector.Evaluate(CollectionSelector.Evaluate(t).SingleOrDefaultEx(kvp => KeySelector.Evaluate(kvp).Equals(key))) + )); } } @@ -295,7 +294,7 @@ protected internal virtual ExtensionToken CreateToken(QueryToken parent) result.Format = ColumnDescriptionFactory.GetFormat(cleanMeta.PropertyRoutes); result.Unit = ColumnDescriptionFactory.GetUnit(cleanMeta.PropertyRoutes); } - else if(me?.Meta is DirtyMeta dirtyMeta) + else if (me?.Meta is DirtyMeta dirtyMeta) { result.PropertyRoute = dirtyMeta.CleanMetas.Select(cm => cm.PropertyRoutes.Only()).Distinct().Only(); result.Implementations = dirtyMeta.CleanMetas.Select(cm => cm.Implementations).Distinct().Only(); @@ -323,10 +322,8 @@ protected internal virtual ExtensionToken CreateToken(QueryToken parent) return result; }); - return new ExtensionToken(parent, Key, Type, IsProjection, info.Unit, info.Format, info.Implementations, info.IsAllowed(), info.PropertyRoute) - { - DisplayName = NiceName() - }; + return new ExtensionToken(parent, Key, Type, IsProjection, info.Unit, info.Format, + info.Implementations, info.IsAllowed(), info.PropertyRoute, displayName: NiceName()); } } diff --git a/Signum.Entities/Basics/Operation.cs b/Signum.Entities/Basics/Operation.cs index d32074f1ec..4362253d19 100644 --- a/Signum.Entities/Basics/Operation.cs +++ b/Signum.Entities/Basics/Operation.cs @@ -1,4 +1,4 @@ -using System; +using System; using Signum.Utilities; using Signum.Utilities.ExpressionTrees; @@ -19,31 +19,31 @@ public static class Construct { public static ConstructSymbol.Simple Simple(Type declaringType, string fieldName) { - return new SimpleImp { Symbol = new OperationSymbol(declaringType, fieldName) }; + return new SimpleImp(new OperationSymbol(declaringType, fieldName)); } public static ConstructSymbol.From From(Type declaringType, string fieldName) where F : class, IEntity { - return new FromImp { Symbol = new OperationSymbol(declaringType, fieldName) }; + return new FromImp(new OperationSymbol(declaringType, fieldName)); } public static ConstructSymbol.FromMany FromMany(Type declaringType, string fieldName) where F : class, IEntity { - return new FromManyImp { Symbol = new OperationSymbol(declaringType, fieldName) }; + return new FromManyImp(new OperationSymbol(declaringType, fieldName)); } [Serializable] class SimpleImp : ConstructSymbol.Simple { - OperationSymbol symbol; - public OperationSymbol Symbol + public SimpleImp(OperationSymbol symbol) { - get { return symbol; } - internal set { this.symbol = value; } + this.Symbol = symbol; } + public OperationSymbol Symbol { get; internal set; } + public override string ToString() { return "{0}({1})".FormatWith(this.GetType().TypeName(), Symbol); @@ -54,13 +54,13 @@ public override string ToString() class FromImp : ConstructSymbol.From where F : class, IEntity { - OperationSymbol symbol; - public OperationSymbol Symbol + public FromImp(OperationSymbol symbol) { - get { return symbol; } - internal set { this.symbol = value; } + Symbol = symbol; } + public OperationSymbol Symbol { get; private set; } + public Type BaseType { get { return typeof(F); } @@ -76,13 +76,13 @@ public override string ToString() class FromManyImp : ConstructSymbol.FromMany where F : class, IEntity { - OperationSymbol symbol; - public OperationSymbol Symbol + public FromManyImp(OperationSymbol symbol) { - get { return symbol; } - internal set { this.symbol = value; } + Symbol = symbol; } + public OperationSymbol Symbol { get; set; } + public Type BaseType { get { return typeof(F); } @@ -98,26 +98,26 @@ public override string ToString() public static ExecuteSymbol Execute(Type declaringType, string fieldName) where T : class, IEntity { - return new ExecuteSymbolImp { Symbol = new OperationSymbol(declaringType, fieldName) }; + return new ExecuteSymbolImp(new OperationSymbol(declaringType, fieldName)); } public static DeleteSymbol Delete(Type declaringType, string fieldName) where T : class, IEntity { - return new DeleteSymbolImp { Symbol = new OperationSymbol(declaringType, fieldName) }; + return new DeleteSymbolImp(new OperationSymbol(declaringType, fieldName)); } [Serializable] class ExecuteSymbolImp : ExecuteSymbol where T : class, IEntity { - OperationSymbol symbol; - public OperationSymbol Symbol + public ExecuteSymbolImp(OperationSymbol symbol) { - get { return symbol; } - internal set { this.symbol = value; } + Symbol = symbol; } + public OperationSymbol Symbol { get; private set; } + public Type BaseType { get { return typeof(T); } @@ -133,13 +133,13 @@ public override string ToString() class DeleteSymbolImp : DeleteSymbol where T : class, IEntity { - OperationSymbol symbol; - public OperationSymbol Symbol + public DeleteSymbolImp(OperationSymbol symbol) { - get { return symbol; } - internal set { this.symbol = value; } + Symbol = symbol; } + public OperationSymbol Symbol { get; private set; } + public Type BaseType { get { return typeof(T); } diff --git a/Signum.Entities/DynamicQuery/Column.cs b/Signum.Entities/DynamicQuery/Column.cs index 649b209527..efede96a8b 100644 --- a/Signum.Entities/DynamicQuery/Column.cs +++ b/Signum.Entities/DynamicQuery/Column.cs @@ -32,8 +32,8 @@ public Column(ColumnDescription cd, object queryName) public string Name { get { return Token.FullKey(); } } public virtual Type Type { get { return Token.Type; } } public Implementations? Implementations { get { return Token.GetImplementations(); } } - public string Format { get { return Token.Format; } } - public string Unit { get { return Token.Unit; } } + public string? Format { get { return Token.Format; } } + public string? Unit { get { return Token.Unit; } } public override string ToString() { @@ -55,7 +55,7 @@ public override int GetHashCode() internal class _EntityColumn : Column { public _EntityColumn(ColumnDescription entityColumn, object queryName) - : base(new ColumnToken(entityColumn, queryName), null) + : base(new ColumnToken(entityColumn, queryName), null!) { if (!entityColumn.IsEntity) throw new ArgumentException("entityColumn"); diff --git a/Signum.Entities/DynamicQuery/Meta.cs b/Signum.Entities/DynamicQuery/Meta.cs index ad2c059460..0aee1f28f0 100644 --- a/Signum.Entities/DynamicQuery/Meta.cs +++ b/Signum.Entities/DynamicQuery/Meta.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using System.Collections.ObjectModel; using Signum.Utilities; @@ -10,7 +10,7 @@ public abstract class Meta { public readonly Implementations? Implementations; - public abstract string IsAllowed(); + public abstract string? IsAllowed(); protected Meta(Implementations? implementations) { @@ -29,7 +29,7 @@ public CleanMeta(Implementations? implementations, params PropertyRoute[] proper this.PropertyRoutes = propertyRoutes; } - public override string IsAllowed() + public override string? IsAllowed() { var result = PropertyRoutes.Select(a => a.IsAllowed()).NotNull(); if (result.IsEmpty()) @@ -58,7 +58,7 @@ public DirtyMeta(Implementations? implementations, Meta[] properties) .ToReadOnly(); } - public override string IsAllowed() + public override string? IsAllowed() { var result = CleanMetas.Select(a => a.IsAllowed()).NotNull(); if (result.IsEmpty()) diff --git a/Signum.Entities/DynamicQuery/QueryUtils.cs b/Signum.Entities/DynamicQuery/QueryUtils.cs index cfcfae54a9..735426ccdc 100644 --- a/Signum.Entities/DynamicQuery/QueryUtils.cs +++ b/Signum.Entities/DynamicQuery/QueryUtils.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Signum.Utilities; @@ -21,13 +21,8 @@ public static string GetKey(object queryName) return (queryName is Type ? Reflector.CleanTypeName((Type) queryName) : queryName.ToString()); } - + public static string GetNiceName(object queryName) - { - return GetNiceName(queryName, null); - } - - public static string GetNiceName(object queryName, CultureInfo ci) { if (queryName is Type) queryName = EnumEntity.Extract((Type)queryName) ?? (Type)queryName; @@ -209,7 +204,7 @@ public static List GetFilterOperations(FilterType filtertype) }; - public static QueryToken SubToken(QueryToken token, QueryDescription qd, SubTokensOptions options, string key) + public static QueryToken? SubToken(QueryToken? token, QueryDescription qd, SubTokensOptions options, string key) { var result = SubTokenBasic(token, qd, options, key); @@ -233,7 +228,7 @@ public static List SubTokens(this QueryToken token, QueryDescription } - private static IEnumerable AggregateTokens(QueryToken token, QueryDescription qd) + private static IEnumerable AggregateTokens(QueryToken? token, QueryDescription qd) { if (token == null) { @@ -286,7 +281,7 @@ private static IEnumerable AggregateTokens(QueryToken token, QueryDe } } - static QueryToken SubTokenBasic(QueryToken token, QueryDescription qd, SubTokensOptions options, string key) + static QueryToken? SubTokenBasic(QueryToken? token, QueryDescription qd, SubTokensOptions options, string key) { if (token == null) { @@ -347,7 +342,7 @@ public static QueryToken Parse(string tokenString, QueryDescription qd, SubToken string firstPart = parts.FirstEx(); - QueryToken result = SubToken(null, qd, options, firstPart); + QueryToken? result = SubToken(null, qd, options, firstPart); if (result == null) throw new FormatException("Column {0} not found on query {1}".FormatWith(firstPart, QueryUtils.GetKey(qd.QueryName))); @@ -361,7 +356,7 @@ public static QueryToken Parse(string tokenString, QueryDescription qd, SubToken return result; } - public static string CanFilter(QueryToken token) + public static string? CanFilter(QueryToken token) { if (token == null) return "No column selected"; @@ -372,7 +367,7 @@ public static string CanFilter(QueryToken token) return null; } - public static string CanColumn(QueryToken token) + public static string? CanColumn(QueryToken token) { if (token == null) return "No column selected"; @@ -402,7 +397,7 @@ public static LambdaExpression CreateOrderLambda(QueryToken token, BuildExpressi return Expression.Lambda(body, ctx.Parameter); } - public static string CanOrder(QueryToken token) + public static string? CanOrder(QueryToken token) { if (token == null) return "No column selected"; diff --git a/Signum.Entities/DynamicQuery/Tokens/AggregateToken.cs b/Signum.Entities/DynamicQuery/Tokens/AggregateToken.cs index 966883a0b2..b182de936d 100644 --- a/Signum.Entities/DynamicQuery/Tokens/AggregateToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/AggregateToken.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq.Expressions; using Signum.Utilities; @@ -9,33 +9,33 @@ namespace Signum.Entities.DynamicQuery public class AggregateToken : QueryToken { public AggregateFunction AggregateFunction { get; private set; } - public object Value { get; private set; } + public object? Value { get; private set; } public FilterOperation? FilterOperation { get; private set; } public bool Distinct { get; private set; } - object queryName; + object? queryName; public override object QueryName { get { return queryName ?? base.QueryName; } } + QueryToken? parent; + public override QueryToken? Parent => parent; + public AggregateToken(AggregateFunction function, object queryName) - : base(null) { if (function != AggregateFunction.Count) throw new ArgumentException("function should be Count for this overload"); - this.queryName = queryName ?? throw new ArgumentNullException(nameof(queryName)); + this.parent = null; + this.queryName = queryName ?? throw new ArgumentNullException("queryName"); this.AggregateFunction = function; } - public AggregateToken(AggregateFunction function, QueryToken parent, FilterOperation? filterOperation = null, object value = null, bool distinct = false) - : base(parent) + public AggregateToken(AggregateFunction function, QueryToken parent, FilterOperation? filterOperation = null, object? value = null, bool distinct = false) { - if (parent == null) - throw new ArgumentNullException(nameof(parent)); - + this.parent = parent ?? throw new ArgumentNullException("parent"); this.AggregateFunction = function; if (function == AggregateFunction.Count) @@ -60,7 +60,7 @@ public AggregateToken(AggregateFunction function, QueryToken parent, FilterOpera public override string ToString() { - string suffix = GetNiceOperation(); + string? suffix = GetNiceOperation(); return " ".CombineIfNotEmpty(AggregateFunction.NiceToString(), this.GeNiceDistinct(), this.GetNiceOperation(), this.GetNiceValue()); } @@ -73,48 +73,48 @@ public override string NiceName() return " ".CombineIfNotEmpty(AggregateFunction.NiceToString(), this.GeNiceDistinct(), this.GetNiceOperation(), this.GetNiceValue(), "of", Parent); } - string GetNiceOperation() + string? GetNiceOperation() { return this.FilterOperation == null || this.FilterOperation == DynamicQuery.FilterOperation.EqualTo ? null : this.FilterOperation == DynamicQuery.FilterOperation.DistinctTo ? QueryTokenMessage.Not.NiceToString() : - this.FilterOperation.NiceToString(); + this.FilterOperation.Value.NiceToString(); } - string GetNiceValue() + string? GetNiceValue() { return this.FilterOperation == null ? null : Value == null ? QueryTokenMessage.Null.NiceToString() : Value is Enum e ? e.NiceToString() : - Value.ToString(); + Value!.ToString(); } - string GeNiceDistinct() + string? GeNiceDistinct() { return this.Distinct ? QueryTokenMessage.Distinct.NiceToString() : null; } - public override string Format + public override string? Format { get { if (AggregateFunction == AggregateFunction.Count) return null; - if (AggregateFunction == AggregateFunction.Average && Parent.Format == "D") + if (AggregateFunction == AggregateFunction.Average && parent!.Format == "D") return "N2"; - return Parent.Format; + return this.parent!.Format; } } - public override string Unit + public override string? Unit { get { if (AggregateFunction == AggregateFunction.Count) return null; - return Parent.Unit; + return parent!.Unit; } } @@ -125,19 +125,21 @@ public override Type Type if (AggregateFunction == AggregateFunction.Count) return typeof(int); - var pu = Parent.Type.UnNullify(); + var pt = parent!.Type; + + var ptu = pt.UnNullify(); - if (AggregateFunction == AggregateFunction.Average && (pu != typeof(float) || pu != typeof(double) || pu == typeof(decimal))) - return Parent.Type.IsNullable() ? typeof(double?) : typeof(double); + if (AggregateFunction == AggregateFunction.Average && (ptu != typeof(float) || ptu != typeof(double) || ptu == typeof(decimal))) + return pt.IsNullable() ? typeof(double?) : typeof(double); - if (pu == typeof(bool) || - pu == typeof(byte) || pu == typeof(sbyte) || - pu == typeof(short) || pu == typeof(ushort) || - pu == typeof(uint) || - pu == typeof(ulong)) - return Parent.Type.IsNullable() ? typeof(int?) : typeof(int); + if (ptu == typeof(bool) || + ptu == typeof(byte) || ptu == typeof(sbyte) || + ptu == typeof(short) || ptu == typeof(ushort) || + ptu == typeof(uint) || + ptu == typeof(ulong)) + return pt.IsNullable() ? typeof(int?) : typeof(int); - return Parent.Type; + return pt; } } @@ -172,7 +174,7 @@ protected override Expression BuildExpressionInternal(BuildExpressionContext con throw new InvalidOperationException("AggregateToken should have a replacement at this stage"); } - public override PropertyRoute GetPropertyRoute() + public override PropertyRoute? GetPropertyRoute() { if (Parent == null) return null; @@ -185,7 +187,7 @@ public override PropertyRoute GetPropertyRoute() return null; } - public override string IsAllowed() + public override string? IsAllowed() { if (Parent == null) return null; @@ -196,7 +198,7 @@ public override string IsAllowed() public override QueryToken Clone() { if (Parent == null) - return new AggregateToken(AggregateFunction, this.queryName); + return new AggregateToken(AggregateFunction, this.queryName!); else return new AggregateToken(AggregateFunction, Parent.Clone(), this.FilterOperation, this.Value, this.Distinct); } diff --git a/Signum.Entities/DynamicQuery/Tokens/AsTypeToken.cs b/Signum.Entities/DynamicQuery/Tokens/AsTypeToken.cs index d5a4777f9e..62ac1ac70e 100644 --- a/Signum.Entities/DynamicQuery/Tokens/AsTypeToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/AsTypeToken.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Signum.Utilities; using System.Linq.Expressions; @@ -10,17 +10,14 @@ namespace Signum.Entities.DynamicQuery [Serializable] public class AsTypeToken : QueryToken { + QueryToken parent; + public override QueryToken? Parent => parent; + Type entityType; internal AsTypeToken(QueryToken parent, Type type) - : base(parent) { - if (parent == null) - throw new ArgumentNullException(nameof(parent)); - - if (type == null) - throw new ArgumentNullException(nameof(type)); - - this.entityType = type; + this.parent = parent ?? throw new ArgumentNullException(nameof(parent)); + this.entityType = type ?? throw new ArgumentNullException(nameof(type)); this.Priority = 8; } @@ -43,7 +40,7 @@ public override string Key protected override Expression BuildExpressionInternal(BuildExpressionContext context) { - Expression baseExpression = Parent.BuildExpression(context); + Expression baseExpression = parent.BuildExpression(context); Expression result = Expression.TypeAs(baseExpression.ExtractEntity(false), entityType); @@ -55,12 +52,12 @@ protected override List SubTokensOverride(SubTokensOptions options) return SubTokensBase(entityType, options, GetImplementations()); } - public override string Format + public override string? Format { get { return null; } } - public override string Unit + public override string? Unit { get { return null; } } @@ -70,18 +67,18 @@ public override string Unit return Implementations.By(entityType); } - public override string IsAllowed() + public override string? IsAllowed() { - var parent = Parent.IsAllowed(); - var routes = GetPropertyRoute().IsAllowed(); + var parent = parent.IsAllowed(); + var routes = GetPropertyRoute()!.IsAllowed(); if (parent.HasText() && routes.HasText()) - QueryTokenMessage.And.NiceToString().Combine(parent, routes); + QueryTokenMessage.And.NiceToString().CombineIfNotEmpty(parent, routes); return parent ?? routes; } - public override PropertyRoute GetPropertyRoute() + public override PropertyRoute? GetPropertyRoute() { return PropertyRoute.Root(entityType); } @@ -89,12 +86,12 @@ public override PropertyRoute GetPropertyRoute() public override string NiceName() { var cleanType = EnumEntity.Extract(entityType) ?? entityType; - return QueryTokenMessage._0As1.NiceToString().FormatWith(Parent.ToString(), cleanType.NiceName()); + return QueryTokenMessage._0As1.NiceToString().FormatWith(parent.ToString(), cleanType.NiceName()); } public override QueryToken Clone() { - return new AsTypeToken(Parent.Clone(), entityType); + return new AsTypeToken(parent.Clone(), entityType); } } diff --git a/Signum.Entities/DynamicQuery/Tokens/CollectionAnyAllToken.cs b/Signum.Entities/DynamicQuery/Tokens/CollectionAnyAllToken.cs index a67877e6dd..53eff2cfcc 100644 --- a/Signum.Entities/DynamicQuery/Tokens/CollectionAnyAllToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/CollectionAnyAllToken.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -14,20 +14,23 @@ public class CollectionAnyAllToken : QueryToken { public CollectionAnyAllType CollectionAnyAllType { get; private set; } + QueryToken parent; + public override QueryToken? Parent => parent; + Type elementType; internal CollectionAnyAllToken(QueryToken parent, CollectionAnyAllType type) - : base(parent) { elementType = parent.Type.ElementType(); if (elementType == null) throw new InvalidOperationException("not a collection"); + this.parent = parent ?? throw new ArgumentNullException(nameof(parent)); this.CollectionAnyAllType = type; } public override Type Type { - get { return elementType.BuildLiteNullifyUnwrapPrimaryKey(new[] { this.GetPropertyRoute() }); } + get { return elementType.BuildLiteNullifyUnwrapPrimaryKey(new[] { this.GetPropertyRoute()! }); } } public override string ToString() @@ -47,46 +50,44 @@ protected override List SubTokensOverride(SubTokensOptions options) public override Implementations? GetImplementations() { - return Parent.GetElementImplementations(); + return parent.GetElementImplementations(); } - public override string Format + public override string? Format { get { - if (Parent is ExtensionToken et && et.IsProjection) return et.ElementFormat; - return Parent.Format; + return parent.Format; } } - public override string Unit + public override string? Unit { get { - if (Parent is ExtensionToken et && et.IsProjection) return et.ElementUnit; - return Parent.Unit; + return parent.Unit; } } - public override string IsAllowed() + public override string? IsAllowed() { - return Parent.IsAllowed(); + return parent.IsAllowed(); } public override bool HasAllOrAny() => true; - public override PropertyRoute GetPropertyRoute() + public override PropertyRoute? GetPropertyRoute() { if (Parent is ExtensionToken et && et.IsProjection) return et.GetElementPropertyRoute(); - PropertyRoute parent = Parent.GetPropertyRoute(); + PropertyRoute parent = Parent!.GetPropertyRoute()!; if (parent != null && parent.Type.ElementType() != null) return parent.Add("Item"); @@ -95,12 +96,12 @@ public override PropertyRoute GetPropertyRoute() public override string NiceName() { - return null; + return null!; } public override QueryToken Clone() { - return new CollectionAnyAllToken(Parent.Clone(), this.CollectionAnyAllType); + return new CollectionAnyAllToken(parent.Clone(), this.CollectionAnyAllType); } protected override Expression BuildExpressionInternal(BuildExpressionContext context) diff --git a/Signum.Entities/DynamicQuery/Tokens/CollectionElementToken.cs b/Signum.Entities/DynamicQuery/Tokens/CollectionElementToken.cs index 423420c65d..3056feef7b 100644 --- a/Signum.Entities/DynamicQuery/Tokens/CollectionElementToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/CollectionElementToken.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -14,20 +14,24 @@ public class CollectionElementToken : QueryToken { public CollectionElementType CollectionElementType { get; private set; } + QueryToken parent; + public override QueryToken? Parent => parent; + + Type elementType; internal CollectionElementToken(QueryToken parent, CollectionElementType type) - : base(parent) { elementType = parent.Type.ElementType(); if (elementType == null) throw new InvalidOperationException("not a collection"); + this.parent = parent ?? throw new ArgumentNullException(nameof(parent)); this.CollectionElementType = type; } public override Type Type { - get { return elementType.BuildLiteNullifyUnwrapPrimaryKey(new[] { this.GetPropertyRoute() }); } + get { return elementType.BuildLiteNullifyUnwrapPrimaryKey(new[] { this.GetPropertyRoute()! }); } } public override string ToString() @@ -47,10 +51,10 @@ protected override List SubTokensOverride(SubTokensOptions options) public override Implementations? GetImplementations() { - return Parent.GetElementImplementations(); + return parent.GetElementImplementations(); } - public override string Format + public override string? Format { get { @@ -58,11 +62,11 @@ public override string Format if (Parent is ExtensionToken et && et.IsProjection) return et.ElementFormat; - return Parent.Format; + return parent.Format; } } - public override string Unit + public override string? Unit { get { @@ -70,13 +74,13 @@ public override string Unit if (Parent is ExtensionToken et && et.IsProjection) return et.ElementUnit; - return Parent.Unit; + return parent.Unit; } } - public override string IsAllowed() + public override string? IsAllowed() { - return Parent.IsAllowed(); + return parent.IsAllowed(); } public override bool HasAllOrAny() @@ -95,16 +99,16 @@ public override bool HasElement() CollectionElementType == CollectionElementType.Element3; } - public override PropertyRoute GetPropertyRoute() + public override PropertyRoute? GetPropertyRoute() { - if (Parent is ExtensionToken et && et.IsProjection) + if (parent is ExtensionToken et && et.IsProjection) return et.GetElementPropertyRoute(); - PropertyRoute parent = Parent.GetPropertyRoute(); - if (parent != null && parent.Type.ElementType() != null) - return parent.Add("Item"); + PropertyRoute? pr = this.parent.GetPropertyRoute(); + if (pr != null && pr.Type.ElementType() != null) + return pr.Add("Item"); - return parent; + return pr; } public override string NiceName() @@ -114,12 +118,12 @@ public override string NiceName() if (parentElement.IsModifiableEntity()) return parentElement.NiceName(); - return "Element of " + Parent.NiceName(); + return "Element of " + Parent?.NiceName(); } public override QueryToken Clone() { - return new CollectionElementToken(Parent.Clone(), CollectionElementType); + return new CollectionElementToken(parent.Clone(), CollectionElementType); } protected override Expression BuildExpressionInternal(BuildExpressionContext context) @@ -148,12 +152,12 @@ public static List GetElements(HashSet allTo .ToList(); } - public static string MultipliedMessage(List elements, Type entityType) + public static string? MultipliedMessage(List elements, Type entityType) { if (elements.IsEmpty()) return null; - return ValidationMessage.TheNumberOf0IsBeingMultipliedBy1.NiceToString().FormatWith(entityType.NiceName(), elements.CommaAnd(a => a.Parent.ToString())); + return ValidationMessage.TheNumberOf0IsBeingMultipliedBy1.NiceToString().FormatWith(entityType.NiceName(), elements.CommaAnd(a => a.parent.ToString())); } public override string TypeColor diff --git a/Signum.Entities/DynamicQuery/Tokens/ColumnToken.cs b/Signum.Entities/DynamicQuery/Tokens/ColumnToken.cs index 7285c38b3b..e4b214e763 100644 --- a/Signum.Entities/DynamicQuery/Tokens/ColumnToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/ColumnToken.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Signum.Utilities; @@ -19,17 +19,12 @@ public override object QueryName get { return queryName; } } + public override QueryToken? Parent => null; + public ColumnToken(ColumnDescription column, object queryName) - : base(null) { - if (column == null) - throw new ArgumentNullException(nameof(column)); - - if (queryName == null) - throw new ArgumentNullException(nameof(queryName)); - - this.column = column; - this.queryName = queryName; + this.column = column ?? throw new ArgumentNullException(nameof(column)); + this.queryName = queryName ?? throw new ArgumentNullException(nameof(queryName)); } public override string Key @@ -47,12 +42,12 @@ public override Type Type get { return Column.Type; } } - public override string Format + public override string? Format { get { return Column.Format; } } - public override string Unit + public override string? Unit { get { return Column.Unit; } } @@ -69,10 +64,11 @@ protected override List SubTokensOverride(SubTokensOptions options) if (Column.PropertyRoutes != null) { DateTimePrecision? precision = - Column.PropertyRoutes.Select(pr => - Validator.TryGetPropertyValidator(pr.Parent.Type, pr.PropertyInfo.Name)?.Validators - .OfType().SingleOrDefaultEx()) - .Select(dtp => dtp?.Precision).Distinct().Only(); + Column.PropertyRoutes + .Select(pr => Validator.TryGetPropertyValidator(pr.Parent!.Type, pr.PropertyInfo!.Name)?.Validators.OfType().SingleOrDefaultEx()) + .Select(dtp => dtp?.Precision) + .Distinct() + .Only(); if (precision != null) return DateTimeProperties(this, precision.Value).AndHasValue(this); @@ -89,10 +85,11 @@ protected override List SubTokensOverride(SubTokensOptions options) if (Column.PropertyRoutes != null) { int? decimalPlaces= - Column.PropertyRoutes.Select(pr => - Validator.TryGetPropertyValidator(pr.Parent.Type, pr.PropertyInfo.Name)?.Validators - .OfType().SingleOrDefaultEx()) - .Select(dtp => dtp?.DecimalPlaces).Distinct().Only(); + Column.PropertyRoutes + .Select(pr => Validator.TryGetPropertyValidator(pr.Parent!.Type, pr.PropertyInfo!.Name)?.Validators.OfType().SingleOrDefaultEx()) + .Select(dtp => dtp?.DecimalPlaces) + .Distinct() + .Only(); if (decimalPlaces != null) return StepTokens(this, decimalPlaces.Value).AndHasValue(this); @@ -110,12 +107,12 @@ protected override List SubTokensOverride(SubTokensOptions options) return Column.Implementations; } - public override string IsAllowed() + public override string? IsAllowed() { return null; //If it wasn't, sould be filtered before } - public override PropertyRoute GetPropertyRoute() + public override PropertyRoute? GetPropertyRoute() { if (Column.PropertyRoutes != null) return Column.PropertyRoutes[0]; //HACK: compatibility with IU entitiy elements diff --git a/Signum.Entities/DynamicQuery/Tokens/CountToken.cs b/Signum.Entities/DynamicQuery/Tokens/CountToken.cs index adc12b3f29..afb50db12f 100644 --- a/Signum.Entities/DynamicQuery/Tokens/CountToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/CountToken.cs @@ -12,12 +12,12 @@ namespace Signum.Entities.DynamicQuery [Serializable] public class CountToken : QueryToken { + QueryToken parent; + public override QueryToken? Parent => parent; + internal CountToken(QueryToken parent) - : base(parent) { - if (parent == null) - throw new ArgumentNullException(nameof(parent)); - + this.parent = parent ?? throw new ArgumentNullException(nameof(parent)); } public override Type Type @@ -39,7 +39,7 @@ public override string Key protected override Expression BuildExpressionInternal(BuildExpressionContext context) { - var parentResult = Parent.BuildExpression(context); + var parentResult = parent.BuildExpression(context); var result = Expression.Call(miCount.MakeGenericMethod(parentResult.Type.ElementType()), parentResult); @@ -51,12 +51,12 @@ protected override List SubTokensOverride(SubTokensOptions options) return new List(); } - public override string Format + public override string? Format { get { return null; } } - public override string Unit + public override string? Unit { get { return null; } } @@ -66,24 +66,24 @@ public override string Unit return null; } - public override string IsAllowed() + public override string? IsAllowed() { - return Parent.IsAllowed(); + return parent.IsAllowed(); } - public override PropertyRoute GetPropertyRoute() + public override PropertyRoute? GetPropertyRoute() { return null; } public override string NiceName() { - return ToString() + QueryTokenMessage.Of.NiceToString() + Parent.ToString(); + return ToString() + QueryTokenMessage.Of.NiceToString() + parent.ToString(); } public override QueryToken Clone() { - return new CountToken(Parent.Clone()); + return new CountToken(parent.Clone()); } public override string TypeColor diff --git a/Signum.Entities/DynamicQuery/Tokens/DateTimeSpecialTokens.cs b/Signum.Entities/DynamicQuery/Tokens/DateTimeSpecialTokens.cs index 9052b4da7a..ef81c16b5f 100644 --- a/Signum.Entities/DynamicQuery/Tokens/DateTimeSpecialTokens.cs +++ b/Signum.Entities/DynamicQuery/Tokens/DateTimeSpecialTokens.cs @@ -12,11 +12,13 @@ namespace Signum.Entities.DynamicQuery public class DatePartStartToken : QueryToken { public QueryTokenMessage Name { get; private set; } - + QueryToken parent; + public override QueryToken? Parent => parent; + internal DatePartStartToken(QueryToken parent, QueryTokenMessage name) - : base(parent) { this.Name = name; + this.parent = parent ?? throw new ArgumentNullException(nameof(parent)); } private static MethodInfo GetMethodInfo(QueryTokenMessage name) @@ -38,10 +40,10 @@ public override string ToString() public override string NiceName() { - return this.Name.NiceToString() + QueryTokenMessage.Of.NiceToString() + Parent.ToString(); + return this.Name.NiceToString() + QueryTokenMessage.Of.NiceToString() + parent.ToString(); } - public override string Format + public override string? Format { get { @@ -56,7 +58,7 @@ public override string Format } } - public override string Unit + public override string? Unit { get { return null; } } @@ -85,14 +87,14 @@ protected override List SubTokensOverride(SubTokensOptions options) protected override Expression BuildExpressionInternal(BuildExpressionContext context) { - var exp = Parent.BuildExpression(context); + var exp = parent.BuildExpression(context); var mi = GetMethodInfo(this.Name); return Expression.Call(mi, exp.UnNullify()).Nullify(); } - public override PropertyRoute GetPropertyRoute() + public override PropertyRoute? GetPropertyRoute() { - return Parent.GetPropertyRoute(); + return parent.GetPropertyRoute(); } public override Implementations? GetImplementations() @@ -100,14 +102,14 @@ public override PropertyRoute GetPropertyRoute() return null; } - public override string IsAllowed() + public override string? IsAllowed() { - return Parent.IsAllowed(); + return parent.IsAllowed(); } public override QueryToken Clone() { - return new DatePartStartToken(Parent.Clone(), this.Name); + return new DatePartStartToken(parent.Clone(), this.Name); } public override bool IsGroupable diff --git a/Signum.Entities/DynamicQuery/Tokens/DateToken.cs b/Signum.Entities/DynamicQuery/Tokens/DateToken.cs index af40823faf..f1e3915ce3 100644 --- a/Signum.Entities/DynamicQuery/Tokens/DateToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/DateToken.cs @@ -11,9 +11,12 @@ namespace Signum.Entities.DynamicQuery [Serializable] public class DateToken : QueryToken { + QueryToken parent; + public override QueryToken? Parent => parent; + internal DateToken(QueryToken parent) - : base(parent) { + this.parent = parent ?? throw new ArgumentNullException(nameof(parent)); } public override string ToString() @@ -23,15 +26,15 @@ public override string ToString() public override string NiceName() { - return QueryTokenMessage.Date.NiceToString() + QueryTokenMessage.Of.NiceToString() + Parent.ToString(); + return QueryTokenMessage.Date.NiceToString() + QueryTokenMessage.Of.NiceToString() + parent.ToString(); } - public override string Format + public override string? Format { get { return "d"; } } - public override string Unit + public override string? Unit { get { return null; } } @@ -55,14 +58,14 @@ protected override List SubTokensOverride(SubTokensOptions options) protected override Expression BuildExpressionInternal(BuildExpressionContext context) { - var exp = Parent.BuildExpression(context); + var exp = parent.BuildExpression(context); return Expression.Property(exp.UnNullify(), miDate).Nullify(); } - public override PropertyRoute GetPropertyRoute() + public override PropertyRoute? GetPropertyRoute() { - return Parent.GetPropertyRoute(); + return parent.GetPropertyRoute(); } public override Implementations? GetImplementations() @@ -70,14 +73,14 @@ public override PropertyRoute GetPropertyRoute() return null; } - public override string IsAllowed() + public override string? IsAllowed() { - return Parent.IsAllowed(); + return parent.IsAllowed(); } public override QueryToken Clone() { - return new DateToken(Parent.Clone()); + return new DateToken(parent.Clone()); } public override bool IsGroupable diff --git a/Signum.Entities/DynamicQuery/Tokens/DecimalSpecialTokens.cs b/Signum.Entities/DynamicQuery/Tokens/DecimalSpecialTokens.cs index 8a9d00a8f0..931f74c097 100644 --- a/Signum.Entities/DynamicQuery/Tokens/DecimalSpecialTokens.cs +++ b/Signum.Entities/DynamicQuery/Tokens/DecimalSpecialTokens.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Reflection; using System.Linq.Expressions; @@ -13,9 +13,12 @@ public class StepToken : QueryToken { public decimal StepSize; + QueryToken parent; + public override QueryToken? Parent => parent; + internal StepToken(QueryToken parent, decimal stepSize) - : base(parent) { + this.parent = parent ?? throw new ArgumentNullException(nameof(parent)); this.StepSize = stepSize; this.Priority = 1; } @@ -27,17 +30,17 @@ public override string ToString() public override string NiceName() { - return QueryTokenMessage._0Steps1.NiceToString(Parent.NiceName(), StepSize); + return QueryTokenMessage._0Steps1.NiceToString(parent.NiceName(), StepSize); } - public override string Format + public override string? Format { - get { return Parent.Format; } + get { return parent.Format; } } public override Type Type { - get { return Parent.Type.Nullify(); } + get { return parent.Type.Nullify(); } } public override string Key @@ -64,34 +67,34 @@ protected override List SubTokensOverride(SubTokensOptions options) protected override Expression BuildExpressionInternal(BuildExpressionContext context) { - var exp = Parent.BuildExpression(context); + var exp = parent.BuildExpression(context); return RoundingExpressionGenerator.RoundExpression(exp, this.StepSize, RoundingType.Ceil); } - public override string Unit + public override string? Unit { - get { return this.Parent.Unit; } + get { return this.parent.Unit; } } - public override PropertyRoute GetPropertyRoute() + public override PropertyRoute? GetPropertyRoute() { - return this.Parent.GetPropertyRoute(); + return this.parent.GetPropertyRoute(); } public override Implementations? GetImplementations() { - return this.Parent.GetImplementations(); + return this.parent.GetImplementations(); } - public override string IsAllowed() + public override string? IsAllowed() { - return this.Parent.IsAllowed(); + return this.parent.IsAllowed(); } public override QueryToken Clone() { - return new StepToken(this.Parent.Clone(), this.StepSize); + return new StepToken(this.parent.Clone(), this.StepSize); } public override bool IsGroupable @@ -103,9 +106,12 @@ public override bool IsGroupable public class StepMultiplierToken : QueryToken { public decimal Multiplier; + internal StepToken parent; + public override QueryToken? Parent => parent; - public StepMultiplierToken(StepToken parent, decimal multiplier) : base(parent) + public StepMultiplierToken(StepToken parent, decimal multiplier) { + this.parent = parent ?? throw new ArgumentNullException(nameof(parent)); this.Multiplier = multiplier; } @@ -117,22 +123,22 @@ public override string ToString() public override string NiceName() { - return QueryTokenMessage._0Steps1.NiceToString(Parent.Parent.NiceName(), StepSize()); + return QueryTokenMessage._0Steps1.NiceToString(parent.NiceName(), StepSize()); } internal decimal StepSize() { - return ((StepToken)this.Parent).StepSize * Multiplier; + return parent.StepSize * Multiplier; } - public override string Format + public override string? Format { - get { return Parent.Format; } + get { return parent.Format; } } public override Type Type { - get { return Parent.Type.Nullify(); } + get { return parent.Type.Nullify(); } } public override string Key @@ -142,7 +148,7 @@ public override string Key protected override Expression BuildExpressionInternal(BuildExpressionContext context) { - var exp = Parent.Parent.BuildExpression(context); + var exp = parent.Parent.BuildExpression(context); return RoundingExpressionGenerator.RoundExpression(exp, this.StepSize(), RoundingType.Ceil); } @@ -160,27 +166,27 @@ protected override List SubTokensOverride(SubTokensOptions options) public override QueryToken Clone() { - return new StepMultiplierToken((StepToken)this.Parent.Clone(), this.Multiplier); + return new StepMultiplierToken((StepToken)this.parent.Clone(), this.Multiplier); } - public override string Unit + public override string? Unit { get { return null; } } - public override PropertyRoute GetPropertyRoute() + public override PropertyRoute? GetPropertyRoute() { - return this.Parent.GetPropertyRoute(); + return this.parent.GetPropertyRoute(); } public override Implementations? GetImplementations() { - return this.Parent.GetImplementations(); + return this.parent.GetImplementations(); } - public override string IsAllowed() + public override string? IsAllowed() { - return this.Parent.IsAllowed(); + return this.parent.IsAllowed(); } public override bool IsGroupable @@ -192,10 +198,11 @@ public override bool IsGroupable public class StepRoundingToken : QueryToken { public RoundingType Rounding; - + StepMultiplierToken parent; + public override QueryToken? Parent => parent; public StepRoundingToken(StepMultiplierToken parent, RoundingType rounding) - : base(parent) { + this.parent = parent ?? throw new ArgumentNullException(nameof(parent)); this.Rounding = rounding; } @@ -206,7 +213,7 @@ public override string ToString() public override string NiceName() { - var num = ((StepMultiplierToken)this.Parent).StepSize(); + var num = parent.StepSize(); string str = Rounding == RoundingType.Ceil ? "⌈{0}⌉" : Rounding == RoundingType.Floor ? "⌊{0}⌋" : @@ -214,17 +221,17 @@ public override string NiceName() Rounding == RoundingType.RoundMiddle ? "|{0}|" : throw new InvalidOperationException(); - return QueryTokenMessage._0Steps1.NiceToString(Parent.Parent.Parent.NiceName(), str.FormatWith(num)); + return QueryTokenMessage._0Steps1.NiceToString(parent.parent.NiceName(), str.FormatWith(num)); } - public override string Format + public override string? Format { - get { return Parent.Format; } + get { return parent.Format; } } public override Type Type { - get { return Parent.Type.Nullify(); } + get { return parent.Type.Nullify(); } } public override string Key @@ -239,34 +246,34 @@ protected override List SubTokensOverride(SubTokensOptions options) protected override Expression BuildExpressionInternal(BuildExpressionContext context) { - var exp = Parent.Parent.Parent.BuildExpression(context); + var exp = Parent!.Parent!.Parent!.BuildExpression(context); - return RoundingExpressionGenerator.RoundExpression(exp, ((StepMultiplierToken)this.Parent).StepSize(), this.Rounding); + return RoundingExpressionGenerator.RoundExpression(exp, ((StepMultiplierToken)this.Parent!).StepSize(), this.Rounding); } - public override string Unit + public override string? Unit { get { return null; } } - public override PropertyRoute GetPropertyRoute() + public override PropertyRoute? GetPropertyRoute() { - return this.Parent.GetPropertyRoute(); + return this.parent.GetPropertyRoute(); } public override Implementations? GetImplementations() { - return this.Parent.GetImplementations(); + return this.parent.GetImplementations(); } - public override string IsAllowed() + public override string? IsAllowed() { - return this.Parent.IsAllowed(); + return this.parent.IsAllowed(); } public override QueryToken Clone() { - return new StepRoundingToken((StepMultiplierToken)this.Parent.Clone(), this.Rounding); + return new StepRoundingToken((StepMultiplierToken)this.parent.Clone(), this.Rounding); } public override bool IsGroupable @@ -342,9 +349,11 @@ public class ModuloToken : QueryToken { public int Divisor; + QueryToken parent; + public override QueryToken? Parent => parent; internal ModuloToken(QueryToken parent, int divisor) - : base(parent) { + this.parent = parent ?? throw new ArgumentNullException(nameof(parent)); this.Divisor = divisor; } @@ -355,10 +364,10 @@ public override string ToString() public override string NiceName() { - return QueryTokenMessage._0Mod1.NiceToString(Parent.NiceName(), Divisor); + return QueryTokenMessage._0Mod1.NiceToString(parent.NiceName(), Divisor); } - public override string Format + public override string? Format { get { return null; } } @@ -382,33 +391,33 @@ protected override List SubTokensOverride(SubTokensOptions options) protected override Expression BuildExpressionInternal(BuildExpressionContext context) { - var exp = Parent.BuildExpression(context); + var exp = parent.BuildExpression(context); return Expression.Modulo(Expression.Convert(exp, typeof(int)), Expression.Constant(Divisor)).Nullify(); } - public override string Unit + public override string? Unit { - get { return this.Parent.Unit; } + get { return this.parent.Unit; } } - public override PropertyRoute GetPropertyRoute() + public override PropertyRoute? GetPropertyRoute() { - return this.Parent.GetPropertyRoute(); + return this.parent.GetPropertyRoute(); } public override Implementations? GetImplementations() { - return this.Parent.GetImplementations(); + return this.parent.GetImplementations(); } - public override string IsAllowed() + public override string? IsAllowed() { - return this.Parent.IsAllowed(); + return this.parent.IsAllowed(); } public override QueryToken Clone() { - return new ModuloToken(this.Parent.Clone(), this.Divisor); + return new ModuloToken(this.parent.Clone(), this.Divisor); } public override bool IsGroupable diff --git a/Signum.Entities/DynamicQuery/Tokens/EntityPropertyToken.cs b/Signum.Entities/DynamicQuery/Tokens/EntityPropertyToken.cs index c279ca69e6..fc2b3dd158 100644 --- a/Signum.Entities/DynamicQuery/Tokens/EntityPropertyToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/EntityPropertyToken.cs @@ -23,19 +23,19 @@ public static QueryToken IdProperty(QueryToken parent) return new EntityPropertyToken(parent, piId, PropertyRoute.Root(parent.Type.CleanType()).Add(piId)) { Priority = 10 }; } - internal EntityPropertyToken(QueryToken parent, PropertyInfo pi, PropertyRoute pr) - : base(parent) + QueryToken parent; + public override QueryToken? Parent => parent; + + internal EntityPropertyToken(QueryToken parent, PropertyInfo pi, PropertyRoute pr) { - if (pi == null) - throw new ArgumentNullException(nameof(pi)); - - this.PropertyInfo = pi; + this.parent = parent ?? throw new ArgumentNullException(nameof(parent)); + this.PropertyInfo = pi ?? throw new ArgumentNullException(nameof(pi)); this.PropertyRoute = pr; } public override Type Type { - get { return PropertyInfo.PropertyType.BuildLiteNullifyUnwrapPrimaryKey(new[] { this.GetPropertyRoute() }); } + get { return PropertyInfo.PropertyType.BuildLiteNullifyUnwrapPrimaryKey(new[] { this.GetPropertyRoute()! }); } } public override string ToString() @@ -50,7 +50,7 @@ public override string Key protected override Expression BuildExpressionInternal(BuildExpressionContext context) { - var baseExpression = Parent.BuildExpression(context); + var baseExpression = parent.BuildExpression(context); if (PropertyInfo.Name == nameof(Entity.Id) || PropertyInfo.Name == nameof(Entity.ToStringProperty)) @@ -78,12 +78,11 @@ protected override List SubTokensOverride(SubTokensOptions options) if (type.UnNullify() == typeof(DateTime)) { - PropertyRoute route = this.GetPropertyRoute(); + PropertyRoute? route = this.GetPropertyRoute(); if (route != null) { - var att = Validator.TryGetPropertyValidator(route.Parent.Type, route.PropertyInfo.Name)?.Validators - .OfType().SingleOrDefaultEx(); + var att = Validator.TryGetPropertyValidator(route.Parent!.Type, route.PropertyInfo!.Name)?.Validators.OfType().SingleOrDefaultEx(); if (att != null) { return DateTimeProperties(this, att.Precision).AndHasValue(this); @@ -95,11 +94,11 @@ protected override List SubTokensOverride(SubTokensOptions options) type.UnNullify() == typeof(float) || type.UnNullify() == typeof(decimal)) { - PropertyRoute route = this.GetPropertyRoute(); + PropertyRoute? route = this.GetPropertyRoute(); if (route != null) { - var att = Validator.TryGetPropertyValidator(route.Parent.Type, route.PropertyInfo.Name)?.Validators + var att = Validator.TryGetPropertyValidator(route.Parent!.Type, route.PropertyInfo!.Name)?.Validators .OfType().SingleOrDefaultEx(); if (att != null) { @@ -117,34 +116,32 @@ protected override List SubTokensOverride(SubTokensOptions options) public override Implementations? GetImplementations() { - return GetPropertyRoute().TryGetImplementations(); + return GetPropertyRoute()!.TryGetImplementations(); } - public override string Format + public override string? Format { - get { return Reflector.FormatString(this.GetPropertyRoute()); } + get { return Reflector.FormatString(this.GetPropertyRoute()!); } } - public override string Unit + public override string? Unit { get { return PropertyInfo.GetCustomAttribute()?.UnitName; } } - public override string IsAllowed() + public override string? IsAllowed() { - PropertyRoute pr = GetPropertyRoute(); - - string parent = Parent.IsAllowed(); + string? parent = this.parent.IsAllowed(); - string route = pr?.IsAllowed(); + string? route = GetPropertyRoute()?.IsAllowed(); if (parent.HasText() && route.HasText()) - return QueryTokenMessage.And.NiceToString().Combine(parent, route); + return QueryTokenMessage.And.NiceToString().Combine(parent!, route!); return parent ?? route; } - public override PropertyRoute GetPropertyRoute() + public override PropertyRoute? GetPropertyRoute() { return PropertyRoute; } @@ -156,7 +153,7 @@ public override string NiceName() public override QueryToken Clone() { - return new EntityPropertyToken(Parent.Clone(), PropertyInfo, PropertyRoute); + return new EntityPropertyToken(parent.Clone(), PropertyInfo, PropertyRoute); } } } diff --git a/Signum.Entities/DynamicQuery/Tokens/EntityToStringToken.cs b/Signum.Entities/DynamicQuery/Tokens/EntityToStringToken.cs index 2e4f8714d7..b61ec97a34 100644 --- a/Signum.Entities/DynamicQuery/Tokens/EntityToStringToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/EntityToStringToken.cs @@ -10,11 +10,13 @@ namespace Signum.Entities.DynamicQuery [Serializable] public class EntityToStringToken : QueryToken { + QueryToken parent; + public override QueryToken? Parent => parent; + internal EntityToStringToken(QueryToken parent) - : base(parent) { Priority = 9; - + this.parent = parent; } public override Type Type @@ -37,7 +39,7 @@ public override string Key protected override Expression BuildExpressionInternal(BuildExpressionContext context) { - var baseExpression = Parent.BuildExpression(context); + var baseExpression = parent.BuildExpression(context); return Expression.Call(baseExpression, miToString); } @@ -52,35 +54,33 @@ protected override List SubTokensOverride(SubTokensOptions options) return null; } - public override string Format + public override string? Format { get { return null; } } - public override string Unit + public override string? Unit { get { return null; } } - public override string IsAllowed() + public override string? IsAllowed() { - PropertyRoute route = GetPropertyRoute(); - - return Parent.IsAllowed(); + return parent.IsAllowed(); } - public override PropertyRoute GetPropertyRoute() + public override PropertyRoute? GetPropertyRoute() { - PropertyRoute parent = Parent.GetPropertyRoute(); - if (parent == null) + PropertyRoute? pr = parent.GetPropertyRoute(); + if (pr == null) { - Type type = Lite.Extract(Parent.Type); //Because Parent.Type is always a lite + Type? type = Lite.Extract(pr.Type); //Because Parent.Type is always a lite if (type != null) return PropertyRoute.Root(type).Add(miToStringProperty); } else { - Type type = Lite.Extract(parent.Type); //Because Add doesn't work with lites + Type? type = Lite.Extract(pr.Type); //Because Add doesn't work with lites if (type != null) return PropertyRoute.Root(type).Add(miToStringProperty); } @@ -90,12 +90,12 @@ public override PropertyRoute GetPropertyRoute() public override string NiceName() { - return LiteMessage.ToStr.NiceToString() + QueryTokenMessage.Of.NiceToString() + Parent.ToString(); + return LiteMessage.ToStr.NiceToString() + QueryTokenMessage.Of.NiceToString() + parent.ToString(); } public override QueryToken Clone() { - return new EntityToStringToken(Parent.Clone()); + return new EntityToStringToken(parent.Clone()); } } } diff --git a/Signum.Entities/DynamicQuery/Tokens/ExtensionDictionaryToken.cs b/Signum.Entities/DynamicQuery/Tokens/ExtensionDictionaryToken.cs index 115b0f0640..ac0dc0d7a0 100644 --- a/Signum.Entities/DynamicQuery/Tokens/ExtensionDictionaryToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/ExtensionDictionaryToken.cs @@ -8,12 +8,16 @@ namespace Signum.Entities.DynamicQuery { [Serializable] public class ExtensionDictionaryToken : QueryToken + where K : Object { + QueryToken parent; + public override QueryToken? Parent => parent; + public ExtensionDictionaryToken(QueryToken parent, K key, string unit, string format, Implementations? implementations, - PropertyRoute propertyRoute) - : base(parent) + PropertyRoute propertyRoute, + Expression> lambda) { this.keyValue= key; this.unit = unit; @@ -21,10 +25,10 @@ public ExtensionDictionaryToken(QueryToken parent, K key, this.implementations = implementations; this.propertyRoute = propertyRoute; this.Priority = -10; + this.Lambda = lambda; + this.parent = parent; } - - public string DisplayName { get; set; } - + public override string ToString() { return "[" + (((object)keyValue) is Enum e ? e.NiceToString() : keyValue.ToString()) + "]"; @@ -35,16 +39,16 @@ public override string NiceName() return ((object)keyValue) is Enum e ? e.NiceToString() : keyValue.ToString(); } - public override Type Type { get { return typeof(V).BuildLiteNullifyUnwrapPrimaryKey(new[] { this.GetPropertyRoute() }); } } + public override Type Type { get { return typeof(V).BuildLiteNullifyUnwrapPrimaryKey(new[] { this.GetPropertyRoute()! }); } } K keyValue; public override string Key => "[" + keyValue.ToString() + "]"; string format; - public override string Format => format; + public override string? Format => format; string unit; - public override string Unit => unit; + public override string? Unit => unit; protected override List SubTokensOverride(SubTokensOptions options) { @@ -55,7 +59,7 @@ protected override List SubTokensOverride(SubTokensOptions options) protected override Expression BuildExpressionInternal(BuildExpressionContext context) { - var parentExpression = Parent.BuildExpression(context).ExtractEntity(false).UnNullify(); + var parentExpression = parent.BuildExpression(context).ExtractEntity(false).UnNullify(); var result = Expression.Invoke(Lambda, parentExpression); @@ -63,31 +67,26 @@ protected override Expression BuildExpressionInternal(BuildExpressionContext con } public PropertyRoute propertyRoute; - public override PropertyRoute GetPropertyRoute() => this.propertyRoute; + public override PropertyRoute? GetPropertyRoute() => this.propertyRoute; public Implementations? implementations; public override Implementations? GetImplementations() => this.implementations; - public override string IsAllowed() + public override string? IsAllowed() { - PropertyRoute pr = GetPropertyRoute(); - - string parent = Parent.IsAllowed(); + string? parentAllowed = this.parent.IsAllowed(); - string route = pr?.IsAllowed(); + string? routeAlllowed = GetPropertyRoute()?.IsAllowed(); - if (parent.HasText() && route.HasText()) - return QueryTokenMessage.And.NiceToString().Combine(parent, route); + if (parentAllowed.HasText() && routeAlllowed.HasText()) + return QueryTokenMessage.And.NiceToString().Combine(parentAllowed!, routeAlllowed!); - return parent ?? route; + return parentAllowed ?? routeAlllowed; } public override QueryToken Clone() { - return new ExtensionDictionaryToken(this.Parent.Clone(), keyValue, unit, format, implementations, propertyRoute) - { - Lambda = Lambda - }; + return new ExtensionDictionaryToken(this.parent.Clone(), keyValue, unit, format, implementations, propertyRoute, Lambda); } } } diff --git a/Signum.Entities/DynamicQuery/Tokens/ExtensionToken.cs b/Signum.Entities/DynamicQuery/Tokens/ExtensionToken.cs index ed0724c622..f0f44998c6 100644 --- a/Signum.Entities/DynamicQuery/Tokens/ExtensionToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/ExtensionToken.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq.Expressions; using Signum.Utilities; @@ -9,12 +9,16 @@ namespace Signum.Entities.DynamicQuery [Serializable] public class ExtensionToken : QueryToken { + QueryToken parent; + public override QueryToken? Parent => parent; + + public ExtensionToken(QueryToken parent, string key, Type type, bool isProjection, - string unit, string format, - Implementations? implementations, - string isAllowed, PropertyRoute propertyRoute) - : base(parent) + string? unit, string? format, Implementations? implementations, + string? isAllowed, PropertyRoute propertyRoute, string displayName) { + this.parent = parent ?? throw new ArgumentNullException(nameof(parent)); + var shouldHaveImplementations = typeof(IEntity).IsAssignableFrom((isProjection ? type.ElementType() : type).CleanType()); if (shouldHaveImplementations && implementations == null) @@ -29,6 +33,7 @@ public ExtensionToken(QueryToken parent, string key, Type type, bool isProjectio this.implementations = implementations; this.isAllowed = isAllowed; this.propertyRoute = propertyRoute; + this.DisplayName = displayName; } public string DisplayName { get; set; } @@ -44,7 +49,7 @@ public override string NiceName() } Type type; - public override Type Type { get { return type.BuildLiteNullifyUnwrapPrimaryKey(new[] { this.GetPropertyRoute() }); } } + public override Type Type { get { return type.BuildLiteNullifyUnwrapPrimaryKey(new[] { this.GetPropertyRoute()! }); } } string key; public override string Key { get { return key; } } @@ -52,13 +57,13 @@ public override string NiceName() bool isProjection; public bool IsProjection { get { return isProjection; } } - string format; - public override string Format { get { return isProjection ? null : format; } } - public string ElementFormat { get { return isProjection? format: null; } } + string? format; + public override string? Format { get { return isProjection ? null : format; } } + public string? ElementFormat { get { return isProjection? format: null; } } - string unit; - public override string Unit { get { return isProjection? null: unit; } } - public string ElementUnit { get { return isProjection? unit: null; } } + string? unit; + public override string? Unit { get { return isProjection ? null: unit; } } + public string? ElementUnit { get { return isProjection ? unit : null; } } protected override List SubTokensOverride(SubTokensOptions options) { @@ -72,20 +77,20 @@ protected override Expression BuildExpressionInternal(BuildExpressionContext con if (BuildExtension == null) throw new InvalidOperationException("ExtensionToken.BuildExtension not set"); - var parentExpression = Parent.BuildExpression(context).ExtractEntity(false).UnNullify(); + var parentExpression = parent.BuildExpression(context).ExtractEntity(false).UnNullify(); - var result = BuildExtension(Parent.Type.CleanType().UnNullify(), Key, parentExpression); + var result = BuildExtension(parent.Type.CleanType().UnNullify(), Key, parentExpression); return result.BuildLiteNulifyUnwrapPrimaryKey(new[] { this.propertyRoute }); } public PropertyRoute propertyRoute; - public override PropertyRoute GetPropertyRoute() + public override PropertyRoute? GetPropertyRoute() { return isProjection ? null : propertyRoute; } - public PropertyRoute GetElementPropertyRoute() + public PropertyRoute? GetElementPropertyRoute() { return isProjection ? propertyRoute : null; } @@ -101,20 +106,20 @@ public PropertyRoute GetElementPropertyRoute() return isProjection ? implementations : null; } - string isAllowed; - public override string IsAllowed() + string? isAllowed; + public override string? IsAllowed() { - string parent = Parent.IsAllowed(); + string? parent = parent.IsAllowed(); if (isAllowed.HasText() && parent.HasText()) - return QueryTokenMessage.And.NiceToString().Combine(isAllowed, parent); + return QueryTokenMessage.And.NiceToString().Combine(isAllowed!, parent!); return isAllowed ?? parent; } public override QueryToken Clone() { - return new ExtensionToken(this.Parent.Clone(), key, type, isProjection, unit, format, implementations, isAllowed, propertyRoute); + return new ExtensionToken(this.parent.Clone(), key, type, isProjection, unit, format, implementations, isAllowed, propertyRoute, DisplayName); } } } diff --git a/Signum.Entities/DynamicQuery/Tokens/HasValueToken.cs b/Signum.Entities/DynamicQuery/Tokens/HasValueToken.cs index e3804de0aa..d4b4869691 100644 --- a/Signum.Entities/DynamicQuery/Tokens/HasValueToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/HasValueToken.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Signum.Utilities; using System.Linq.Expressions; @@ -29,11 +29,12 @@ internal static List AndModuloTokens(this List list, Que [Serializable] public class HasValueToken : QueryToken { + QueryToken parent; + public override QueryToken? Parent => parent; + internal HasValueToken(QueryToken parent) - : base(parent) { - if (parent == null) - throw new ArgumentNullException(nameof(parent)); + this.parent = parent ?? throw new ArgumentNullException(nameof(parent)); this.Priority = -1; } @@ -55,7 +56,7 @@ public override string Key protected override Expression BuildExpressionInternal(BuildExpressionContext context) { - Expression baseExpression = Parent.BuildExpression(context); + Expression baseExpression = parent.BuildExpression(context); var result = Expression.NotEqual(baseExpression, Expression.Constant(null, baseExpression.Type.Nullify())); @@ -70,12 +71,12 @@ protected override List SubTokensOverride(SubTokensOptions options) return new List(); } - public override string Format + public override string? Format { get { return null; } } - public override string Unit + public override string? Unit { get { return null; } } @@ -85,24 +86,24 @@ public override string Unit return null; } - public override string IsAllowed() + public override string? IsAllowed() { - return Parent.IsAllowed(); + return parent.IsAllowed(); } - public override PropertyRoute GetPropertyRoute() + public override PropertyRoute? GetPropertyRoute() { return null; ; } public override string NiceName() { - return QueryTokenMessage._0HasValue.NiceToString(Parent.ToString()); + return QueryTokenMessage._0HasValue.NiceToString(parent.ToString()); } public override QueryToken Clone() { - return new HasValueToken(Parent.Clone()); + return new HasValueToken(parent.Clone()); } } diff --git a/Signum.Entities/DynamicQuery/Tokens/NetPropertyToken.cs b/Signum.Entities/DynamicQuery/Tokens/NetPropertyToken.cs index c6cf176ad6..fcbb872729 100644 --- a/Signum.Entities/DynamicQuery/Tokens/NetPropertyToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/NetPropertyToken.cs @@ -14,6 +14,10 @@ public class NetPropertyToken : QueryToken public MemberInfo MemberInfo { get; private set; } public Func DisplayName { get; private set; } + QueryToken parent; + public override QueryToken? Parent => parent; + + internal NetPropertyToken(QueryToken parent, Expression> pi, Func displayName) : this(parent, ReflectionTools.GetPropertyInfo(pi), displayName) { @@ -21,19 +25,11 @@ internal NetPropertyToken(QueryToken parent, Expression> pi, Func displayName) - : base(parent) { - if (parent == null) - throw new ArgumentNullException(nameof(parent)); - - if (pi == null) - throw new ArgumentNullException(nameof(pi)); - - if (displayName == null) - throw new ArgumentNullException(nameof(displayName)); + this.parent = parent ?? throw new ArgumentNullException(nameof(parent)); - this.DisplayName = displayName; - this.MemberInfo = pi; + this.DisplayName = displayName ?? throw new ArgumentNullException(nameof(displayName)); + this.MemberInfo = pi ?? throw new ArgumentNullException(nameof(pi)); } public override Type Type @@ -43,7 +39,7 @@ public override Type Type return MemberInfo is PropertyInfo pi ? pi.PropertyType.Nullify() : MemberInfo is MethodInfo mi ? mi.ReturnType.Nullify() : - throw new UnexpectedValueException(MemberInfo); + throw new UnexpectedValueException(MemberInfo! /*CSBUG*/); } } @@ -61,12 +57,12 @@ public override string Key protected override Expression BuildExpressionInternal(BuildExpressionContext context) { - var result = Parent.BuildExpression(context); + var result = parent.BuildExpression(context); var prop = MemberInfo is PropertyInfo pi ? (Expression)Expression.Property(result.UnNullify(), pi) : MemberInfo is MethodInfo mi ? (mi.IsStatic ? Expression.Call(null, mi, result.UnNullify()) : Expression.Call(result.UnNullify(), mi)) : - throw new UnexpectedValueException(MemberInfo); + throw new UnexpectedValueException(MemberInfo! /*CSBUG*/); return Expression.Call(miInSql.MakeGenericMethod(prop.Type), prop).Nullify(); } @@ -76,12 +72,12 @@ protected override List SubTokensOverride(SubTokensOptions options) return SubTokensBase(this.Type, options, GetImplementations()); } - public override string Format + public override string? Format { get { return null; } } - public override string Unit + public override string? Unit { get { return null; } } @@ -91,24 +87,24 @@ public override string Unit return null; } - public override string IsAllowed() + public override string? IsAllowed() { - return Parent.IsAllowed(); + return parent.IsAllowed(); } - public override PropertyRoute GetPropertyRoute() + public override PropertyRoute? GetPropertyRoute() { return null; } public override string NiceName() { - return DisplayName() + QueryTokenMessage.Of.NiceToString() + Parent.ToString(); + return DisplayName() + QueryTokenMessage.Of.NiceToString() + parent.ToString(); } public override QueryToken Clone() { - return new NetPropertyToken(Parent.Clone(), MemberInfo, DisplayName); + return new NetPropertyToken(parent.Clone(), MemberInfo, DisplayName); } } diff --git a/Signum.Entities/DynamicQuery/Tokens/QueryToken.cs b/Signum.Entities/DynamicQuery/Tokens/QueryToken.cs index 73d2a71564..d56fb20635 100644 --- a/Signum.Entities/DynamicQuery/Tokens/QueryToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/QueryToken.cs @@ -19,8 +19,8 @@ public abstract class QueryToken : IEquatable public abstract override string ToString(); public abstract string NiceName(); - public abstract string Format { get; } - public abstract string Unit { get; } + public abstract string? Format { get; } + public abstract string? Unit { get; } public abstract Type Type { get; } public abstract string Key { get; } @@ -45,7 +45,7 @@ public virtual bool IsGroupable case FilterType.DateTime: { - PropertyRoute route = this.GetPropertyRoute(); + PropertyRoute? route = this.GetPropertyRoute(); if (route != null && route.PropertyRouteType == PropertyRouteType.FieldOrProperty) { @@ -70,10 +70,7 @@ public virtual bool IsGroupable protected abstract List SubTokensOverride(SubTokensOptions options); - public virtual object QueryName - { - get { return this.parent.QueryName; } - } + public virtual object QueryName => this.Parent!.QueryName; public Func GetAccessor(BuildExpressionContext context) { @@ -90,18 +87,18 @@ public Expression BuildExpression(BuildExpressionContext context) protected abstract Expression BuildExpressionInternal(BuildExpressionContext context); - public abstract PropertyRoute GetPropertyRoute(); + public abstract PropertyRoute? GetPropertyRoute(); internal PropertyRoute? AddPropertyRoute(PropertyInfo pi) { if (typeof(ModelEntity).IsAssignableFrom(Type)) return PropertyRoute.Root(Type).Add(pi); - Type type = Lite.Extract(Type); //Because Add doesn't work with lites + Type? type = Lite.Extract(Type); //Because Add doesn't work with lites if (type != null) return PropertyRoute.Root(type).Add(pi); - PropertyRoute pr = GetPropertyRoute(); + PropertyRoute? pr = GetPropertyRoute(); if (pr == null) return null; @@ -109,32 +106,27 @@ public Expression BuildExpression(BuildExpressionContext context) } public abstract Implementations? GetImplementations(); - public abstract string IsAllowed(); + public abstract string? IsAllowed(); public abstract QueryToken Clone(); - QueryToken parent; - public QueryToken Parent - { - get { return parent; } - } + public abstract QueryToken? Parent { get; } - public QueryToken(QueryToken parent) + public QueryToken() { - this.parent = parent; } static ConcurrentDictionary<(QueryToken, SubTokensOptions), Dictionary> subTokensOverrideCache = new ConcurrentDictionary<(QueryToken, SubTokensOptions), Dictionary>(); - public QueryToken SubTokenInternal(string key, SubTokensOptions options) + public QueryToken? SubTokenInternal(string key, SubTokensOptions options) { var result = CachedSubTokensOverride(options).TryGetC(key) ?? OnEntityExtension(this).SingleOrDefaultEx(a => a.Key == key); if (result == null) return null; - string allowed = result.IsAllowed(); + string? allowed = result.IsAllowed(); if (allowed != null) throw new UnauthorizedAccessException($"Access to token '{this.FullKey()}.{key}' in query '{QueryUtils.GetKey(this.QueryName)}' is not allowed because: {allowed}"); @@ -232,7 +224,7 @@ public static List DateTimeProperties(QueryToken parent, DateTimePre { string utc = TimeZoneManager.Mode == TimeZoneMode.Utc ? "Utc - " : ""; - return new List + return new List { new NetPropertyToken(parent, ReflectionTools.GetPropertyInfo((DateTime dt)=>dt.Year), () => utc + QueryTokenMessage.Year.NiceToString()), new NetPropertyToken(parent, ReflectionTools.GetMethodInfo((DateTime dt ) => dt.Quarter()), ()=> utc + QueryTokenMessage.Quarter.NiceToString()), @@ -257,7 +249,7 @@ public static List DateTimeProperties(QueryToken parent, DateTimePre public static List StepTokens(QueryToken parent, int decimals) { - return new List + return new List { decimals >= 4? new StepToken(parent, 0.0001m): null, decimals >= 3? new StepToken(parent, 0.001m) : null, @@ -303,7 +295,7 @@ IEnumerable EntityProperties(Type type) { var result = from p in Reflector.PublicInstancePropertiesInOrder(type) where Reflector.QueryableProperty(type, p) - select (QueryToken)new EntityPropertyToken(this, p, this.AddPropertyRoute(p)); + select (QueryToken)new EntityPropertyToken(this, p, this.AddPropertyRoute(p)!); if (!type.IsEntity()) return result; @@ -427,6 +419,7 @@ public class BuildExpressionContext { public BuildExpressionContext(Type tupleType, ParameterExpression parameter, Dictionary replacemens) { + this.TupleType = tupleType; this.Parameter = parameter; this.Replacemens = replacemens; } diff --git a/Signum.Entities/DynamicQuery/Tokens/SystemTimeToken.cs b/Signum.Entities/DynamicQuery/Tokens/SystemTimeToken.cs index c123db4380..3de3c8050a 100644 --- a/Signum.Entities/DynamicQuery/Tokens/SystemTimeToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/SystemTimeToken.cs @@ -12,12 +12,15 @@ namespace Signum.Entities.DynamicQuery [Serializable] public class SystemTimeToken : QueryToken { + QueryToken parent; + public override QueryToken? Parent => parent; + SystemTimeProperty property; internal SystemTimeToken(QueryToken parent, SystemTimeProperty property) - : base(parent) { Priority = 8; this.property = property; + this.parent = parent; } public override Type Type @@ -38,7 +41,7 @@ public override string Key protected override Expression BuildExpressionInternal(BuildExpressionContext context) { - var result = Parent.BuildExpression(context).ExtractEntity(false); + var result = parent.BuildExpression(context).ExtractEntity(false); var period = Expression.Call(miSystemPeriod, result.UnNullify()); @@ -55,22 +58,22 @@ protected override List SubTokensOverride(SubTokensOptions options) return null; } - public override string Format + public override string? Format { get { return "s"; } } - public override string Unit + public override string? Unit { get { return null; } } - public override string IsAllowed() + public override string? IsAllowed() { - return Parent.IsAllowed(); + return parent.IsAllowed(); } - public override PropertyRoute GetPropertyRoute() + public override PropertyRoute? GetPropertyRoute() { return null; } @@ -82,7 +85,7 @@ public override string NiceName() public override QueryToken Clone() { - return new SystemTimeToken(Parent.Clone(), this.property); + return new SystemTimeToken(parent.Clone(), this.property); } } } diff --git a/Signum.Entities/Entity.cs b/Signum.Entities/Entity.cs index 70dcc207c4..beb74c0d16 100644 --- a/Signum.Entities/Entity.cs +++ b/Signum.Entities/Entity.cs @@ -97,7 +97,7 @@ public override bool Equals(object obj) return false; } - public virtual Dictionary EntityIntegrityCheck() + public virtual Dictionary? EntityIntegrityCheck() { using (Mixins.OfType().Any(c => c.Corrupt) ? Corruption.AllowScope() : null) { @@ -105,7 +105,7 @@ public virtual Dictionary EntityIntegrityCheck() } } - internal virtual Dictionary EntityIntegrityCheckBase() + internal virtual Dictionary? EntityIntegrityCheckBase() { using (HeavyProfiler.LogNoStackTrace("EntityIntegrityCheckBase", () => GetType().Name)) return GraphExplorer.EntityIntegrityCheck(GraphExplorer.FromRootEntity(this)); @@ -124,7 +124,7 @@ public Entity() } [Ignore, DebuggerBrowsable(DebuggerBrowsableState.Never)] - readonly MixinEntity mixin; + readonly MixinEntity? mixin; public M Mixin() where M : MixinEntity { var result = TryMixin(); diff --git a/Signum.Entities/EnumEntity.cs b/Signum.Entities/EnumEntity.cs index 300a9a73c3..10a8b7eb0f 100644 --- a/Signum.Entities/EnumEntity.cs +++ b/Signum.Entities/EnumEntity.cs @@ -69,8 +69,6 @@ public static class EnumEntity { public static Entity FromEnumUntyped(Enum value) { - if (value == null) return null; - Entity ident = (Entity)Activator.CreateInstance(Generate(value.GetType())); ident.Id = new PrimaryKey(EnumExtensions.GetUnderlyingValue(value)); @@ -79,9 +77,7 @@ public static Entity FromEnumUntyped(Enum value) public static Enum ToEnum(Entity ident) { - if (ident == null) return null; - - Type enumType = Extract(ident.GetType()); + Type enumType = Extract(ident.GetType())!; return (Enum)Enum.ToObject(enumType, ident.id); } @@ -111,7 +107,7 @@ public static Type Generate(Type enumType) return typeof(EnumEntity<>).MakeGenericType(enumType); } - public static Type Extract(Type enumEntityType) + public static Type? Extract(Type enumEntityType) { if (enumEntityType.IsGenericType && enumEntityType.GetGenericTypeDefinition() == typeof(EnumEntity<>)) return enumEntityType.GetGenericArguments()[0]; diff --git a/Signum.Entities/Lite.cs b/Signum.Entities/Lite.cs index e1e25f4d79..d81f0dc2a4 100644 --- a/Signum.Entities/Lite.cs +++ b/Signum.Entities/Lite.cs @@ -1,4 +1,4 @@ -using System; +using System; using Signum.Utilities; using Signum.Entities.Reflection; using System.Reflection; @@ -22,7 +22,7 @@ public interface Lite : IComparable, IComparable> where T : class, IEntity { T Entity { get; } - T EntityOrNull { get; } + T? EntityOrNull { get; } PrimaryKey Id { get; } bool IsNew { get; } @@ -52,16 +52,16 @@ public abstract class LiteImp : Modifiable public sealed class LiteImp : LiteImp, Lite, ISerializable where T : Entity { - T entityOrNull; + T? entityOrNull; PrimaryKey? id; - string toStr; + string? toStr; // Methods private LiteImp() { } - public LiteImp(PrimaryKey id, string toStr) + public LiteImp(PrimaryKey id, string? toStr) { if (typeof(T).IsAbstract) throw new InvalidOperationException(typeof(T).Name + " is abstract"); @@ -88,12 +88,12 @@ public LiteImp(T entity, string toStr) this.toStr = toStr; } - public Entity UntypedEntityOrNull + public Entity? UntypedEntityOrNull { - get { return (Entity)(object)entityOrNull; } + get { return (Entity?)(object?)entityOrNull; } } - public T EntityOrNull + public T? EntityOrNull { get { return entityOrNull; } } @@ -157,7 +157,7 @@ public void ClearEntity() public void RefreshId() { - id = entityOrNull.Id; + id = entityOrNull?.Id; } protected internal override void PreSaving(PreSavingContext ctx) @@ -168,7 +168,7 @@ protected internal override void PreSaving(PreSavingContext ctx) } } - public override string ToString() + public override string? ToString() { if (this.entityOrNull != null) return this.entityOrNull.ToString(); @@ -197,8 +197,7 @@ public override bool Equals(object obj) const int MagicMask = 123456853; public override int GetHashCode() { - return this.id == null ? - entityOrNull.GetHashCode() ^ MagicMask : + return this.id == null ? entityOrNull!.GetHashCode() ^ MagicMask : this.EntityType.FullName.GetHashCode() ^ this.Id.GetHashCode() ^ MagicMask; } @@ -214,7 +213,7 @@ public string KeyLong() public int CompareTo(Lite other) { - return ToString().CompareTo(other.ToString()); + return ToString()!.CompareTo(other.ToString()); } public int CompareTo(object obj) @@ -276,21 +275,22 @@ public static class Lite { public static Type BaseImplementationType = typeof(LiteImp); - static GenericInvoker>> giNewLite = - new GenericInvoker>>((id, str) => new LiteImp(id, str)); + static GenericInvoker>> giNewLite = + new GenericInvoker>>((id, str) => new LiteImp(id, str)); - static GenericInvoker>> giNewLiteFat = - new GenericInvoker>>((entity, str) => new LiteImp(entity, str)); + static GenericInvoker>> giNewLiteFat = + new GenericInvoker>>((entity, str) => new LiteImp(entity, str)); public static Type Generate(Type identificableType) { return typeof(Lite<>).MakeGenericType(identificableType); } - public static Type Extract(Type liteType) + public static Type? Extract(Type liteType) { if (liteType.IsInstantiationOf(typeof(Lite<>)) || typeof(LiteImp).IsAssignableFrom(liteType)) return liteType.GetGenericArguments()[0]; + return null; } @@ -298,9 +298,9 @@ public static Type Extract(Type liteType) public static Lite Parse(string liteKey) { - string error = TryParseLite(liteKey, out Lite result); + string? error = TryParseLite(liteKey, out Lite? result); if (error == null) - return result; + return result!; else throw new FormatException(error); } @@ -310,7 +310,7 @@ public static Lite Parse(string liteKey) where T : class, IEntity return (Lite)Lite.Parse(liteKey); } - public static string TryParseLite(string liteKey, out Lite result) + public static string? TryParseLite(string liteKey, out Lite? result) { result = null; if (string.IsNullOrEmpty(liteKey)) @@ -327,16 +327,16 @@ public static string TryParseLite(string liteKey, out Lite result) if (!PrimaryKey.TryParse(match.Groups["id"].Value, type, out PrimaryKey id)) return LiteMessage.IdNotValid.NiceToString(); - string toStr = match.Groups["toStr"].Value.DefaultText(null); //maybe null + string? toStr = match.Groups["toStr"].Value.DefaultText(null!); //maybe null result = giNewLite.GetInvoker(type)(id, toStr); return null; } - public static string TryParse(string liteKey, out Lite lite) where T : class, IEntity + public static string? TryParse(string liteKey, out Lite? lite) where T : class, IEntity { - var result = Lite.TryParseLite(liteKey, out Lite untypedLite); - lite = (Lite)untypedLite; + var result = Lite.TryParseLite(liteKey, out Lite? untypedLite); + lite = (Lite?)untypedLite; return result; } @@ -568,7 +568,7 @@ public static NewExpression NewExpression(Type type, Expression id, Expression t } - static Lite ToLiteFatInternal(this T entity, string toStr) + static Lite? ToLiteFatInternal(this T? entity, string? toStr) where T : class, IEntity { if (entity == null) diff --git a/Signum.Entities/MList.cs b/Signum.Entities/MList.cs index 48bf795825..a70f8c47ba 100644 --- a/Signum.Entities/MList.cs +++ b/Signum.Entities/MList.cs @@ -89,7 +89,7 @@ public override string ToString() private RowIdElement(SerializationInfo info, StreamingContext ctxt) { this.RowId = null; - this.Element = default(T); + this.Element = default(T)!; this.OldIndex = null; foreach (SerializationEntry item in info) { @@ -117,10 +117,10 @@ void ISerializable.GetObjectData(SerializationInfo info, StreamingContext contex [field: NonSerialized] - public event PropertyChangedEventHandler PropertyChanged; + public event PropertyChangedEventHandler? PropertyChanged; [NonSerialized] - NotifyCollectionChangedEventHandler collectionChanged; + NotifyCollectionChangedEventHandler? collectionChanged; event NotifyCollectionChangedEventHandler INotifyCollectionChanged.CollectionChanged { add { collectionChanged += value; } @@ -611,7 +611,7 @@ void IList.Remove(object value) this.Remove((T)value); } - object IList.this[int index] + object? IList.this[int index] { get { return this[index]; } set { this[index] = (T)value; } @@ -850,13 +850,13 @@ public static MList ToMList(this IEnumerable collection) [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = false, AllowMultiple = false)] public sealed class PreserveOrderAttribute : SqlDbTypeAttribute { - public string Name { get; set; } + public string? Name { get; set; } public PreserveOrderAttribute() { } - public PreserveOrderAttribute(string name) + public PreserveOrderAttribute(string? name) { this.Name = name; } diff --git a/Signum.Entities/MixinEntity.cs b/Signum.Entities/MixinEntity.cs index a0ebfc178c..ff9a304f89 100644 --- a/Signum.Entities/MixinEntity.cs +++ b/Signum.Entities/MixinEntity.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; @@ -48,7 +48,7 @@ public static class MixinDeclarations public static ConcurrentDictionary> Declarations = new ConcurrentDictionary>(); - public static ConcurrentDictionary> Constructors = new ConcurrentDictionary>(); + public static ConcurrentDictionary> Constructors = new ConcurrentDictionary>(); public static Action AssertNotIncluded = t => { throw new NotImplementedException("Call MixinDeclarations.Register in the server, after the Connector is created."); }; @@ -102,7 +102,7 @@ static void AddConstructor(Type mixinEntity) if (ci.IsPublic || pi.Length != 2 || pi[0].ParameterType != typeof(Entity) || pi[1].ParameterType != typeof(MixinEntity)) throw new InvalidOperationException("{0} does not have a non-public construtor with parameters (Entity mainEntity, MixinEntity next)"); - return (Func)Expression.Lambda(Expression.New(ci, pMainEntity, pNext), pMainEntity, pNext).Compile(); + return (Func)Expression.Lambda(Expression.New(ci, pMainEntity, pNext), pMainEntity, pNext).Compile(); }); } @@ -135,11 +135,11 @@ public static void AssertDeclared(Type mainEntity, Type mixinType) throw new InvalidOperationException("Mixin {0} is not registered for {1}. Consider writing MixinDeclarations.Register<{1}, {0}>() at the beginning of Starter.Start".FormatWith(mixinType.TypeName(), mainEntity.TypeName())); } - internal static MixinEntity CreateMixins(Entity mainEntity) + internal static MixinEntity? CreateMixins(Entity mainEntity) { var types = GetMixinDeclarations(mainEntity.GetType()); - MixinEntity result = null; + MixinEntity? result = null; foreach (var t in types) result = Constructors[t](mainEntity, result); diff --git a/Signum.Entities/ModelEntity.cs b/Signum.Entities/ModelEntity.cs index 0235c7a1a7..7edb1207f7 100644 --- a/Signum.Entities/ModelEntity.cs +++ b/Signum.Entities/ModelEntity.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Reflection; using Signum.Utilities; @@ -29,10 +29,10 @@ public static Implementations GetImplementations(PropertyRoute route) PropertyRoute fieldRoute = route; if (fieldRoute.PropertyRouteType == PropertyRouteType.LiteEntity) - fieldRoute = fieldRoute.Parent; + fieldRoute = fieldRoute.Parent!; if (fieldRoute.PropertyRouteType == PropertyRouteType.MListItems) - fieldRoute = fieldRoute.Parent; + fieldRoute = fieldRoute.Parent!; return Implementations.FromAttributes( route.Type.CleanType(), diff --git a/Signum.Entities/ModifiableEntity.cs b/Signum.Entities/ModifiableEntity.cs index c4d1a6235c..0fdf2ab85e 100644 --- a/Signum.Entities/ModifiableEntity.cs +++ b/Signum.Entities/ModifiableEntity.cs @@ -383,7 +383,7 @@ object ICloneable.Clone() [Ignore] internal Dictionary? temporalErrors; - internal void SetTemporalErrors(Dictionary errors) + internal void SetTemporalErrors(Dictionary? errors) { NotifyTemporalErrors(); diff --git a/Signum.Entities/ObjectDumper.cs b/Signum.Entities/ObjectDumper.cs index 5d47f50e5d..078a89f4cb 100644 --- a/Signum.Entities/ObjectDumper.cs +++ b/Signum.Entities/ObjectDumper.cs @@ -69,7 +69,7 @@ public void DumpObject(object o) return; } - Type t = o.GetType(); + Type t = o!.GetType(); /*CSBUG*/ if (IsDelegate(t)) { @@ -79,7 +79,7 @@ public void DumpObject(object o) if (IsBasicType(t) || t.IsValueType) { - Sb.Append(DumpValue(o)); + Sb.Append(DumpValue(o!)); return; } @@ -89,19 +89,16 @@ public void DumpObject(object o) if (IgnoreTypes.Contains(t)) { - Sb.Append("{ " + o.ToString() + " }"); + Sb.Append("{ " + o!.ToString() + " }"); return; } - if (objects.Contains(o)) + if (objects.Contains(o!)) { - if (o is Entity) + if (o is Entity ent) { - var ident = o as Entity; - var ent = o as Entity; - Sb.Append("({0}{1})".FormatWith( - ident.IsNew ? "IsNew": ident.IdOrNull.ToString(), + ent.IsNew ? "IsNew": ent.IdOrNull.ToString(), ent == null ? null : ", ticks: " + ent.ticks )); } @@ -110,18 +107,17 @@ public void DumpObject(object o) var id = ((Lite)o).IdOrNull; Sb.Append(id.HasValue ? "({0})".FormatWith(id.Value) : ""); } - Sb.Append(" /* [CICLE] {0} */".FormatWith(SafeToString(o))); + Sb.Append(" /* [CICLE] {0} */".FormatWith(SafeToString(o!))); return; } - objects.Add(o); + objects.Add(o!); - if (o is Entity) + if (o is Entity e) { - var ent = (Entity)o; Sb.Append("({0}{1})".FormatWith( - ent.IsNew ? "IsNew" : ent.IdOrNull.ToString(), - ent.ticks == 0 ? null : ", ticks: " + ent.ticks + e.IsNew ? "IsNew" : e.IdOrNull.ToString(), + e.ticks == 0 ? null : ", ticks: " + e.ticks )); string toString = SafeToString(o); @@ -129,9 +125,8 @@ public void DumpObject(object o) Sb.Append(" /* {0} */".FormatWith(toString)); } - if (o is Lite) + if (o is Lite l) { - var l = o as Lite; Sb.Append("({0}, \"{1}\")".FormatWith((l.IdOrNull.HasValue ? l.Id.ToString() : "null"), l.ToString())); if (((Lite)o).EntityOrNull != null) { @@ -145,7 +140,7 @@ public void DumpObject(object o) return; } - if (o is IEnumerable && !Any((o as IEnumerable))) + if (o is IEnumerable ie && !Any(ie)) { Sb.Append("{}"); return; @@ -161,10 +156,9 @@ public void DumpObject(object o) level += 1; if (t.Namespace.HasText() && t.Namespace.StartsWith("System.Reflection")) - Sb.AppendLine("ToString = {0},".FormatWith(SafeToString(o)).Indent(level)); - else if (o is Exception) + Sb.AppendLine("ToString = {0},".FormatWith(SafeToString(o!)).Indent(level)); + else if (o is Exception ex) { - var ex = o as Exception; DumpPropertyOrField(typeof(string), "Message", ex.Message); DumpPropertyOrField(typeof(string), "StackTrace", ex.StackTrace); DumpPropertyOrField(typeof(Exception), "InnerException", ex.InnerException); @@ -174,7 +168,7 @@ public void DumpObject(object o) { if (o is IDictionary) { - foreach (DictionaryEntry item in (o as IDictionary)) + foreach (DictionaryEntry item in (o as IDictionary)!) { Sb.Append("{".Indent(level)); DumpObject(item.Key); @@ -185,7 +179,7 @@ public void DumpObject(object o) } else { - foreach (var item in (o as IEnumerable)) + foreach (var item in (o as IEnumerable)!) { Sb.Append("".Indent(level)); DumpObject(item); @@ -271,13 +265,13 @@ private bool IsIdOrTicks(FieldInfo field) private bool Any(IEnumerable ie) { - if (ie is IList) - return (ie as IList).Count > 0; + if (ie is IList l) + return l.Count > 0; - if (ie is Array) - return (ie as Array).Length > 0; + if (ie is Array a) + return a.Length > 0; - foreach (var item in ie) + foreach (var item in ie!) { return true; } @@ -306,8 +300,8 @@ bool IsBasicType(Type type) string DumpValue(object item) { string value = item?.ToString() ?? "null"; - string startDelimiter = null; - string endDelimiter = null; + string? startDelimiter = null; + string? endDelimiter = null; if (item != null) { diff --git a/Signum.Entities/Patterns/LockeableEntity.cs b/Signum.Entities/Patterns/LockeableEntity.cs index a539aa76c1..f14d833a61 100644 --- a/Signum.Entities/Patterns/LockeableEntity.cs +++ b/Signum.Entities/Patterns/LockeableEntity.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.ComponentModel; using Signum.Utilities; @@ -20,7 +20,7 @@ public bool Locked } } - protected bool UnsafeSet(ref T field, T value, [CallerMemberNameAttribute]string automaticPropertyName = null) + protected bool UnsafeSet(ref T field, T value, [CallerMemberNameAttribute]string? automaticPropertyName = null) { return base.Set(ref field, value, automaticPropertyName); } @@ -29,7 +29,7 @@ protected virtual void ItemLockedChanged(bool locked) { } - protected override bool Set(ref T field, T value, [CallerMemberNameAttribute]string automaticPropertyName = null) + protected override bool Set(ref T field, T value, [CallerMemberNameAttribute]string? automaticPropertyName = null) { if (EqualityComparer.Default.Equals(field, value)) return false; diff --git a/Signum.Entities/PropertyRoute.cs b/Signum.Entities/PropertyRoute.cs index 5ac2cda2ce..67aedee18b 100644 --- a/Signum.Entities/PropertyRoute.cs +++ b/Signum.Entities/PropertyRoute.cs @@ -17,25 +17,25 @@ namespace Signum.Entities [Serializable] public class PropertyRoute : IEquatable, ISerializable { - Type type; + Type? type; public PropertyRouteType PropertyRouteType { get; private set; } - public FieldInfo FieldInfo { get; private set; } - public PropertyInfo PropertyInfo { get; private set; } - public PropertyRoute Parent { get; private set; } + public FieldInfo? FieldInfo { get; private set; } + public PropertyInfo? PropertyInfo { get; private set; } + public PropertyRoute? Parent { get; private set; } public MemberInfo[] Members { get { return this.Follow(a => a.Parent).Select(a => - a.PropertyRouteType == Entities.PropertyRouteType.Mixin ? a.type : - a.FieldInfo ?? (MemberInfo)a.PropertyInfo).Reverse().Skip(1).ToArray(); + a.PropertyRouteType == Entities.PropertyRouteType.Mixin ? a.type! : + a.FieldInfo ?? (MemberInfo)a.PropertyInfo!).Reverse().Skip(1).ToArray(); } } public PropertyInfo[] Properties { - get { return this.Follow(a => a.Parent).Select(a => a.PropertyInfo).Reverse().Skip(1).ToArray(); } + get { return this.Follow(a => a.Parent).Select(a => a.PropertyInfo!).Reverse().Skip(1).ToArray(); } } [ForceEagerEvaluation] @@ -79,7 +79,7 @@ MemberInfo GetMember(string fieldOrProperty) if (mi == null && Type.IsEntity()) { - string name = ExtractMixin(fieldOrProperty); + string? name = ExtractMixin(fieldOrProperty); mi = MixinDeclarations.GetMixinDeclarations(Type).FirstOrDefault(t => t.Name == name); } @@ -95,7 +95,7 @@ private bool IsCollection() return Type.ElementType() != null && Type != typeof(string); } - static string ExtractMixin(string fieldOrProperty) + static string? ExtractMixin(string fieldOrProperty) { Match match = Regex.Match(fieldOrProperty, @"^\[(?.*)\]$"); @@ -160,7 +160,7 @@ void SetParentAndProperty(PropertyRoute parent, MemberInfo fieldOrProperty) } else if (typeof(Entity).IsAssignableFrom(parent.type) && fieldOrProperty is Type) { - MixinDeclarations.AssertDeclared(parent.type, (Type)fieldOrProperty); + MixinDeclarations.AssertDeclared(parent.type!, (Type)fieldOrProperty); type = (Type)fieldOrProperty; PropertyRouteType = PropertyRouteType.Mixin; @@ -255,7 +255,7 @@ public Type RootType if (type != null && type.IsIRootEntity()) return type; - return Parent.RootType; + return Parent!.RootType; } } @@ -264,15 +264,15 @@ public override string ToString() switch (PropertyRouteType) { case PropertyRouteType.Root: - return "({0})".FormatWith(typeof(Entity).IsAssignableFrom(type) ? TypeEntity.GetCleanName(type) : type.Name); + return "({0})".FormatWith(typeof(Entity).IsAssignableFrom(type!) ? TypeEntity.GetCleanName(type!) : type!.Name); case PropertyRouteType.FieldOrProperty: - return Parent.ToString() + (Parent.PropertyRouteType == PropertyRouteType.MListItems ? "" : ".") + (PropertyInfo != null ? PropertyInfo.Name : FieldInfo.Name); + return Parent!.ToString() + (Parent!.PropertyRouteType == PropertyRouteType.MListItems ? "" : ".") + (PropertyInfo != null ? PropertyInfo.Name : FieldInfo!.Name); case PropertyRouteType.Mixin: - return Parent.ToString() + "[{0}]".FormatWith(type.Name); + return Parent!.ToString() + "[{0}]".FormatWith(type!.Name); case PropertyRouteType.MListItems: - return Parent.ToString() + "/"; + return Parent!.ToString() + "/"; case PropertyRouteType.LiteEntity: - return Parent.ToString() + ".Entity"; + return Parent!.ToString() + ".Entity"; } throw new InvalidOperationException(); } @@ -284,22 +284,22 @@ public string PropertyString() case PropertyRouteType.Root: throw new InvalidOperationException("Root has no PropertyString"); case PropertyRouteType.FieldOrProperty: - switch (Parent.PropertyRouteType) + switch (Parent!.PropertyRouteType) { - case PropertyRouteType.Root: return (PropertyInfo != null ? PropertyInfo.Name : FieldInfo.Name); + case PropertyRouteType.Root: return (PropertyInfo != null ? PropertyInfo.Name : FieldInfo!.Name); case PropertyRouteType.FieldOrProperty: case PropertyRouteType.Mixin: - return Parent.PropertyString() + "." + (PropertyInfo != null ? PropertyInfo.Name : FieldInfo.Name); - case PropertyRouteType.MListItems: return Parent.PropertyString() + (PropertyInfo != null ? PropertyInfo.Name : FieldInfo.Name); + return Parent!.PropertyString() + "." + (PropertyInfo != null ? PropertyInfo.Name : FieldInfo!.Name); + case PropertyRouteType.MListItems: return Parent!.PropertyString() + (PropertyInfo != null ? PropertyInfo.Name : FieldInfo!.Name); default: throw new InvalidOperationException(); } case PropertyRouteType.Mixin: - return "[{0}]".FormatWith(type.Name); + return "[{0}]".FormatWith(type!.Name); case PropertyRouteType.MListItems: - return Parent.PropertyString() + "/"; + return Parent!.PropertyString() + "/"; case PropertyRouteType.LiteEntity: - return Parent.ToString() + ".Entity"; + return Parent!.ToString() + ".Entity"; } throw new InvalidOperationException(); } @@ -374,7 +374,7 @@ public static void SetIsAllowedCallback(Func isAllowed) static Func IsAllowedCallback; - public string IsAllowed() + public string? IsAllowed() { if (IsAllowedCallback != null) return IsAllowedCallback(this); @@ -442,6 +442,12 @@ static List GenerateEmbeddedProperties(PropertyRoute embeddedProp return result; } + public override int GetHashCode() + { + return this.RootType.GetHashCode() ^ (this.PropertyRouteType == Entities.PropertyRouteType.Root ? 0 : this.PropertyString().GetHashCode()); + } + + public override bool Equals(object obj) => obj is PropertyRoute pr && Equals(pr); public bool Equals(PropertyRoute other) { if (other.PropertyRouteType != this.PropertyRouteType) @@ -475,28 +481,14 @@ private bool PropertyEquals(PropertyRoute other) return other.PropertyInfo != null && ReflectionTools.PropertyEquals(PropertyInfo, other.PropertyInfo); } - public override int GetHashCode() - { - return this.RootType.GetHashCode() ^ (this.PropertyRouteType == Entities.PropertyRouteType.Root ? 0 : this.PropertyString().GetHashCode()); - } - - public override bool Equals(object obj) - { - PropertyRoute other = obj as PropertyRoute; - - if (obj == null) - return false; - - return Equals(other); - } - + public PropertyRoute SimplifyToProperty() { switch (PropertyRouteType) { case PropertyRouteType.FieldOrProperty: return this; case PropertyRouteType.LiteEntity: - case PropertyRouteType.MListItems: return this.Parent.SimplifyToProperty(); + case PropertyRouteType.MListItems: return this.Parent!.SimplifyToProperty(); default: throw new InvalidOperationException("PropertyRoute of type {0} not expected".FormatWith(PropertyRouteType)); } @@ -510,7 +502,7 @@ public PropertyRoute SimplifyToPropertyOrRoot() case PropertyRouteType.FieldOrProperty: return this; case PropertyRouteType.LiteEntity: case PropertyRouteType.MListItems: - case PropertyRouteType.Mixin: return this.Parent.SimplifyToPropertyOrRoot(); + case PropertyRouteType.Mixin: return this.Parent!.SimplifyToPropertyOrRoot(); default: throw new InvalidOperationException("PropertyRoute of type {0} not expected".FormatWith(PropertyRouteType)); } @@ -528,7 +520,7 @@ private PropertyRoute(SerializationInfo info, StreamingContext ctxt) this.SetRootType(root); else { - string before = route.TryBeforeLast("."); + string? before = route.TryBeforeLast("."); if (before != null) { @@ -549,17 +541,17 @@ public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("rootType", RootType.AssemblyQualifiedName); - string property = + string? property = PropertyRouteType == Entities.PropertyRouteType.Root ? null : - (PropertyRouteType == Entities.PropertyRouteType.LiteEntity ? this.Parent.PropertyString() + ".Entity" : + (PropertyRouteType == Entities.PropertyRouteType.LiteEntity ? this.Parent!.PropertyString() + ".Entity" : this.PropertyString()).Replace("/", ".Item.").TrimEnd('.'); info.AddValue("property", property); } - public PropertyRoute GetMListItemsRoute() + public PropertyRoute? GetMListItemsRoute() { - for (var r = this; r != null; r = r.Parent) + for (PropertyRoute? r = this; r != null; r = r.Parent) { if (r.PropertyRouteType == PropertyRouteType.MListItems) return r; @@ -571,14 +563,14 @@ public PropertyRoute GetMListItemsRoute() /// The RootType or the type of MListElement /// Result type /// - public Expression> GetLambdaExpression(bool safeNullAccess, PropertyRoute skipBefore = null) + public Expression> GetLambdaExpression(bool safeNullAccess, PropertyRoute? skipBefore = null) { ParameterExpression pe = Expression.Parameter(typeof(T)); - Expression exp = null; + Expression? exp = null; var steps = this.Follow(a => a.Parent).Reverse(); if (skipBefore != null) - steps = steps.SkipWhile(a => !a.Equals(skipBefore)); + steps = steps.SkipWhile(a => !a.Equals(skipBefore!)); foreach (var p in steps) { @@ -589,10 +581,10 @@ public Expression> GetLambdaExpression(bool safeNullAccess, Pro exp = pe.TryConvert(p.Type); break; case PropertyRouteType.FieldOrProperty: - var memberExp = Expression.MakeMemberAccess(exp, (MemberInfo)p.PropertyInfo ?? p.FieldInfo); - if (exp.Type.IsEmbeddedEntity() && safeNullAccess) + var memberExp = Expression.MakeMemberAccess(exp, (MemberInfo?)p.PropertyInfo ?? p.FieldInfo!); + if (exp!.Type.IsEmbeddedEntity() && safeNullAccess) exp = Expression.Condition( - Expression.Equal(exp, Expression.Constant(null, exp.Type)), + Expression.Equal(exp, Expression.Constant(null, exp!.Type)), Expression.Constant(null, memberExp.Type.Nullify()), memberExp.Nullify()); else @@ -617,24 +609,12 @@ public Expression> GetLambdaExpression(bool safeNullAccess, Pro public bool IsToStringProperty() { return PropertyRouteType == PropertyRouteType.FieldOrProperty && - Parent.PropertyRouteType == PropertyRouteType.Root && + Parent!.PropertyRouteType == PropertyRouteType.Root && PropertyInfo != null && ReflectionTools.PropertyEquals(PropertyInfo, piToStringProperty); } static readonly PropertyInfo piToStringProperty = ReflectionTools.GetPropertyInfo((Entity ident) => ident.ToStringProperty); - - /// null means impossible to determine because lack of NotifyChildPropertyAttribute - public bool? MatchesProperty(ModifiableEntity entity, PropertyInfo pi) - { - if (this.PropertyRouteType != PropertyRouteType.FieldOrProperty) - return false; - - if (!ReflectionTools.PropertyEquals(PropertyInfo, pi)) - return false; - - return this.Parent.MatchesEntity(entity); - } - + public bool? MatchesEntity(ModifiableEntity entity) { if (this.Type != entity.GetType()) @@ -655,11 +635,11 @@ public bool IsToStringProperty() if (parentEntity == null) return null; - var result = this.Parent.MatchesEntity(parentEntity); + var result = this.Parent!.MatchesEntity(parentEntity); if (result != true) return result; - return this.PropertyInfo.GetValue(parentEntity) == entity; + return this.PropertyInfo!.GetValue(parentEntity) == entity; } case PropertyRouteType.Mixin: @@ -667,7 +647,7 @@ public bool IsToStringProperty() var mixin = (MixinEntity)entity; var mainEntity = mixin.MainEntity; - var result = this.Parent.MatchesEntity(mainEntity); + var result = this.Parent!.MatchesEntity(mainEntity); if (result != true) return result; @@ -680,11 +660,11 @@ public bool IsToStringProperty() if (parentEntity == null) return null; - var result = this.Parent.Parent.MatchesEntity(parentEntity); + var result = this.Parent!.Parent!.MatchesEntity(parentEntity); if (result != true) return result; - var list = (IList)this.PropertyInfo.GetValue(parentEntity); + var list = (IList)this.PropertyInfo!.GetValue(parentEntity); return list != null && list.Contains(entity); } diff --git a/Signum.Entities/Reflection/GraphExplorer.cs b/Signum.Entities/Reflection/GraphExplorer.cs index d2d052ab20..bca73c788f 100644 --- a/Signum.Entities/Reflection/GraphExplorer.cs +++ b/Signum.Entities/Reflection/GraphExplorer.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Collections; using Signum.Utilities; @@ -78,9 +78,9 @@ public static DirectedGraph FromRootsEntity(IEnumerable roots) return DirectedGraph.Generate(roots.Cast(), ModifyInspector.EntityExplore, ReferenceEqualityComparer.Default); } - public static Dictionary ToDictionaryOrNull(this IEnumerable collection, Func keySelector, Func nullableValueSelector) where V : class + public static Dictionary? ToDictionaryOrNull(this IEnumerable collection, Func keySelector, Func nullableValueSelector) where V : class { - Dictionary result = null; + Dictionary? result = null; foreach (var item in collection) { @@ -98,13 +98,13 @@ public static Dictionary ToDictionaryOrNull(this IEnumerable c return result; } - public static Dictionary EntityIntegrityCheck(DirectedGraph graph) + public static Dictionary? EntityIntegrityCheck(DirectedGraph graph) { return graph.OfType() .ToDictionaryOrNull(a => a.temporalId, a => a.IntegrityCheck()); } - public static Dictionary FullIntegrityCheck(DirectedGraph graph) + public static Dictionary? FullIntegrityCheck(DirectedGraph graph) { AssertCloneAttack(graph); @@ -129,7 +129,7 @@ public static List WithEntities(this Dictionary graph) { var problems = (from m in graph.OfType() - group m by new { Type = m.GetType(), Id = (m as Entity)?.Let(ident => (object)ident.IdOrNull) ?? (object)m.temporalId } into g + group m by new { Type = m.GetType(), Id = (m as Entity)?.Let(ident => (object?)ident.IdOrNull) ?? (object)m.temporalId } into g where g.Count() > 1 && g.Count(m => m.Modified == ModifiedState.SelfModified) > 0 select g).ToList(); @@ -157,7 +157,7 @@ public static DirectedGraph PreSaving(Func if (m is ModifiableEntity me) me.SetTemporalErrors(null); - m.PreSaving(ctx); + m!.PreSaving(ctx); /*CSBUG*/ }); } @@ -231,7 +231,7 @@ public static string SuperGraphviz(this DirectedGraph modifiables) }).ToList(); - string nodes = listNodes.ToString(t => " {0} [color={1}, fillcolor={2} shape={3}{4}, label=\"{5}\"]".FormatWith(modifiables.Comparer.GetHashCode(t.Node), t.Color, t.Fillcolor, t.Shape, t.Style, t.Label), "\r\n"); + string nodes = listNodes.ToString(t => " {0} [color={1}, fillcolor={2} shape={3}{4}, label=\"{5}\"]".FormatWith(modifiables.Comparer.GetHashCode(t.Node! /*CSBUG*/), t.Color, t.Fillcolor, t.Shape, t.Style, t.Label), "\r\n"); string arrows = modifiables.Edges.ToString(e => " {0} -> {1}".FormatWith(modifiables.Comparer.GetHashCode(e.From), modifiables.Comparer.GetHashCode(e.To)), "\r\n"); diff --git a/Signum.Entities/Reflection/ModifyInspector.cs b/Signum.Entities/Reflection/ModifyInspector.cs index 1d2071933b..301009fe5e 100644 --- a/Signum.Entities/Reflection/ModifyInspector.cs +++ b/Signum.Entities/Reflection/ModifyInspector.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Reflection; using System.Collections; @@ -58,7 +58,7 @@ public static IEnumerable FullExplore(Modifiable obj) Type t = obj.GetType().ElementType(); if (Reflector.IsModifiableIdentifiableOrLite(t)) { - IEnumerable col = obj as IEnumerable; + IEnumerable col = (IEnumerable)obj; foreach (Modifiable item in col) if (item != null) yield return item; @@ -96,8 +96,8 @@ public static IEnumerable FullExploreVirtual(Modifiable obj) Type t = obj.GetType().ElementType(); if (Reflector.IsModifiableIdentifiableOrLite(t)) { - IEnumerable col = obj as IEnumerable; - foreach (Modifiable item in col) + IEnumerable col = (IEnumerable)obj; + foreach (Modifiable item in col!) if (item != null) yield return item; } @@ -135,7 +135,7 @@ public static IEnumerable EntityExplore(Modifiable obj) if (t.IsModifiable() && !t.IsEntity()) { - IEnumerable col = obj as IEnumerable; + IEnumerable col = (IEnumerable)obj; foreach (Modifiable item in col) if (item != null) yield return item; diff --git a/Signum.Entities/Signum.Entities.csproj b/Signum.Entities/Signum.Entities.csproj index 715a252080..429301ed45 100644 --- a/Signum.Entities/Signum.Entities.csproj +++ b/Signum.Entities/Signum.Entities.csproj @@ -5,7 +5,7 @@ 8.0 true true - true + x64 diff --git a/Signum.Utilities/Extensions/DictionaryExtensions.cs b/Signum.Utilities/Extensions/DictionaryExtensions.cs index 2e0759a7cd..4d8976de78 100644 --- a/Signum.Utilities/Extensions/DictionaryExtensions.cs +++ b/Signum.Utilities/Extensions/DictionaryExtensions.cs @@ -96,7 +96,7 @@ public static V GetOrThrow(this IDictionary dictionary, K key, strin return result; } - public static V GetOrThrow(this IDictionary dictionary, K key) + public static V GetOrThrow(this IDictionary dictionary, K key) where K : object { if (!dictionary.TryGetValue(key, out V result)) throw new KeyNotFoundException("Key '{0}' ({1}) not found on {2}".FormatWith(key, key.GetType().TypeName(), dictionary.GetType().TypeName())); @@ -133,7 +133,7 @@ public static Dictionary ToDictionary(this IEnumerable ToDictionaryEx(this IEnumerable> collection, string errorContext = null) + public static Dictionary ToDictionaryEx(this IEnumerable> collection, string? errorContext = null) { var result = new Dictionary(); result.AddRange(collection, errorContext ?? typeof(K).TypeName()); @@ -147,7 +147,7 @@ public static Dictionary ToDictionary(this IEnumerable ToDictionaryEx(this IEnumerable> collection, IEqualityComparer comparer, string errorContext = null) + public static Dictionary ToDictionaryEx(this IEnumerable> collection, IEqualityComparer comparer, string? errorContext = null) { var result = new Dictionary(comparer); result.AddRange(collection, errorContext ?? typeof(K).TypeName()); @@ -155,28 +155,28 @@ public static Dictionary ToDictionaryEx(this IEnumerable ToDictionaryEx(this IEnumerable source, Func keySelector, string errorContext = null) + public static Dictionary ToDictionaryEx(this IEnumerable source, Func keySelector, string? errorContext = null) { Dictionary result = new Dictionary(); result.AddRange(source, keySelector, v => v, errorContext ?? typeof(K).TypeName()); return result; } - public static Dictionary ToDictionaryEx(this IEnumerable source, Func keySelector, Func elementSelector, string errorContext = null) + public static Dictionary ToDictionaryEx(this IEnumerable source, Func keySelector, Func elementSelector, string? errorContext = null) { Dictionary result = new Dictionary(); result.AddRange(source, keySelector, elementSelector, errorContext ?? typeof(K).TypeName()); return result; } - public static Dictionary ToDictionaryEx(this IEnumerable source, Func keySelector, IEqualityComparer comparer, string errorContext = null) + public static Dictionary ToDictionaryEx(this IEnumerable source, Func keySelector, IEqualityComparer comparer, string? errorContext = null) { Dictionary result = new Dictionary(comparer); result.AddRange(source, keySelector, v => v, errorContext ?? typeof(K).TypeName()); return result; } - public static Dictionary ToDictionaryEx(this IEnumerable source, Func keySelector, Func elementSelector, IEqualityComparer comparer, string errorContext = null) + public static Dictionary ToDictionaryEx(this IEnumerable source, Func keySelector, Func elementSelector, IEqualityComparer comparer, string? errorContext = null) { Dictionary result = new Dictionary(comparer); result.AddRange(source, keySelector, elementSelector, errorContext ?? typeof(K).TypeName()); @@ -252,7 +252,7 @@ public static void JoinDictionaryForeachStrict( } } - public static Dictionary OuterJoinDictionaryCC(this IReadOnlyDictionary dic1, IReadOnlyDictionary dic2, Func mixer) + public static Dictionary OuterJoinDictionaryCC(this IReadOnlyDictionary dic1, IReadOnlyDictionary dic2, Func mixer) where V1 : class where V2 : class { @@ -263,7 +263,7 @@ public static Dictionary OuterJoinDictionaryCC(this IReadOnl return set.ToDictionaryEx(k => k, k => mixer(k, dic1.TryGetC(k), dic2.TryGetC(k))); } - public static Dictionary OuterJoinDictionarySC(this IReadOnlyDictionary dic1, IReadOnlyDictionary dic2, Func mixer) + public static Dictionary OuterJoinDictionarySC(this IReadOnlyDictionary dic1, IReadOnlyDictionary dic2, Func mixer) where V1 : struct where V2 : class { @@ -274,7 +274,7 @@ public static Dictionary OuterJoinDictionarySC(this IReadOnl return set.ToDictionaryEx(k => k, k => mixer(k, dic1.TryGetS(k), dic2.TryGetC(k))); } - public static Dictionary OuterJoinDictionarySC(this IReadOnlyDictionary dic1, IReadOnlyDictionary dic2, Func mixer) + public static Dictionary OuterJoinDictionarySC(this IReadOnlyDictionary dic1, IReadOnlyDictionary dic2, Func mixer) where V1 : struct where V2 : class { @@ -285,7 +285,7 @@ public static Dictionary OuterJoinDictionarySC(this IReadO return set.ToDictionaryEx(k => k, k => mixer(k, dic1.TryGetS(k), dic2.TryGetC(k))); } - public static Dictionary OuterJoinDictionaryCS(this IReadOnlyDictionary dic1, IReadOnlyDictionary dic2, Func mixer) + public static Dictionary OuterJoinDictionaryCS(this IReadOnlyDictionary dic1, IReadOnlyDictionary dic2, Func mixer) where V1 : class where V2 : struct { @@ -296,7 +296,7 @@ public static Dictionary OuterJoinDictionaryCS(this IReadOnl return set.ToDictionaryEx(k => k, k => mixer(k, dic1.TryGetC(k), dic2.TryGetS(k))); } - public static Dictionary OuterJoinDictionaryCS(this IReadOnlyDictionary dic1, IReadOnlyDictionary dic2, Func mixer) + public static Dictionary OuterJoinDictionaryCS(this IReadOnlyDictionary dic1, IReadOnlyDictionary dic2, Func mixer) where V1 : class where V2 : struct { diff --git a/Signum.Utilities/Extensions/EnumerableExtensions.cs b/Signum.Utilities/Extensions/EnumerableExtensions.cs index 02ba64527c..ee6fa5fba1 100644 --- a/Signum.Utilities/Extensions/EnumerableExtensions.cs +++ b/Signum.Utilities/Extensions/EnumerableExtensions.cs @@ -409,7 +409,7 @@ public static bool HasItems(this IEnumerable collection) return collection != null && collection.Any(); } - public static IEnumerable NotNull(this IEnumerable collection) where T : class + public static IEnumerable NotNull(this IEnumerable collection) where T : class { foreach (var item in collection) { diff --git a/Signum.Utilities/Extensions/Extensions.cs b/Signum.Utilities/Extensions/Extensions.cs index 9bf50b1551..df9b9c7ba4 100644 --- a/Signum.Utilities/Extensions/Extensions.cs +++ b/Signum.Utilities/Extensions/Extensions.cs @@ -350,9 +350,9 @@ public static IEnumerable For(this T start, Func condition, Func< public delegate R FuncCC(T input) where T : class where R : class; - public static IEnumerable Follow(this T start, FuncCC next) where T : class + public static IEnumerable Follow(this T start, FuncCC next) where T : class { - for (T i = start; i != null; i = next(i)) + for (T? i = start; i != null; i = next(i)) yield return i; } diff --git a/Signum.Utilities/Extensions/StringExtensions.cs b/Signum.Utilities/Extensions/StringExtensions.cs index e61cd499ae..013d2df83b 100644 --- a/Signum.Utilities/Extensions/StringExtensions.cs +++ b/Signum.Utilities/Extensions/StringExtensions.cs @@ -603,22 +603,22 @@ public static string FormatWith(this string format, object? arg0) return string.Format(format, arg0); } - public static string FormatWith(this string format, object? arg0, object arg1) + public static string FormatWith(this string format, object? arg0, object? arg1) { return string.Format(format, arg0, arg1); } - public static string FormatWith(this string format, object arg0, object arg1, object arg2) + public static string FormatWith(this string format, object? arg0, object? arg1, object? arg2) { return string.Format(format, arg0, arg1, arg2); } - public static string FormatWith(this string pattern, params object[] parameters) + public static string FormatWith(this string pattern, params object?[] parameters) { return string.Format(pattern, parameters); } - public static string FormatWith(this string format, IFormatProvider provider, params object[] args) + public static string FormatWith(this string format, IFormatProvider provider, params object?[] args) { return string.Format(provider, format, args); } From 09ea18114734102d467444cdc9935f56492445b1 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Fri, 11 Jan 2019 19:40:09 +0100 Subject: [PATCH 07/25] not nullable in Signum.Entities --- Signum.Entities/Basics/Exception.cs | 48 ++++--- Signum.Entities/Basics/Operation.cs | 11 +- Signum.Entities/Basics/OperationLog.cs | 9 +- Signum.Entities/Basics/PropertyRouteEntity.cs | 7 +- Signum.Entities/Basics/QueryEntity.cs | 7 +- Signum.Entities/Basics/SemiSymbol.cs | 19 +-- Signum.Entities/Basics/Symbol.cs | 9 +- Signum.Entities/Basics/Type.cs | 11 +- Signum.Entities/DynamicQuery/Column.cs | 11 +- .../DynamicQuery/QueryDescription.cs | 131 +++--------------- Signum.Entities/DynamicQuery/Requests.cs | 1 + .../DynamicQuery/Tokens/AsTypeToken.cs | 10 +- .../DynamicQuery/Tokens/ColumnToken.cs | 2 +- .../DynamicQuery/Tokens/ExtensionToken.cs | 8 +- .../FieldNotificationAttributes.cs | 29 ++-- Signum.Entities/MList.cs | 2 + Signum.Entities/ModifiableEntity.cs | 11 +- Signum.Entities/PrimaryKey.cs | 18 +-- Signum.Entities/PropertyAttributes.cs | 2 +- .../EntityStructuralEqualityComparer.cs | 59 ++++---- Signum.Entities/Reflection/Reflector.cs | 32 ++--- Signum.Entities/Signum.Entities.csproj | 2 +- Signum.Entities/SystemTime.cs | 4 +- Signum.Entities/ValidationAttributes.cs | 97 ++++++------- Signum.Entities/Validator.cs | 50 +++---- 25 files changed, 249 insertions(+), 341 deletions(-) diff --git a/Signum.Entities/Basics/Exception.cs b/Signum.Entities/Basics/Exception.cs index 372fd61e12..49c40de353 100644 --- a/Signum.Entities/Basics/Exception.cs +++ b/Signum.Entities/Basics/Exception.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using Signum.Utilities; using System.Threading; @@ -11,25 +11,27 @@ public class ExceptionEntity : Entity { public const string ExceptionDataKey = "exceptionEntity"; +#pragma warning disable CS8618 // Non-nullable field is uninitialized. public ExceptionEntity() { } public ExceptionEntity(Exception ex) { this.ExceptionType = ex.GetType().Name; - this.ExceptionMessage = ex.Message; - this.StackTrace = ex.StackTrace; + this.ExceptionMessage = ex.Message!; + this.StackTrace = ex.StackTrace!; this.ThreadId = Thread.CurrentThread.ManagedThreadId; ex.Data[ExceptionDataKey] = this; this.MachineName = System.Environment.MachineName; this.ApplicationName = AppDomain.CurrentDomain.FriendlyName; } +#pragma warning restore CS8618 // Non-nullable field is uninitialized. public DateTime CreationDate { get; private set; } = TimeZoneManager.Now; [NotNullable, SqlDbType(Size = 100)] - public string ExceptionType { get; set; } + public string? ExceptionType { get; set; } - [NotNullable, SqlDbType(Size = int.MaxValue)] + [SqlDbType(Size = int.MaxValue)] string exceptionMessage; public string ExceptionMessage { @@ -43,7 +45,7 @@ public string ExceptionMessage public int ExceptionMessageHash { get; private set; } - [NotNullable, SqlDbType(Size = int.MaxValue)] + [SqlDbType(Size = int.MaxValue)] string stackTrace; public string StackTrace { @@ -59,52 +61,52 @@ public string StackTrace public int ThreadId { get; set; } - public Lite User { get; set; } + public Lite? User { get; set; } [SqlDbType(Size = 100)] - public string Environment { get; set; } + public string? Environment { get; set; } [SqlDbType(Size = 100)] - public string Version { get; set; } + public string? Version { get; set; } [SqlDbType(Size = 300)] - public string UserAgent { get; set; } + public string? UserAgent { get; set; } [SqlDbType(Size = int.MaxValue)] - public string RequestUrl { get; set; } + public string? RequestUrl { get; set; } [SqlDbType(Size = 100)] - public string ControllerName { get; set; } + public string? ControllerName { get; set; } [SqlDbType(Size = 100)] - public string ActionName { get; set; } + public string? ActionName { get; set; } [SqlDbType(Size = int.MaxValue)] - public string UrlReferer { get; set; } + public string? UrlReferer { get; set; } [SqlDbType(Size = 100)] - public string MachineName { get; set; } + public string? MachineName { get; set; } [SqlDbType(Size = 100)] - public string ApplicationName { get; set; } + public string? ApplicationName { get; set; } [SqlDbType(Size = 100)] - public string UserHostAddress { get; set; } + public string? UserHostAddress { get; set; } [SqlDbType(Size = 100)] - public string UserHostName { get; set; } + public string? UserHostName { get; set; } [SqlDbType(Size = int.MaxValue)] - public string Form { get; set; } + public string? Form { get; set; } [SqlDbType(Size = int.MaxValue)] - public string QueryString { get; set; } + public string? QueryString { get; set; } [SqlDbType(Size = int.MaxValue)] - public string Session { get; set; } + public string? Session { get; set; } [SqlDbType(Size = int.MaxValue)] - public string Data { get; set; } + public string? Data { get; set; } public int HResult { get; internal set; } @@ -157,6 +159,7 @@ public class DeleteLogParametersEmbedded : EmbeddedEntity public int? PauseTime { get; set; } = 5000; } +#pragma warning disable CS8618 // Non-nullable field is uninitialized. [Serializable] public class DeleteLogsTypeOverridesEmbedded : EmbeddedEntity { @@ -169,4 +172,5 @@ public class DeleteLogsTypeOverridesEmbedded : EmbeddedEntity [Unit("Days"), NumberIsValidator(ComparisonType.GreaterThanOrEqualTo, 0)] public int? CleanLogsWithMoreThan { get; set; } = 30 * 6; } +#pragma warning restore CS8618 // Non-nullable field is uninitialized. } diff --git a/Signum.Entities/Basics/Operation.cs b/Signum.Entities/Basics/Operation.cs index 4362253d19..b7da310566 100644 --- a/Signum.Entities/Basics/Operation.cs +++ b/Signum.Entities/Basics/Operation.cs @@ -205,6 +205,13 @@ public interface DeleteSymbol : IEntityOperationSymbolContainer [Serializable] public class OperationInfo { + public OperationInfo(OperationSymbol symbol, OperationType type) + { + this.OperationSymbol = symbol; + this.OperationType = type; + } + + public OperationSymbol OperationSymbol { get; internal set; } public OperationType OperationType { get; internal set; } @@ -214,8 +221,8 @@ public class OperationInfo public bool? HasCanExecute { get; internal set; } public bool Returns { get; internal set; } - public Type ReturnType { get; internal set; } - public Type BaseType { get; internal set; } + public Type? ReturnType { get; internal set; } + public Type? BaseType { get; internal set; } public override string ToString() { diff --git a/Signum.Entities/Basics/OperationLog.cs b/Signum.Entities/Basics/OperationLog.cs index a0a18c3311..61b91df511 100644 --- a/Signum.Entities/Basics/OperationLog.cs +++ b/Signum.Entities/Basics/OperationLog.cs @@ -1,22 +1,21 @@ -using System; +using System; using Signum.Utilities; using System.Linq.Expressions; namespace Signum.Entities.Basics { +#pragma warning disable CS8618 // Non-nullable field is uninitialized. [Serializable, EntityKind(EntityKind.System, EntityData.Transactional), TicksColumn(false), InTypeScript(Undefined = false)] public class OperationLogEntity : Entity { [ImplementedByAll] - public Lite Target { get; set; } + public Lite? Target { get; set; } [ImplementedByAll] - public Lite Origin { get; set; } + public Lite? Origin { get; set; } - [NotNullValidator] public OperationSymbol Operation { get; set; } - [NotNullValidator] public Lite User { get; set; } public DateTime Start { get; set; } diff --git a/Signum.Entities/Basics/PropertyRouteEntity.cs b/Signum.Entities/Basics/PropertyRouteEntity.cs index 17f1380663..88aedb04ab 100644 --- a/Signum.Entities/Basics/PropertyRouteEntity.cs +++ b/Signum.Entities/Basics/PropertyRouteEntity.cs @@ -1,14 +1,13 @@ -using System; +using System; using Signum.Utilities; using System.Linq.Expressions; namespace Signum.Entities.Basics { +#pragma warning disable CS8618 // Non-nullable field is uninitialized. [Serializable, EntityKind(EntityKind.SystemString, EntityData.Master), TicksColumn(false), InTypeScript(Undefined = false)] public class PropertyRouteEntity : Entity { - public PropertyRouteEntity() { } - [field: Ignore] PropertyRoute route; [HiddenProperty] @@ -18,7 +17,7 @@ public PropertyRoute Route set { route = value; } } - [StringLengthValidator(AllowNulls = false, Min = 1, Max = 100)] + [StringLengthValidator(Min = 1, Max = 100)] public string Path { get; set; } [NotNullValidator] diff --git a/Signum.Entities/Basics/QueryEntity.cs b/Signum.Entities/Basics/QueryEntity.cs index 15bf38704d..aba91f425f 100644 --- a/Signum.Entities/Basics/QueryEntity.cs +++ b/Signum.Entities/Basics/QueryEntity.cs @@ -1,14 +1,15 @@ -using System; +using System; using Signum.Utilities; using System.Linq.Expressions; namespace Signum.Entities.Basics { +#pragma warning disable CS8618 // Non-nullable field is uninitialized. [Serializable, EntityKind(EntityKind.SystemString, EntityData.Master), TicksColumn(false), InTypeScript(Undefined = false)] public class QueryEntity : Entity { [UniqueIndex] - [StringLengthValidator(AllowNulls = false, Min = 3, Max = 100)] + [StringLengthValidator(Min = 3, Max = 100)] public string Key { get; set; } public static Func GetEntityImplementations; @@ -20,4 +21,4 @@ public override string ToString() return ToStringExpression.Evaluate(this); } } -} \ No newline at end of file +} diff --git a/Signum.Entities/Basics/SemiSymbol.cs b/Signum.Entities/Basics/SemiSymbol.cs index 312bb333d0..9bcae8c658 100644 --- a/Signum.Entities/Basics/SemiSymbol.cs +++ b/Signum.Entities/Basics/SemiSymbol.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -7,6 +7,7 @@ namespace Signum.Entities.Basics { +#pragma warning disable CS8618 // Non-nullable field is uninitialized. [Serializable, EntityKind(EntityKind.SystemString, EntityData.Master), TicksColumn(false)] public abstract class SemiSymbol : Entity { @@ -44,28 +45,28 @@ public SemiSymbol(Type declaringType, string fieldName) var dic = FromDatabase.TryGetC(this.GetType()); if (dic != null) { - SemiSymbol semiS = dic.TryGetC(this.Key); + SemiSymbol? semiS = dic.TryGetC(this.Key!); if (semiS != null) this.SetIdAndProps(semiS); } } [Ignore] - FieldInfo fieldInfo; + FieldInfo? fieldInfo; [HiddenProperty] - public FieldInfo FieldInfo + public FieldInfo? FieldInfo { get { return fieldInfo; } internal set { fieldInfo = value; } } [UniqueIndex(AllowMultipleNulls = true)] - [StringLengthValidator(AllowNulls = true, Min = 3, Max = 200)] - public string Key { get; set; } + [StringLengthValidator(Min = 3, Max = 200)] + public string? Key { get; set; } - internal string NiceToString() + internal string? NiceToString() { - return this.FieldInfo.NiceName(); + return this.FieldInfo?.NiceName(); } @@ -92,7 +93,7 @@ static SemiSymbol() .Any(a => typeof(SemiSymbol).IsAssignableFrom(a.FieldType)) ? DescriptionOptions.Members : (DescriptionOptions?)null; } - [StringLengthValidator(AllowNulls = false, Min = 3, Max = 100)] + [StringLengthValidator(Min = 3, Max = 100)] public string Name { get; set; } static Expression> ToStringExpression = e => e.Name; diff --git a/Signum.Entities/Basics/Symbol.cs b/Signum.Entities/Basics/Symbol.cs index e2ec03fff6..3c25ebf05c 100644 --- a/Signum.Entities/Basics/Symbol.cs +++ b/Signum.Entities/Basics/Symbol.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Reflection; @@ -6,6 +6,7 @@ namespace Signum.Entities { +#pragma warning disable CS8618 // Non-nullable field is uninitialized. [Serializable, EntityKind(EntityKind.SystemString, EntityData.Master), TicksColumn(false), InTypeScript(Undefined = false)] public abstract class Symbol : Entity { @@ -33,8 +34,8 @@ public Symbol(Type declaringType, string fieldName) catch (Exception e) when (StartParameters.IgnoredCodeErrors != null) { //Could happend if Dynamic code has a duplicated name - this.fieldInfo = null; - this.Key = null; + this.fieldInfo = null!; + this.Key = null!; StartParameters.IgnoredCodeErrors.Add(e); return; } @@ -59,7 +60,7 @@ public FieldInfo FieldInfo [UniqueIndex] - [StringLengthValidator(AllowNulls = false, Min = 3, Max = 200)] + [StringLengthValidator(Min = 3, Max = 200)] public string Key { get; set; } static Expression> ToStringExpression = e => e.Key; diff --git a/Signum.Entities/Basics/Type.cs b/Signum.Entities/Basics/Type.cs index 35803e32ce..7d05422b92 100644 --- a/Signum.Entities/Basics/Type.cs +++ b/Signum.Entities/Basics/Type.cs @@ -1,22 +1,23 @@ -using System; +using System; using Signum.Utilities; using System.Linq.Expressions; namespace Signum.Entities.Basics { +#pragma warning disable CS8618 // Non-nullable field is uninitialized. [Serializable, EntityKind(EntityKind.System, EntityData.Master), TicksColumn(false), InTypeScript(Undefined = false)] public class TypeEntity : Entity { - [StringLengthValidator(AllowNulls = false, Max = 200), UniqueIndex] + [StringLengthValidator(Max = 200), UniqueIndex] public string TableName { get; set; } - [StringLengthValidator(AllowNulls = false, Max = 200), UniqueIndex] + [StringLengthValidator(Max = 200), UniqueIndex] public string CleanName { get; set; } - [StringLengthValidator(AllowNulls = false, Max = 200)] + [StringLengthValidator(Max = 200)] public string Namespace { get; set; } - [StringLengthValidator(AllowNulls = false, Max = 200)] + [StringLengthValidator(Max = 200)] public string ClassName { get; set; } static Expression> FullClassNameExpression = diff --git a/Signum.Entities/DynamicQuery/Column.cs b/Signum.Entities/DynamicQuery/Column.cs index efede96a8b..1bc2ba2e5b 100644 --- a/Signum.Entities/DynamicQuery/Column.cs +++ b/Signum.Entities/DynamicQuery/Column.cs @@ -6,22 +6,17 @@ namespace Signum.Entities.DynamicQuery [Serializable] public class Column { - string displayName; - public string DisplayName - { - get { return displayName; } - set { displayName = value; } - } + public string? DisplayName { get; set; } QueryToken token; public QueryToken Token { get { return token; } } public bool IsVisible = true; - public Column(QueryToken token, string displayName) + public Column(QueryToken token, string? displayName) { this.token = token; - this.displayName = displayName; + this.DisplayName = displayName; } public Column(ColumnDescription cd, object queryName) diff --git a/Signum.Entities/DynamicQuery/QueryDescription.cs b/Signum.Entities/DynamicQuery/QueryDescription.cs index 01f36e8eb5..f71a3f7424 100644 --- a/Signum.Entities/DynamicQuery/QueryDescription.cs +++ b/Signum.Entities/DynamicQuery/QueryDescription.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; @@ -8,85 +8,33 @@ namespace Signum.Entities.DynamicQuery [Serializable] public class QueryDescription { - object queryName; - public object QueryName - { - get { return queryName; } - } - - List columns; - public List Columns - { - get { return columns; } - } - - public QueryDescription() { } - + public object QueryName { get; private set; } + public List Columns { get; private set; } + public QueryDescription(object queryName, List columns) { - this.queryName = queryName; - this.columns = columns; + this.QueryName = queryName; + this.Columns = columns; } } [Serializable] - public class ColumnDescription :ISerializable + public class ColumnDescription { public const string Entity = "Entity"; + public string Name { get; internal set; } + public Type Type { get; internal set; } + public string? Unit { get; internal set; } + public string? Format { get; internal set; } + public Implementations? Implementations { get; internal set; } + public PropertyRoute[]? PropertyRoutes { get; internal set; } + public string DisplayName { get; internal set; } - string name; - public string Name - { - get { return name; } - internal set { name = value; } - } - - Type type; - public Type Type - { - get { return type; } - internal set { type = value; } - } - - string unit; - public string Unit - { - get { return unit; } - internal set { unit = value; } - } - - string format; - public string Format - { - get { return format; } - internal set { format = value; } - } - - Implementations? implementations; - public Implementations? Implementations - { - get { return implementations; } - internal set { implementations = value; } - } - - PropertyRoute[] propertyRoutes; - public PropertyRoute[] PropertyRoutes - { - get { return propertyRoutes; } - internal set { propertyRoutes = value; } - } - - string displayName; - public string DisplayName - { - get { return displayName; } - internal set { displayName = value; } - } - - public ColumnDescription(string name, Type type) + public ColumnDescription(string name, Type type, string displayName) { this.Name = name; this.Type = type; + this.DisplayName = displayName; } public bool IsEntity @@ -96,52 +44,7 @@ public bool IsEntity public override string ToString() { - return DisplayName; - } - - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("name", name); - info.AddValue("type", type.AssemblyQualifiedName); - - if (unit != null) - info.AddValue("unit", unit); - - if (format != null) - info.AddValue("format", format); - - if (implementations != null) - info.AddValue("implementations", implementations); - - if (propertyRoutes != null) - { - if (propertyRoutes.Length == 1) - info.AddValue("propertyRoute", propertyRoutes.Single()); - else - info.AddValue("propertyRoutes", propertyRoutes); - } - - if (displayName != null) - info.AddValue("displayName", displayName); - } - - - ColumnDescription(SerializationInfo info, StreamingContext context) - { - foreach (SerializationEntry entry in info) - { - switch (entry.Name) - { - case "name": name = (string)entry.Value; break; - case "type": type = Type.GetType((string)entry.Value); break; - case "unit": unit = (string)entry.Value; break; - case "format": format = (string)entry.Value; break; - case "implementations": implementations = (Implementations)entry.Value; break; - case "propertyRoutes": propertyRoutes = (PropertyRoute[])entry.Value; break; - case "propertyRoute": propertyRoutes = new[] { (PropertyRoute)entry.Value }; break; - case "displayName": displayName = (string)entry.Value; break; - } - } + return DisplayName!; } } } diff --git a/Signum.Entities/DynamicQuery/Requests.cs b/Signum.Entities/DynamicQuery/Requests.cs index 326f3f6e50..c5ac1a62f7 100644 --- a/Signum.Entities/DynamicQuery/Requests.cs +++ b/Signum.Entities/DynamicQuery/Requests.cs @@ -3,6 +3,7 @@ using System.Linq; using Signum.Utilities; +#pragma warning disable CS8618 // Non-nullable field is uninitialized. namespace Signum.Entities.DynamicQuery { [Serializable] diff --git a/Signum.Entities/DynamicQuery/Tokens/AsTypeToken.cs b/Signum.Entities/DynamicQuery/Tokens/AsTypeToken.cs index 62ac1ac70e..40ab75ba78 100644 --- a/Signum.Entities/DynamicQuery/Tokens/AsTypeToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/AsTypeToken.cs @@ -69,13 +69,13 @@ public override string? Unit public override string? IsAllowed() { - var parent = parent.IsAllowed(); - var routes = GetPropertyRoute()!.IsAllowed(); + var parentAllowed = this.parent.IsAllowed(); + var routeAllowed = GetPropertyRoute()!.IsAllowed(); - if (parent.HasText() && routes.HasText()) - QueryTokenMessage.And.NiceToString().CombineIfNotEmpty(parent, routes); + if (parentAllowed.HasText() && routeAllowed.HasText()) + QueryTokenMessage.And.NiceToString().CombineIfNotEmpty(parentAllowed, routeAllowed); - return parent ?? routes; + return parentAllowed ?? routeAllowed; } public override PropertyRoute? GetPropertyRoute() diff --git a/Signum.Entities/DynamicQuery/Tokens/ColumnToken.cs b/Signum.Entities/DynamicQuery/Tokens/ColumnToken.cs index e4b214e763..7730f1c733 100644 --- a/Signum.Entities/DynamicQuery/Tokens/ColumnToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/ColumnToken.cs @@ -117,7 +117,7 @@ protected override List SubTokensOverride(SubTokensOptions options) if (Column.PropertyRoutes != null) return Column.PropertyRoutes[0]; //HACK: compatibility with IU entitiy elements - Type type = Lite.Extract(Type); // Useful? + Type? type = Lite.Extract(Type); // Useful? if (type != null && type.IsIEntity()) { var implementations = Column.Implementations; diff --git a/Signum.Entities/DynamicQuery/Tokens/ExtensionToken.cs b/Signum.Entities/DynamicQuery/Tokens/ExtensionToken.cs index f0f44998c6..b3c64cd87f 100644 --- a/Signum.Entities/DynamicQuery/Tokens/ExtensionToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/ExtensionToken.cs @@ -109,12 +109,12 @@ protected override Expression BuildExpressionInternal(BuildExpressionContext con string? isAllowed; public override string? IsAllowed() { - string? parent = parent.IsAllowed(); + string? parentAllowed = this.parent.IsAllowed(); - if (isAllowed.HasText() && parent.HasText()) - return QueryTokenMessage.And.NiceToString().Combine(isAllowed!, parent!); + if (isAllowed.HasText() && parentAllowed.HasText()) + return QueryTokenMessage.And.NiceToString().Combine(isAllowed!, parentAllowed!); - return isAllowed ?? parent; + return isAllowed ?? parentAllowed; } public override QueryToken Clone() diff --git a/Signum.Entities/FieldNotificationAttributes.cs b/Signum.Entities/FieldNotificationAttributes.cs index a3dff7f371..777d981ff6 100644 --- a/Signum.Entities/FieldNotificationAttributes.cs +++ b/Signum.Entities/FieldNotificationAttributes.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -26,9 +26,9 @@ internal static class AttributeManager where T : Attribute { //Consider using ImmutableAVLTree instead - readonly static Dictionary fieldAndProperties = new Dictionary(); + readonly static Dictionary fieldAndProperties = new Dictionary(); - static TypeAttributePack GetFieldsAndProperties(Type type) + static TypeAttributePack? GetFieldsAndProperties(Type type) { lock (fieldAndProperties) { @@ -39,18 +39,17 @@ static TypeAttributePack GetFieldsAndProperties(Type type) if (list.Count == 0) return null; - return new TypeAttributePack - { - Fields = list.Select(fi => ReflectionTools.CreateGetterUntyped(type, fi)).ToArray(), - PropertyNames = list.Select(fi => Reflector.FindPropertyInfo(fi).Name).ToArray() - }; + return new TypeAttributePack( + fields: list.Select(fi => ReflectionTools.CreateGetterUntyped(type, fi)).ToArray(), + propertyNames: list.Select(fi => Reflector.FindPropertyInfo(fi).Name).ToArray() + ); }); } } public static bool FieldContainsAttribute(Type type, PropertyInfo pi) { - TypeAttributePack pack = GetFieldsAndProperties(type); + TypeAttributePack? pack = GetFieldsAndProperties(type); if (pack == null) return false; @@ -62,7 +61,7 @@ public static bool FieldContainsAttribute(Type type, PropertyInfo pi) public static object[] FieldsWithAttribute(ModifiableEntity entity) { - TypeAttributePack pack = GetFieldsAndProperties(entity.GetType()); + TypeAttributePack? pack = GetFieldsAndProperties(entity.GetType()); if (pack == null) return EmptyArray; @@ -70,9 +69,9 @@ public static object[] FieldsWithAttribute(ModifiableEntity entity) return pack.Fields.Select(f => f(entity)).ToArray(); } - public static string FindPropertyName(ModifiableEntity entity, object fieldValue) + public static string? FindPropertyName(ModifiableEntity entity, object fieldValue) { - TypeAttributePack pack = GetFieldsAndProperties(entity.GetType()); + TypeAttributePack? pack = GetFieldsAndProperties(entity.GetType()); if (pack == null) return null; @@ -90,5 +89,11 @@ internal class TypeAttributePack { public Func[] Fields; public string[] PropertyNames; + + public TypeAttributePack(Func[] fields, string[] propertyNames) + { + Fields = fields; + PropertyNames = propertyNames; + } } } diff --git a/Signum.Entities/MList.cs b/Signum.Entities/MList.cs index a70f8c47ba..db3590bf3b 100644 --- a/Signum.Entities/MList.cs +++ b/Signum.Entities/MList.cs @@ -780,6 +780,7 @@ public void AssignAndPostRetrieving(IMListPrivate newList) } +#pragma warning disable CS8618 // Non-nullable field is uninitialized. public class MListElement where E : Entity { public PrimaryKey RowId { get; set; } @@ -792,6 +793,7 @@ public override string ToString() return $"MListEntity: ({nameof(RowId)}:{RowId}, {nameof(Order)}:{Order}, {nameof(Parent)}:{Parent}, {nameof(Element)}:{Element})"; } } +#pragma warning restore CS8618 // Non-nullable field is uninitialized. public interface IMListPrivate { diff --git a/Signum.Entities/ModifiableEntity.cs b/Signum.Entities/ModifiableEntity.cs index 0fdf2ab85e..a8eb69c778 100644 --- a/Signum.Entities/ModifiableEntity.cs +++ b/Signum.Entities/ModifiableEntity.cs @@ -174,7 +174,7 @@ protected virtual void RebindEvents() protected virtual void ChildCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) { - string propertyName = AttributeManager.FindPropertyName(this, sender); + string? propertyName = AttributeManager.FindPropertyName(this, sender); if (propertyName != null) NotifyPrivate(propertyName); @@ -327,7 +327,7 @@ public string? Error public string? PropertyCheck(string propertyName) { - IPropertyValidator pp = Validator.TryGetPropertyValidator(GetType(), propertyName); + IPropertyValidator? pp = Validator.TryGetPropertyValidator(GetType(), propertyName); if (pp == null) return null; //Hidden properties @@ -345,7 +345,7 @@ protected static void Validate(Expression> property, Func FullIntegrityCheck() + public Dictionary? FullIntegrityCheck() { var graph = GraphExplorer.FromRoot(this); return GraphExplorer.FullIntegrityCheck(graph); @@ -450,10 +450,11 @@ public IntegrityCheckWithEntity(IntegrityCheck integrityCheck, ModifiableEntity public override string ToString() { + var validators = Validator.GetPropertyValidators(Entity.GetType()); return $"{IntegrityCheck.Errors.Count} errors in {" ".CombineIfNotEmpty(IntegrityCheck.Type.Name, IntegrityCheck.Id)}\r\n" + IntegrityCheck.Errors.ToString(kvp => " {0} ({1}): {2}".FormatWith( - kvp.Key, - Validator.TryGetPropertyValidator(Entity.GetType(), kvp.Key).GetValueUntyped(Entity), + kvp.Key, + validators.GetOrThrow(kvp.Key).GetValueUntyped(Entity), kvp.Value), "\r\n"); } diff --git a/Signum.Entities/PrimaryKey.cs b/Signum.Entities/PrimaryKey.cs index b08c44416f..d40f79dc6e 100644 --- a/Signum.Entities/PrimaryKey.cs +++ b/Signum.Entities/PrimaryKey.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; @@ -38,7 +38,7 @@ public static void Import(Dictionary dic) PrimaryKeyType.ImportDefinitions(dic); } - public readonly string VariableName; //Used for Sync scenarios + public readonly string? VariableName; //Used for Sync scenarios public readonly IComparable Object; public PrimaryKey(IComparable obj) @@ -226,9 +226,9 @@ public static explicit operator DateTime(PrimaryKey key) public static bool TryParse(string value, Type entityType, out PrimaryKey id) { - if (ReflectionTools.TryParse(value, Type(entityType), out object val)) + if (ReflectionTools.TryParse(value, Type(entityType), out object? val)) { - id = new PrimaryKey((IComparable)val); + id = new PrimaryKey((IComparable)val!); return true; } else @@ -240,7 +240,7 @@ public static bool TryParse(string value, Type entityType, out PrimaryKey id) public static PrimaryKey Parse(string value, Type entityType) { - return new PrimaryKey((IComparable)ReflectionTools.Parse(value, Type(entityType))); + return new PrimaryKey((IComparable)ReflectionTools.Parse(value, Type(entityType))!); } public static PrimaryKey? Wrap(IComparable value) @@ -251,7 +251,7 @@ public static PrimaryKey Parse(string value, Type entityType) return new PrimaryKey(value); } - public static IComparable Unwrap(PrimaryKey? id) + public static IComparable? Unwrap(PrimaryKey? id) { if (id == null) return null; @@ -259,7 +259,7 @@ public static IComparable Unwrap(PrimaryKey? id) return id.Value.Object; } - public static string UnwrapToString(PrimaryKey? id) + public static string? UnwrapToString(PrimaryKey? id) { if (id == null) return null; @@ -274,8 +274,8 @@ public string ToString(string format) private PrimaryKey(SerializationInfo info, StreamingContext ctxt) { - this.Object = null; - this.VariableName = null; + this.Object = null!; + this.VariableName = null!; foreach (SerializationEntry item in info) { switch (item.Name) diff --git a/Signum.Entities/PropertyAttributes.cs b/Signum.Entities/PropertyAttributes.cs index 3982a3005b..6c649a52f8 100644 --- a/Signum.Entities/PropertyAttributes.cs +++ b/Signum.Entities/PropertyAttributes.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; namespace Signum.Entities diff --git a/Signum.Entities/Reflection/EntityStructuralEqualityComparer.cs b/Signum.Entities/Reflection/EntityStructuralEqualityComparer.cs index 230b5de1eb..9d9a5dd53c 100644 --- a/Signum.Entities/Reflection/EntityStructuralEqualityComparer.cs +++ b/Signum.Entities/Reflection/EntityStructuralEqualityComparer.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -11,32 +11,32 @@ namespace Signum.Entities.Reflection public interface IEqualityComparerResolver { - IEqualityComparer GetEqualityComparer(Type type, PropertyInfo pi); + IEqualityComparer GetEqualityComparer(Type type, PropertyInfo? pi); } public interface ICompletableComparer { - void Complete(IEqualityComparerResolver resolver, PropertyInfo pi); + void Complete(IEqualityComparerResolver resolver, PropertyInfo? pi); } public class EntityStructuralEqualityComparer : EqualityComparer, ICompletableComparer where T : ModifiableEntity { public Dictionary> Properties; - public Dictionary Mixins; + public Dictionary? Mixins; public EntityStructuralEqualityComparer() { + this.Properties = null!; } - public void Complete(IEqualityComparerResolver resolver, PropertyInfo pi) + public void Complete(IEqualityComparerResolver resolver, PropertyInfo? pi) { Properties = MemberEntryFactory.GenerateList(MemberOptions.Properties | MemberOptions.Typed | MemberOptions.Getter) .Where(p => !((PropertyInfo)p.MemberInfo).HasAttribute()) - .ToDictionary(a => a.Name, a => new PropertyComparer((PropertyInfo)a.MemberInfo, a.Getter) - { - Comparer = resolver.GetEqualityComparer(((PropertyInfo)a.MemberInfo).PropertyType, ((PropertyInfo)a.MemberInfo)) - }); + .ToDictionary(a => a.Name, a => new PropertyComparer( + propertyInfo: (PropertyInfo)a.MemberInfo, a.Getter!, + comparer: resolver.GetEqualityComparer(((PropertyInfo)a.MemberInfo).PropertyType, (PropertyInfo)a.MemberInfo))); Mixins = !typeof(Entity).IsAssignableFrom(typeof(T)) ? null : MixinDeclarations.GetMixinDeclarations(typeof(T)).ToDictionary(t => t, t => resolver.GetEqualityComparer(t, null)); @@ -97,20 +97,22 @@ public override int GetHashCode(T obj) } public class ClassStructuralEqualityComparer : EqualityComparer, ICompletableComparer + where T: object { public Dictionary> Properties; public ClassStructuralEqualityComparer() { + this.Properties = null!; } - public void Complete(IEqualityComparerResolver resolver, PropertyInfo pi) + public void Complete(IEqualityComparerResolver resolver, PropertyInfo? pi) { Properties = MemberEntryFactory.GenerateList(MemberOptions.Properties | MemberOptions.Typed | MemberOptions.Getter) - .ToDictionary(a => a.Name, a => new PropertyComparer((PropertyInfo)a.MemberInfo, a.Getter) - { - Comparer = resolver.GetEqualityComparer(((PropertyInfo)a.MemberInfo).PropertyType, ((PropertyInfo)a.MemberInfo)) - }); ; + .ToDictionary(a => a.Name, a => new PropertyComparer( + propertyInfo: (PropertyInfo)a.MemberInfo, + getter: a.Getter!, + comparer: resolver.GetEqualityComparer(((PropertyInfo)a.MemberInfo).PropertyType, (PropertyInfo)a.MemberInfo))); } public override bool Equals(T x, T y) @@ -144,23 +146,22 @@ public override int GetHashCode(T obj) return result; } - - } public class PropertyComparer { - public PropertyInfo MemberInfo { get; set; } - public Func Getter { get; set; } + public PropertyInfo PropertyInfo { get; set; } + public Func Getter { get; set; } public IEqualityComparer Comparer { get; set; } - public PropertyComparer(PropertyInfo memberInfo, Func getter) + public PropertyComparer(PropertyInfo propertyInfo, Func getter, IEqualityComparer comparer) { + this.PropertyInfo = propertyInfo; this.Getter = getter; - this.MemberInfo = memberInfo; + this.Comparer = comparer; } - public override string ToString() => $"{MemberInfo} -> {Comparer}"; + public override string ToString() => $"{PropertyInfo} -> {Comparer}"; } public class SortedListEqualityComparer : EqualityComparer>, ICompletableComparer @@ -169,9 +170,10 @@ public class SortedListEqualityComparer : EqualityComparer>, IComple public SortedListEqualityComparer() { + this.ElementComparer = null!; } - public void Complete(IEqualityComparerResolver resolver, PropertyInfo pi) + public void Complete(IEqualityComparerResolver resolver, PropertyInfo? pi) { ElementComparer = (IEqualityComparer)resolver.GetEqualityComparer(typeof(T), pi); } @@ -214,9 +216,10 @@ public class UnsortedListEqualityComparer : EqualityComparer>, IComp public UnsortedListEqualityComparer() { + this.ElementComparer = null!; } - public void Complete(IEqualityComparerResolver resolver, PropertyInfo pi) + public void Complete(IEqualityComparerResolver resolver, PropertyInfo? pi) { ElementComparer = (IEqualityComparer)resolver.GetEqualityComparer(typeof(T), pi); } @@ -264,8 +267,8 @@ public override int GetHashCode(IList obj) public abstract class EqualityComparerResolverWithCache : IEqualityComparerResolver { - Dictionary<(Type, PropertyInfo), IEqualityComparer> cache = new Dictionary<(Type, PropertyInfo), IEqualityComparer>(); - public virtual IEqualityComparer GetEqualityComparer(Type type, PropertyInfo pi) + Dictionary<(Type, PropertyInfo?), IEqualityComparer> cache = new Dictionary<(Type, PropertyInfo?), IEqualityComparer>(); + public virtual IEqualityComparer GetEqualityComparer(Type type, PropertyInfo? pi) { if (cache.TryGetValue((type, pi), out var comparer)) return comparer; @@ -277,16 +280,16 @@ public virtual IEqualityComparer GetEqualityComparer(Type type, PropertyInfo pi) if (comp is ICompletableComparer cc) cc.Complete(this, pi); - return comp; + return comp! /*CSBUG*/; } } - protected abstract IEqualityComparer GetEqualityComparerInternal(Type type, PropertyInfo pi); + protected abstract IEqualityComparer GetEqualityComparerInternal(Type type, PropertyInfo? pi); } public class DefaultEqualityComparerResolver : EqualityComparerResolverWithCache { - protected override IEqualityComparer GetEqualityComparerInternal(Type type, PropertyInfo pi) + protected override IEqualityComparer GetEqualityComparerInternal(Type type, PropertyInfo? pi) { if (typeof(ModifiableEntity).IsAssignableFrom(type)) { diff --git a/Signum.Entities/Reflection/Reflector.cs b/Signum.Entities/Reflection/Reflector.cs index a797c556ba..495d6658ce 100644 --- a/Signum.Entities/Reflection/Reflector.cs +++ b/Signum.Entities/Reflection/Reflector.cs @@ -209,7 +209,7 @@ public static MemberInfo[] GetMemberListUntyped(LambdaExpression lambdaToField) if (e is UnaryExpression ue && ue.NodeType == ExpressionType.Convert && ue.Type == typeof(object)) e = ue.Operand; - MemberInfo[] result = GetMemberListBase(e); + MemberInfo[] result = GetMemberListBase(e! /*CSBUG*/); return result; } @@ -219,7 +219,7 @@ public static MemberInfo[] GetMemberListBase(Expression e) return e.Follow(NextExpression).Select(GetMember).NotNull().Reverse().ToArray(); } - static Expression NextExpression(Expression e) + static Expression? NextExpression(Expression e) { switch (e.NodeType) { @@ -244,7 +244,7 @@ static Expression NextExpression(Expression e) static readonly string[] collectionMethods = new[] { "Element" }; - static MemberInfo GetMember(Expression e) + static MemberInfo? GetMember(Expression e) { switch (e.NodeType) { @@ -284,11 +284,11 @@ internal static FieldInfo FindFieldInfo(Type type, PropertyInfo value) } static readonly BindingFlags privateFlags = BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.NonPublic; - public static FieldInfo TryFindFieldInfo(Type type, PropertyInfo pi) + public static FieldInfo? TryFindFieldInfo(Type type, PropertyInfo pi) { - string prefix = pi.DeclaringType != type && pi.DeclaringType.IsInterface ? pi.DeclaringType.FullName + "." : null; + string? prefix = pi.DeclaringType != type && pi.DeclaringType.IsInterface ? pi.DeclaringType.FullName + "." : null; - FieldInfo fi = null; + FieldInfo? fi = null; for (Type tempType = type; tempType != null && fi == null; tempType = tempType.BaseType) { fi = tempType.GetField("<" + pi.Name + ">k__BackingField", privateFlags) ?? @@ -323,13 +323,13 @@ public static PropertyInfo FindPropertyInfo(FieldInfo fi) return pi; } - public static PropertyInfo TryFindPropertyInfo(FieldInfo fi) + public static PropertyInfo? TryFindPropertyInfo(FieldInfo fi) { using (HeavyProfiler.LogNoStackTrace("TryFindPropertyInfo", () => fi.Name)) { const BindingFlags flags = BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; - string propertyName = null; + string? propertyName = null; if (fi.Name.StartsWith("<")) { CheckSignumProcessed(fi); @@ -358,11 +358,11 @@ public static PropertyInfo TryFindPropertyInfo(FieldInfo fi) public static bool QueryableProperty(Type type, PropertyInfo pi) { - QueryablePropertyAttribute spa = pi.GetCustomAttribute(); + QueryablePropertyAttribute? spa = pi.GetCustomAttribute(); if (spa != null) return spa.AvailableForQueries; - FieldInfo fi = TryFindFieldInfo(type, pi); + FieldInfo? fi = TryFindFieldInfo(type, pi); if (fi != null && !fi.HasAttribute() && !pi.HasAttribute()) return true; @@ -372,7 +372,7 @@ public static bool QueryableProperty(Type type, PropertyInfo pi) return false; } - public static Func GetPropertyFormatter(string format, string unitName) + public static Func GetPropertyFormatter(string format, string unitName) { if (format != null) { @@ -390,7 +390,7 @@ public static Func GetPropertyFormatter(string format, str } } - public static string FormatString(PropertyRoute route) + public static string? FormatString(PropertyRoute route) { PropertyRoute simpleRoute = route.SimplifyToProperty(); @@ -424,7 +424,7 @@ public static string FormatString(PropertyRoute route) return FormatString(route.Type); } - public static string FormatString(Type type) + public static string? FormatString(Type type) { type = type.UnNullify(); if (type.IsEnum) @@ -450,11 +450,7 @@ public static string FormatString(Type type) } return null; } - - - - - + public static PropertyInfo PropertyInfo(this T entity, Expression> property) where T : ModifiableEntity { return ReflectionTools.GetPropertyInfo(property); diff --git a/Signum.Entities/Signum.Entities.csproj b/Signum.Entities/Signum.Entities.csproj index 429301ed45..715a252080 100644 --- a/Signum.Entities/Signum.Entities.csproj +++ b/Signum.Entities/Signum.Entities.csproj @@ -5,7 +5,7 @@ 8.0 true true - + true x64 diff --git a/Signum.Entities/SystemTime.cs b/Signum.Entities/SystemTime.cs index 19a749e645..5eb56edf23 100644 --- a/Signum.Entities/SystemTime.cs +++ b/Signum.Entities/SystemTime.cs @@ -1,4 +1,4 @@ -using Signum.Utilities; +using Signum.Utilities; using Signum.Utilities.DataStructures; using Signum.Utilities.Reflection; using System; @@ -111,7 +111,7 @@ public static Interval SystemPeriod(this MListElement mlis static MethodInfo miOverlaps = ReflectionTools.GetMethodInfo((Interval pair) => pair.Overlaps(new Interval())); - internal static Expression Overlaps(this NewExpression interval1, NewExpression interval2) + internal static Expression? Overlaps(this NewExpression interval1, NewExpression interval2) { if (interval1 == null) return null; diff --git a/Signum.Entities/ValidationAttributes.cs b/Signum.Entities/ValidationAttributes.cs index b4c6a94203..8098f0925b 100644 --- a/Signum.Entities/ValidationAttributes.cs +++ b/Signum.Entities/ValidationAttributes.cs @@ -18,13 +18,13 @@ namespace Signum.Entities [AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = true)] public abstract class ValidatorAttribute : Attribute { - public Func IsApplicable; - public Func ErrorMessage { get; set; } + public Func? IsApplicable; + public Func? ErrorMessage { get; set; } - public string UnlocalizableErrorMessage + public string? UnlocalizableErrorMessage { get { return ErrorMessage == null ? null : ErrorMessage(); } - set { ErrorMessage = () => value; } + set { ErrorMessage = () => value!; } } public int Order { get; set; } @@ -35,7 +35,7 @@ public string UnlocalizableErrorMessage //Used for documentation purposes only public abstract string HelpMessage { get; } - public string Error(ModifiableEntity entity, PropertyInfo property, object value) + public string? Error(ModifiableEntity entity, PropertyInfo property, object? value) { if (DisabledInModelBinder && Validator.InModelBinder) return null; @@ -43,7 +43,7 @@ public string Error(ModifiableEntity entity, PropertyInfo property, object value if (IsApplicable != null && !IsApplicable(entity)) return null; - string defaultError = OverrideError(value); + string? defaultError = OverrideError(value); if (defaultError == null) return null; @@ -61,12 +61,12 @@ public string Error(ModifiableEntity entity, PropertyInfo property, object value /// /// /// returns an string with the error message, using {0} if you want the property name to be inserted - protected abstract string OverrideError(object value); + protected abstract string? OverrideError(object? value); } public class NotNullValidatorAttribute : ValidatorAttribute { - protected override string OverrideError(object obj) + protected override string? OverrideError(object? obj) { if (obj == null) return ValidationMessage._0IsNotSet.NiceToString(); @@ -82,8 +82,6 @@ public override string HelpMessage public class StringLengthValidatorAttribute : ValidatorAttribute { - public bool AllowNulls { get; set; } - bool? allowLeadingSpaces; public bool AllowLeadingSpaces { @@ -114,17 +112,12 @@ public int Max set { max = value; } } - protected override string OverrideError(object value) + protected override string? OverrideError(object? value) { - string val = (string)value; + string val = (string)value!; if (string.IsNullOrEmpty(val)) - { - if (AllowNulls) - return null; - - return ValidationMessage._0IsNotSet.NiceToString(); - } + return null; if(!MultiLine && (val.Contains('\n') || val.Contains('\r'))) return ValidationMessage._0ShouldHaveJustOneLine.NiceToString(); @@ -154,11 +147,8 @@ public override string HelpMessage string result = min != -1 && max != -1 ? ValidationMessage.HaveBetween0And1Characters.NiceToString().FormatWith(min, max) : min != -1 ? ValidationMessage.HaveMinimum0Characters.NiceToString().FormatWith(min) : - max != -1 ? ValidationMessage.HaveMaximum0Characters.NiceToString().FormatWith(max) : null; - - if (AllowNulls) - result = result.Add(" ", ValidationMessage.OrBeNull.NiceToString()); - + max != -1 ? ValidationMessage.HaveMaximum0Characters.NiceToString().FormatWith(max) : ValidationMessage.BeAString.NiceToString(); + return result; } } @@ -188,9 +178,9 @@ public abstract string FormatName get; } - protected override string OverrideError(object value) + protected override string? OverrideError(object? value) { - string str = (string)value; + string? str = (string?)value; if (string.IsNullOrEmpty(str)) return null; @@ -271,7 +261,7 @@ public IdentifierValidatorAttribute(IdentifierType type) type == IdentifierType.PascalAscii ? PascalAscii : type == IdentifierType.Ascii ? Ascii: type == IdentifierType.International ? International : - null + throw new UnexpectedValueException(type) ) { this.type = type; @@ -362,9 +352,9 @@ public override string HelpMessage get { return ValidationMessage.HaveValid0Format.NiceToString().FormatWith(FormatName); } } - protected override string OverrideError(object value) + protected override string? OverrideError(object? value) { - string str = (string)value; + string? str = (string?)value; if (str == null) return null; @@ -395,7 +385,7 @@ public DecimalsValidatorAttribute(int decimalPlaces) this.DecimalPlaces = decimalPlaces; } - protected override string OverrideError(object value) + protected override string? OverrideError(object? value) { if (value == null) return null; @@ -456,7 +446,7 @@ public NumberIsValidatorAttribute(ComparisonType comparison, long number) this.number = number; } - protected override string OverrideError(object value) + protected override string? OverrideError(object? value) { if (value == null) return null; @@ -527,7 +517,7 @@ public NumberBetweenValidatorAttribute(long min, long max) this.max = max; } - protected override string OverrideError(object value) + protected override string? OverrideError(object? value) { if (value == null) return null; @@ -555,9 +545,9 @@ public override string HelpMessage public class NoRepeatValidatorAttribute : ValidatorAttribute { - protected override string OverrideError(object value) + protected override string? OverrideError(object? value) { - IList list = (IList)value; + IList? list = (IList?)value; if (list == null || list.Count <= 1) return null; string ex = list.Cast().GroupCount().Where(kvp => kvp.Value > 1).ToString(e => "{0} x {1}".FormatWith(e.Key, e.Value), ", "); @@ -571,14 +561,14 @@ public override string HelpMessage get { return ValidationMessage.HaveNoRepeatedElements.NiceToString(); } } - public static string ByKey(IEnumerable collection, Func keySelector) + public static string? ByKey(IEnumerable collection, Func keySelector) { var errors = collection.GroupBy(keySelector) .Select(gr => new { gr.Key, Count = gr.Count() }) .Where(a => a.Count > 1) .ToString(e => "{0} x {1}".FormatWith(e.Key, e.Count), ", "); - return errors.DefaultText(null); + return errors.DefaultText(null!); } } @@ -593,11 +583,11 @@ public CountIsValidatorAttribute(ComparisonType comparison, int number) this.number = number; } - protected override string OverrideError(object value) + protected override string? OverrideError(object? value) { - IList list = (IList)value; + IList? list = (IList?)value; - int val = list == null? 0: list.Count; + int val = list == null ? 0 : list.Count; if ((ComparisonType == ComparisonType.EqualTo && val.CompareTo(number) == 0) || (ComparisonType == ComparisonType.DistinctTo && val.CompareTo(number) != 0) || @@ -658,7 +648,7 @@ public DateTimePrecisionValidatorAttribute(DateTimePrecision precision) this.Precision = precision; } - protected override string OverrideError(object value) + protected override string? OverrideError(object? value) { if (value == null) return null; @@ -698,7 +688,7 @@ public override string HelpMessage public class DateInPastValidator : ValidatorAttribute { - protected override string OverrideError(object value) + protected override string? OverrideError(object? value) { if (value == null) return null; @@ -727,7 +717,7 @@ public TimeSpanPrecisionValidatorAttribute(DateTimePrecision precision) this.Precision = precision; } - protected override string OverrideError(object value) + protected override string? OverrideError(object? value) { if (value == null) return null; @@ -780,12 +770,12 @@ public StringCaseValidatorAttribute(StringCase textCase) this.textCase = textCase; } - protected override string OverrideError(object value) + protected override string? OverrideError(object? value) { - if (string.IsNullOrEmpty((string)value)) return null; - - string str = (string)value; - + string? str = (string?)value; + if (string.IsNullOrEmpty(str)) + return null; + if ((this.textCase == StringCase.Uppercase) && (str != str.ToUpper())) return ValidationMessage._0HasToBeUppercase.NiceToString(); @@ -819,7 +809,7 @@ public IsAssignableToValidatorAttribute(Type type) this.Type = type; } - protected override string OverrideError(object value) + protected override string? OverrideError(object? value) { if (value == null) return null; @@ -882,7 +872,7 @@ public void Add(S state, params bool?[] necessary) dictionary.Add(state, necessary); } - public string Validate(E entity, PropertyInfo pi) + public string? Validate(E entity, PropertyInfo pi) { return Validate(entity, pi, true); } @@ -896,9 +886,7 @@ public string Validate(E entity, PropertyInfo pi) return Necessary(state, index); } - - - public string Validate(E entity, PropertyInfo pi, bool showState) + public string? Validate(E entity, PropertyInfo pi, bool showState) { int index = propertyNames.IndexOf(pi.Name); if (index == -1) @@ -909,14 +897,14 @@ public string Validate(E entity, PropertyInfo pi, bool showState) return GetMessage(entity, state, showState, index); } - private string GetMessage(E entity, S state, bool showState, int index) + private string? GetMessage(E entity, S state, bool showState, int index) { bool? necessary = Necessary(state, index); if (necessary == null) return null; - object val = getters[index](entity); + object? val = getters[index](entity); if (val is IList && ((IList)val).Count == 0 || val is string && ((string)val).Length == 0) //both are indistinguible after retrieving val = null; @@ -950,7 +938,7 @@ public IEnumerator GetEnumerator() //just to use object initializer throw new NotImplementedException(); } - public string PreviewErrors(E entity, S targetState, bool showState) + public string? PreviewErrors(E entity, S targetState, bool showState) { string result = propertyNames.Select((pn, i) => GetMessage(entity, targetState, showState, i)).NotNull().ToString("\r\n"); @@ -1095,5 +1083,6 @@ public enum ValidationMessage _0IsEmpty, [Description("At least one value is needed")] _AtLeastOneValueIsNeeded, + BeAString, } } diff --git a/Signum.Entities/Validator.cs b/Signum.Entities/Validator.cs index bf7c186611..b4745de5de 100644 --- a/Signum.Entities/Validator.cs +++ b/Signum.Entities/Validator.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Signum.Utilities; @@ -60,9 +60,9 @@ public static PropertyValidator OverridePropertyValidator(Expression result = (PropertyValidator)dic?.TryGetC(pi.Name); + PropertyValidator? result = (PropertyValidator?)dic?.TryGetC(pi.Name); if (result == null) { @@ -82,7 +82,7 @@ public static PropertyValidator PropertyValidator(Expression result = (PropertyValidator)dic?.TryGetC(pi.Name); + PropertyValidator? result = (PropertyValidator?)dic?.TryGetC(pi.Name); if (result == null) throw new InvalidOperationException("{0} is not defined in {1}, try calling OverridePropertyValidator".FormatWith(pi.PropertyName(), typeof(T).TypeName())); @@ -90,15 +90,15 @@ public static PropertyValidator PropertyValidator(Expression Validators { get; } - string PropertyCheck(ModifiableEntity modifiableEntity); - object GetValueUntyped(ModifiableEntity entity); + string? PropertyCheck(ModifiableEntity modifiableEntity); + object? GetValueUntyped(ModifiableEntity entity); } public class PropertyValidator : IPropertyValidator where T : ModifiableEntity { - public Func GetValue { get; private set; } - public Action SetValue { get; private set; } + public Func GetValue { get; private set; } + public Action SetValue { get; private set; } public PropertyInfo PropertyInfo { get; private set; } public List Validators { get; private set; } - public Func IsApplicable { get; set; } - public Func IsApplicablePropertyValidation { get; set; } - public Func IsApplicableParentChildPropertyValidation { get; set; } - public Func IsApplicableStaticPropertyValidation { get; set; } + public Func? IsApplicable { get; set; } + public Func? IsApplicablePropertyValidation { get; set; } + public Func? IsApplicableParentChildPropertyValidation { get; set; } + public Func? IsApplicableStaticPropertyValidation { get; set; } - public Func StaticPropertyValidation { get; set; } + public Func? StaticPropertyValidation { get; set; } internal PropertyValidator(PropertyInfo pi) { @@ -162,8 +162,8 @@ internal PropertyValidator(PropertyInfo pi) this.Validators = pi.GetCustomAttributes(typeof(ValidatorAttribute), false).OfType().OrderBy(va => va.Order).ThenBy(va => va.GetType().Name).ToList(); - this.GetValue = ReflectionTools.CreateGetter(pi); - this.SetValue = ReflectionTools.CreateSetter(pi); + this.GetValue = ReflectionTools.CreateGetter(pi)!; + this.SetValue = ReflectionTools.CreateSetter(pi)!; } public void ReplaceValidators(params ValidatorAttribute[] validators) @@ -172,19 +172,19 @@ public void ReplaceValidators(params ValidatorAttribute[] validators) Validators.AddRange(validators); } - public string PropertyCheck(T entity) + public string? PropertyCheck(T entity) { if (IsApplicable != null && !IsApplicable(entity)) return null; if (Validators.Count > 0) { - object propertyValue = GetValue(entity); + object? propertyValue = GetValue(entity); //ValidatorAttributes foreach (var validator in Validators) { - string result = validator.Error(entity, PropertyInfo, propertyValue); + string? result = validator.Error(entity, PropertyInfo, propertyValue); if (result != null) return result; } @@ -193,7 +193,7 @@ public string PropertyCheck(T entity) //Internal Validation if (IsApplicablePropertyValidation == null || IsApplicablePropertyValidation(entity)) { - string result = entity.PropertyValidation(PropertyInfo); + string? result = entity.PropertyValidation(PropertyInfo); if (result != null) return result; } @@ -201,7 +201,7 @@ public string PropertyCheck(T entity) //Parent Validation if (IsApplicableParentChildPropertyValidation == null || IsApplicableParentChildPropertyValidation(entity)) { - string result = entity.OnParentChildPropertyValidation(PropertyInfo); + string? result = entity.OnParentChildPropertyValidation(PropertyInfo); if (result != null) return result; } @@ -234,7 +234,7 @@ public string PropertyCheck(T entity) return null; } - public string PropertyCheck(ModifiableEntity modifiableEntity) + public string? PropertyCheck(ModifiableEntity modifiableEntity) { return PropertyCheck((T)modifiableEntity); } @@ -248,7 +248,7 @@ public void IsApplicableValidator(Func isApplicable) where V : Valid validator.IsApplicable = m => isApplicable((T)m); } - public object GetValueUntyped(ModifiableEntity entity) + public object? GetValueUntyped(ModifiableEntity entity) { return GetValue((T)entity); } From 2c97532a4d2ebbf6fa42c01af7ca5cdd23c5e4f0 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Tue, 15 Jan 2019 08:14:59 +0100 Subject: [PATCH 08/25] not nullable (QueryBinder!) --- Signum.Engine/Administrator.cs | 83 ++-- Signum.Engine/Basics/TypeLogic.cs | 18 +- Signum.Engine/BulkInserter.cs | 27 +- Signum.Engine/Connection/Connector.cs | 16 +- Signum.Engine/Connection/Executor.cs | 16 +- Signum.Engine/Connection/SqlConnector.cs | 39 +- Signum.Engine/Database.cs | 67 ++- .../DynamicQuery/ColumnDescriptionFactory.cs | 40 +- .../DynamicQuery/ExpressionContainer.cs | 83 ++-- Signum.Engine/Engine/ProgressExtensions.cs | 28 +- Signum.Engine/Engine/SchemaSynchronizer.cs | 91 ++-- Signum.Engine/Engine/SqlBuilder.cs | 59 ++- Signum.Engine/Engine/SqlPreCommand.cs | 34 +- Signum.Engine/Engine/Synchronizer.cs | 70 +-- Signum.Engine/Linq/DbExpressions.Signum.cs | 43 +- Signum.Engine/Linq/DbExpressions.Sql.cs | 65 ++- Signum.Engine/Linq/DbQueryProvider.cs | 20 +- .../ChildProjectionFlattener.cs | 8 +- .../ExpressionVisitor/DbExpressionComparer.cs | 10 +- .../DbExpressionNominator.cs | 124 ++--- .../OverloadingSimplifier.cs | 6 +- .../Linq/ExpressionVisitor/QueryBinder.cs | 437 ++++++++++-------- .../Linq/ExpressionVisitor/QueryFilterer.cs | 4 +- Signum.Engine/Patterns/VirtualMList.cs | 28 +- Signum.Engine/Schema/EntityEvents.cs | 69 +-- Signum.Engine/Schema/FluentInclude.cs | 18 +- Signum.Engine/Schema/ObjectName.cs | 24 +- Signum.Engine/Schema/Schema.Basics.cs | 222 +++++---- Signum.Engine/Schema/Schema.Delete.cs | 2 +- Signum.Engine/Schema/Schema.Save.cs | 202 ++++---- Signum.Engine/Schema/Schema.cs | 167 +++---- .../Schema/SchemaBuilder/SchemaBuilder.cs | 191 ++++---- .../SchemaBuilder/SchemaBuilderSettings.cs | 2 +- Signum.Engine/Signum.Engine.csproj | 4 +- Signum.Entities/Basics/Type.cs | 10 +- .../Tokens/ExtensionDictionaryToken.cs | 15 +- .../DynamicQuery/Tokens/ExtensionToken.cs | 6 +- Signum.Entities/SystemTime.cs | 6 +- .../DataStructures/ImmutableStack.cs | 2 +- Signum.Utilities/Disposable.cs | 4 +- .../ExpressionTrees/ExpressionCleaner.cs | 32 +- .../Extensions/DateTimeExtensions.cs | 6 +- .../Extensions/EnumerableExtensions.cs | 8 +- .../Extensions/StreamExtensions.cs | 4 +- Signum.Utilities/Profiler/HeavyProfiler.cs | 12 +- .../Synchronization/CultureInfoUtils.cs | 14 +- 46 files changed, 1277 insertions(+), 1159 deletions(-) diff --git a/Signum.Engine/Administrator.cs b/Signum.Engine/Administrator.cs index c4c5e578bd..19cce5b203 100644 --- a/Signum.Engine/Administrator.cs +++ b/Signum.Engine/Administrator.cs @@ -1,4 +1,4 @@ -using Signum.Engine.Linq; +using Signum.Engine.Linq; using Signum.Engine.Maps; using Signum.Engine.SchemaInfoTables; using Signum.Entities; @@ -21,7 +21,7 @@ public static void TotalGeneration() foreach (var db in Schema.Current.DatabaseNames()) Connector.Current.CleanDatabase(db); - SqlPreCommandConcat totalScript = (SqlPreCommandConcat)Schema.Current.GenerationScipt(); + SqlPreCommandConcat totalScript = (SqlPreCommandConcat)Schema.Current.GenerationScipt()!; foreach (SqlPreCommand command in totalScript.Commands) { command.ExecuteLeaves(); @@ -72,12 +72,12 @@ private static string GenerateColumnCode(DiffColumn c) return sb.ToString(); } - public static SqlPreCommand TotalGenerationScript() + public static SqlPreCommand? TotalGenerationScript() { return Schema.Current.GenerationScipt(); } - public static SqlPreCommand TotalSynchronizeScript(bool interactive = true, bool schemaOnly = false) + public static SqlPreCommand? TotalSynchronizeScript(bool interactive = true, bool schemaOnly = false) { var command = Schema.Current.SynchronizationScript(interactive, schemaOnly); @@ -120,8 +120,8 @@ public static void CreateTemporaryIndex(Expression> fields, b SqlBuilder.CreateIndex(index, checkUnique: null).ExecuteLeaves(); } - internal static readonly ThreadVariable sysViewDatabase = Statics.ThreadVariable("viewDatabase"); - public static IDisposable OverrideDatabaseInSysViews(DatabaseName database) + internal static readonly ThreadVariable sysViewDatabase = Statics.ThreadVariable("viewDatabase"); + public static IDisposable OverrideDatabaseInSysViews(DatabaseName? database) { var old = sysViewDatabase.Value; sysViewDatabase.Value = database; @@ -143,10 +143,10 @@ public static bool ExistsTable(ITable table) { SchemaName schema = table.Name.Schema; - if (schema.Database != null && schema.Database.Server != null && !Database.View().Any(ss => ss.name == schema.Database.Server.Name)) + if (schema.Database != null && schema.Database.Server != null && !Database.View().Any(ss => ss.name == schema.Database!.Server!.Name)) return false; - if (schema.Database != null && !Database.View().Any(ss => ss.name == schema.Database.Name)) + if (schema.Database != null && !Database.View().Any(ss => ss.name == schema.Database!.Name)) return false; using (schema.Database == null ? null : Administrator.OverrideDatabaseInSysViews(schema.Database)) @@ -244,7 +244,7 @@ public static void SaveListDisableIdentity(IEnumerable entities) } } - public static int UnsafeDeleteDuplicates(this IQueryable query, Expression> key, string message = null) + public static int UnsafeDeleteDuplicates(this IQueryable query, Expression> key, string? message = null) where E : Entity { return (from e in query @@ -252,7 +252,7 @@ public static int UnsafeDeleteDuplicates(this IQueryable query, Express select e).UnsafeDelete(message); } - public static int UnsafeDeleteMListDuplicates(this IQueryable> query, Expression, K>> key, string message = null) + public static int UnsafeDeleteMListDuplicates(this IQueryable> query, Expression, K>> key, string? message = null) where E : Entity { return (from e in query @@ -267,7 +267,7 @@ public static SqlPreCommandSimple QueryPreCommand(IQueryable query) return prov.Translate(query.Expression, tr => tr.MainCommand); } - public static SqlPreCommandSimple UnsafeDeletePreCommand(IQueryable query) + public static SqlPreCommandSimple? UnsafeDeletePreCommand(IQueryable query) where T : Entity { if (!Administrator.ExistsTable() || !query.Any()) @@ -278,7 +278,7 @@ public static SqlPreCommandSimple UnsafeDeletePreCommand(IQueryable query) return prov.Delete(query, cm => cm, removeSelectRowCount: true); } - public static SqlPreCommandSimple UnsafeDeletePreCommandMList(Expression>> mListProperty, IQueryable> query) + public static SqlPreCommandSimple? UnsafeDeletePreCommandMList(Expression>> mListProperty, IQueryable> query) where E : Entity { if (!Administrator.ExistsTable(Schema.Current.TableMList(mListProperty)) || !query.Any()) @@ -322,12 +322,12 @@ public static SqlPreCommandSimple UnsafeUpdatePartPreCommand(IUpdateable update) }); } - public static void UpdateToStrings(Expression> expression) where T : Entity, new() + public static void UpdateToStrings(Expression> expression) where T : Entity, new() { UpdateToStrings(Database.Query(), expression); } - public static void UpdateToStrings(IQueryable query, Expression> expression) where T : Entity, new() + public static void UpdateToStrings(IQueryable query, Expression> expression) where T : Entity, new() { SafeConsole.WaitRows("UnsafeUpdate toStr for {0}".FormatWith(typeof(T).TypeName()), () => query.UnsafeUpdate().Set(a => a.toStr, expression).Execute()); @@ -340,7 +340,7 @@ public static SqlPreCommandSimple UnsafeUpdatePartPreCommand(IUpdateable update) .Execute(); } - public static void UpdateToString(T entity, Expression> expression) where T : Entity, new() + public static void UpdateToString(T entity, Expression> expression) where T : Entity, new() { entity.InDB().UnsafeUpdate() .Set(e => e.toStr, expression) @@ -393,13 +393,13 @@ public static IDisposable PrepareTableForBatchLoadScope(ITable table, bool disab if (multiIndexes.Any()) { SafeConsole.WriteColor(ConsoleColor.DarkMagenta, " DISABLE Multiple Indexes"); - multiIndexes.Select(i => SqlBuilder.DisableIndex(table.Name, i)).Combine(Spacing.Simple).ExecuteLeaves(); + multiIndexes.Select(i => SqlBuilder.DisableIndex(table.Name, i)).Combine(Spacing.Simple)!.ExecuteLeaves(); Executor.ExecuteNonQuery(multiIndexes.ToString(i => "ALTER INDEX [{0}] ON {1} DISABLE".FormatWith(i, table.Name), "\r\n")); onDispose += () => { SafeConsole.WriteColor(ConsoleColor.DarkMagenta, " REBUILD Multiple Indexes"); - multiIndexes.Select(i => SqlBuilder.RebuildIndex(table.Name, i)).Combine(Spacing.Simple).ExecuteLeaves(); + multiIndexes.Select(i => SqlBuilder.RebuildIndex(table.Name, i)).Combine(Spacing.Simple)!.ExecuteLeaves(); }; } } @@ -411,11 +411,11 @@ public static IDisposable PrepareTableForBatchLoadScope(ITable table, bool disab if (uniqueIndexes.Any()) { SafeConsole.WriteColor(ConsoleColor.DarkMagenta, " DISABLE Unique Indexes"); - uniqueIndexes.Select(i => SqlBuilder.DisableIndex(table.Name, i)).Combine(Spacing.Simple).ExecuteLeaves(); + uniqueIndexes.Select(i => SqlBuilder.DisableIndex(table.Name, i)).Combine(Spacing.Simple)!.ExecuteLeaves(); onDispose += () => { SafeConsole.WriteColor(ConsoleColor.DarkMagenta, " REBUILD Unique Indexes"); - uniqueIndexes.Select(i => SqlBuilder.RebuildIndex(table.Name, i)).Combine(Spacing.Simple).ExecuteLeaves(); + uniqueIndexes.Select(i => SqlBuilder.RebuildIndex(table.Name, i)).Combine(Spacing.Simple)!.ExecuteLeaves(); }; } } @@ -452,11 +452,11 @@ from ifk in targetTable.IncommingForeignKeys() ParentColumn = parentTable.Columns().SingleEx(c => c.column_id == ifk.ForeignKeyColumns().SingleEx().parent_column_id).name, }).ToList()); - foreignKeys.ForEach(fk => SqlBuilder.AlterTableDropConstraint(fk.ParentTable, fk.Name).ExecuteLeaves()); + foreignKeys.ForEach(fk => SqlBuilder.AlterTableDropConstraint(fk.ParentTable!, fk.Name! /*CSBUG*/).ExecuteLeaves()); return new Disposable(() => { - foreignKeys.ToList().ForEach(fk => SqlBuilder.AlterTableAddConstraintForeignKey(fk.ParentTable, fk.ParentColumn, table.Name, table.PrimaryKey.Name).ExecuteLeaves()); + foreignKeys.ToList().ForEach(fk => SqlBuilder.AlterTableAddConstraintForeignKey(fk.ParentTable!, fk.ParentColumn!, table.Name, table.PrimaryKey.Name)!.ExecuteLeaves()); }); } @@ -491,27 +491,27 @@ public static void DropUniqueIndexes() where T : Entity var indexesNames = Administrator.GetIndixesNames(table, unique: true); if (indexesNames.HasItems()) - indexesNames.Select(n => SqlBuilder.DropIndex(table.Name, n)).Combine(Spacing.Simple).ExecuteLeaves(); + indexesNames.Select(n => SqlBuilder.DropIndex(table.Name, n)).Combine(Spacing.Simple)!.ExecuteLeaves(); } - public static void MoveAllForeignKeys(Lite fromEntity, Lite toEntity, Func shouldMove = null) + public static void MoveAllForeignKeys(Lite fromEntity, Lite toEntity, Func? shouldMove = null) where T : Entity { using (Transaction tr = new Transaction()) { - MoveAllForeignKeysPrivate(fromEntity, toEntity, shouldMove).Select(a => a.UpdateScript).Combine(Spacing.Double).ExecuteLeaves(); + MoveAllForeignKeysPrivate(fromEntity, toEntity, shouldMove).Select(a => a.UpdateScript).Combine(Spacing.Double)!.ExecuteLeaves(); tr.Commit(); } } - public static SqlPreCommand MoveAllForeignKeysScript(Lite fromEntity, Lite toEntity, Func shouldMove = null) + public static SqlPreCommand? MoveAllForeignKeysScript(Lite fromEntity, Lite toEntity, Func? shouldMove = null) where T : Entity { return MoveAllForeignKeysPrivate(fromEntity, toEntity, shouldMove).Select(a => a.UpdateScript).Combine(Spacing.Double); } - public static void MoveAllForeignKeysConsole(Lite fromEntity, Lite toEntity, Func shouldMove = null) + public static void MoveAllForeignKeysConsole(Lite fromEntity, Lite toEntity, Func? shouldMove = null) where T : Entity { var tuples = MoveAllForeignKeysPrivate(fromEntity, toEntity, shouldMove); @@ -525,9 +525,15 @@ class ColumnTableScript { public ColumnTable ColumnTable; public SqlPreCommandSimple UpdateScript; + + public ColumnTableScript(ColumnTable columnTable, SqlPreCommandSimple updateScript) + { + ColumnTable = columnTable; + UpdateScript = updateScript; + } } - static List MoveAllForeignKeysPrivate(Lite fromEntity, Lite toEntity, Func shouldMove) + static List MoveAllForeignKeysPrivate(Lite fromEntity, Lite toEntity, Func? shouldMove) where T : Entity { if (fromEntity.GetType() != toEntity.GetType()) @@ -542,24 +548,26 @@ static List MoveAllForeignKeysPrivate(Lite fromEntity, List columns = GetColumnTables(s, refTable); if (shouldMove != null) - columns = columns.Where(p => shouldMove(p.Table, p.Column)).ToList(); + columns = columns.Where(p => shouldMove!(p.Table, p.Column)).ToList(); var pb = Connector.Current.ParameterBuilder; - return columns.Select(ct => new ColumnTableScript - { - ColumnTable = ct, - UpdateScript = new SqlPreCommandSimple("UPDATE {0}\r\nSET {1} = @toEntity\r\nWHERE {1} = @fromEntity".FormatWith(ct.Table.Name, ct.Column.Name.SqlEscape()), new List + return columns.Select(ct => new ColumnTableScript(ct, new SqlPreCommandSimple("UPDATE {0}\r\nSET {1} = @toEntity\r\nWHERE {1} = @fromEntity".FormatWith(ct.Table.Name, ct.Column.Name.SqlEscape()), new List { pb.CreateReferenceParameter("@fromEntity", fromEntity.Id, ct.Column), pb.CreateReferenceParameter("@toEntity", toEntity.Id, ct.Column), - }) - }).ToList(); + }))).ToList(); } class ColumnTable { public ITable Table; public IColumn Column; + + public ColumnTable(ITable table, IColumn column) + { + Table = table; + Column = column; + } } static ConcurrentDictionary> columns = new ConcurrentDictionary>(); @@ -571,11 +579,8 @@ static List GetColumnTables(Schema schema, Table refTable) return (from t in schema.GetDatabaseTables() from c in t.Columns.Values where c.ReferenceTable == rt - select new ColumnTable - { - Table = t, - Column = c, - }).ToList(); + select new ColumnTable(t,c)) + .ToList(); }); } diff --git a/Signum.Engine/Basics/TypeLogic.cs b/Signum.Engine/Basics/TypeLogic.cs index 86e18d4737..7a90ad2bcc 100644 --- a/Signum.Engine/Basics/TypeLogic.cs +++ b/Signum.Engine/Basics/TypeLogic.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Signum.Entities; @@ -37,7 +37,7 @@ public static Dictionary EntityToType public static void AssertStarted(SchemaBuilder sb) { - sb.AssertDefined(ReflectionTools.GetMethodInfo(() => Start(null))); + sb.AssertDefined(ReflectionTools.GetMethodInfo(() => Start(null!))); } public static void Start(SchemaBuilder sb) @@ -86,10 +86,10 @@ public static Dictionary TryEntityToType(Replacements replacem { return (from dn in Administrator.TryRetrieveAll(replacements) join t in Schema.Current.Tables.Keys on dn.FullClassName equals (EnumEntity.Extract(t) ?? t).FullName - select new { dn, t }).ToDictionary(a => a.dn, a => a.t); + select (dn, t)).ToDictionary(a => a.dn, a => a.t); } - public static SqlPreCommand Schema_Synchronizing(Replacements replacements) + public static SqlPreCommand? Schema_Synchronizing(Replacements replacements) { var schema = Schema.Current; @@ -159,7 +159,7 @@ static bool EqualsIgnoringDatabasePrefix(ObjectName pc, ObjectName ps) => pc.Schema.Name == ps.Schema.Name && Suffix(pc.Schema.Database?.Name) == Suffix(ps.Schema.Database?.Name); - static string Suffix(string name) => name.TryAfterLast("_") ?? name; + static string? Suffix(string? name) => name.TryAfterLast("_") ?? name; static Dictionary ApplyReplacementsToOld(this Replacements replacements, Dictionary oldDictionary, string replacementsKey) { @@ -177,7 +177,7 @@ internal static SqlPreCommand Schema_Generating() return GenerateSchemaTypes() .Select((e, i) => table.InsertSqlSync(e, suffix: i.ToString())) - .Combine(Spacing.Simple) + .Combine(Spacing.Simple)! .PlainSqlCommand(); } @@ -210,7 +210,7 @@ public static Type GetType(string cleanName) return NameToType.GetOrThrow(cleanName, "Type {0} not found in the schema"); } - public static Type TryGetType(string cleanName) + public static Type? TryGetType(string cleanName) { return NameToType.TryGetC(cleanName); } @@ -220,7 +220,7 @@ public static string GetCleanName(Type type) return TypeToName.GetOrThrow(type, "Type {0} not found in the schema"); } - public static string TryGetCleanName(Type type) + public static string? TryGetCleanName(Type type) { return TypeToName.TryGetC(type); } @@ -240,7 +240,7 @@ public TypeCaches(Schema current) current.Tables.Keys, t => t.FullClassName, t => (EnumEntity.Extract(t) ?? t).FullName, - (typeEntity, type) => new { typeEntity, type }, + (typeEntity, type) => (typeEntity, type), "caching {0}".FormatWith(current.Table(typeof(TypeEntity)).Name) ).ToDictionary(a => a.type, a => a.typeEntity); diff --git a/Signum.Engine/BulkInserter.cs b/Signum.Engine/BulkInserter.cs index f562063cdd..493552bc2d 100644 --- a/Signum.Engine/BulkInserter.cs +++ b/Signum.Engine/BulkInserter.cs @@ -1,4 +1,4 @@ -using Signum.Engine.Maps; +using Signum.Engine.Maps; using Signum.Entities; using Signum.Entities.Reflection; using Signum.Utilities; @@ -22,7 +22,7 @@ public static int BulkInsert(this IEnumerable entities, bool validateFirst = true, bool disableIdentity = false, int? timeout = null, - string message = null) + string? message = null) where T : Entity { using (HeavyProfiler.Log(nameof(BulkInsert), () => typeof(T).TypeName())) @@ -52,13 +52,14 @@ public static int BulkInsert(this IEnumerable entities, /// Optional filter to query only the recently inseted entities public static int BulkInsertQueryIds(this IEnumerable entities, Expression> keySelector, - Expression> isNewPredicate = null, + Expression>? isNewPredicate = null, SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, bool preSaving = true, bool validateFirst = true, int? timeout = null, - string message = null) - where T : Entity + string? message = null) + where T : Entity + where K : object { using (HeavyProfiler.Log(nameof(BulkInsertQueryIds), () => typeof(T).TypeName())) using (Transaction tr = new Transaction()) @@ -90,7 +91,7 @@ public static int BulkInsertQueryIds(this IEnumerable entities, } } - static void BulkInsertMLists(List list, SqlBulkCopyOptions options, int? timeout, string message) where T : Entity + static void BulkInsertMLists(List list, SqlBulkCopyOptions options, int? timeout, string? message) where T : Entity { var mlistPrs = PropertyRoute.GenerateRoutes(typeof(T), includeIgnored: false).Where(a => a.PropertyRouteType == PropertyRouteType.FieldOrProperty && a.Type.IsMList()).ToList(); foreach (var pr in mlistPrs) @@ -124,7 +125,7 @@ public static int BulkInsertTable(IEnumerable entities, bool validateFirst = true, bool disableIdentity = false, int? timeout = null, - string message = null) + string? message = null) where T : Entity { using (HeavyProfiler.Log(nameof(BulkInsertTable), () => typeof(T).TypeName())) @@ -201,11 +202,11 @@ static void Validate(IEnumerable entities) where T : Entity } } - static GenericInvoker> giBulkInsertMListFromEntities = - new GenericInvoker>((entities, propertyRoute, options, timeout, message) => + static GenericInvoker> giBulkInsertMListFromEntities = + new GenericInvoker>((entities, propertyRoute, options, timeout, message) => BulkInsertMListTablePropertyRoute((List)entities, propertyRoute, options, timeout, message)); - static int BulkInsertMListTablePropertyRoute(List entities, PropertyRoute route, SqlBulkCopyOptions copyOptions, int? timeout, string message) + static int BulkInsertMListTablePropertyRoute(List entities, PropertyRoute route, SqlBulkCopyOptions copyOptions, int? timeout, string? message) where E : Entity { return BulkInsertMListTable(entities, route.GetLambdaExpression>(safeNullAccess: false), copyOptions, timeout, message); @@ -216,7 +217,7 @@ public static int BulkInsertMListTable( Expression>> mListProperty, SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, int? timeout = null, - string message = null) + string? message = null) where E : Entity { using (HeavyProfiler.Log(nameof(BulkInsertMListTable), () => $"{mListProperty} ({typeof(E).TypeName()})")) @@ -251,7 +252,7 @@ public static int BulkInsertMListTable( SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, int? timeout = null, bool? updateParentTicks = null, /*Needed for concurrency and Temporal tables*/ - string message = null) + string? message = null) where E : Entity { using (HeavyProfiler.Log(nameof(BulkInsertMListTable), () => $"{mListProperty} ({typeof(MListElement).TypeName()})")) @@ -310,7 +311,7 @@ public static int BulkInsertMListTable( public static int BulkInsertView(this IEnumerable entities, SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, int? timeout = null, - string message = null) + string? message = null) where T : IView { using (HeavyProfiler.Log(nameof(BulkInsertView), () => typeof(T).Name)) diff --git a/Signum.Engine/Connection/Connector.cs b/Signum.Engine/Connection/Connector.cs index d4fa504391..3c3a2dcdfe 100644 --- a/Signum.Engine/Connection/Connector.cs +++ b/Signum.Engine/Connection/Connector.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Data; using Signum.Utilities; using Signum.Engine.Maps; @@ -82,7 +82,7 @@ protected static void Log(SqlPreCommandSimple pcs) public abstract SqlDbType GetSqlDbType(DbParameter p); - protected internal abstract object ExecuteScalar(SqlPreCommandSimple preCommand, CommandType commandType); + protected internal abstract object? ExecuteScalar(SqlPreCommandSimple preCommand, CommandType commandType); protected internal abstract int ExecuteNonQuery(SqlPreCommandSimple preCommand, CommandType commandType); protected internal abstract DataTable ExecuteDataTable(SqlPreCommandSimple command, CommandType commandType); protected internal abstract DbDataReaderWithCommand UnsafeExecuteDataReader(SqlPreCommandSimple sqlPreCommandSimple, CommandType commandType); @@ -108,7 +108,7 @@ protected static void Log(SqlPreCommandSimple pcs) public abstract ParameterBuilder ParameterBuilder { get; protected set; } - public abstract void CleanDatabase(DatabaseName database); + public abstract void CleanDatabase(DatabaseName? database); public abstract bool AllowsMultipleQueries { get; } @@ -116,11 +116,11 @@ protected static void Log(SqlPreCommandSimple pcs) public abstract bool SupportsScalarSubqueryInAggregates { get; } - public static string TryExtractDatabaseNameWithPostfix(ref string connectionString, string catalogPostfix) + public static string? TryExtractDatabaseNameWithPostfix(ref string connectionString, string catalogPostfix) { string toFind = "+" + catalogPostfix; - string result = connectionString.TryBefore(toFind).TryAfterLast("="); + string? result = connectionString.TryBefore(toFind).TryAfterLast("="); if (result == null) return null; @@ -168,7 +168,7 @@ public static string GetParameterName(string name) public DbParameter CreateReferenceParameter(string parameterName, PrimaryKey? id, IColumn column) { - return CreateParameter(parameterName, column.SqlDbType, null, column.Nullable.ToBool(), id == null ? (object)null : id.Value.Object); + return CreateParameter(parameterName, column.SqlDbType, null, column.Nullable.ToBool(), id == null ? null : id.Value.Object); } public DbParameter CreateParameter(string parameterName, object value, Type type) @@ -178,8 +178,8 @@ public DbParameter CreateParameter(string parameterName, object value, Type type return CreateParameter(parameterName, pair.SqlDbType, pair.UserDefinedTypeName, type == null || type.IsByRef || type.IsNullable(), value); } - public abstract DbParameter CreateParameter(string parameterName, SqlDbType type, string udtTypeName, bool nullable, object value); - public abstract MemberInitExpression ParameterFactory(Expression parameterName, SqlDbType type, string udtTypeName, bool nullable, Expression value); + public abstract DbParameter CreateParameter(string parameterName, SqlDbType type, string? udtTypeName, bool nullable, object? value); + public abstract MemberInitExpression ParameterFactory(Expression parameterName, SqlDbType type, string? udtTypeName, bool nullable, Expression value); protected static bool IsDate(SqlDbType type) { diff --git a/Signum.Engine/Connection/Executor.cs b/Signum.Engine/Connection/Executor.cs index 6f6ec21f2d..a15d55a3b9 100644 --- a/Signum.Engine/Connection/Executor.cs +++ b/Signum.Engine/Connection/Executor.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Data.SqlClient; @@ -10,7 +10,7 @@ namespace Signum.Engine { public static class Executor { - public static object ExecuteScalar(string sql, List parameters = null, CommandType commandType = CommandType.Text) + public static object ExecuteScalar(string sql, List? parameters = null, CommandType commandType = CommandType.Text) { return Connector.Current.ExecuteScalar(new SqlPreCommandSimple(sql, parameters), commandType); } @@ -21,7 +21,7 @@ public static object ExecuteScalar(this SqlPreCommandSimple preCommand, CommandT } - public static int ExecuteNonQuery(string sql, List parameters = null, CommandType commandType = CommandType.Text) + public static int ExecuteNonQuery(string sql, List? parameters = null, CommandType commandType = CommandType.Text) { return Connector.Current.ExecuteNonQuery(new SqlPreCommandSimple(sql, parameters), commandType); } @@ -32,7 +32,7 @@ public static int ExecuteNonQuery(this SqlPreCommandSimple preCommand, CommandTy } - public static DbDataReaderWithCommand UnsafeExecuteDataReader(string sql, List parameters = null, CommandType commandType = CommandType.Text) + public static DbDataReaderWithCommand UnsafeExecuteDataReader(string sql, List? parameters = null, CommandType commandType = CommandType.Text) { return Connector.Current.UnsafeExecuteDataReader(new SqlPreCommandSimple(sql, parameters), commandType); } @@ -42,7 +42,7 @@ public static DbDataReaderWithCommand UnsafeExecuteDataReader(this SqlPreCommand return Connector.Current.UnsafeExecuteDataReader(preCommand, commandType); } - public static Task UnsafeExecuteDataReaderAsync(string sql, List parameters = null, CommandType commandType = CommandType.Text, CancellationToken token = default(CancellationToken)) + public static Task UnsafeExecuteDataReaderAsync(string sql, List? parameters = null, CommandType commandType = CommandType.Text, CancellationToken token = default(CancellationToken)) { return Connector.Current.UnsafeExecuteDataReaderAsync(new SqlPreCommandSimple(sql, parameters), commandType, token); } @@ -52,7 +52,7 @@ public static DbDataReaderWithCommand UnsafeExecuteDataReader(this SqlPreCommand return Connector.Current.UnsafeExecuteDataReaderAsync(preCommand, commandType, token); } - public static DataTable ExecuteDataTable(string sql, List parameters = null, CommandType commandType = CommandType.Text) + public static DataTable ExecuteDataTable(string sql, List? parameters = null, CommandType commandType = CommandType.Text) { return Connector.Current.ExecuteDataTable(new SqlPreCommandSimple(sql, parameters), commandType); } @@ -63,7 +63,7 @@ public static DataTable ExecuteDataTable(this SqlPreCommandSimple preCommand, Co } - public static DataSet ExecuteDataSet(string sql, List parameters = null, CommandType commandType = CommandType.Text) + public static DataSet ExecuteDataSet(string sql, List? parameters = null, CommandType commandType = CommandType.Text) { return Connector.Current.ExecuteDataSet(new SqlPreCommandSimple(sql, parameters), commandType); } @@ -86,4 +86,4 @@ public static void BulkCopy(DataTable dt, ObjectName destinationTable, SqlBulkCo Connector.Current.BulkCopy(dt, destinationTable, options, timeout); } } -} \ No newline at end of file +} diff --git a/Signum.Engine/Connection/SqlConnector.cs b/Signum.Engine/Connection/SqlConnector.cs index bc607c865e..e8293c8003 100644 --- a/Signum.Engine/Connection/SqlConnector.cs +++ b/Signum.Engine/Connection/SqlConnector.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Data.SqlClient; @@ -112,7 +112,7 @@ public string ConnectionString public override bool SupportsScalarSubquery { get { return true; } } public override bool SupportsScalarSubqueryInAggregates { get { return false; } } - SqlConnection EnsureConnection() + SqlConnection? EnsureConnection() { if (Transaction.HasTransaction) return null; @@ -122,7 +122,7 @@ SqlConnection EnsureConnection() return result; } - SqlCommand NewCommand(SqlPreCommandSimple preCommand, SqlConnection overridenConnection, CommandType commandType) + SqlCommand NewCommand(SqlPreCommandSimple preCommand, SqlConnection? overridenConnection, CommandType commandType) { SqlCommand cmd = new SqlCommand { CommandType = commandType }; @@ -153,9 +153,9 @@ SqlCommand NewCommand(SqlPreCommandSimple preCommand, SqlConnection overridenCon return cmd; } - protected internal override object ExecuteScalar(SqlPreCommandSimple preCommand, CommandType commandType) + protected internal override object? ExecuteScalar(SqlPreCommandSimple preCommand, CommandType commandType) { - using (SqlConnection con = EnsureConnection()) + using (SqlConnection? con = EnsureConnection()) using (SqlCommand cmd = NewCommand(preCommand, con, commandType)) using (HeavyProfiler.Log("SQL", () => preCommand.sp_executesql())) { @@ -181,7 +181,7 @@ protected internal override object ExecuteScalar(SqlPreCommandSimple preCommand, protected internal override int ExecuteNonQuery(SqlPreCommandSimple preCommand, CommandType commandType) { - using (SqlConnection con = EnsureConnection()) + using (SqlConnection? con = EnsureConnection()) using (SqlCommand cmd = NewCommand(preCommand, con, commandType)) using (HeavyProfiler.Log("SQL", () => preCommand.sp_executesql())) { @@ -207,7 +207,7 @@ public void ExecuteDataReaderDependency(SqlPreCommandSimple preCommand, OnChange retry: try { - using (SqlConnection con = EnsureConnection()) + using (SqlConnection? con = EnsureConnection()) using (SqlCommand cmd = NewCommand(preCommand, con, commandType)) using (HeavyProfiler.Log("SQL-Dependency")) using (HeavyProfiler.Log("SQL", () => preCommand.sp_executesql())) @@ -308,7 +308,7 @@ protected internal override async Task UnsafeExecuteDat protected internal override DataTable ExecuteDataTable(SqlPreCommandSimple preCommand, CommandType commandType) { - using (SqlConnection con = EnsureConnection()) + using (SqlConnection? con = EnsureConnection()) using (SqlCommand cmd = NewCommand(preCommand, con, commandType)) using (HeavyProfiler.Log("SQL", () => preCommand.sp_executesql())) { @@ -333,7 +333,7 @@ protected internal override DataTable ExecuteDataTable(SqlPreCommandSimple preCo protected internal override DataSet ExecuteDataSet(SqlPreCommandSimple preCommand, CommandType commandType) { - using (SqlConnection con = EnsureConnection()) + using (SqlConnection? con = EnsureConnection()) using (SqlCommand cmd = NewCommand(preCommand, con, commandType)) using (HeavyProfiler.Log("SQL", () => preCommand.sp_executesql())) { @@ -387,13 +387,12 @@ Exception ReplaceException(Exception ex, SqlPreCommandSimple command) } } - return ex; - + return ex! /*CSBUG*/; } protected internal override void BulkCopy(DataTable dt, ObjectName destinationTable, SqlBulkCopyOptions options, int? timeout) { - using (SqlConnection con = EnsureConnection()) + using (SqlConnection? con = EnsureConnection()) using (SqlBulkCopy bulkCopy = new SqlBulkCopy( options.HasFlag(SqlBulkCopyOptions.UseInternalTransaction) ? con : (SqlConnection)Transaction.CurrentConnection, options, @@ -448,7 +447,7 @@ public override DbConnection CreateConnection() public override ParameterBuilder ParameterBuilder { get; protected set; } - public override void CleanDatabase(DatabaseName databaseName) + public override void CleanDatabase(DatabaseName? databaseName) { SqlConnectorScripts.RemoveAllScript(databaseName).ExecuteLeaves(); SqlConnectorScripts.ShrinkDatabase(DatabaseName()); @@ -498,11 +497,11 @@ public override SqlPreCommand ShrinkDatabase(string schemaName) new SqlPreCommandSimple("DECLARE @fileID BIGINT"), new SqlPreCommandSimple("SET @fileID = (SELECT FILE_IDEX((SELECT TOP(1)name FROM sys.database_files WHERE type = 1)))"), new SqlPreCommandSimple("DBCC SHRINKFILE(@fileID, 1)"), - }.Combine(Spacing.Simple).PlainSqlCommand(), + }.Combine(Spacing.Simple)!.PlainSqlCommand(), new SqlPreCommandSimple("ALTER DATABASE {0} SET RECOVERY FULL WITH NO_WAIT".FormatWith(schemaName)), }.Combine(Spacing.Simple), new SqlPreCommandSimple("DBCC SHRINKDATABASE ( {0} , TRUNCATEONLY )".FormatWith(schemaName)) - }.Combine(Spacing.Simple); + }.Combine(Spacing.Simple)!; } public override bool AllowsConvertToDate @@ -535,7 +534,7 @@ public override bool SupportsTemporalTables public class SqlParameterBuilder : ParameterBuilder { - public override DbParameter CreateParameter(string parameterName, SqlDbType sqlType, string udtTypeName, bool nullable, object value) + public override DbParameter CreateParameter(string parameterName, SqlDbType sqlType, string? udtTypeName, bool nullable, object? value) { if (IsDate(sqlType)) AssertDateTime((DateTime?)value); @@ -554,7 +553,7 @@ public override DbParameter CreateParameter(string parameterName, SqlDbType sqlT return result; } - public override MemberInitExpression ParameterFactory(Expression parameterName, SqlDbType sqlType, string udtTypeName, bool nullable, Expression value) + public override MemberInitExpression ParameterFactory(Expression parameterName, SqlDbType sqlType, string? udtTypeName, bool nullable, Expression value) { Expression valueExpr = Expression.Convert(IsDate(sqlType) ? Expression.Call(miAsserDateTime, Expression.Convert(value, typeof(DateTime?))) : value, typeof(object)); @@ -692,7 +691,7 @@ exec sp_executesql @sql close cur deallocate cur"; - public static SqlPreCommand RemoveAllScript(DatabaseName databaseName) + public static SqlPreCommand RemoveAllScript(DatabaseName? databaseName) { var schemas = SqlBuilder.SystemSchemas.ToString(a => "'" + a + "'", ", "); @@ -703,10 +702,10 @@ public static SqlPreCommand RemoveAllScript(DatabaseName databaseName) Connector.Current.SupportsTemporalTables ? new SqlPreCommandSimple(Use(databaseName, StopSystemVersioning)) : null, new SqlPreCommandSimple(Use(databaseName, RemoveAllTablesScript)), new SqlPreCommandSimple(Use(databaseName, RemoveAllSchemasScript.FormatWith(schemas))) - ); + )!; } - static string Use(DatabaseName databaseName, string script) + static string Use(DatabaseName? databaseName, string script) { if (databaseName == null) return script; diff --git a/Signum.Engine/Database.cs b/Signum.Engine/Database.cs index 9ab46cf0fe..0742be5554 100644 --- a/Signum.Engine/Database.cs +++ b/Signum.Engine/Database.cs @@ -85,7 +85,7 @@ public static T Retrieve(this Lite lite) where T : class, IEntity if (lite.EntityOrNull == null) lite.SetEntity(Retrieve(lite.EntityType, lite.Id)); - return lite.EntityOrNull; + return lite.EntityOrNull!; } public static async Task RetrieveAsyc(this Lite lite, CancellationToken token) where T : class, IEntity @@ -96,7 +96,7 @@ public static async Task RetrieveAsyc(this Lite lite, CancellationToken if (lite.EntityOrNull == null) lite.SetEntity(await RetrieveAsync(lite.EntityType, lite.Id, token)); - return lite.EntityOrNull; + return lite.EntityOrNull!; } @@ -212,7 +212,7 @@ public static async Task RetrieveAsync(PrimaryKey id, CancellationToken to } } - static CacheControllerBase GetCacheController() where T : Entity + static CacheControllerBase? GetCacheController() where T : Entity { CacheControllerBase cc = Schema.Current.CacheController(); @@ -224,7 +224,7 @@ static CacheControllerBase GetCacheController() where T : Entity return cc; } - static FilterQueryResult GetFilterQuery() where T : Entity + static FilterQueryResult? GetFilterQuery() where T : Entity { if (EntityCache.HasRetriever) //Filtering is not necessary when retrieving IBA? return null; @@ -314,7 +314,7 @@ public static async Task> RetrieveLiteAsync(PrimaryKey id, Cancellati } } - public static Lite FillToString(this Lite lite) where T : class, IEntity + public static Lite? FillToString(this Lite lite) where T : class, IEntity { if (lite == null) return null; @@ -326,9 +326,6 @@ public static Lite FillToString(this Lite lite) where T : class, IEntit public static async Task> FillToStringAsync(this Lite lite, CancellationToken token) where T : class, IEntity { - if (lite == null) - return null; - lite.SetToString(await GetToStrAsync(lite.EntityType, lite.Id, token)); return lite; @@ -629,9 +626,9 @@ public static async Task>> RetrieveAllLiteAsync(Type type, Can } - private static GenericInvoker, string, IList>> giRetrieveList = - new GenericInvoker, string, IList>>((ids, message) => RetrieveList(ids, message)); - public static List RetrieveList(List ids, string message = null) + private static GenericInvoker, string?, IList>> giRetrieveList = + new GenericInvoker, string?, IList>>((ids, message) => RetrieveList(ids, message)); + public static List RetrieveList(List ids, string? message = null) where T : Entity { using (HeavyProfiler.Log("DBRetrieve", () => "List<{0}>".FormatWith(typeof(T).TypeName()))) @@ -639,7 +636,7 @@ public static List RetrieveList(List ids, string message = nul if (ids == null) throw new ArgumentNullException(nameof(ids)); List remainingIds; - Dictionary result = null; + Dictionary? result = null; if (EntityCache.Created) { result = ids.Select(id => EntityCache.Get(id)).NotNull().ToDictionary(a => a.Id); @@ -677,7 +674,7 @@ public static List RetrieveList(List ids, string message = nul } } - static List RetrieveFromDatabaseOrCache(List ids, string message = null) where T : Entity + static List RetrieveFromDatabaseOrCache(List ids, string? message = null) where T : Entity { var cc = GetCacheController(); if (cc != null) @@ -733,7 +730,7 @@ public static async Task> RetrieveListAsync(List ids, Can if (ids == null) throw new ArgumentNullException(nameof(ids)); List remainingIds; - Dictionary result = null; + Dictionary? result = null; if (EntityCache.Created) { result = ids.Select(id => EntityCache.Get(id)).NotNull().ToDictionary(a => a.Id); @@ -805,7 +802,7 @@ static async Task> RetrieveFromDatabaseOrCache(List ids, return task.SelectMany(list => list).ToList(); } - public static List RetrieveList(Type type, List ids, string message = null) + public static List RetrieveList(Type type, List ids, string? message = null) { if (type == null) throw new ArgumentNullException(nameof(type)); @@ -902,7 +899,7 @@ public static async Task>> RetrieveListLite(Type type, List>().ToList(); } - public static List RetrieveFromListOfLite(this IEnumerable> lites, string message = null) + public static List RetrieveFromListOfLite(this IEnumerable> lites, string? message = null) where T : class, IEntity { if (lites == null) @@ -1262,7 +1259,7 @@ public static IQueryable View() #endregion #region UnsafeDelete - public static int UnsafeDelete(this IQueryable query, string message = null) + public static int UnsafeDelete(this IQueryable query, string? message = null) where T : Entity { if (message != null) @@ -1286,7 +1283,7 @@ public static int UnsafeDelete(this IQueryable query, string message = nul } } - public static int UnsafeDeleteMList(this IQueryable> mlistQuery, string message = null) + public static int UnsafeDeleteMList(this IQueryable> mlistQuery, string? message = null) where E : Entity { if (message != null) @@ -1309,7 +1306,7 @@ public static int UnsafeDeleteMList(this IQueryable> ml } } - public static int UnsafeDeleteView(this IQueryable query, string message = null) + public static int UnsafeDeleteView(this IQueryable query, string? message = null) where T : IView { if (message != null) @@ -1409,7 +1406,7 @@ public static IUpdateablePart UnsafeUpdateViewPart(this IQueryable(query, partSelector, null); } - public static int Execute(this IUpdateable update, string message = null) + public static int Execute(this IUpdateable update, string? message = null) { if (message != null) return SafeConsole.WaitRows(message == "auto" ? $"Updating { update.EntityType.TypeName()}" : message, @@ -1453,13 +1450,13 @@ public static int ExecuteChunks(this IUpdateable update, int chunkSize = 10000, #region UnsafeInsert - public static int UnsafeInsert(this IQueryable query, string message = null) + public static int UnsafeInsert(this IQueryable query, string? message = null) where E : Entity { return query.UnsafeInsert(a => a, message); } - public static int UnsafeInsert(this IQueryable query, Expression> constructor, string message = null) + public static int UnsafeInsert(this IQueryable query, Expression> constructor, string? message = null) where E : Entity { if (message != null) @@ -1485,13 +1482,13 @@ public static int UnsafeInsert(this IQueryable query, Expression(this IQueryable> query, Expression>> mListProperty, string message = null) + public static int UnsafeInsertMList(this IQueryable> query, Expression>> mListProperty, string? message = null) where E : Entity { return query.UnsafeInsertMList(mListProperty, a => a, message); } - public static int UnsafeInsertMList(this IQueryable query, Expression>> mListProperty, Expression>> constructor, string message = null) + public static int UnsafeInsertMList(this IQueryable query, Expression>> mListProperty, Expression>> constructor, string? message = null) where E : Entity { @@ -1518,7 +1515,7 @@ public static int UnsafeInsertMList(this IQueryable query, Expressio } } - public static int UnsafeInsertView(this IQueryable query, Expression> constructor, string message = null) + public static int UnsafeInsertView(this IQueryable query, Expression> constructor, string? message = null) where E : IView { if (message != null) @@ -1546,7 +1543,7 @@ public static int UnsafeInsertView(this IQueryable query, Expression(string title, IQueryable should, IQueryable current, Expression> getKey, List>> toUpdate = null) + public static void Merge(string? title, IQueryable should, IQueryable current, Expression> getKey, List>>? toUpdate = null) where E : Entity where A : class { @@ -1560,12 +1557,12 @@ public static void Merge(string title, IQueryable should, IQueryable if (toUpdate != null) { var updater = (from c in current - join s in should on getKey.Evaluate(c) equals getKey.Evaluate(s) - select new { c, s }).UnsafeUpdatePart(a => a.c); + join s in should on getKey.Evaluate(c) equals getKey.Evaluate(s) + select new { c, s }).UnsafeUpdatePart(a => a.c!); /*CSBUG*/ foreach (var prop in toUpdate) { - updater = updater.Set(prop, a => prop.Evaluate(a.s)); + updater = updater.Set(prop, a => prop.Evaluate(a.s!));/*CSBUG*/ } updater.Execute(title != null ? "auto" : null); @@ -1598,7 +1595,7 @@ public static List ToListWait(this IQueryable query, string message) return result; } - public static List ToListWait(this IQueryable query, int timeoutSeconds, string message = null) + public static List ToListWait(this IQueryable query, int timeoutSeconds, string? message = null) { using (Connector.CommandTimeoutScope(timeoutSeconds)) { @@ -1631,7 +1628,7 @@ public SignumTable(QueryProvider provider, ITable table) public interface IUpdateable { IQueryable Query { get; } - LambdaExpression PartSelector { get; } + LambdaExpression? PartSelector { get; } IEnumerable SetterExpressions { get; } Type EntityType { get; } @@ -1657,7 +1654,7 @@ class UpdateablePart : IUpdateablePart Expression> partSelector; ReadOnlyCollection settersExpressions; - public UpdateablePart(IQueryable query, Expression> partSelector, IEnumerable setters) + public UpdateablePart(IQueryable query, Expression> partSelector, IEnumerable? setters) { this.query = query; this.partSelector = partSelector; @@ -1666,7 +1663,7 @@ public UpdateablePart(IQueryable query, Expression> partSelector, public IQueryable Query { get { return this.query; } } - public LambdaExpression PartSelector { get { return this.partSelector; } } + public LambdaExpression? PartSelector { get { return this.partSelector; } } public IEnumerable SetterExpressions { get { return this.settersExpressions; } } @@ -1722,7 +1719,7 @@ class Updateable : IUpdateable IQueryable query; ReadOnlyCollection settersExpressions; - public Updateable(IQueryable query, IEnumerable setters) + public Updateable(IQueryable query, IEnumerable? setters) { this.query = query; this.settersExpressions = (setters ?? Enumerable.Empty()).ToReadOnly(); @@ -1730,7 +1727,7 @@ public Updateable(IQueryable query, IEnumerable setters) public IQueryable Query { get { return this.query; } } - public LambdaExpression PartSelector { get { return null; } } + public LambdaExpression? PartSelector { get { return null; } } public IEnumerable SetterExpressions { get { return this.settersExpressions; } } diff --git a/Signum.Engine/DynamicQuery/ColumnDescriptionFactory.cs b/Signum.Engine/DynamicQuery/ColumnDescriptionFactory.cs index 002c3f9feb..39b17e532f 100644 --- a/Signum.Engine/DynamicQuery/ColumnDescriptionFactory.cs +++ b/Signum.Engine/DynamicQuery/ColumnDescriptionFactory.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using Signum.Entities; using Signum.Entities.DynamicQuery; @@ -12,14 +12,14 @@ namespace Signum.Engine.DynamicQuery public class ColumnDescriptionFactory { readonly internal Meta Meta; - public Func OverrideDisplayName { get; set; } - public Func OverrideIsAllowed { get; set; } + public Func? OverrideDisplayName { get; set; } + public Func? OverrideIsAllowed { get; set; } public string Name { get; internal set; } public Type Type { get; internal set; } - public string Format { get; set; } - public string Unit { get; set; } + public string? Format { get; set; } + public string? Unit { get; set; } Implementations? implementations; public Implementations? Implementations { @@ -40,8 +40,8 @@ public Implementations? Implementations } } - PropertyRoute[] propertyRoutes; - public PropertyRoute[] PropertyRoutes + PropertyRoute[]? propertyRoutes; + public PropertyRoute[]? PropertyRoutes { get { return propertyRoutes; } set @@ -60,7 +60,7 @@ public PropertyRoute[] PropertyRoutes - internal static string GetUnit(PropertyRoute[] routes) + internal static string? GetUnit(PropertyRoute[] routes) { switch (routes[0].PropertyRouteType) { @@ -76,7 +76,7 @@ internal static string GetUnit(PropertyRoute[] routes) throw new InvalidOperationException(); } - internal static string GetFormat(PropertyRoute[] routes) + internal static string? GetFormat(PropertyRoute[] routes) { switch (routes[0].PropertyRouteType) { @@ -124,9 +124,9 @@ public string DisplayName() if (propertyRoutes != null && propertyRoutes[0].PropertyRouteType == PropertyRouteType.FieldOrProperty && - propertyRoutes[0].PropertyInfo.Name == Name) + propertyRoutes[0].PropertyInfo!.Name == Name) { - var result = propertyRoutes.Select(pr=>pr.PropertyInfo.NiceName()).Only(); + var result = propertyRoutes.Select(pr => pr.PropertyInfo!.NiceName()).Only(); if (result != null) return result; } @@ -145,7 +145,7 @@ public bool IsEntity get { return this.Name == ColumnDescription.Entity; } } - public string IsAllowed() + public string? IsAllowed() { if (OverrideIsAllowed != null) return OverrideIsAllowed(); @@ -156,13 +156,13 @@ public string IsAllowed() return null; } - Type processedType; + Type? processedType; Type ProcessedType { get { - return processedType ?? - (processedType = (Reflector.IsIEntity(Type) ? Lite.Generate(Type) : + return processedType ?? (processedType = + (Reflector.IsIEntity(Type) ? Lite.Generate(Type) : Type.UnNullify() == typeof(PrimaryKey) ? UnwrapFromPropertRoutes().Nullify() : Type.Nullify())); } @@ -170,21 +170,19 @@ Type ProcessedType private Type UnwrapFromPropertRoutes() { - if(propertyRoutes.IsNullOrEmpty()) - throw new InvalidOperationException("Impossible to determine the underlying type of the PrimaryKey of column {0} if PropertyRoutes is not set" - .FormatWith(this.Name)); + if(propertyRoutes == null || propertyRoutes.Length == 0) + throw new InvalidOperationException($"Impossible to determine the underlying type of the PrimaryKey of column {this.Name} if PropertyRoutes is not set"); return propertyRoutes.Select(a => PrimaryKey.Type(a.RootType)).Distinct().SingleEx(); } public ColumnDescription BuildColumnDescription() { - return new ColumnDescription(Name, ProcessedType) + return new ColumnDescription(Name, ProcessedType, DisplayName()) { PropertyRoutes = propertyRoutes, Implementations = Implementations, - - DisplayName = DisplayName(), + Format = Format, Unit = Unit, }; diff --git a/Signum.Engine/DynamicQuery/ExpressionContainer.cs b/Signum.Engine/DynamicQuery/ExpressionContainer.cs index cf5d378562..3f87872350 100644 --- a/Signum.Engine/DynamicQuery/ExpressionContainer.cs +++ b/Signum.Engine/DynamicQuery/ExpressionContainer.cs @@ -49,7 +49,7 @@ public IEnumerable GetExtensions(QueryToken parent) return extensionsTokens.Concat(dicExtensionsTokens); } - public ExtensionInfo Register(Expression> lambdaToMethodOrProperty, Func niceName = null) + public ExtensionInfo Register(Expression> lambdaToMethodOrProperty, Func? niceName = null) { using (HeavyProfiler.LogNoStackTrace("RegisterExpression")) { @@ -106,17 +106,12 @@ public ExtensionDictionaryInfo RegisterDictionary( Expression>> collectionSelector, Expression> keySelector, Expression> valueSelector, - ResetLazy> allKeys = null) + ResetLazy>? allKeys = null) where T : Entity + where K : object { - var mei = new ExtensionDictionaryInfo - { - CollectionSelector = collectionSelector, - KeySelector = keySelector, - ValueSelector = valueSelector, - - AllKeys = allKeys ?? GetAllKeysLazy(collectionSelector, keySelector) - }; + var mei = new ExtensionDictionaryInfo(collectionSelector, keySelector, valueSelector, + allKeys ?? GetAllKeysLazy(collectionSelector, keySelector)); RegisteredExtensionsDictionaries.Add(PropertyRoute.Root(typeof(T)), mei); @@ -128,20 +123,14 @@ public ExtensionDictionaryInfo RegisterDictionaryInEmbedded>> collectionSelector, Expression> keySelector, Expression> valueSelector, - ResetLazy> allKeys = null) + ResetLazy>? allKeys = null) where T : Entity where M : ModifiableEntity - + where K : object { - var mei = new ExtensionDictionaryInfo - { - CollectionSelector = collectionSelector, - KeySelector = keySelector, - ValueSelector = valueSelector, - - AllKeys = allKeys ?? GetAllKeysLazy(CombineSelectors(embeddedSelector, collectionSelector) , keySelector) - }; - + var mei = new ExtensionDictionaryInfo(collectionSelector, keySelector, valueSelector, + allKeys ?? GetAllKeysLazy(CombineSelectors(embeddedSelector, collectionSelector), keySelector)); + RegisteredExtensionsDictionaries.Add(PropertyRoute.Construct(embeddedSelector), mei); return mei; @@ -184,6 +173,7 @@ public interface IExtensionDictionaryInfo } public class ExtensionDictionaryInfo : IExtensionDictionaryInfo + where K : object { public ResetLazy> AllKeys; @@ -195,6 +185,18 @@ public class ExtensionDictionaryInfo : IExtensionDictionaryInfo ConcurrentDictionary metas = new ConcurrentDictionary(); + public ExtensionDictionaryInfo( + Expression>> collectionSelector, + Expression> keySelector, + Expression> valueSelector, + ResetLazy> allKeys) + { + CollectionSelector = collectionSelector; + KeySelector = keySelector; + ValueSelector = valueSelector; + AllKeys = allKeys; + } + public IEnumerable GetAllTokens(QueryToken parent) { var info = metas.GetOrAdd(parent, qt => @@ -202,17 +204,15 @@ public IEnumerable GetAllTokens(QueryToken parent) Expression> lambda = t => ValueSelector.Evaluate(CollectionSelector.Evaluate(t).SingleOrDefaultEx()); Expression e = MetadataVisitor.JustVisit(lambda, MetaExpression.FromToken(qt, typeof(T))); - - MetaExpression me = e as MetaExpression; - + var result = new ExtensionRouteInfo(); - if (me?.Meta is CleanMeta cm && cm.PropertyRoutes.Any()) + if (e is MetaExpression me && me.Meta is CleanMeta cm && cm.PropertyRoutes.Any()) { - var cleanType = me.Type.CleanType(); + var cleanType = me!.Type.CleanType(); result.PropertyRoute = cm.PropertyRoutes.Only(); - result.Implementations = me.Meta.Implementations; + result.Implementations = me!.Meta.Implementations; result.Format = ColumnDescriptionFactory.GetFormat(cm.PropertyRoutes); result.Unit = ColumnDescriptionFactory.GetUnit(cm.PropertyRoutes); } @@ -235,8 +235,7 @@ public IEnumerable GetAllTokens(QueryToken parent) public class ExtensionInfo { ConcurrentDictionary metas = new ConcurrentDictionary(); - - + public ExtensionInfo(Type sourceType, LambdaExpression lambda, Type type, string key, Func niceName) { this.Type = type; @@ -254,10 +253,10 @@ public ExtensionInfo(Type sourceType, LambdaExpression lambda, Type type, string public bool Inherit = true; public Implementations? ForceImplementations; - public PropertyRoute ForcePropertyRoute; - public string ForceFormat; - public string ForceUnit; - public Func ForceIsAllowed; + public PropertyRoute? ForcePropertyRoute; + public string? ForceFormat; + public string? ForceUnit; + public Func? ForceIsAllowed; internal readonly LambdaExpression Lambda; @@ -269,7 +268,7 @@ protected internal virtual ExtensionToken CreateToken(QueryToken parent) { Expression e = MetadataVisitor.JustVisit(Lambda, MetaExpression.FromToken(qt, SourceType)); - MetaExpression me; + MetaExpression? me; if (this.IsProjection) { @@ -287,7 +286,7 @@ protected internal virtual ExtensionToken CreateToken(QueryToken parent) var result = new ExtensionRouteInfo(); - if (me?.Meta is CleanMeta cleanMeta && cleanMeta.PropertyRoutes.Any()) + if (me != null && me.Meta is CleanMeta cleanMeta && cleanMeta.PropertyRoutes.Any()) { result.PropertyRoute = cleanMeta.PropertyRoutes.Only(); result.Implementations = me.Meta.Implementations; @@ -305,7 +304,7 @@ protected internal virtual ExtensionToken CreateToken(QueryToken parent) result.IsAllowed = () => (me == null || me.Meta == null) ? null : me.Meta.IsAllowed(); if (ForcePropertyRoute != null) - result.PropertyRoute = ForcePropertyRoute; + result.PropertyRoute = ForcePropertyRoute!; if (ForceImplementations != null) result.Implementations = ForceImplementations; @@ -317,7 +316,7 @@ protected internal virtual ExtensionToken CreateToken(QueryToken parent) result.Unit = ForceUnit; if (ForceIsAllowed != null) - result.IsAllowed = ForceIsAllowed; + result.IsAllowed = ForceIsAllowed!; return result; }); @@ -327,12 +326,14 @@ protected internal virtual ExtensionToken CreateToken(QueryToken parent) } } +#pragma warning disable CS8618 // Non-nullable field is uninitialized. public class ExtensionRouteInfo { - public string Format; - public string Unit; + public string? Format; + public string? Unit; public Implementations? Implementations; - public Func IsAllowed; - public PropertyRoute PropertyRoute; + public Func IsAllowed; + public PropertyRoute? PropertyRoute; } +#pragma warning restore CS8618 // Non-nullable field is uninitialized. } diff --git a/Signum.Engine/Engine/ProgressExtensions.cs b/Signum.Engine/Engine/ProgressExtensions.cs index f48d41206c..deb31b983a 100644 --- a/Signum.Engine/Engine/ProgressExtensions.cs +++ b/Signum.Engine/Engine/ProgressExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Signum.Engine.Maps; using System.Threading; @@ -25,10 +25,10 @@ public static class ProgressExtensions public static List ProgressSelect(this IEnumerable collection, Func selector, - Func elementID = null, - LogWriter writer = null, + Func? elementID = null, + LogWriter? writer = null, bool showProgress = true, - ParallelOptions parallelOptions = null) + ParallelOptions? parallelOptions = null) { List result = new List(); @@ -47,20 +47,20 @@ public static List ProgressSelect(this IEnumerable collection, /// Executes an action for each element in the collection transactionally and showing the progress in the Console /// public static void ProgressForeach(this IEnumerable collection, - Func elementID = null, - Action action = null, + Func? elementID = null, + Action? action = null, bool transactional = true, bool showProgress = true, - LogWriter writer = null, - ParallelOptions parallelOptions = null, - Type disableIdentityFor = null) + LogWriter? writer = null, + ParallelOptions? parallelOptions = null, + Type? disableIdentityFor = null) { if (action == null) throw new InvalidOperationException("no action specified"); if (elementID == null) { - elementID = e => e.ToString(); + elementID = e => e!.ToString(); } if (writer == null) writer = GetConsoleWriter(); @@ -90,7 +90,7 @@ public static void ProgressForeach(this IEnumerable collection, using (table.PrimaryKey.Default != null ? null : Administrator.DisableIdentity(table.Name)) - action(item); + action!(item); tr.Commit(); } }); @@ -105,7 +105,7 @@ public static void ProgressForeach(this IEnumerable collection, private static void ProgressForeachInternal(this IEnumerable collection, Func elementID, LogWriter writer, - ParallelOptions parallelOptions, + ParallelOptions? parallelOptions, bool transactional, bool showProgress, Action action @@ -187,7 +187,7 @@ Action action lock (SafeConsole.SyncKey) SafeConsole.WriteSameLine(pi.ToString()); - Exception stopException = null; + Exception? stopException = null; using (ExecutionContext.SuppressFlow()) Parallel.ForEach(col, @@ -242,7 +242,7 @@ Action action public static string DefaultLogFolder = "Log"; - public static StreamWriter TryOpenAutoFlush(string fileName) + public static StreamWriter? TryOpenAutoFlush(string fileName) { if (string.IsNullOrEmpty(fileName)) return null; diff --git a/Signum.Engine/Engine/SchemaSynchronizer.cs b/Signum.Engine/Engine/SchemaSynchronizer.cs index 25abfd2ca1..1c35e66bcc 100644 --- a/Signum.Engine/Engine/SchemaSynchronizer.cs +++ b/Signum.Engine/Engine/SchemaSynchronizer.cs @@ -17,7 +17,7 @@ public static class SchemaSynchronizer public static Action> SimplifyDiffTables; - public static SqlPreCommand SynchronizeTablesScript(Replacements replacements) + public static SqlPreCommand? SynchronizeTablesScript(Replacements replacements) { Schema s = Schema.Current; @@ -127,7 +127,7 @@ 3. Drop {diff.Name} - Func DeleteAllForeignKey = tableName => + Func DeleteAllForeignKey = tableName => { var dropFks = (from t in databaseTables.Values from c in t.Columns.Values @@ -142,12 +142,12 @@ from c in t.Columns.Values using (replacements.WithReplacedDatabaseName()) { - SqlPreCommand preRenameTables = preRenames.Select(a => SqlBuilder.RenameTable(a.Key, a.Value.Name)).Combine(Spacing.Double); + SqlPreCommand? preRenameTables = preRenames.Select(a => SqlBuilder.RenameTable(a.Key, a.Value.Name)).Combine(Spacing.Double); if (preRenameTables != null) preRenameTables.GoAfter = true; - SqlPreCommand createSchemas = Synchronizer.SynchronizeScriptReplacing(replacements, "Schemas", Spacing.Double, + SqlPreCommand? createSchemas = Synchronizer.SynchronizeScriptReplacing(replacements, "Schemas", Spacing.Double, modelSchemas.ToDictionary(a => a.ToString()), databaseSchemas.ToDictionary(a => a.ToString()), createNew: (_, newSN) => SqlBuilder.CreateSchema(newSN), @@ -156,7 +156,7 @@ from c in t.Columns.Values ); //use database without replacements to just remove indexes - SqlPreCommand dropStatistics = + SqlPreCommand? dropStatistics = Synchronizer.SynchronizeScript(Spacing.Double, modelTables, databaseTables, createNew: null, removeOld: (tn, dif) => SqlBuilder.DropStatistics(tn, dif.Stats), @@ -167,7 +167,7 @@ from c in t.Columns.Values return SqlBuilder.DropStatistics(tn, dif.Stats.Where(a => a.Columns.Any(removedColums.Contains)).ToList()); }); - SqlPreCommand dropIndices = + SqlPreCommand? dropIndices = Synchronizer.SynchronizeScript(Spacing.Double, modelTables, databaseTables, createNew: null, removeOld: (tn, dif) => dif.Indices.Values.Where(ix => !ix.IsPrimary).Select(ix => SqlBuilder.DropIndex(dif.Name, ix)).Combine(Spacing.Simple), @@ -186,7 +186,7 @@ from c in t.Columns.Values return changes; }); - SqlPreCommand dropIndicesHistory = + SqlPreCommand? dropIndicesHistory = Synchronizer.SynchronizeScript(Spacing.Double, modelTablesHistory, databaseTablesHistory, createNew: null, removeOld: (tn, dif) => dif.Indices.Values.Where(ix => ix.Type != DiffIndexType.Clustered).Select(ix => SqlBuilder.DropIndex(dif.Name, ix)).Combine(Spacing.Simple), @@ -205,7 +205,7 @@ from c in t.Columns.Values return changes; }); - SqlPreCommand dropForeignKeys = Synchronizer.SynchronizeScript( + SqlPreCommand? dropForeignKeys = Synchronizer.SynchronizeScript( Spacing.Double, modelTables, databaseTables, @@ -226,9 +226,9 @@ from c in t.Columns.Values dif.MultiForeignKeys.Select(fk => SqlBuilder.AlterTableDropConstraint(dif.Name, fk.Name)).Combine(Spacing.Simple)) ); - SqlPreCommand preRenamePks = preRenames.Select(a => SqlBuilder.DropPrimaryKeyConstraint(a.Value)).Combine(Spacing.Double); + SqlPreCommand? preRenamePks = preRenames.Select(a => SqlBuilder.DropPrimaryKeyConstraint(a.Value)).Combine(Spacing.Double); - SqlPreCommand tables = + SqlPreCommand? tables = Synchronizer.SynchronizeScript( Spacing.Double, modelTables, @@ -243,7 +243,7 @@ from c in t.Columns.Values var rename = !object.Equals(dif.Name, tab.Name) ? SqlBuilder.RenameOrMove(dif, tab) : null; var disableSystemVersioning = (dif.TemporalType != SysTableTemporalType.None && - (tab.SystemVersioned == null || !object.Equals(replacements.Apply(Replacements.KeyTables, dif.TemporalTableName.ToString()), tab.SystemVersioned.TableName.ToString())) ? + (tab.SystemVersioned == null || !object.Equals(replacements.Apply(Replacements.KeyTables, dif.TemporalTableName!.ToString()), tab.SystemVersioned.TableName.ToString())) ? SqlBuilder.AlterTableDisableSystemVersioning(tab.Name) : null); var dropPeriod = (dif.Period != null && @@ -285,7 +285,7 @@ from c in t.Columns.Values difCol.DefaultEquals(tabCol) ? null : SqlPreCommand.Combine(Spacing.Simple, difCol.DefaultConstraint != null ? SqlBuilder.AlterTableDropConstraint(tab.Name, difCol.DefaultConstraint.Name) : null, - tabCol.Default != null ? SqlBuilder.AlterTableAddDefaultConstraint(tab.Name, SqlBuilder.GetDefaultConstaint(tab, tabCol)) : null), + tabCol.Default != null ? SqlBuilder.AlterTableAddDefaultConstraint(tab.Name, SqlBuilder.GetDefaultConstaint(tab, tabCol)!) : null), UpdateByFkChange(tn, difCol, tabCol, ChangeName, copyDataFrom) ) @@ -300,7 +300,7 @@ from c in t.Columns.Values SqlBuilder.AlterTableEnableSystemVersioning(tab).Do(a=>a.GoBefore = true) : null); - SqlPreCommand combinedAddPeriod = null; + SqlPreCommand? combinedAddPeriod = null; if(addPeriod != null && columns is SqlPreCommandConcat cols) { var periodRows = cols.Leaves().Where(pcs => pcs.Sql.Contains(" ADD ") && pcs.Sql.Contains("GENERATED ALWAYS AS ROW")).ToList(); @@ -322,14 +322,14 @@ from c in t.Columns.Values if (tables != null) tables.GoAfter = true; - SqlPreCommand historyTables = Synchronizer.SynchronizeScript(Spacing.Double, modelTablesHistory, databaseTablesHistory, + SqlPreCommand? historyTables = Synchronizer.SynchronizeScript(Spacing.Double, modelTablesHistory, databaseTablesHistory, createNew: null, removeOld: (tn, dif) => SqlBuilder.DropTable(dif.Name), mergeBoth: (tn, tab, dif) => !object.Equals(dif.Name, tab.SystemVersioned.TableName) ? SqlBuilder.RenameOrChangeSchema(dif.Name, tab.SystemVersioned.TableName) : null); - SqlPreCommand syncEnums = SynchronizeEnumsScript(replacements); + SqlPreCommand? syncEnums = SynchronizeEnumsScript(replacements); - SqlPreCommand addForeingKeys = Synchronizer.SynchronizeScript( + SqlPreCommand? addForeingKeys = Synchronizer.SynchronizeScript( Spacing.Double, modelTables, databaseTables, @@ -362,7 +362,7 @@ from c in t.Columns.Values bool? createMissingFreeIndexes = null; - SqlPreCommand addIndices = + SqlPreCommand? addIndices = Synchronizer.SynchronizeScript(Spacing.Double, modelTables, databaseTables, createNew: (tn, tab) => modelIndices[tab].Values.Where(a => !(a is PrimaryClusteredIndex)).Select(index => SqlBuilder.CreateIndex(index, null)).Combine(Spacing.Simple), removeOld: null, @@ -383,7 +383,7 @@ from c in t.Columns.Values return SqlPreCommand.Combine(Spacing.Simple, controlledIndexes); }); - SqlPreCommand addIndicesHistory = + SqlPreCommand? addIndicesHistory = Synchronizer.SynchronizeScript(Spacing.Double, modelTablesHistory, databaseTablesHistory, createNew: (tn, tab) => modelIndices[tab].Values.Where(a => a.GetType() == typeof(Index)).Select(mix => SqlBuilder.CreateIndexBasic(mix, forHistoryTable: true)).Combine(Spacing.Simple), removeOld: null, @@ -404,7 +404,7 @@ from c in t.Columns.Values return SqlPreCommand.Combine(Spacing.Simple, controlledIndexes); }); - SqlPreCommand dropSchemas = Synchronizer.SynchronizeScriptReplacing(replacements, "Schemas", Spacing.Double, + SqlPreCommand? dropSchemas = Synchronizer.SynchronizeScriptReplacing(replacements, "Schemas", Spacing.Double, modelSchemas.ToDictionary(a => a.ToString()), databaseSchemas.ToDictionary(a => a.ToString()), createNew: null, @@ -421,7 +421,7 @@ from c in t.Columns.Values } } - private static SqlPreCommandSimple NotNullUpdate(ITable tab, IColumn tabCol, Replacements rep, bool goBefore) + private static SqlPreCommandSimple? NotNullUpdate(ITable tab, IColumn tabCol, Replacements rep, bool goBefore) { var defaultValue = GetDefaultValue(tab, tabCol, rep, forNewColumn: false); @@ -453,7 +453,7 @@ private static HashSet DefaultGetSchemas(List list) return result; } - private static SqlPreCommand AlterTableAddColumnDefault(ITable table, IColumn column, Replacements rep, string forceDefaultValue) + private static SqlPreCommand AlterTableAddColumnDefault(ITable table, IColumn column, Replacements rep, string? forceDefaultValue) { if (column.Nullable == IsNullable.Yes || column.Identity || column.Default != null || column is ImplementationColumn) return SqlBuilder.AlterTableAddColumn(table, column); @@ -475,19 +475,18 @@ private static SqlPreCommand AlterTableAddColumnDefault(ITable table, IColumn co SqlBuilder.AlterTableAddColumn(table, column).Do(a => a.GoAfter = true), new SqlPreCommandSimple($@"UPDATE {table.Name} SET {column.Name} = {SqlBuilder.Quote(column.SqlDbType, defaultValue)} -WHERE {where}")); +WHERE {where}"))!; } - var tempDefault = new SqlBuilder.DefaultConstraint - { - ColumnName = column.Name, - Name = "DF_TEMP_" + column.Name, - QuotedDefinition = SqlBuilder.Quote(column.SqlDbType, defaultValue), - }; + var tempDefault = new SqlBuilder.DefaultConstraint( + columnName: column.Name, + name: "DF_TEMP_" + column.Name, + quotedDefinition : SqlBuilder.Quote(column.SqlDbType, defaultValue) + ); return SqlPreCommand.Combine(Spacing.Simple, SqlBuilder.AlterTableAddColumn(table, column, tempDefault), - SqlBuilder.AlterTableDropConstraint(table.Name, tempDefault.Name)); + SqlBuilder.AlterTableDropConstraint(table.Name, tempDefault.Name))!; } internal static SqlPreCommand CopyData(ITable newTable, DiffTable oldTable, Replacements rep) @@ -508,10 +507,10 @@ internal static SqlPreCommand CopyData(ITable newTable, DiffTable oldTable, Repl SqlBuilder.SetIdentityInsert(newTable.Name, true), insertSelect, SqlBuilder.SetIdentityInsert(newTable.Name, false) - ); + )!; } - public static string GetDefaultValue(ITable table, IColumn column, Replacements rep, bool forNewColumn, string forceDefaultValue = null) + public static string GetDefaultValue(ITable table, IColumn column, Replacements rep, bool forNewColumn, string? forceDefaultValue = null) { if(column is SystemVersionedInfo.Column svc) { @@ -520,6 +519,8 @@ public static string GetDefaultValue(ITable table, IColumn column, Replacements return $"CONVERT(datetime2, '{date:yyyy-MM-dd HH:mm:ss.fffffff}')"; } + column = column!; /*CSBUG*/ + string typeDefault = forceDefaultValue ?? (SqlBuilder.IsNumber(column.SqlDbType) ? "0" : SqlBuilder.IsString(column.SqlDbType) ? "''" : @@ -595,7 +596,7 @@ private static Dictionary ApplyIndexAutoReplacements(DiffTabl return diff.Indices.SelectDictionary(on => replacements.TryGetC(on) ?? on, dif => dif); } - private static SqlPreCommandSimple UpdateByFkChange(string tn, DiffColumn difCol, IColumn tabCol, Func changeName, Dictionary copyDataFrom) + private static SqlPreCommandSimple? UpdateByFkChange(string tn, DiffColumn difCol, IColumn tabCol, Func changeName, Dictionary copyDataFrom) { if (difCol.ForeignKey == null || tabCol.ReferenceTable == null || tabCol.AvoidForeignKey) return null; @@ -776,7 +777,7 @@ public static SqlDbType ToSqlDbType(string str) } - static SqlPreCommand SynchronizeEnumsScript(Replacements replacements) + static SqlPreCommand? SynchronizeEnumsScript(Replacements replacements) { try { @@ -786,7 +787,7 @@ static SqlPreCommand SynchronizeEnumsScript(Replacements replacements) foreach (var table in schema.Tables.Values) { - Type enumType = EnumEntity.Extract(table.Type); + Type? enumType = EnumEntity.Extract(table.Type); if (enumType != null) { Console.Write("."); @@ -795,7 +796,7 @@ static SqlPreCommand SynchronizeEnumsScript(Replacements replacements) Dictionary shouldByName = should.ToDictionary(a => a.ToString()); List current = Administrator.TryRetrieveAll(table.Type, replacements); - Dictionary currentByName = current.ToDictionaryEx(a => a.toStr, table.Name.Name); + Dictionary currentByName = current.ToDictionaryEx(a => a.toStr!, table.Name.Name); string key = Replacements.KeyEnumsForTable(table.Name.Name); @@ -803,7 +804,7 @@ static SqlPreCommand SynchronizeEnumsScript(Replacements replacements) currentByName = replacements.ApplyReplacementsToOld(currentByName, key); - var mix = shouldByName.JoinDictionary(currentByName, (n, s, c) => new { s, c }).Where(a => a.Value.s.id != a.Value.c.id).ToDictionary(); + var mix = shouldByName.JoinDictionary(currentByName, (n, s, c) => (s, c)).Where(a => a.Value.s.id != a.Value.c.id).ToDictionary(); HashSet usedIds = current.Select(a => a.Id).ToHashSet(); @@ -888,7 +889,7 @@ private static Entity Clone(Entity current) return instance; } - public static SqlPreCommand SnapshotIsolation(Replacements replacements) + public static SqlPreCommand? SnapshotIsolation(Replacements replacements) { if (replacements.SchemaOnly) return null; @@ -907,9 +908,9 @@ public static SqlPreCommand SnapshotIsolation(Replacements replacements) var cmd = replacements.WithReplacedDatabaseName().Using(_ => results.Select((a, i) => SqlPreCommand.Combine(Spacing.Simple, - !a.snapshot_isolation_state || !a.is_read_committed_snapshot_on ? DisconnectUsers(a.name, "SPID" + i) : null, - !a.snapshot_isolation_state ? SqlBuilder.SetSnapshotIsolation(a.name, true) : null, - !a.is_read_committed_snapshot_on ? SqlBuilder.MakeSnapshotIsolationDefault(a.name, true) : null)).Combine(Spacing.Double)); + !a.snapshot_isolation_state || !a.is_read_committed_snapshot_on ? DisconnectUsers(a.name!/*CSBUG*/, "SPID" + i) : null, + !a.snapshot_isolation_state ? SqlBuilder.SetSnapshotIsolation(a.name!/*CSBUG*/, true) : null, + !a.is_read_committed_snapshot_on ? SqlBuilder.MakeSnapshotIsolationDefault(a.name!/*CSBUG*/, true) : null)).Combine(Spacing.Double)); if (cmd == null) return null; @@ -961,8 +962,8 @@ public List ViewIndices } public SysTableTemporalType TemporalType; - public ObjectName TemporalTableName; - public DiffPeriod Period; + public ObjectName? TemporalTableName; + public DiffPeriod? Period; public Dictionary Indices = new Dictionary(); @@ -1102,9 +1103,9 @@ public class DiffColumn { public string Name; public SqlDbType SqlDbType; - public string UserTypeName; + public string? UserTypeName; public bool Nullable; - public string Collation; + public string? Collation; public int Length; public int Precision; public int Scale; @@ -1113,7 +1114,7 @@ public class DiffColumn public DiffForeignKey ForeignKey; - public DiffDefaultConstraint DefaultConstraint; + public DiffDefaultConstraint? DefaultConstraint; public GeneratedAlwaysType GeneratedAlwaysType; diff --git a/Signum.Engine/Engine/SqlBuilder.cs b/Signum.Engine/Engine/SqlBuilder.cs index 41b700c807..20dc172dfa 100644 --- a/Signum.Engine/Engine/SqlBuilder.cs +++ b/Signum.Engine/Engine/SqlBuilder.cs @@ -57,7 +57,7 @@ public static SqlPreCommand DropTable(DiffTable diffTable) AlterTableDisableSystemVersioning(diffTable.Name), DropTable(diffTable.Name), DropTable(diffTable.TemporalTableName) - ); + )!; } public static SqlPreCommand DropTable(ObjectName tableName) @@ -75,7 +75,7 @@ static SqlPreCommand DropViewIndex(ObjectName viewName, string index) return new[]{ DropIndex(viewName, index), DropView(viewName) - }.Combine(Spacing.Simple); + }.Combine(Spacing.Simple)!; } public static SqlPreCommand AlterTableAddPeriod(ITable table) @@ -111,7 +111,7 @@ public static SqlPreCommand AlterTableDropColumn(ITable table, string columnName return new SqlPreCommandSimple("ALTER TABLE {0} DROP COLUMN {1}".FormatWith(table.Name, columnName.SqlEscape())); } - public static SqlPreCommand AlterTableAddColumn(ITable table, IColumn column, SqlBuilder.DefaultConstraint tempDefault = null) + public static SqlPreCommand AlterTableAddColumn(ITable table, IColumn column, SqlBuilder.DefaultConstraint? tempDefault = null) { return new SqlPreCommandSimple("ALTER TABLE {0} ADD {1}".FormatWith(table.Name, CreateColumn(column, tempDefault ?? GetDefaultConstaint(table, column)))); } @@ -163,28 +163,28 @@ public static bool IsDate(SqlDbType sqlDbType) return false; } - public static SqlPreCommand AlterTableAlterColumn(ITable table, IColumn column, string defaultConstraintName = null) + public static SqlPreCommand AlterTableAlterColumn(ITable table, IColumn column, string? defaultConstraintName = null) { var alterColumn = new SqlPreCommandSimple("ALTER TABLE {0} ALTER COLUMN {1}".FormatWith(table.Name, CreateColumn(column, null))); if (column.Default == null) return alterColumn; - var defCons = GetDefaultConstaint(table, column); + var defCons = GetDefaultConstaint(table, column)!; return SqlPreCommand.Combine(Spacing.Simple, AlterTableDropConstraint(table.Name, defaultConstraintName ?? defCons.Name), alterColumn, AlterTableAddDefaultConstraint(table.Name, defCons) - ); + )!; } - public static DefaultConstraint GetDefaultConstaint(ITable t, IColumn c) + public static DefaultConstraint? GetDefaultConstaint(ITable t, IColumn c) { if (c.Default == null) return null; - return new DefaultConstraint { ColumnName = c.Name, Name = $"DF_{t.Name.Name}_{c.Name}", QuotedDefinition = Quote(c.SqlDbType, c.Default) }; + return new DefaultConstraint(c.Name, $"DF_{t.Name.Name}_{c.Name}", Quote(c.SqlDbType, c.Default)); } public class DefaultConstraint @@ -192,10 +192,17 @@ public class DefaultConstraint public string ColumnName; public string Name; public string QuotedDefinition; + + public DefaultConstraint(string columnName, string name, string quotedDefinition) + { + ColumnName = columnName; + Name = name; + QuotedDefinition = quotedDefinition; + } } - public static string CreateColumn(IColumn c, DefaultConstraint constraint) + public static string CreateColumn(IColumn c, DefaultConstraint? constraint) { string fullType = GetColumnType(c); @@ -204,11 +211,12 @@ public static string CreateColumn(IColumn c, DefaultConstraint constraint) null; var defaultConstraint = constraint != null ? $"CONSTRAINT {constraint.Name} DEFAULT " + constraint.QuotedDefinition : null; + c = c!;/*CSBUG*/ return $" ".CombineIfNotEmpty( c.Name.SqlEscape(), fullType, - c.Identity ? "IDENTITY " : null, + c.Identity ? "IDENTITY " : null, generatedAlways, c.Collation != null ? ("COLLATE " + c.Collation) : null, c.Nullable.ToBool() ? "NULL" : "NOT NULL", @@ -243,7 +251,7 @@ public static string GetSizeScale(int? size, int? scale) return "({0},{1})".FormatWith(size, scale); } - public static SqlPreCommand AlterTableForeignKeys(ITable t) + public static SqlPreCommand? AlterTableForeignKeys(ITable t) { return t.Columns.Values.Select(c => (c.ReferenceTable == null || c.AvoidForeignKey) ? null : SqlBuilder.AlterTableAddConstraintForeignKey(t, c.Name, c.ReferenceTable)) @@ -272,7 +280,7 @@ public static SqlPreCommand DropIndex(ObjectName objectName, string indexName) .FormatWith(objectName.Schema.Database.ToString().SqlEscape(), indexName.SqlEscape(), objectName.OnDatabase(null).ToString())); } - public static SqlPreCommand CreateIndex(Index index, Replacements checkUnique) + public static SqlPreCommand CreateIndex(Index index, Replacements? checkUnique) { if (index is PrimaryClusteredIndex) { @@ -294,18 +302,21 @@ public static SqlPreCommand CreateIndex(Index index, Replacements checkUnique) SqlPreCommandSimple indexSql = new SqlPreCommandSimple($"CREATE UNIQUE CLUSTERED INDEX {uIndex.IndexName} ON {viewName}({columns})"); - return SqlPreCommand.Combine(Spacing.Simple, checkUnique!=null ? RemoveDuplicatesIfNecessary(uIndex, checkUnique) : null, viewSql, indexSql); + return SqlPreCommand.Combine(Spacing.Simple, + checkUnique!=null ? RemoveDuplicatesIfNecessary(uIndex, checkUnique) : null, + viewSql, + indexSql)!; } else { return SqlPreCommand.Combine(Spacing.Double, checkUnique != null ? RemoveDuplicatesIfNecessary(uIndex, checkUnique) : null, - CreateIndexBasic(index, false)); + CreateIndexBasic(index, false))!; } } else { - return CreateIndexBasic(index, forHistoryTable: false); + return CreateIndexBasic(index! /*CSBUG*/, forHistoryTable: false); } } @@ -335,7 +346,7 @@ GROUP BY {oldColumns} ){(string.IsNullOrWhiteSpace(uniqueIndex.Where) ? "" : "AND " + uniqueIndex.Where.Replace(columnReplacement))}"); } - public static SqlPreCommand RemoveDuplicatesIfNecessary(UniqueIndex uniqueIndex, Replacements rep) + public static SqlPreCommand? RemoveDuplicatesIfNecessary(UniqueIndex uniqueIndex, Replacements rep) { try { @@ -415,12 +426,12 @@ public static SqlPreCommandSimple AlterTableAddDefaultConstraint(ObjectName tabl return new SqlPreCommandSimple($"ALTER TABLE {tableName} ADD CONSTRAINT {constraint.Name} DEFAULT {constraint.QuotedDefinition} FOR {constraint.ColumnName}"); } - public static SqlPreCommand AlterTableAddConstraintForeignKey(ITable table, string fieldName, ITable foreignTable) + public static SqlPreCommand? AlterTableAddConstraintForeignKey(ITable table, string fieldName, ITable foreignTable) { return AlterTableAddConstraintForeignKey(table.Name, fieldName, foreignTable.Name, foreignTable.PrimaryKey.Name); } - public static SqlPreCommand AlterTableAddConstraintForeignKey(ObjectName parentTable, string parentColumn, ObjectName targetTable, string targetPrimaryKey) + public static SqlPreCommand? AlterTableAddConstraintForeignKey(ObjectName parentTable, string parentColumn, ObjectName targetTable, string targetPrimaryKey) { if (!object.Equals(parentTable.Schema.Database, targetTable.Schema.Database)) return null; @@ -443,7 +454,7 @@ public static SqlPreCommand RenameForeignKey(ObjectName foreignKeyName, string n return SP_RENAME(foreignKeyName.Schema.Database, foreignKeyName.OnDatabase(null).ToString(), newName, "OBJECT"); } - public static SqlPreCommandSimple SP_RENAME(DatabaseName database, string oldName, string newName, string objectType) + public static SqlPreCommandSimple SP_RENAME(DatabaseName? database, string oldName, string newName, string? objectType) { return new SqlPreCommandSimple("EXEC {0}SP_RENAME '{1}' , '{2}'{3}".FormatWith( database == null ? null: (new SchemaName(database, "dbo").ToString() + "."), @@ -465,7 +476,7 @@ public static SqlPreCommand RenameOrChangeSchema(ObjectName oldTableName, Object return SqlPreCommand.Combine(Spacing.Simple, AlterSchema(oldTableName, newTableName.Schema), - oldNewSchema.Equals(newTableName) ? null : RenameTable(oldNewSchema, newTableName.Name)); + oldNewSchema.Equals(newTableName) ? null : RenameTable(oldNewSchema, newTableName.Name))!; } public static SqlPreCommand RenameOrMove(DiffTable oldTable, ITable newTable) @@ -476,7 +487,7 @@ public static SqlPreCommand RenameOrMove(DiffTable oldTable, ITable newTable) return SqlPreCommand.Combine(Spacing.Simple, CreateTableSql(newTable), MoveRows(oldTable.Name, newTable.Name, newTable.Columns.Keys), - DropTable(oldTable)); + DropTable(oldTable))!; } public static SqlPreCommand MoveRows(ObjectName oldTable, ObjectName newTable, IEnumerable columnNames) @@ -493,7 +504,7 @@ public static SqlPreCommand MoveRows(ObjectName oldTable, ObjectName newTable, I return SqlPreCommand.Combine(Spacing.Simple, new SqlPreCommandSimple("SET IDENTITY_INSERT {0} ON".FormatWith(newTable)) { GoBefore = true }, command, - new SqlPreCommandSimple("SET IDENTITY_INSERT {0} OFF".FormatWith(newTable)) { GoAfter = true }); + new SqlPreCommandSimple("SET IDENTITY_INSERT {0} OFF".FormatWith(newTable)) { GoAfter = true })!; } public static SqlPreCommand RenameTable(ObjectName oldName, string newName) @@ -583,7 +594,7 @@ public static SqlPreCommandSimple RebuildIndex(ObjectName tableName, string inde public static SqlPreCommandSimple DropPrimaryKeyConstraint(ObjectName tableName) { - DatabaseName db = tableName.Schema.Database; + DatabaseName? db = tableName.Schema.Database; var tn = tableName.OnDatabase(null); @@ -604,7 +615,7 @@ EXEC DB.dbo.sp_executesql @sql" } - internal static SqlPreCommand DropStatistics(string tn, List list) + internal static SqlPreCommand? DropStatistics(string tn, List list) { if (list.IsEmpty()) return null; diff --git a/Signum.Engine/Engine/SqlPreCommand.cs b/Signum.Engine/Engine/SqlPreCommand.cs index cc688fcf9d..a4953cedd9 100644 --- a/Signum.Engine/Engine/SqlPreCommand.cs +++ b/Signum.Engine/Engine/SqlPreCommand.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -52,7 +52,7 @@ public override string ToString() return this.PlainSql(); } - public static SqlPreCommand Combine(Spacing spacing, params SqlPreCommand[] sentences) + public static SqlPreCommand? Combine(Spacing spacing, params SqlPreCommand?[] sentences) { if (sentences.Contains(null)) sentences = sentences.NotNull().ToArray(); @@ -63,7 +63,7 @@ public static SqlPreCommand Combine(Spacing spacing, params SqlPreCommand[] sent if (sentences.Length == 1) return sentences[0]; - return new SqlPreCommandConcat(spacing, sentences); + return new SqlPreCommandConcat(spacing, sentences as SqlPreCommand[]); } @@ -71,19 +71,16 @@ public static SqlPreCommand Combine(Spacing spacing, params SqlPreCommand[] sent public static class SqlPreCommandExtensions { - public static SqlPreCommand Combine(this IEnumerable preCommands, Spacing spacing) + public static SqlPreCommand? Combine(this IEnumerable preCommands, Spacing spacing) { return SqlPreCommand.Combine(spacing, preCommands.ToArray()); } public static SqlPreCommand PlainSqlCommand(this SqlPreCommand command) { - if (command == null) - return null; - return command.PlainSql().SplitNoEmpty("GO\r\n" ) .Select(s => new SqlPreCommandSimple(s)) - .Combine(Spacing.Simple); + .Combine(Spacing.Simple)!; } public static bool AvoidOpenOpenSqlFileRetry = true; @@ -132,14 +129,14 @@ public class SqlPreCommandSimple : SqlPreCommand public override bool GoAfter { get; set; } public string Sql { get; private set; } - public List Parameters { get; private set; } + public List? Parameters { get; private set; } public SqlPreCommandSimple(string sql) { this.Sql = sql; } - public SqlPreCommandSimple(string sql, List parameters) + public SqlPreCommandSimple(string sql, List? parameters) { this.Sql = sql; this.Parameters = parameters; @@ -182,16 +179,16 @@ internal static string Encode(object value) if (value is bool b) return (b ? 1 : 0).ToString(); - if (Schema.Current.Settings.UdtSqlName.TryGetValue(value.GetType(), out var name)) + if (Schema.Current.Settings.UdtSqlName.TryGetValue(value!.GetType() /*CSBUG*/, out var name)) return "CAST('{0}' AS {1})".FormatWith(value, name); - if (value.GetType().IsEnum) + if (value!.GetType().IsEnum /*CSBUG*/) return Convert.ToInt32(value).ToString(); if (value is byte[] bytes) return "0x" + BitConverter.ToString(bytes).Replace("-", ""); - return value.ToString(); + return value!.ToString(); /*CSBUG*/ } protected internal override void PlainSql(StringBuilder sb) @@ -218,11 +215,10 @@ public string sp_executesql() public override SqlPreCommand Clone() { - return new SqlPreCommandSimple(Sql, Parameters?.Select(p => Connector.Current.CloneParameter(p)) - .ToList()); + return new SqlPreCommandSimple(Sql, Parameters?.Select(p => Connector.Current.CloneParameter(p)).ToList()); } - public SqlPreCommandSimple AddComment(string comment) + public SqlPreCommandSimple AddComment(string? comment) { if (comment.HasText()) { @@ -236,14 +232,14 @@ public SqlPreCommandSimple AddComment(string comment) return this; } - public SqlPreCommandSimple ReplaceFirstParameter(string variableName) + public SqlPreCommandSimple ReplaceFirstParameter(string? variableName) { if (variableName == null) return this; - var first = Parameters.FirstEx(); + var first = Parameters!.FirstEx(); Sql = Regex.Replace(Sql, $@"(?{first.ParameterName})(\b|$)", variableName); //HACK - Parameters.Remove(first); + Parameters!.Remove(first); return this; } } diff --git a/Signum.Engine/Engine/Synchronizer.cs b/Signum.Engine/Engine/Synchronizer.cs index 111b32d6da..e16993c802 100644 --- a/Signum.Engine/Engine/Synchronizer.cs +++ b/Signum.Engine/Engine/Synchronizer.cs @@ -11,9 +11,10 @@ public static class Synchronizer public static void Synchronize( Dictionary newDictionary, Dictionary oldDictionary, - Action createNew, - Action removeOld, - Action merge) + Action? createNew, + Action? removeOld, + Action? merge) + where K : object { HashSet keys = new HashSet(); keys.UnionWith(oldDictionary.Keys); @@ -42,11 +43,12 @@ public static void Synchronize( public static void SynchronizeProgressForeach( Dictionary newDictionary, Dictionary oldDictionary, - Action createNew, - Action removeOld, - Action merge, + Action? createNew, + Action? removeOld, + Action? merge, bool showProgress = true, bool transactional = true) + where K : object { HashSet keys = new HashSet(); keys.UnionWith(oldDictionary.Keys); @@ -77,9 +79,9 @@ public static void SynchronizeReplacing( string replacementsKey, Dictionary newDictionary, Dictionary oldDictionary, - Action createNew, - Action removeOld, - Action merge) + Action? createNew, + Action? removeOld, + Action? merge) { replacements.AskForReplacements( oldDictionary.Keys.ToHashSet(), @@ -109,20 +111,21 @@ public static void SynchronizeReplacing( } } - public static SqlPreCommand SynchronizeScript( + public static SqlPreCommand? SynchronizeScript( Spacing spacing, Dictionary newDictionary, Dictionary oldDictionary, - Func createNew, - Func removeOld, - Func mergeBoth) + Func? createNew, + Func? removeOld, + Func? mergeBoth) where O : class where N : class + where K : object { return newDictionary.OuterJoinDictionaryCC(oldDictionary, (key, newVal, oldVal) => { if (newVal == null) - return removeOld == null ? null : removeOld(key, oldVal); + return removeOld == null ? null : removeOld(key, oldVal!); if (oldVal == null) return createNew == null ? null : createNew(key, newVal); @@ -133,15 +136,15 @@ public static SqlPreCommand SynchronizeScript( - public static SqlPreCommand SynchronizeScriptReplacing( + public static SqlPreCommand? SynchronizeScriptReplacing( Replacements replacements, string replacementsKey, Spacing spacing, Dictionary newDictionary, Dictionary oldDictionary, - Func createNew, - Func removeOld, - Func mergeBoth) + Func? createNew, + Func? removeOld, + Func? mergeBoth) where O : class where N : class { @@ -154,9 +157,9 @@ public static SqlPreCommand SynchronizeScriptReplacing( return SynchronizeScript(spacing, newDictionary, repOldDictionary, createNew, removeOld, mergeBoth); } - public static IDisposable RenameTable(Table table, Replacements replacements) + public static IDisposable? RenameTable(Table table, Replacements replacements) { - string fullName = replacements.TryGetC(Replacements.KeyTablesInverse)?.TryGetC(table.Name.ToString()); + string? fullName = replacements.TryGetC(Replacements.KeyTablesInverse)?.TryGetC(table.Name.ToString()); if (fullName == null) return null; @@ -184,9 +187,9 @@ public static string KeyEnumsForTable(string tableName) public bool Interactive = true; public bool SchemaOnly = false; - public string ReplaceDatabaseName = null; + public string? ReplaceDatabaseName = null; - public IDisposable WithReplacedDatabaseName() + public IDisposable? WithReplacedDatabaseName() { if (ReplaceDatabaseName == null) return null; @@ -196,7 +199,7 @@ public IDisposable WithReplacedDatabaseName() public string Apply(string replacementsKey, string textToReplace) { - Dictionary repDic = this.TryGetC(replacementsKey); + Dictionary? repDic = this.TryGetC(replacementsKey); return repDic?.TryGetC(textToReplace) ?? textToReplace; } @@ -286,7 +289,7 @@ static float Distance(StringDistance sd, string o, string n) return sd.LevenshteinDistance(o, n, weight: c => c.Type == StringDistance.ChoiceType.Substitute ? 2 : 1); } - public string SelectInteractive(string oldValue, ICollection newValues, string replacementsKey, StringDistance sd) + public string? SelectInteractive(string oldValue, ICollection newValues, string replacementsKey, StringDistance sd) { if (newValues.Contains(oldValue)) return oldValue; @@ -313,6 +316,13 @@ public class AutoReplacementContext public string ReplacementKey; public string OldValue; public List NewValues; + + public AutoReplacementContext(string replacementKey, string oldValue, List newValues) + { + ReplacementKey = replacementKey; + OldValue = oldValue; + NewValues = newValues; + } } public static Func AutoReplacement; @@ -321,12 +331,7 @@ private static Selection SelectInteractive(string oldValue, List newValu { if (AutoReplacement != null) { - Selection? selection = AutoReplacement(new AutoReplacementContext - { - ReplacementKey = replacementsKey, - OldValue = oldValue, - NewValues = newValues - }); + Selection? selection = AutoReplacement(new AutoReplacementContext(replacementsKey, oldValue, newValues)); if (selection != null) { SafeConsole.WriteLineColor(ConsoleColor.DarkGray, "AutoReplacement:"); @@ -396,14 +401,15 @@ private static Selection SelectInteractive(string oldValue, List newValu public struct Selection { - public Selection(string oldValue, string newValue) + /// Null for removed + public Selection(string oldValue, string? newValue) { this.OldValue = oldValue; this.NewValue = newValue; } public readonly string OldValue; - public readonly string NewValue; + public readonly string? NewValue; } } diff --git a/Signum.Engine/Linq/DbExpressions.Signum.cs b/Signum.Engine/Linq/DbExpressions.Signum.cs index 9422eb8fad..8325c6749d 100644 --- a/Signum.Engine/Linq/DbExpressions.Signum.cs +++ b/Signum.Engine/Linq/DbExpressions.Signum.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -22,19 +22,24 @@ internal class EntityExpression : DbExpression public readonly Table Table; public readonly PrimaryKeyExpression ExternalId; - public readonly NewExpression ExternalPeriod; + public readonly NewExpression? ExternalPeriod; //Optional - public readonly Alias TableAlias; - public readonly ReadOnlyCollection Bindings; - public readonly ReadOnlyCollection Mixins; + public readonly Alias? TableAlias; + public readonly ReadOnlyCollection? Bindings; + public readonly ReadOnlyCollection? Mixins; public readonly bool AvoidExpandOnRetrieving; - public readonly NewExpression TablePeriod; + public readonly NewExpression? TablePeriod; - public EntityExpression(Type type, PrimaryKeyExpression externalId, NewExpression externalPeriod, Alias tableAlias, IEnumerable bindings, IEnumerable mixins, NewExpression tablePeriod, bool avoidExpandOnRetrieving) + public EntityExpression(Type type, PrimaryKeyExpression externalId, + NewExpression? externalPeriod, + Alias? tableAlias, + IEnumerable? bindings, + IEnumerable? mixins, + NewExpression? tablePeriod, bool avoidExpandOnRetrieving) : base(DbExpressionType.Entity, type) { if (type == null) @@ -101,10 +106,10 @@ internal class EmbeddedEntityExpression : DbExpression public readonly ReadOnlyCollection Bindings; - public readonly FieldEmbedded FieldEmbedded; //used for updates - public readonly Table ViewTable; //used for updates + public readonly FieldEmbedded? FieldEmbedded; //used for updates + public readonly Table? ViewTable; //used for updates - public EmbeddedEntityExpression(Type type, Expression hasValue, IEnumerable bindings, FieldEmbedded fieldEmbedded, Table viewTable) + public EmbeddedEntityExpression(Type type, Expression hasValue, IEnumerable bindings, FieldEmbedded? fieldEmbedded, Table? viewTable) : base(DbExpressionType.EmbeddedInit, type) { if (bindings == null) @@ -144,7 +149,7 @@ protected override Expression Accept(DbExpressionVisitor visitor) public Expression GetViewId() { - var field = ViewTable.GetViewPrimaryKey(); + var field = ViewTable!.GetViewPrimaryKey(); return this.Bindings.SingleEx(b => ReflectionTools.FieldEquals(b.FieldInfo, field.FieldInfo)).Binding; } @@ -154,11 +159,11 @@ internal class MixinEntityExpression : DbExpression { public readonly ReadOnlyCollection Bindings; - public readonly FieldMixin FieldMixin; //used for updates + public readonly FieldMixin? FieldMixin; //used for updates - public readonly Alias MainEntityAlias; + public readonly Alias? MainEntityAlias; - public MixinEntityExpression(Type type, IEnumerable bindings, Alias mainEntityAlias, FieldMixin fieldMixin) + public MixinEntityExpression(Type type, IEnumerable bindings, Alias? mainEntityAlias, FieldMixin? fieldMixin) : base(DbExpressionType.MixinInit, type) { if (bindings == null) @@ -249,10 +254,10 @@ internal class ImplementedByAllExpression : DbExpression { public readonly Expression Id; public readonly TypeImplementedByAllExpression TypeId; - public readonly NewExpression ExternalPeriod; + public readonly NewExpression? ExternalPeriod; - public ImplementedByAllExpression(Type type, Expression id, TypeImplementedByAllExpression typeId, NewExpression externalPeriod) + public ImplementedByAllExpression(Type type, Expression id, TypeImplementedByAllExpression typeId, NewExpression? externalPeriod) : base(DbExpressionType.ImplementedByAll, type) { if (id == null) @@ -281,12 +286,12 @@ internal class LiteReferenceExpression : DbExpression public bool LazyToStr; public bool EagerEntity; public readonly Expression Reference; //Fie, ImplementedBy, ImplementedByAll or Constant to NullEntityExpression - public readonly Expression CustomToStr; //Not readonly + public readonly Expression? CustomToStr; //Not readonly - public LiteReferenceExpression(Type type, Expression reference, Expression customToStr, bool lazyToStr, bool eagerEntity) : + public LiteReferenceExpression(Type type, Expression reference, Expression? customToStr, bool lazyToStr, bool eagerEntity) : base(DbExpressionType.LiteReference, type) { - Type cleanType = Lite.Extract(type); + Type? cleanType = Lite.Extract(type); if (cleanType != reference.Type) throw new ArgumentException("The type {0} is not the Lite version of {1}".FormatWith(type.TypeName(), reference.Type.TypeName())); diff --git a/Signum.Engine/Linq/DbExpressions.Sql.cs b/Signum.Engine/Linq/DbExpressions.Sql.cs index 49857bd169..bddce390db 100644 --- a/Signum.Engine/Linq/DbExpressions.Sql.cs +++ b/Signum.Engine/Linq/DbExpressions.Sql.cs @@ -177,18 +177,18 @@ internal class TableExpression : SourceWithAliasExpression { public readonly ITable Table; - public ObjectName Name { get { return SystemTime is SystemTime.HistoryTable ? Table.SystemVersioned.TableName : Table.Name; } } + public ObjectName Name { get { return SystemTime is SystemTime.HistoryTable ? Table.SystemVersioned!.TableName : Table.Name; } } - public SystemTime SystemTime { get; private set; } + public SystemTime? SystemTime { get; private set; } - public readonly string WithHint; + public readonly string? WithHint; public override Alias[] KnownAliases { get { return new[] { Alias }; } } - internal TableExpression(Alias alias, ITable table, SystemTime systemTime, string withHint) + internal TableExpression(Alias alias, ITable table, SystemTime? systemTime, string? withHint) : base(DbExpressionType.Table, alias) { this.Table = table; @@ -239,11 +239,7 @@ public override string ToString() return "{0}.{1}".FormatWith(Alias, Name); } - public override bool Equals(object obj) - { - return Equals(obj as ColumnExpression); - } - + public override bool Equals(object obj) => obj is ColumnExpression ce && Equals(ce); public bool Equals(ColumnExpression other) { return other != null && other.Alias == Alias && other.Name == Name; @@ -365,11 +361,11 @@ internal enum SelectOptions internal class SelectExpression : SourceWithAliasExpression { public readonly ReadOnlyCollection Columns; - public readonly SourceExpression From; - public readonly Expression Where; + public readonly SourceExpression? From; + public readonly Expression? Where; public readonly ReadOnlyCollection OrderBy; public readonly ReadOnlyCollection GroupBy; - public readonly Expression Top; + public readonly Expression? Top; public readonly bool IsDistinct; public readonly SelectOptions SelectOptions; @@ -400,7 +396,7 @@ public override Alias[] KnownAliases get { return knownAliases; } } - internal SelectExpression(Alias alias, bool distinct, Expression top, IEnumerable columns, SourceExpression from, Expression where, IEnumerable orderBy, IEnumerable groupBy, SelectOptions options) + internal SelectExpression(Alias alias, bool distinct, Expression? top, IEnumerable? columns, SourceExpression? from, Expression? where, IEnumerable? orderBy, IEnumerable? groupBy, SelectOptions options) : base(DbExpressionType.Select, alias) { this.IsDistinct = distinct; @@ -492,14 +488,14 @@ internal class JoinExpression : SourceExpression public readonly JoinType JoinType; public readonly SourceExpression Left; public readonly SourceExpression Right; - public new readonly Expression Condition; + public new readonly Expression? Condition; public override Alias[] KnownAliases { get { return Left.KnownAliases.Concat(Right.KnownAliases).ToArray(); } } - internal JoinExpression(JoinType joinType, SourceExpression left, SourceExpression right, Expression condition) + internal JoinExpression(JoinType joinType, SourceExpression left, SourceExpression right, Expression? condition) : base(DbExpressionType.Join) { if (condition == null && joinType != JoinType.CrossApply && joinType != JoinType.OuterApply && joinType != JoinType.CrossJoin) @@ -716,11 +712,11 @@ protected override Expression Accept(DbExpressionVisitor visitor) internal class SqlFunctionExpression : DbExpression { - public readonly Expression Object; + public readonly Expression? Object; public readonly string SqlFunction; public readonly ReadOnlyCollection Arguments; - public SqlFunctionExpression(Type type, Expression obj, string sqlFunction, IEnumerable arguments) + public SqlFunctionExpression(Type type, Expression? obj, string sqlFunction, IEnumerable arguments) : base(DbExpressionType.SqlFunction, type) { this.SqlFunction = sqlFunction; @@ -744,14 +740,14 @@ protected override Expression Accept(DbExpressionVisitor visitor) internal class SqlConstantExpression : DbExpression { - public readonly object Value; + public readonly object? Value; public SqlConstantExpression(object value) : this(value, value.GetType()) { } - public SqlConstantExpression(object value, Type type) + public SqlConstantExpression(object? value, Type type) : base(DbExpressionType.SqlConstant, type) { this.Value = value; @@ -853,10 +849,9 @@ public static Expression NotEqualsNulll(this Expression exp) internal class CaseExpression : DbExpression { public readonly ReadOnlyCollection Whens; - public readonly Expression DefaultValue; - - - public CaseExpression(IEnumerable whens, Expression defaultValue) + public readonly Expression? DefaultValue; + + public CaseExpression(IEnumerable whens, Expression? defaultValue) : base(DbExpressionType.Case, GetType(whens, defaultValue)) { if (whens.IsEmpty()) @@ -871,7 +866,7 @@ public CaseExpression(IEnumerable whens, Expression defaultValue) this.DefaultValue = defaultValue; } - static Type GetType(IEnumerable whens, Expression defaultValue) + static Type GetType(IEnumerable whens, Expression? defaultValue) { var types = whens.Select(w => w.Value.Type).ToList(); if (defaultValue != null) @@ -933,8 +928,8 @@ protected override Expression Accept(DbExpressionVisitor visitor) internal abstract class SubqueryExpression : DbExpression { - public readonly SelectExpression Select; - protected SubqueryExpression(DbExpressionType nodeType, Type type, SelectExpression select) + public readonly SelectExpression? Select; + protected SubqueryExpression(DbExpressionType nodeType, Type type, SelectExpression? select) : base(nodeType, type) { System.Diagnostics.Debug.Assert(nodeType == DbExpressionType.Scalar || nodeType == DbExpressionType.Exists || nodeType == DbExpressionType.In); @@ -951,7 +946,7 @@ public ScalarExpression(Type type, SelectExpression select) public override string ToString() { - return "SCALAR({0})".FormatWith(Select.ToString()); + return "SCALAR({0})".FormatWith(Select!.ToString()); } protected override Expression Accept(DbExpressionVisitor visitor) @@ -1011,7 +1006,7 @@ public ExistsExpression(SelectExpression select) public override string ToString() { - return "EXIST({0})".FormatWith(Select.ToString()); + return "EXIST({0})".FormatWith(Select!.ToString()); } protected override Expression Accept(DbExpressionVisitor visitor) @@ -1023,7 +1018,7 @@ protected override Expression Accept(DbExpressionVisitor visitor) internal class InExpression : SubqueryExpression { public readonly Expression Expression; - public readonly object[] Values; + public readonly object[]? Values; public InExpression(Expression expression, SelectExpression select) : base(DbExpressionType.In, typeof(bool), select) @@ -1054,7 +1049,7 @@ public static Expression FromValues(Expression expression, object[] values) public override string ToString() { if (Values == null) - return "{0} IN ({1})".FormatWith(Expression.ToString(), Select.ToString()); + return "{0} IN ({1})".FormatWith(Expression.ToString(), Select!.ToString()); else return "{0} IN ({1})".FormatWith(Expression.ToString(), Values.ToString(", ")); } @@ -1089,9 +1084,9 @@ protected override Expression Accept(DbExpressionVisitor visitor) internal class RowNumberExpression : DbExpression { - public readonly ReadOnlyCollection OrderBy; + public readonly ReadOnlyCollection? OrderBy; - public RowNumberExpression(IEnumerable orderBy) + public RowNumberExpression(IEnumerable? orderBy) : base(DbExpressionType.RowNumber, typeof(int)) { this.OrderBy = orderBy.ToReadOnly(); @@ -1193,7 +1188,7 @@ internal class DeleteExpression : CommandExpression { public readonly ITable Table; public readonly bool UseHistoryTable; - public ObjectName Name { get { return UseHistoryTable ? Table.SystemVersioned.TableName : Table.Name; } } + public ObjectName Name { get { return UseHistoryTable ? Table.SystemVersioned!.TableName : Table.Name; } } public readonly SourceWithAliasExpression Source; public readonly Expression Where; @@ -1225,7 +1220,7 @@ internal class UpdateExpression : CommandExpression { public readonly ITable Table; public readonly bool UseHistoryTable; - public ObjectName Name { get { return UseHistoryTable ? Table.SystemVersioned.TableName : Table.Name; } } + public ObjectName Name { get { return UseHistoryTable ? Table.SystemVersioned!.TableName : Table.Name; } } public readonly ReadOnlyCollection Assigments; public readonly SourceWithAliasExpression Source; @@ -1260,7 +1255,7 @@ internal class InsertSelectExpression : CommandExpression { public readonly ITable Table; public readonly bool UseHistoryTable; - public ObjectName Name { get { return UseHistoryTable ? Table.SystemVersioned.TableName : Table.Name; } } + public ObjectName Name { get { return UseHistoryTable ? Table.SystemVersioned!.TableName : Table.Name; } } public readonly ReadOnlyCollection Assigments; public readonly SourceWithAliasExpression Source; diff --git a/Signum.Engine/Linq/DbQueryProvider.cs b/Signum.Engine/Linq/DbQueryProvider.cs index f7008a827b..5352d43af0 100644 --- a/Signum.Engine/Linq/DbQueryProvider.cs +++ b/Signum.Engine/Linq/DbQueryProvider.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using System.Linq.Expressions; using Signum.Utilities; @@ -57,7 +57,7 @@ internal R Translate(Expression expression, Func continu using (HeavyProfiler.Log("LINQ", () => expression.ToString())) using (var log = HeavyProfiler.LogNoStackTrace("Clean")) { - Expression cleaned = Clean(expression, true, log); + Expression cleaned = Clean(expression, true, log)!; var binder = new QueryBinder(aliasGenerator); log.Switch("Bind"); ProjectionExpression binded = (ProjectionExpression)binder.BindQuery(cleaned); @@ -71,17 +71,17 @@ internal R Translate(Expression expression, Func continu } - public static Expression Clean(Expression expression, bool filter, HeavyProfiler.Tracer log) + public static Expression? Clean(Expression? expression, bool filter, HeavyProfiler.Tracer? log) { - Expression clean = ExpressionCleaner.Clean(expression); + Expression? clean = ExpressionCleaner.Clean(expression); log.Switch("OvrLdSmp"); - Expression simplified = OverloadingSimplifier.Simplify(clean); + Expression? simplified = OverloadingSimplifier.Simplify(clean); log.Switch("QrFlr"); - Expression filtered = QueryFilterer.Filter(simplified, filter); + Expression? filtered = QueryFilterer.Filter(simplified, filter); return filtered; } - internal static Expression Optimize(Expression binded, QueryBinder binder, AliasGenerator aliasGenerator, HeavyProfiler.Tracer log) + internal static Expression Optimize(Expression binded, QueryBinder binder, AliasGenerator aliasGenerator, HeavyProfiler.Tracer? log) { log.Switch("Aggregate"); Expression rewrited = AggregateRewriter.Rewrite(binded); @@ -112,7 +112,7 @@ internal R Delete(IQueryable query, Func continuation using (HeavyProfiler.Log("LINQ")) using (var log = HeavyProfiler.LogNoStackTrace("Clean")) { - Expression cleaned = Clean(query.Expression, true, log); + Expression cleaned = Clean(query.Expression, true, log)!; log.Switch("Bind"); var binder = new QueryBinder(aliasGenerator); @@ -133,7 +133,7 @@ internal R Update(IUpdateable updateable, Func contin using (HeavyProfiler.Log("LINQ")) using (var log = HeavyProfiler.LogNoStackTrace("Clean")) { - Expression cleaned = Clean(updateable.Query.Expression, true, log); + Expression cleaned = Clean(updateable.Query.Expression, true, log)!; var binder = new QueryBinder(aliasGenerator); log.Switch("Bind"); @@ -154,7 +154,7 @@ internal R Insert(IQueryable query, LambdaExpression constructor, ITable tabl using (HeavyProfiler.Log("LINQ")) using (var log = HeavyProfiler.LogNoStackTrace("Clean")) { - Expression cleaned = Clean(query.Expression, true, log); + Expression cleaned = Clean(query.Expression, true, log)!; var binder = new QueryBinder(aliasGenerator); log.Switch("Bind"); CommandExpression insert = binder.BindInsert(cleaned, constructor, table); diff --git a/Signum.Engine/Linq/ExpressionVisitor/ChildProjectionFlattener.cs b/Signum.Engine/Linq/ExpressionVisitor/ChildProjectionFlattener.cs index af25aac84a..cb84a3187d 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/ChildProjectionFlattener.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/ChildProjectionFlattener.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -13,11 +13,11 @@ namespace Signum.Engine.Linq { internal class ChildProjectionFlattener : DbExpressionVisitor { - SelectExpression currentSource; + SelectExpression? currentSource; AliasGenerator aliasGenerator; private ChildProjectionFlattener(){} - public Type inMList = null; + public Type? inMList = null; protected internal override Expression VisitMListProjection(MListProjectionExpression mlp) { @@ -335,4 +335,4 @@ protected internal override Expression VisitColumn(ColumnExpression column) } } -} \ No newline at end of file +} diff --git a/Signum.Engine/Linq/ExpressionVisitor/DbExpressionComparer.cs b/Signum.Engine/Linq/ExpressionVisitor/DbExpressionComparer.cs index c37030c2c5..629d0f0528 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/DbExpressionComparer.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/DbExpressionComparer.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Signum.Utilities.ExpressionTrees; @@ -14,7 +14,7 @@ namespace Signum.Engine.Linq /// internal class DbExpressionComparer : ExpressionComparer { - ScopedDictionary aliasMap; + ScopedDictionary? aliasMap; protected IDisposable AliasScope() { @@ -23,13 +23,13 @@ protected IDisposable AliasScope() return new Disposable(() => aliasMap = saved); } - protected DbExpressionComparer(ScopedDictionary parameterScope, ScopedDictionary aliasScope, bool checkParameterNames) + protected DbExpressionComparer(ScopedDictionary? parameterScope, ScopedDictionary? aliasScope, bool checkParameterNames) : base(parameterScope, checkParameterNames) { this.aliasMap = aliasScope; } - public static bool AreEqual(Expression a, Expression b, ScopedDictionary parameterScope = null, ScopedDictionary aliasScope = null, bool checkParameterNames = false) + public static bool AreEqual(Expression a, Expression b, ScopedDictionary? parameterScope = null, ScopedDictionary? aliasScope = null, bool checkParameterNames = false) { return new DbExpressionComparer(parameterScope, aliasScope, checkParameterNames ).Compare(a, b); } @@ -195,7 +195,7 @@ protected virtual void MapAliases(SourceExpression sourceA, SourceExpression sou { for (int i = 0, n = sourceA.KnownAliases.Length; i < n; i++) { - aliasMap.Add(sourceA.KnownAliases[i], sourceB.KnownAliases[i]); + aliasMap!.Add(sourceA.KnownAliases[i], sourceB.KnownAliases[i]); } } diff --git a/Signum.Engine/Linq/ExpressionVisitor/DbExpressionNominator.cs b/Signum.Engine/Linq/ExpressionVisitor/DbExpressionNominator.cs index 4b13001506..1953166715 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/DbExpressionNominator.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/DbExpressionNominator.cs @@ -32,14 +32,17 @@ internal class DbExpressionNominator : DbExpressionVisitor bool isGroupKey = false; - Expression isNotNullRoot; + Expression? isNotNullRoot; bool innerProjection = false; HashSet candidates = new HashSet(); - T Add(T expression) where T : Expression + T Add(T expression) where T : Expression? { + if (expression == null) + return null; + this.candidates.Add(expression); return expression; } @@ -51,33 +54,33 @@ bool Has(Expression expression) private DbExpressionNominator() { } - static internal HashSet Nominate(Expression expression, out Expression newExpression, bool isGroupKey = false) + static internal HashSet Nominate(Expression? expression, out Expression newExpression, bool isGroupKey = false) { DbExpressionNominator n = new DbExpressionNominator { isFullNominate = false, isGroupKey = isGroupKey }; - newExpression = n.Visit(expression); + newExpression = n.Visit(expression)!; return n.candidates; } - static internal Expression FullNominate(Expression expression) + static internal Expression? FullNominate(Expression? expression) { DbExpressionNominator n = new DbExpressionNominator { isFullNominate = true }; - Expression result = n.Visit(expression); + Expression result = n.Visit(expression)!; return result; } - static internal Expression FullNominateNotNullable(Expression expression) + static internal Expression? FullNominateNotNullable(Expression? expression) { DbExpressionNominator n = new DbExpressionNominator { isFullNominate = true, isNotNullRoot = expression }; - Expression result = n.Visit(expression); + Expression result = n.Visit(expression)!; return result; } - public override Expression Visit(Expression exp) + public override Expression Visit(Expression? exp) { Expression result = base.Visit(exp); - if (isFullNominate && result != null && !Has(result) && !IsExcluded(exp) && !ExtractDayOfWeek(result, out var bla)) + if (isFullNominate && result != null && !Has(result) && !IsExcluded(exp!) && !ExtractDayOfWeek(result, out var bla)) throw new InvalidOperationException("The expression can not be translated to SQL: " + result.ToString()); @@ -86,7 +89,7 @@ public override Expression Visit(Expression exp) private bool IsExcluded(Expression exp) { - DbExpression expDb = exp as DbExpression; + DbExpression? expDb = exp as DbExpression; if (expDb == null) return false; @@ -267,7 +270,7 @@ protected override Expression VisitConstant(ConstantExpression c) protected internal override Expression VisitSqlFunction(SqlFunctionExpression sqlFunction) { //We can not assume allways true because neasted projections - Expression obj = Visit(sqlFunction.Object); + Expression? obj = Visit(sqlFunction.Object); ReadOnlyCollection args = Visit(sqlFunction.Arguments); if (args != sqlFunction.Arguments || obj != sqlFunction.Object) sqlFunction = new SqlFunctionExpression(sqlFunction.Type, obj, sqlFunction.SqlFunction, args); ; @@ -280,7 +283,7 @@ protected internal override Expression VisitSqlFunction(SqlFunctionExpression sq protected internal override Expression VisitSqlTableValuedFunction(SqlTableValuedFunctionExpression sqlFunction) { - ReadOnlyCollection args = Visit(sqlFunction.Arguments, a => Visit(a)); + ReadOnlyCollection args = Visit(sqlFunction.Arguments, a => Visit(a)!); if (args != sqlFunction.Arguments) sqlFunction = new SqlTableValuedFunctionExpression(sqlFunction.SqlFunction, sqlFunction.Table, sqlFunction.Alias, args); ; @@ -294,7 +297,7 @@ protected internal override Expression VisitSqlCast(SqlCastExpression castExpr) { var expression = Visit(castExpr.Expression); if (expression != castExpr.Expression) - castExpr = new SqlCastExpression(castExpr.Type, expression, castExpr.SqlDbType); + castExpr = new SqlCastExpression(castExpr.Type, expression!, castExpr.SqlDbType); return Add(castExpr); } @@ -341,7 +344,7 @@ protected internal override Expression VisitCase(CaseExpression cex) return cex; } - protected Expression TrySqlToString(MethodCallExpression m) + protected Expression? TrySqlToString(MethodCallExpression m) { var expression = m.Object; @@ -363,11 +366,11 @@ protected Expression TrySqlToString(MethodCallExpression m) return null; } - protected Expression GetFormatToString(MethodCallExpression m, string defaultFormat = null) + protected Expression GetFormatToString(MethodCallExpression m, string? defaultFormat = null) { var culture = m.TryGetArgument("culture")?.Let(e => (CultureInfo)((ConstantExpression)Visit(e)).Value) ?? CultureInfo.CurrentCulture; - string format = m.TryGetArgument("format")?.Let(e => (string)((ConstantExpression)Visit(e)).Value) ?? defaultFormat; + string format = m.TryGetArgument("format")?.Let(e => (string)((ConstantExpression)Visit(e)).Value) ?? defaultFormat!; var obj = Visit(m.Object); @@ -380,17 +383,17 @@ protected Expression GetFormatToString(MethodCallExpression m, string defaultFor new SqlConstantExpression(culture.Name) })); } - protected Expression TrySqlFunction(Expression obj, SqlFunction sqlFunction, Type type, params Expression[] expression) + protected Expression? TrySqlFunction(Expression? obj, SqlFunction sqlFunction, Type type, params Expression[] expression) { return TrySqlFunction(obj, sqlFunction.ToString(), type, expression); } - protected Expression TrySqlFunction(Expression obj, string sqlFunction, Type type, params Expression[] expression) + protected Expression? TrySqlFunction(Expression? obj, string sqlFunction, Type type, params Expression[] expression) { if (innerProjection) return null; - Expression newObj = null; + Expression? newObj = null; if (obj != null) { newObj = Visit(obj); @@ -411,7 +414,7 @@ protected Expression TrySqlFunction(Expression obj, string sqlFunction, Type typ return Add(new SqlFunctionExpression(type, newObj, sqlFunction.ToString(), newExpressions)); } - private SqlFunctionExpression TrySqlDifference(SqlEnums sqlEnums, Type type, Expression expression) + private SqlFunctionExpression? TrySqlDifference(SqlEnums sqlEnums, Type type, Expression expression) { if (innerProjection) return null; @@ -427,7 +430,7 @@ private SqlFunctionExpression TrySqlDifference(SqlEnums sqlEnums, Type type, Exp return null; } - private SqlFunctionExpression TrySqlDifference(SqlEnums sqlEnums, Type type, Expression leftSide, Expression rightSide) + private SqlFunctionExpression? TrySqlDifference(SqlEnums sqlEnums, Type type, Expression leftSide, Expression rightSide) { Expression left = Visit(leftSide); if (!Has(left.RemoveNullify())) @@ -443,7 +446,7 @@ private SqlFunctionExpression TrySqlDifference(SqlEnums sqlEnums, Type type, Exp return Add(result); } - private Expression TrySqlDate(Expression expression) + private Expression? TrySqlDate(Expression expression) { Expression expr = Visit(expression); if (innerProjection || !Has(expr)) @@ -464,7 +467,7 @@ private Expression TrySqlDate(Expression expression) } - private Expression TrySqlTime(Expression expression) + private Expression? TrySqlTime(Expression expression) { Expression expr = Visit(expression); if (innerProjection || !Has(expr)) @@ -480,20 +483,20 @@ private Expression TrySqlTime(Expression expression) throw new InvalidOperationException("{0} not supported on SQL Server 2005"); } - private Expression TrySqlDayOftheWeek(Expression expression) + private Expression? TrySqlDayOftheWeek(Expression expression) { Expression expr = Visit(expression); if (innerProjection || !Has(expr)) return null; - var number = TrySqlFunction(null, SqlFunction.DATEPART, typeof(int?), new SqlEnumExpression(SqlEnums.weekday), expr); + var number = TrySqlFunction(null, SqlFunction.DATEPART, typeof(int?), new SqlEnumExpression(SqlEnums.weekday), expr)!; Add(number); return new ToDayOfWeekExpression(number).TryConvert(typeof(DayOfWeek)); } - private Expression TrySqlStartOf(Expression expression, SqlEnums part) + private Expression? TrySqlStartOf(Expression expression, SqlEnums part) { Expression expr = Visit(expression); if (innerProjection || !Has(expr)) @@ -501,13 +504,13 @@ private Expression TrySqlStartOf(Expression expression, SqlEnums part) Expression result = TrySqlFunction(null, SqlFunction.DATEADD, expr.Type, new SqlEnumExpression(part), - TrySqlFunction(null, SqlFunction.DATEDIFF, typeof(int), new SqlEnumExpression(part), new SqlConstantExpression(0), expr), - new SqlConstantExpression(0)); + TrySqlFunction(null, SqlFunction.DATEDIFF, typeof(int), new SqlEnumExpression(part), new SqlConstantExpression(0), expr)!, + new SqlConstantExpression(0))!; return Add(result); } - private Expression TrySqlSecondsStart(Expression expression) + private Expression? TrySqlSecondsStart(Expression expression) { Expression expr = Visit(expression); if (innerProjection || !Has(expr)) @@ -516,13 +519,13 @@ private Expression TrySqlSecondsStart(Expression expression) Expression result = TrySqlFunction(null, SqlFunction.DATEADD, expr.Type, new SqlEnumExpression(SqlEnums.millisecond), - Expression.Negate(TrySqlFunction(null, SqlFunction.DATEPART, typeof(int), new SqlEnumExpression(SqlEnums.millisecond), expr)), expr); + Expression.Negate(TrySqlFunction(null, SqlFunction.DATEPART, typeof(int), new SqlEnumExpression(SqlEnums.millisecond), expr)), expr)!; return Add(result); } - private Expression TryAddSubtractDateTimeTimeSpan(Expression date, Expression time, bool add) + private Expression? TryAddSubtractDateTimeTimeSpan(Expression date, Expression time, bool add) { Expression exprDate = Visit(date); Expression exprTime = Visit(time); @@ -538,7 +541,7 @@ private Expression TryAddSubtractDateTimeTimeSpan(Expression date, Expression ti return Add(result); } - private Expression TryDatePartTo(SqlEnumExpression datePart, Expression start, Expression end) + private Expression? TryDatePartTo(SqlEnumExpression datePart, Expression start, Expression end) { Expression exprStart = Visit(start); Expression exprEnd = Visit(end); @@ -557,7 +560,7 @@ private Expression TryDatePartTo(SqlEnumExpression datePart, Expression start, E } - private Expression TrySqlTrim(Expression expression) + private Expression? TrySqlTrim(Expression expression) { Expression expr = Visit(expression); if (innerProjection || !Has(expr)) @@ -565,7 +568,7 @@ private Expression TrySqlTrim(Expression expression) Expression result = TrySqlFunction(null, SqlFunction.LTRIM, expression.Type, - TrySqlFunction(null, SqlFunction.RTRIM, expression.Type, expression)); + TrySqlFunction(null, SqlFunction.RTRIM, expression.Type, expression)!)!; return Add(result); } @@ -596,8 +599,8 @@ protected override Expression VisitBinary(BinaryExpression b) if(ExtractDayOfWeek(left, out var ldow) && ExtractDayOfWeek(right, out var rdow)) { - left = ldow; - right = rdow; + left = ldow!; + right = rdow!; } newB = MakeBinaryFlexible(b.NodeType, left, right); @@ -668,7 +671,7 @@ protected override Expression VisitBinary(BinaryExpression b) } } - private bool ExtractDayOfWeek(Expression exp, out Expression result) + private bool ExtractDayOfWeek(Expression exp, out Expression? result) { if (exp is ToDayOfWeekExpression tdow) { @@ -676,8 +679,8 @@ private bool ExtractDayOfWeek(Expression exp, out Expression result) return true; } - if (exp.NodeType == ExpressionType.Convert && exp.Type.UnNullify() == typeof(DayOfWeek)) - return ExtractDayOfWeek(((UnaryExpression)exp).Operand, out result); + if (exp!/*CSBUG*/.NodeType == ExpressionType.Convert && exp!/*CSBUG*/.Type.UnNullify() == typeof(DayOfWeek)) + return ExtractDayOfWeek(((UnaryExpression)exp!/*CSBUG*/).Operand, out result); result = null; return false; @@ -718,7 +721,7 @@ public static Expression ConvertNull(Expression nullNode, Type type) } } - public Expression SimpleNot(Expression e) + public Expression? SimpleNot(Expression e) { if (e.NodeType == ExpressionType.Not) return ((UnaryExpression)e).Operand; @@ -741,12 +744,12 @@ private Expression ConvertToSqlCoallesce(BinaryExpression b) if (left is SqlFunctionExpression fLeft && fLeft.SqlFunction == SqlFunction.COALESCE.ToString()) expressions.AddRange(fLeft.Arguments); else - expressions.Add(left); + expressions.Add(left!/*CSBUG*/); if (right is SqlFunctionExpression fRight && fRight.SqlFunction == SqlFunction.COALESCE.ToString()) expressions.AddRange(fRight.Arguments); else - expressions.Add(right); + expressions.Add(right!/*CSBUG*/); return Add(new SqlFunctionExpression(b.Type, null, SqlFunction.COALESCE.ToString(), expressions)); } @@ -910,6 +913,8 @@ protected override Expression VisitConditional(ConditionalExpression c) } else { + ifFalse = ifFalse!; /*CSBUG*/ + if (ifTrue.IsNull() && ifFalse.IsNull()) return ifTrue; //cond? null: null doesn't work in sql @@ -1102,7 +1107,7 @@ protected internal override Expression VisitLike(LikeExpression like) return like; } - private Expression TryLike(Expression expression, Expression pattern) + private Expression? TryLike(Expression expression, Expression pattern) { if (expression.IsNull()) return Add(Expression.Constant(false)); @@ -1120,7 +1125,7 @@ private Expression TryLike(Expression expression, Expression pattern) return null; } - private Expression TryCharIndex(Expression expression, Expression subExpression, Func compare) + private Expression? TryCharIndex(Expression expression, Expression subExpression, Func compare) { if (expression.IsNull()) return Add(Expression.Constant(false)); @@ -1171,14 +1176,14 @@ protected override Expression VisitMember(MemberExpression m) return nullable; } - Expression hardResult = HardCodedMembers(m); + Expression? hardResult = HardCodedMembers(m); if (hardResult != null) return hardResult; return base.VisitMember(m); } - public Expression HardCodedMembers(MemberExpression m) + public Expression? HardCodedMembers(MemberExpression m) { switch (m.Member.DeclaringType.TypeName() + "." + m.Member.Name) { @@ -1202,8 +1207,7 @@ public Expression HardCodedMembers(MemberExpression m) if (diff == null) return null; - return Add(new SqlCastExpression(typeof(int?), - TrySqlFunction(null, SqlFunction.FLOOR, typeof(double?), diff))); + return Add(new SqlCastExpression(typeof(int?), TrySqlFunction(null, SqlFunction.FLOOR, typeof(double?), diff)!)); } case "TimeSpan.Hours": return TrySqlFunction(null, SqlFunction.DATEPART, m.Type, new SqlEnumExpression(SqlEnums.hour), m.Expression); case "TimeSpan.Minutes": return TrySqlFunction(null, SqlFunction.DATEPART, m.Type, new SqlEnumExpression(SqlEnums.minute), m.Expression); @@ -1232,9 +1236,9 @@ public Expression HardCodedMembers(MemberExpression m) } } - protected override Expression VisitMethodCall(MethodCallExpression m) + protected override Expression? VisitMethodCall(MethodCallExpression m) { - Expression result = HardCodedMethods(m); + Expression? result = HardCodedMethods(m); if (result != null) return result; @@ -1246,12 +1250,12 @@ protected override Expression VisitMethodCall(MethodCallExpression m) return base.VisitMethodCall(m); } - private Expression GetDateTimeToStringSqlFunction(MethodCallExpression m, string defaultFormat = null) + private Expression? GetDateTimeToStringSqlFunction(MethodCallExpression m, string? defaultFormat = null) { return Connector.Current.SupportsFormat ? GetFormatToString(m, defaultFormat) : TrySqlToString(m); } - private Expression HardCodedMethods(MethodCallExpression m) + private Expression? HardCodedMethods(MethodCallExpression m) { if (m.Method.Name == "ToString") return TrySqlToString(m); @@ -1282,7 +1286,7 @@ private Expression HardCodedMethods(MethodCallExpression m) { Expression startIndex = m.TryGetArgument("startIndex")?.Let(e => Expression.Add(e, new SqlConstantExpression(1))); - Expression charIndex = TrySqlFunction(null, SqlFunction.CHARINDEX, m.Type, m.GetArgument("value"), m.Object, startIndex); + Expression? charIndex = TrySqlFunction(null, SqlFunction.CHARINDEX, m.Type, m.GetArgument("value"), m.Object, startIndex); if (charIndex == null) return null; Expression result = Expression.Subtract(charIndex, new SqlConstantExpression(1)); @@ -1311,8 +1315,8 @@ private Expression HardCodedMethods(MethodCallExpression m) return TryCharIndex(m.GetArgument("value"), m.Object, index => Expression.Equal(index, new SqlConstantExpression(1))); case "string.EndsWith": return TryCharIndex( - TrySqlFunction(null, SqlFunction.REVERSE, m.Type, m.GetArgument("value")), - TrySqlFunction(null, SqlFunction.REVERSE, m.Type, m.Object), + TrySqlFunction(null, SqlFunction.REVERSE, m.Type, m.GetArgument("value"))!, + TrySqlFunction(null, SqlFunction.REVERSE, m.Type, m.Object)!, index => Expression.Equal(index, new SqlConstantExpression(1))); case "string.Format": case "StringExtensions.FormatWith": @@ -1408,13 +1412,13 @@ private Expression HardCodedMethods(MethodCallExpression m) } } - private Expression TryStringFormat(MethodCallExpression m) + private Expression? TryStringFormat(MethodCallExpression m) { var prov = m.TryGetArgument("provider"); if (prov != null) return null; - var format = (m.Object ?? m.GetArgument("format")) as ConstantExpression; + var format = (ConstantExpression)(m.Object ?? m.GetArgument("format")); var args = m.TryGetArgument("args")?.Let(a => ((NewArrayExpression)a).Expressions) ?? new[] { m.TryGetArgument("arg0"), m.TryGetArgument("arg1"), m.TryGetArgument("arg2"), m.TryGetArgument("arg3") }.NotNull().ToReadOnly(); @@ -1428,7 +1432,7 @@ private Expression TryStringFormat(MethodCallExpression m) var firsStr = strFormat.Substring(0, matches.FirstEx().Index); - Expression acum = firsStr.HasText() ? new SqlConstantExpression(firsStr) : null; + Expression? acum = firsStr.HasText() ? new SqlConstantExpression(firsStr) : null; for (int i = 0; i < matches.Count; i++) { @@ -1454,7 +1458,7 @@ private Expression TryStringFormat(MethodCallExpression m) return Add(acum); } - private Expression TryEtc(Expression str, Expression max, Expression etcString) + private Expression? TryEtc(Expression str, Expression max, Expression etcString) { var newStr = Visit(str); if (!Has(newStr)) diff --git a/Signum.Engine/Linq/ExpressionVisitor/OverloadingSimplifier.cs b/Signum.Engine/Linq/ExpressionVisitor/OverloadingSimplifier.cs index 41d57c6b42..e9aee96131 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/OverloadingSimplifier.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/OverloadingSimplifier.cs @@ -91,7 +91,7 @@ internal class OverloadingSimplifier : ExpressionVisitor static int i = 0; - public static Expression Simplify(Expression expression) + public static Expression? Simplify(Expression? expression) { return new OverloadingSimplifier().Visit(expression); } @@ -471,14 +471,14 @@ private Expression CallToString(Expression expression) var visitedToStrExp = Visit(toStrExp); return Expression.Condition( - Expression.Equal(expression, Expression.Constant(null, expression.Type.Nullify())), + Expression.Equal(expression, Expression.Constant(null, expression!/*CSBUG*/.Type.Nullify())), Expression.Constant(null, typeof(string)), Visit(visitedToStrExp)); } public static bool ExtractDefaultIfEmpty(ref Expression expression) { - MethodCallExpression mce = expression as MethodCallExpression; + MethodCallExpression? mce = expression as MethodCallExpression; if (mce == null || !mce.Method.IsGenericMethod) return false; diff --git a/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs b/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs index d4e8356f56..a0118e2278 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs @@ -37,6 +37,7 @@ public QueryBinder(AliasGenerator aliasGenerator) { this.systemTime = SystemTime.Current; this.aliasGenerator = aliasGenerator; + this.root = null!; } public class GroupByInfo @@ -44,6 +45,13 @@ public class GroupByInfo public Alias GroupAlias; public Expression Projector; public SourceExpression Source; + + public GroupByInfo(Alias groupAlias, Expression projector, SourceExpression source) + { + GroupAlias = groupAlias; + Projector = projector; + Source = source; + } } Expression root; @@ -59,7 +67,7 @@ public Expression BindQuery(Expression expression) return expandedResult; } - protected override Expression VisitMethodCall(MethodCallExpression m) + protected override Expression? VisitMethodCall(MethodCallExpression m) { if (m.Method.DeclaringType == typeof(Queryable) || m.Method.DeclaringType == typeof(Enumerable) || @@ -135,7 +143,7 @@ protected override Expression VisitMethodCall(MethodCallExpression m) } else if (m.Method.DeclaringType == typeof(LinqHintsExpand)) { - if(m.Method.Name == nameof(LinqHintsExpand.ExpandLite)) + if (m.Method.Name == nameof(LinqHintsExpand.ExpandLite)) return BindExpandLite(m.Type, m.GetArgument("source"), m.GetArgument("liteSelector").StripQuotes(), (ExpandLite)((ConstantExpression)m.GetArgument("expandLite")).Value); if (m.Method.Name == nameof(LinqHintsExpand.ExpandEntity)) @@ -159,23 +167,21 @@ protected override Expression VisitMethodCall(MethodCallExpression m) } else if (m.Method.DeclaringType == typeof(LinqHintEntities)) { - var expression = Visit(m.Arguments[0]) as ImplementedByExpression; - - var ib = expression as ImplementedByExpression; + var ib = Visit(m.Arguments[0]) as ImplementedByExpression; if (ib == null) throw new InvalidOperationException("Method {0} is only meant to be used on {1}".FormatWith(m.Method.Name, typeof(ImplementedByExpression).Name)); CombineStrategy strategy = GetStrategy(m.Method); - return new ImplementedByExpression(ib.Type, strategy, expression.Implementations); + return new ImplementedByExpression(ib.Type, strategy, ib.Implementations); } else if (m.Method.DeclaringType == typeof(Lite) && m.Method.Name == "ToLite") { Expression toStr = Visit(m.TryGetArgument("toStr")); //could be null var entity = Visit(m.GetArgument("entity")); - var converted = EntityCasting(entity, Lite.Extract(m.Type)); + var converted = EntityCasting(entity, Lite.Extract(m.Type)!)!; return MakeLite(converted, toStr); } else if (m.Method.DeclaringType.IsInstantiationOf(typeof(EnumEntity<>)) && m.Method.Name == "ToEnum") @@ -218,7 +224,7 @@ private Expression BindExpandEntity(Type type, Expression source, LambdaExpressi kvp => kvp.Key, kvp => kvp.Value.WithExpandEntity(expandEntity))); - throw new NotImplementedException("Expand Entity not supported for " + e.GetType()); + throw new NotImplementedException("Expand Entity not supported for " + e!/*CSBUG*/.GetType()); }); return new ProjectionExpression(projection.Select, newProjector, projection.UniqueFunction, projection.Type); @@ -230,7 +236,7 @@ private Expression BindExpandLite(Type type, Expression source, LambdaExpression var members = Reflector.GetMemberListUntyped(entitySelector); - var newProjector = ChangeProjector(0, members, projection.Projector, + var newProjector = ChangeProjector(0, members, projection.Projector, e => ((LiteReferenceExpression)e).WithExpandLite(expandLite)); return new ProjectionExpression(projection.Select, newProjector, projection.UniqueFunction, projection.Type); @@ -273,7 +279,7 @@ private Expression ChangeProjector(int index, MemberInfo[] members, Expression p ee = Completed(ee); - var fi = m as FieldInfo ?? Reflector.FindFieldInfo(m.DeclaringType, (PropertyInfo)m); + var fi = m as FieldInfo ?? Reflector.FindFieldInfo(m!/*CSBUG*/.DeclaringType, (PropertyInfo)m! /*CSBUG*/); var newBinding = ChangeProjector(index + 1, members, ee.GetBinding(fi), changeExpression); @@ -285,7 +291,7 @@ private Expression ChangeProjector(int index, MemberInfo[] members, Expression p } else if (projector is NewExpression ne) { - var p = (PropertyInfo)m; + var p = (PropertyInfo)m! /*CSBUG*/; var mIndex = ne.Members.IndexOf(pi => ReflectionTools.PropertyEquals((PropertyInfo)pi, p)); @@ -300,7 +306,7 @@ private Expression ChangeProjector(int index, MemberInfo[] members, Expression p var proj = MListProjection(me, true); using (SetCurrentSource(proj.Select)) { - var mle = (NewExpression) proj.Projector; + var mle = (NewExpression)proj.Projector; var paramIndex = mle.Constructor.GetParameters().IndexOf(p => p.Name == "value"); @@ -316,13 +322,13 @@ private Expression ChangeProjector(int index, MemberInfo[] members, Expression p } } - throw new NotImplementedException($"ChangeProjector not implemented for projector of type {projector.Type} and member {m}"); + throw new NotImplementedException($"ChangeProjector not implemented for projector of type {projector!/*CSBUG*/.Type} and member {m}"); } - string currentTableHint; + string? currentTableHint; private Expression BindWithHints(Expression source, ConstantExpression hint) { - string oldHint = currentTableHint; + string? oldHint = currentTableHint; try { currentTableHint = (string)hint.Value; @@ -360,7 +366,7 @@ private Expression MapVisitExpand(LambdaExpression lambda, ProjectionExpression return MapVisitExpand(lambda, projection.Projector, projection.Select); } - internal Expression MapVisitExpand(LambdaExpression lambda, Expression projector, SourceExpression source) + internal Expression MapVisitExpand(LambdaExpression lambda, Expression projector, SourceExpression? source) { using (SetCurrentSource(source)) { @@ -475,10 +481,10 @@ private Expression BindUniqueRow(Type resultType, UniqueFunction function, Expre ProjectionExpression projection = (ProjectionExpression)AliasReplacer.Replace(expandedProjector, this.aliasGenerator); - Expression where = predicate == null ? null : DbExpressionNominator.FullNominate(MapVisitExpand(predicate, projection)); + Expression? where = predicate == null ? null : DbExpressionNominator.FullNominate(MapVisitExpand(predicate, projection)); Alias alias = NextSelectAlias(); - Expression top = function == UniqueFunction.First || function == UniqueFunction.FirstOrDefault ? Expression.Constant(1) : null; + Expression? top = function == UniqueFunction.First || function == UniqueFunction.FirstOrDefault ? Expression.Constant(1) : null; ProjectedColumns pc = ColumnProjector.ProjectColumns(projection.Projector, alias); @@ -497,11 +503,7 @@ private Expression BindUniqueRow(Type resultType, UniqueFunction function, Expre { - AddRequest(new UniqueRequest - { - Select = newProjector.Select, - OuterApply = function == UniqueFunction.SingleOrDefault || function == UniqueFunction.FirstOrDefault - }); + AddRequest(new UniqueRequest(newProjector.Select, outerApply: function == UniqueFunction.SingleOrDefault || function == UniqueFunction.FirstOrDefault)); return newProjector.Projector; }); @@ -563,7 +565,7 @@ private Expression BindToString(Expression source, Expression separator, MethodI string value = (string)((ConstantExpression)separator).Value; - ColumnDeclaration cd = new ColumnDeclaration(null, Expression.Add(new SqlConstantExpression(value, typeof(string)), nominated, miStringConcat)); + ColumnDeclaration cd = new ColumnDeclaration(null!, Expression.Add(new SqlConstantExpression(value, typeof(string)), nominated, miStringConcat)); Alias alias = NextSelectAlias(); @@ -581,9 +583,9 @@ private Expression BindToString(Expression source, Expression separator, MethodI static MethodInfo miStringConcat = ReflectionTools.GetMethodInfo(() => string.Concat("", "")); - (Expression newSource, LambdaExpression selector, bool distinct) DisassembleAggregate(AggregateSqlFunction aggregate, Expression source, LambdaExpression selectorOrPredicate, bool isRoot) + (Expression newSource, LambdaExpression? selector, bool distinct) DisassembleAggregate(AggregateSqlFunction aggregate, Expression source, LambdaExpression? selectorOrPredicate, bool isRoot) { - if(aggregate == AggregateSqlFunction.Count) + if (aggregate == AggregateSqlFunction.Count) { if (selectorOrPredicate != null) { @@ -599,38 +601,38 @@ private Expression BindToString(Expression source, Expression separator, MethodI { if (ExtractWhere(source, out var inner, out var predicate) && ExtractDistinct(inner, out var inner2) && - ExtractSelect(inner2, out var inner3, out var selector) && - IsNotNull(predicate.Body, out var p) && p == predicate.Parameters.SingleEx()) - return (inner3, selector, true); + ExtractSelect(inner2!, out var inner3, out var selector) && + IsNotNull(predicate!.Body, out var p) && p == predicate!.Parameters.SingleEx()) + return (inner3!, selector!, true); } //Select NotNull Distinct { if (ExtractDistinct(source, out var inner) && ExtractWhere(inner, out var inner2, out var predicate) && - ExtractSelect(inner2, out var inner3, out var selector) && - IsNotNull(predicate.Body, out var p) && p == predicate.Parameters.SingleEx()) - return (inner3, selector, true); + ExtractSelect(inner2!, out var inner3, out var selector) && + IsNotNull(predicate!.Body, out var p) && p == predicate!.Parameters.SingleEx()) + return (inner3!, selector!, true); } //NotNull Select Distinct { if (ExtractDistinct(source, out var inner) && - ExtractSelect(inner, out var inner2, out var selector) && + ExtractSelect(inner!, out var inner2, out var selector) && ExtractWhere(inner2, out var inner3, out var predicate) && - IsNotNull(predicate.Body, out var p) && ExpressionComparer.AreEqual(p, selector.Body, - new ScopedDictionary(null) { { predicate.Parameters.Single(), selector.Parameters.Single() } })) - return (inner3, selector, true); + IsNotNull(predicate!.Body, out var p) && ExpressionComparer.AreEqual(p!, selector!.Body, + new ScopedDictionary(null) { { predicate!.Parameters.Single(), selector!.Parameters.Single() } })) + return (inner3!, selector!, true); } - if(!isRoot) + if (!isRoot) { //Preferring Count(predicate) //instead of Count (*) Where predicate //is tricky if (ExtractWhere(source, out var inner, out var predicate) && inner is ParameterExpression p && p.Type.IsInstantiationOf(typeof(IGrouping<,>)) && - SimplePredicateVisitor.IsSimple(predicate)) + SimplePredicateVisitor.IsSimple(predicate!)) return (inner, predicate, false); } @@ -638,10 +640,10 @@ private Expression BindToString(Expression source, Expression separator, MethodI } else { - if(selectorOrPredicate != null) + if (selectorOrPredicate != null) return (source, selectorOrPredicate, false); - else if(ExtractSelect(source, out var innerSource, out var selector)) - return (innerSource, selector, false); + else if (ExtractSelect(source, out var innerSource, out var selector)) + return (innerSource!, selector!, false); else return (source, null, false); } @@ -651,12 +653,15 @@ class SimplePredicateVisitor : ExpressionVisitor { public ParameterExpression[] AllowedParameters; public bool HasExternalParameter = false; + + public SimplePredicateVisitor(ParameterExpression[] allowedParameters) + { + AllowedParameters = allowedParameters; + } + public static bool IsSimple(LambdaExpression lambda) { - var extParam = new SimplePredicateVisitor - { - AllowedParameters = lambda.Parameters.ToArray() - }; + var extParam = new SimplePredicateVisitor(lambda.Parameters.ToArray()); extParam.Visit(lambda.Body); return !extParam.HasExternalParameter; } @@ -670,9 +675,9 @@ protected override Expression VisitParameter(ParameterExpression node) } } - private bool IsNotNull(Expression body, out Expression p) + private bool IsNotNull(Expression? body, out Expression? p) { - if(body is BinaryExpression b && b.NodeType == ExpressionType.NotEqual) + if (body is BinaryExpression b && b.NodeType == ExpressionType.NotEqual) { p = b.Left.IsNull() ? b.Right : b.Right.IsNull() ? b.Left : @@ -687,9 +692,9 @@ private bool IsNotNull(Expression body, out Expression p) } - bool ExtractSelect(Expression source, out Expression innerSource, out LambdaExpression selector) + bool ExtractSelect(Expression source, out Expression? innerSource, out LambdaExpression? selector) { - if(source is MethodCallExpression mc && + if (source is MethodCallExpression mc && (mc.Method.IsInstantiationOf(OverloadingSimplifier.miSelectE) || mc.Method.IsInstantiationOf(OverloadingSimplifier.miSelectQ))) { @@ -705,7 +710,7 @@ bool ExtractSelect(Expression source, out Expression innerSource, out LambdaExpr } } - bool ExtractWhere(Expression source, out Expression innerSource, out LambdaExpression predicate) + bool ExtractWhere(Expression? source, out Expression? innerSource, out LambdaExpression? predicate) { if (source is MethodCallExpression mc && (mc.Method.IsInstantiationOf(OverloadingSimplifier.miWhereE) || @@ -723,7 +728,7 @@ bool ExtractWhere(Expression source, out Expression innerSource, out LambdaExpre } } - bool ExtractDistinct(Expression source, out Expression innerSource) + bool ExtractDistinct(Expression? source, out Expression? innerSource) { if (source is MethodCallExpression mc && (mc.Method.IsInstantiationOf(OverloadingSimplifier.miDistinctE) || @@ -740,35 +745,37 @@ bool ExtractDistinct(Expression source, out Expression innerSource) } - private Expression BindAggregate(Type resultType, AggregateSqlFunction aggregateFunction, Expression source, LambdaExpression selectorOrPredicate, bool isRoot) + private Expression? BindAggregate(Type resultType, AggregateSqlFunction aggregateFunction, Expression source, LambdaExpression selectorOrPredicate, bool isRoot) { var (newSource, selector, distinct) = DisassembleAggregate(aggregateFunction, source, selectorOrPredicate, isRoot); ProjectionExpression projection = VisitCastProjection(newSource); - GroupByInfo info = groupByMap.TryGetC(projection.Select.Alias); + GroupByInfo? info = groupByMap.TryGetC(projection.Select.Alias); if (info != null) { - Expression exp = aggregateFunction == AggregateSqlFunction.Count && selector == null ? null : //Count(*) + Expression? exp = aggregateFunction == AggregateSqlFunction.Count && selector == null ? null : //Count(*) aggregateFunction == AggregateSqlFunction.Count && !distinct ? MapVisitExpand(ToNotNullPredicate(selector), info.Projector, info.Source) : selector != null ? MapVisitExpand(selector, info.Projector, info.Source) : //Sum(Amount), Avg(Amount), ... info.Projector; exp = exp == null ? null : SmartEqualizer.UnwrapPrimaryKey(exp); - var nominated = aggregateFunction == AggregateSqlFunction.Count ? DbExpressionNominator.FullNominateNotNullable(exp) : + var nominated = aggregateFunction == AggregateSqlFunction.Count ? + DbExpressionNominator.FullNominateNotNullable(exp): DbExpressionNominator.FullNominate(exp); var result = new AggregateRequestsExpression(info.GroupAlias, new AggregateExpression(aggregateFunction == AggregateSqlFunction.Count ? typeof(int) : GetBasicType(nominated), - nominated, aggregateFunction, + nominated!, + aggregateFunction, distinct)); return RestoreWrappedType(result, resultType); } else //Complicated SubQuery { - Expression exp = aggregateFunction == AggregateSqlFunction.Count && selector == null ? null : + Expression? exp = aggregateFunction == AggregateSqlFunction.Count && selector == null ? null : aggregateFunction == AggregateSqlFunction.Count && !distinct ? MapVisitExpand(ToNotNullPredicate(selector), projection) : selector != null ? MapVisitExpand(selector, projection) : projection.Projector; @@ -778,7 +785,7 @@ private Expression BindAggregate(Type resultType, AggregateSqlFunction aggregate Expression aggregate; if (aggregateFunction == AggregateSqlFunction.Sum && !resultType.IsNullable()) { - var nominated = DbExpressionNominator.FullNominate(exp).Nullify(); + var nominated = DbExpressionNominator.FullNominate(exp)!.Nullify(); aggregate = (Expression)Expression.Coalesce( new AggregateExpression(GetBasicType(nominated), nominated, aggregateFunction, distinct), @@ -786,11 +793,12 @@ private Expression BindAggregate(Type resultType, AggregateSqlFunction aggregate } else { - var nominated = aggregateFunction == AggregateSqlFunction.Count ? DbExpressionNominator.FullNominateNotNullable(exp) : + var nominated = aggregateFunction == AggregateSqlFunction.Count ? + DbExpressionNominator.FullNominateNotNullable(exp): DbExpressionNominator.FullNominate(exp); aggregate = new AggregateExpression(aggregateFunction == AggregateSqlFunction.Count ? typeof(int) : GetBasicType(nominated), - nominated, + nominated!, aggregateFunction, distinct); } @@ -814,7 +822,7 @@ private Expression BindAggregate(Type resultType, AggregateSqlFunction aggregate private LambdaExpression ToNotNullPredicate(LambdaExpression predicate) { - if(predicate.Body is BinaryExpression be && be.NodeType == ExpressionType.NotEqual) + if (predicate.Body is BinaryExpression be && be.NodeType == ExpressionType.NotEqual) { var exp = be.Left.IsNull() ? be.Right : @@ -825,17 +833,13 @@ private LambdaExpression ToNotNullPredicate(LambdaExpression predicate) return Expression.Lambda(exp, predicate.Parameters); } } - else - { - var conditional = Expression.Condition(predicate.Body, Expression.Constant("placeholder"), Expression.Constant(null, typeof(string))); - return Expression.Lambda(conditional, predicate.Parameters); - } + var conditional = Expression.Condition(predicate.Body, Expression.Constant("placeholder"), Expression.Constant(null, typeof(string))); - return null; + return Expression.Lambda(conditional, predicate.Parameters); } - private Type GetBasicType(Expression nominated) + private Type GetBasicType(Expression? nominated) { if (nominated == null) return typeof(int); @@ -886,7 +890,7 @@ private Expression BindAnyAll(Type resultType, Expression source, LambdaExpressi if (predicate != null) source = Expression.Call(typeof(Enumerable), "Where", method.GetGenericArguments(), source, predicate); - ProjectionExpression projection = this.VisitCastProjection(source); + ProjectionExpression projection = this.VisitCastProjection(source!/*CSBUG*/); Expression result = new ExistsExpression(projection.Select); if (isAll) result = Expression.Not(result); @@ -931,12 +935,12 @@ private Expression BindContains(Type resultType, Expression source, Expression i Alias alias = NextSelectAlias(); var pc = ColumnProjector.ProjectColumns(projection.Projector, alias, isGroupKey: false, selectTrivialColumns: true); - SubqueryExpression se = null; + SubqueryExpression? se = null; if (Schema.Current.Settings.IsDbType(pc.Projector.Type)) se = new InExpression(newItem, new SelectExpression(alias, false, null, pc.Columns, projection.Select, null, null, null, 0)); else { - Expression where = DbExpressionNominator.FullNominate(SmartEqualizer.PolymorphicEqual(projection.Projector, newItem)); + Expression where = DbExpressionNominator.FullNominate(SmartEqualizer.PolymorphicEqual(projection.Projector, newItem))!; se = new ExistsExpression(new SelectExpression(alias, false, null, pc.Columns, projection.Select, where, null, null, 0)); } @@ -968,7 +972,7 @@ private Expression BindWhere(Type resultType, Expression source, LambdaExpressio if (exp.NodeType == ExpressionType.Constant && ((bool)((ConstantExpression)exp).Value)) return projection; - Expression where = DbExpressionNominator.FullNominate(exp); + Expression where = DbExpressionNominator.FullNominate(exp)!; Alias alias = NextSelectAlias(); ProjectedColumns pc = ColumnProjector.ProjectColumns(projection.Projector, alias); @@ -991,7 +995,7 @@ private Expression BindSelect(Type resultType, Expression source, LambdaExpressi pc.Projector, null, resultType); } - protected virtual Expression BindSelectMany(Type resultType, Expression source, LambdaExpression collectionSelector, LambdaExpression resultSelector) + protected virtual Expression BindSelectMany(Type resultType, Expression source, LambdaExpression collectionSelector, LambdaExpression? resultSelector) { ProjectionExpression projection = this.VisitCastProjection(source); bool outer = OverloadingSimplifier.ExtractDefaultIfEmpty(ref collectionSelector); @@ -1052,7 +1056,7 @@ protected virtual Expression BindJoin(Type resultType, Expression outerSource, E Expression outerKeyExpr = MapVisitExpand(outerKey, outerProj); Expression innerKeyExpr = MapVisitExpand(innerKey, innerProj); - Expression condition = DbExpressionNominator.FullNominate(SmartEqualizer.EqualNullable(outerKeyExpr, innerKeyExpr)); + Expression condition = DbExpressionNominator.FullNominate(SmartEqualizer.EqualNullable(outerKeyExpr, innerKeyExpr))!; JoinType jt = rightOuter && leftOuter ? JoinType.FullOuterJoin : rightOuter ? JoinType.RightOuterJoin : @@ -1109,7 +1113,7 @@ private Expression BindGroupBy(Type resultType, Expression source, LambdaExpress ProjectedColumns subqueryKeyPC = ColumnProjector.ProjectColumns(subqueryKey, aliasGenerator.Raw("basura"), isGroupKey: true, selectTrivialColumns: true); // use same projection trick to get group-by expressions based on subquery Expression subqueryElemExpr = MapVisitExpand(elementSelector, subqueryProjection); // compute element based on duplicated subquery - Expression subqueryCorrelation = keyPC.Columns.IsEmpty() ? null : + Expression? subqueryCorrelation = keyPC.Columns.IsEmpty() ? null : keyPC.Columns.Zip(subqueryKeyPC.Columns, (c1, c2) => SmartEqualizer.EqualNullableGroupBy(new ColumnExpression(c1.Expression.Type, alias, c1.Name), c2.Expression)) .AggregateAnd(); @@ -1127,12 +1131,7 @@ private Expression BindGroupBy(Type resultType, Expression source, LambdaExpress Expression resultExpr = Expression.Convert(newResult , typeof(IGrouping<,>).MakeGenericType(key.Type, subqueryElemExpr.Type)); - this.groupByMap.Add(elementAlias, new GroupByInfo - { - GroupAlias = alias, - Projector = elemExpr, - Source = select, - }); + this.groupByMap.Add(elementAlias, new GroupByInfo(alias, elemExpr, select)); var result = new ProjectionExpression( new SelectExpression(alias, false, null, keyPC.Columns, select, null, null, keyPC.Columns.Select(c => c.Expression), 0), @@ -1163,9 +1162,14 @@ class ColumnReplacerVisitor : DbExpressionVisitor { Dictionary Replacements; + public ColumnReplacerVisitor(Dictionary replacements) + { + Replacements = replacements; + } + public static Expression ReplaceColumns(Dictionary replacements, Expression exp) { - return new ColumnReplacerVisitor { Replacements = replacements }.Visit(exp); + return new ColumnReplacerVisitor(replacements).Visit(exp); } protected internal override Expression VisitColumn(ColumnExpression column) @@ -1175,10 +1179,10 @@ protected internal override Expression VisitColumn(ColumnExpression column) } - List thenBys; + List? thenBys; protected virtual Expression BindOrderBy(Type resultType, Expression source, LambdaExpression orderSelector, OrderType orderType) { - List myThenBys = this.thenBys; + List? myThenBys = this.thenBys; this.thenBys = null; ProjectionExpression projection = this.VisitCastProjection(source); @@ -1227,17 +1231,17 @@ private Expression GetOrderExpression(LambdaExpression lambda, ProjectionExpress { expr = ((MethodCallExpression)expr).Arguments[0]; } - else if (expr.Type == typeof(Type)) + else if (expr!/*CSBUG*/.Type == typeof(Type)) { - expr = ExtractTypeId(expr); + expr = ExtractTypeId(expr!/*CSBUG*/); } - if (expr.Type.UnNullify() == typeof(PrimaryKey)) + if (expr!/*CSBUG*/.Type.UnNullify() == typeof(PrimaryKey)) { - expr = SmartEqualizer.UnwrapPrimaryKey(expr); + expr = SmartEqualizer.UnwrapPrimaryKey(expr!/*CSBUG*/); } - return DbExpressionNominator.FullNominate(expr); + return DbExpressionNominator.FullNominate(expr)!; } } @@ -1255,13 +1259,13 @@ protected virtual Expression BindThenBy(Expression source, LambdaExpression orde private bool IsTable(Expression expression) { - ConstantExpression c = expression as ConstantExpression; + ConstantExpression? c = expression as ConstantExpression; return c != null && IsTable(c.Value); } public bool IsTable(object value) { - IQueryable query = value as IQueryable; + IQueryable? query = value as IQueryable; if (query == null) return false; @@ -1350,7 +1354,7 @@ protected override Expression VisitConstant(ConstantExpression c) static bool IsNewId(Expression expression) { - ConstantExpression ce = expression as ConstantExpression; + ConstantExpression? ce = expression as ConstantExpression; return ce != null && ce.Type.UnNullify() == typeof(int) && int.MinValue.Equals(ce.Value); } @@ -1372,10 +1376,10 @@ protected override MemberAssignment VisitMemberAssignment(MemberAssignment assig return assignment; } - protected override Expression VisitMember(MemberExpression m) + protected override Expression? VisitMember(MemberExpression m) { Expression ex = base.VisitMember(m); - Expression binded = BindMemberAccess((MemberExpression)ex); + Expression? binded = BindMemberAccess((MemberExpression)ex); return binded; } @@ -1401,7 +1405,7 @@ public Expression BindMethodCall(MethodCallExpression m) if (ExpressionCleaner.HasExpansions(source.Type, m.Method) && source is EntityExpression) //new expansions discovered { Dictionary replacements = new Dictionary(); - Func replace = (e, pi) => + Func replace = (e, pi) => { if (e == null || e.NodeType == ExpressionType.Quote || e.NodeType == ExpressionType.Lambda || pi != null && pi.HasAttribute()) return e; @@ -1414,9 +1418,9 @@ public Expression BindMethodCall(MethodCallExpression m) MethodCallExpression simple = Expression.Call(replace(m.Object, null), m.Method, m.Arguments.Select((a, i) => replace(a, parameters[i])).ToArray()); - Expression binded = ExpressionCleaner.BindMethodExpression(simple, true); + Expression binded = ExpressionCleaner.BindMethodExpression(simple, true)!; - Expression cleanedSimple = DbQueryProvider.Clean(binded, true, null); + Expression cleanedSimple = DbQueryProvider.Clean(binded, true, null)!; map.AddRange(replacements); Expression result = Visit(cleanedSimple); map.RemoveRange(replacements.Keys); @@ -1456,14 +1460,14 @@ public Expression BindMethodCall(MethodCallExpression m) return toStr; } - else if (source.NodeType == ExpressionType.Convert && source.Type.UnNullify().IsEnum) + else if (source!/*CSBUG*/.NodeType == ExpressionType.Convert && source!/*CSBUG*/.Type.UnNullify().IsEnum) { - var table = Schema.Current.Table(EnumEntity.Generate(source.Type.UnNullify())); + var table = Schema.Current.Table(EnumEntity.Generate(source!/*CSBUG*/.Type.UnNullify())); if (table != null) { - var ee = new EntityExpression(EnumEntity.Generate(source.Type.UnNullify()), - new PrimaryKeyExpression(((UnaryExpression)source).Operand.Nullify()), null, null, null, null, null, false); + var ee = new EntityExpression(EnumEntity.Generate(source!/*CSBUG*/.Type.UnNullify()), + new PrimaryKeyExpression(((UnaryExpression)source!/*CSBUG*/).Operand.Nullify()), null, null, null, null, null, false); return Completed(ee).GetBinding(EntityExpression.ToStrField); } @@ -1488,7 +1492,7 @@ public Expression BindMethodCall(MethodCallExpression m) if(m.Method.DeclaringType == typeof(SystemTimeExtensions) && m.Method.Name.StartsWith(nameof(SystemTimeExtensions.SystemPeriod))) { var tablePeriod = - source is EntityExpression e ? Completed(e).Let(ec => ec.TablePeriod ?? ec.Table.GenerateSystemPeriod(ec.TableAlias, this, force: true)) : + source is EntityExpression e ? Completed(e).Let(ec => ec.TablePeriod ?? ec.Table.GenerateSystemPeriod(ec.TableAlias!, this, force: true)) : source is MListElementExpression mle ? mle.TablePeriod ?? mle.Table.GenerateSystemPeriod(mle.Alias, this, force: true) : throw new InvalidOperationException("Unexpected source"); @@ -1521,7 +1525,7 @@ private ConditionalExpression DispatchConditional(MethodCallExpression m, Expres static readonly PropertyInfo piIdClass = ReflectionTools.GetPropertyInfo((Entity e) => e.Id); static readonly PropertyInfo piIdInterface = ReflectionTools.GetPropertyInfo((IEntity e) => e.Id); - public Expression BindMemberAccess(MemberExpression m) + public Expression? BindMemberAccess(MemberExpression m) { Expression source = m.Expression; @@ -1547,11 +1551,11 @@ public Expression BindMemberAccess(MemberExpression m) ParameterExpression parameter = Expression.Parameter(m.Expression.Type, "temp"); MemberExpression simple = Expression.MakeMemberAccess(parameter, m.Member); - Expression binded = ExpressionCleaner.BindMemberExpression(simple, true); + Expression? binded = ExpressionCleaner.BindMemberExpression(simple, true); - Expression cleanedSimple = DbQueryProvider.Clean(binded, true, null); + Expression? cleanedSimple = DbQueryProvider.Clean(binded, true, null); map.Add(parameter, source); - Expression result = Visit(cleanedSimple); + Expression? result = Visit(cleanedSimple); map.Remove(parameter); return result; } @@ -1569,7 +1573,7 @@ public Expression BindMemberAccess(MemberExpression m) } } - source = RemoveProjectionConvert(source); + source = RemoveProjectionConvert(source!/*CSBUG*/); switch (source.NodeType) { @@ -1621,7 +1625,7 @@ public Expression BindMemberAccess(MemberExpression m) if (pi != null && ReflectionTools.PropertyEquals(pi, EntityExpression.IdOrNullProperty)) return ee.ExternalId; - FieldInfo fi = m.Member as FieldInfo ?? Reflector.TryFindFieldInfo(ee.Type, pi); + FieldInfo? fi = m.Member as FieldInfo ?? Reflector.TryFindFieldInfo(ee.Type, pi!); if (fi == null) throw new InvalidOperationException("The member {0} of {1} is not accessible on queries".FormatWith(m.Member.Name, ee.Type.TypeName())); @@ -1642,8 +1646,7 @@ public Expression BindMemberAccess(MemberExpression m) case DbExpressionType.EmbeddedInit: { EmbeddedEntityExpression eee = (EmbeddedEntityExpression)source; - FieldInfo fi = m.Member as FieldInfo ?? Reflector.TryFindFieldInfo(eee.Type, (PropertyInfo)m.Member); - + FieldInfo? fi = m.Member as FieldInfo ?? Reflector.TryFindFieldInfo(eee.Type, (PropertyInfo)m.Member); if (fi == null) throw new InvalidOperationException("The member {0} of {1} is not accesible on queries".FormatWith(m.Member.Name, eee.Type.TypeName())); @@ -1661,9 +1664,9 @@ public Expression BindMemberAccess(MemberExpression m) { MixinEntityExpression mee = (MixinEntityExpression)source; - PropertyInfo pi = m.Member as PropertyInfo; + PropertyInfo pi = (PropertyInfo)m.Member; if (pi.Name == "MainEntity") - return mee.FieldMixin.MainEntityTable.GetProjectorExpression(mee.MainEntityAlias, this); + return mee.FieldMixin!.MainEntityTable.GetProjectorExpression(mee.MainEntityAlias!, this); FieldInfo fi = m.Member as FieldInfo ?? Reflector.FindFieldInfo(mee.Type, (PropertyInfo)m.Member); @@ -1683,18 +1686,17 @@ public Expression BindMemberAccess(MemberExpression m) case DbExpressionType.LiteReference: { LiteReferenceExpression liteRef = (LiteReferenceExpression)source; - PropertyInfo pi = m.Member as PropertyInfo; + PropertyInfo? pi = m.Member as PropertyInfo; if (pi != null) { if (pi.Name == "Id") return BindMemberAccess(Expression.Property(liteRef.Reference, liteRef.Reference.Type.IsInterface ? piIdInterface : piIdClass)); if (pi.Name == "EntityOrNull" || pi.Name == "Entity") return liteRef.Reference; + if (pi.Name == "EntityType") + return GetEntityType(liteRef.Reference); } - if (pi.Name == "EntityType") - return GetEntityType(liteRef.Reference); - throw new InvalidOperationException("The member {0} of Lite is not accessible on queries".FormatWith(m.Member)); } case DbExpressionType.ImplementedBy: @@ -1702,7 +1704,7 @@ public Expression BindMemberAccess(MemberExpression m) var ib = (ImplementedByExpression)source; return DispatchIb(ib, m.Member.ReturningType(), ee => - BindMemberAccess(Expression.MakeMemberAccess(ee, m.Member))); + BindMemberAccess(Expression.MakeMemberAccess(ee, m.Member))!); } case DbExpressionType.ImplementedByAll: { @@ -1804,7 +1806,7 @@ private Expression CombineImplementations(ICombineStrategy strategy, Dictionary< if (expressions.All(e => e.Value is LiteReferenceExpression)) { Expression entity = CombineImplementations(strategy, expressions.SelectDictionary(ex => - ((LiteReferenceExpression)ex).Reference), Lite.Extract(returnType)); + ((LiteReferenceExpression)ex).Reference), Lite.Extract(returnType)!); return MakeLite(entity, null); } @@ -1966,7 +1968,7 @@ internal static PrimaryKeyExpression ExtractTypeId(Expression exp) TypeConstant(imp.Key).Nullify(), acum))); } - throw new InvalidOperationException("Impossible to extract TypeId from {0}".FormatWith(exp.ToString())); + throw new InvalidOperationException("Impossible to extract TypeId from {0}".FormatWith(exp!/*CSBUG*/.ToString())); } protected override Expression VisitInvocation(InvocationExpression iv) @@ -2080,7 +2082,7 @@ public Expression SimplifyRedundandConverts(UnaryExpression unary) return unary; } - private Expression EntityCasting(Expression operand, Type uType) + private Expression? EntityCasting(Expression? operand, Type uType) { if (operand == null) return null; @@ -2138,7 +2140,7 @@ private Expression EntityCasting(Expression operand, Type uType) if (!uType.IsLite()) throw new InvalidCastException("Impossible to convert an expression of type {0} to {1}".FormatWith(lite.Type.TypeName(), uType.TypeName())); - Expression entity = EntityCasting(lite.Reference, Lite.Extract(uType)); + Expression entity = EntityCasting(lite.Reference, Lite.Extract(uType)!)!; return MakeLite(entity, lite.CustomToStr); } @@ -2208,19 +2210,21 @@ internal CommandExpression BindDelete(Expression source) } else if (pr.Projector is EmbeddedEntityExpression eee) { - Expression id = eee.ViewTable.GetIdExpression(aliasGenerator.Table(eee.ViewTable.Name)); + var vn = eee.ViewTable!; + + Expression id = vn.GetIdExpression(aliasGenerator.Table(vn.Name)); - commands.Add(new DeleteExpression(eee.ViewTable, false, pr.Select, SmartEqualizer.EqualNullable(id, eee.GetViewId()))); + commands.Add(new DeleteExpression(vn, false, pr.Select, SmartEqualizer.EqualNullable(id, eee.GetViewId()))); } else - throw new InvalidOperationException("Delete not supported for {0}".FormatWith(pr.Projector.GetType().TypeName())); + throw new InvalidOperationException("Delete not supported for {0}".FormatWith(pr.Projector!/*CSBUG*/.GetType().TypeName())); commands.Add(new SelectRowCountExpression()); return new CommandAggregateExpression(commands); } - internal CommandExpression BindUpdate(Expression source, LambdaExpression partSelector, IEnumerable setterExpressions) + internal CommandExpression BindUpdate(Expression source, LambdaExpression? partSelector, IEnumerable setterExpressions) { ProjectionExpression pr = VisitCastProjection(source); @@ -2229,16 +2233,16 @@ internal CommandExpression BindUpdate(Expression source, LambdaExpression partSe entity = pr.Projector; else { - var cleanedSelector = (LambdaExpression)DbQueryProvider.Clean(partSelector, false, null); + var cleanedSelector = (LambdaExpression)DbQueryProvider.Clean(partSelector, false, null)!; entity = MapVisitExpand(cleanedSelector, pr); } ITable table = entity is EntityExpression entEx ? (ITable)entEx.Table : - entity is EmbeddedEntityExpression eeEx ? (ITable)eeEx.ViewTable: - entity is MListElementExpression mlistEx ? (ITable)mlistEx.Table : - throw new InvalidOperationException(); + entity is EmbeddedEntityExpression eeEx ? (ITable)eeEx.ViewTable!: + entity is MListElementExpression mlistEx ? (ITable)mlistEx.Table!: + throw new UnexpectedValueException(entity!/*CSBUG*/); Alias alias = aliasGenerator.Table(table.Name); @@ -2247,7 +2251,7 @@ internal CommandExpression BindUpdate(Expression source, LambdaExpression partSe ((TableMList)table).GetProjectorExpression(alias, this); List assignments = new List(); - using (SetCurrentSource(pr.Select.From)) + using (SetCurrentSource(pr.Select.From!)) { foreach (var setter in setterExpressions) { @@ -2261,9 +2265,7 @@ internal CommandExpression BindUpdate(Expression source, LambdaExpression partSe } catch (CurrentSourceNotFoundException e) { - throw new InvalidOperationException("The expression '{0}' can not be used as a propertyExpression. Consider using UnsafeUpdatePart" - .FormatWith(setter.PropertyExpression.ToString()), - e); + throw new InvalidOperationException($"The expression '{setter.PropertyExpression}' can not be used as a propertyExpression. Consider using UnsafeUpdatePart", e); } var param = setter.ValueExpression.Parameters.Single(); @@ -2295,13 +2297,13 @@ internal CommandExpression BindUpdate(Expression source, LambdaExpression partSe } else if (entity is EmbeddedEntityExpression eee) { - Expression id = eee.ViewTable.GetIdExpression(aliasGenerator.Table(eee.ViewTable.GetName(isHistory))); + Expression id = eee.ViewTable!.GetIdExpression(aliasGenerator.Table(eee.ViewTable!.GetName(isHistory))); condition = SmartEqualizer.EqualNullable(id, eee.GetViewId()); - table = eee.ViewTable; + table = eee.ViewTable!; } else - throw new InvalidOperationException("Update not supported for {0}".FormatWith(entity.GetType().TypeName())); + throw new InvalidOperationException("Update not supported for {0}".FormatWith(entity!/*CSBUG*/.GetType().TypeName())); var result = new CommandAggregateExpression(new CommandExpression[] @@ -2331,7 +2333,7 @@ internal CommandExpression BindInsert(Expression source, LambdaExpression constr { map.Add(param, pr.Projector); map.Add(toInsertParam, toInsert); - var cleanedConstructor = DbQueryProvider.Clean(constructor.Body, false, null); + var cleanedConstructor = DbQueryProvider.Clean(constructor.Body, false, null)!; FillColumnAssigments(assignments, toInsertParam, cleanedConstructor, e => { var cleaned = DbQueryProvider.Clean(e, true, null); @@ -2347,6 +2349,8 @@ internal CommandExpression BindInsert(Expression source, LambdaExpression constr assignments.Add(new ColumnAssignment(entityTable.Ticks.Name, Expression.Constant(0L, typeof(long)))); } + table = table!; /*CSBUG*/ + var isHistory = this.systemTime is SystemTime.HistoryTable; var result = new CommandAggregateExpression(new CommandExpression[] @@ -2463,7 +2467,7 @@ private ColumnAssignment[] Assign(Expression colExpression, Expression expressio var bindings = cEmb.Bindings.SelectMany(b => AdaptAssign(b.Binding, expEmb.GetBinding(b.FieldInfo))); - if (cEmb.FieldEmbedded.HasValue != null) + if (cEmb.FieldEmbedded!.HasValue != null) { var setValue = AssignColumn(cEmb.HasValue, expEmb.HasValue); bindings = bindings.PreAnd(setValue); @@ -2510,7 +2514,7 @@ ColumnAssignment AssignColumn(Expression column, Expression expression) if (col == null) throw new InvalidOperationException("{0} does not represent a column".FormatWith(column.ToString())); - return new ColumnAssignment(col.Name, DbExpressionNominator.FullNominate(expression)); + return new ColumnAssignment(col.Name, DbExpressionNominator.FullNominate(expression)!); } #region BinderTools @@ -2519,21 +2523,18 @@ public UnionAllRequest Completed(ImplementedByExpression ib) { return implementedByReplacements.GetOrCreate(ib, () => { - UnionAllRequest result = new UnionAllRequest(ib) - { - UnionAlias = aliasGenerator.NextTableAlias("Union" + ib.Type.Name), - - Implementations = ib.Implementations.SelectDictionary(k => k, ee => + UnionAllRequest result = new UnionAllRequest(ib, + unionAlias: aliasGenerator.NextTableAlias("Union" + ib.Type.Name), + implementations: ib.Implementations.SelectDictionary(k => k, ee => { var alias = NextTableAlias(ee.Table.Name); - return new UnionEntity - { - Table = new TableExpression(alias, ee.Table, ee.Table.SystemVersioned != null ? this.systemTime : null, null), - Entity = (EntityExpression)ee.Table.GetProjectorExpression(alias, this), - }; + return new UnionEntity( + entity: (EntityExpression)ee.Table.GetProjectorExpression(alias, this), + table: new TableExpression(alias, ee.Table, ee.Table.SystemVersioned != null ? this.systemTime : null, null) + ); }).ToReadOnly() - }; + ); List equals = new List(); foreach (var unionEntity in result.Implementations.Values) { @@ -2553,9 +2554,9 @@ public UnionAllRequest Completed(ImplementedByExpression ib) ImmutableStack currentSource = ImmutableStack.Empty; - public IDisposable SetCurrentSource(SourceExpression source) + public IDisposable SetCurrentSource(SourceExpression? source) { - this.currentSource = currentSource.Push(source); + this.currentSource = currentSource.Push(source!/*CSBUG*/); return new Disposable(() => currentSource = currentSource.Pop()); } @@ -2650,11 +2651,10 @@ public EntityExpression Completed(EntityExpression entity) var result = new EntityExpression(entity.Type, entity.ExternalId, entity.ExternalPeriod, newAlias, bindings, mixins, period, avoidExpandOnRetrieving: false); - AddRequest(new TableRequest - { - CompleteEntity = result, - Table = new TableExpression(newAlias, table, table.SystemVersioned != null ? this.systemTime : null, null), - }); + AddRequest(new TableRequest( + table: new TableExpression(newAlias, table, table.SystemVersioned != null ? this.systemTime : null, null), + completeEntity: result + )); return result; }); @@ -2671,7 +2671,7 @@ internal static PrimaryKeyExpression NullId(Type type) return new PrimaryKeyExpression(new SqlConstantExpression(null, type.Nullify())); } - public Expression MakeLite(Expression entity, Expression customToStr) + public Expression MakeLite(Expression entity, Expression? customToStr) { return new LiteReferenceExpression(Lite.Generate(entity.Type), entity, customToStr, false, false); } @@ -2690,6 +2690,8 @@ public PrimaryKeyExpression GetId(Expression expression) return aggregate; } + expression = expression!;/*CSBUG*/ + if (expression.NodeType == ExpressionType.Conditional) { var con = (ConditionalExpression)expression; @@ -2730,8 +2732,10 @@ public Expression GetIdString(Expression expression) return aggregate; } - if (expression is ImplementedByAllExpression) - return ((ImplementedByAllExpression)expression).Id; + if (expression is ImplementedByAllExpression iba) + return iba.Id; + + expression = expression!; /*CSBUG*/ if (expression.NodeType == ExpressionType.Conditional) { @@ -2772,11 +2776,12 @@ public Expression GetEntityType(Expression expression) return new TypeImplementedByExpression(ib.Implementations.SelectDictionary(k => k, v => v.ExternalId)); } - if (expression is ImplementedByAllExpression) + if (expression is ImplementedByAllExpression iba) { - return ((ImplementedByAllExpression)expression).TypeId; + return iba.TypeId; } + expression = expression!; /*CSBUG*/ if (expression.NodeType == ExpressionType.Conditional) { var con = (ConditionalExpression)expression; @@ -2850,14 +2855,14 @@ internal ProjectionExpression MListProjection(MListExpression mle, bool withRowI return proj; } - internal Expression BindAdditionalField(AdditionalFieldExpression af, bool entityCompleter) + internal Expression? BindAdditionalField(AdditionalFieldExpression af, bool entityCompleter) { var lambda = Schema.Current.GetAdditionalQueryBinding(af.Route, entityCompleter); if (lambda == null) return null; - var cleanLambda = (LambdaExpression)DbQueryProvider.Clean(lambda, filter: true, log: null); + var cleanLambda = (LambdaExpression)DbQueryProvider.Clean(lambda, filter: true, log: null)!; var parentEntity = new EntityExpression(af.Route.RootType, af.BackID, af.ExternalPeriod, null, null, null, null, false); @@ -2936,6 +2941,12 @@ class UniqueRequest : ExpansionRequest public bool OuterApply; public SelectExpression Select; + public UniqueRequest(SelectExpression select, bool outerApply) + { + OuterApply = outerApply; + Select = select; + } + public override string ToString() { return base.ToString() + (OuterApply ? " OUTER APPLY" : " CROSS APPLY") + " with " + Select.ToString(); @@ -2960,6 +2971,12 @@ class TableRequest : ExpansionRequest public TableExpression Table; public EntityExpression CompleteEntity; + public TableRequest(TableExpression table, EntityExpression completeEntity) + { + Table = table; + CompleteEntity = completeEntity; + } + public override string ToString() { return base.ToString() + " LEFT OUTER JOIN with " + Table.ToString(); @@ -2983,9 +3000,11 @@ class UnionAllRequest : ExpansionRequest, QueryBinder.ICombineStrategy Dictionary> declarations = new Dictionary>(); - public UnionAllRequest(ImplementedByExpression ib) + public UnionAllRequest(ImplementedByExpression ib, Alias unionAlias, ReadOnlyDictionary implementations) { this.OriginalImplementedBy = ib; + this.UnionAlias = unionAlias; + this.Implementations = implementations; } public override string ToString() @@ -3032,7 +3051,7 @@ public Expression CombineValues(Dictionary implementations, Ty { var union = Implementations[kvp.Key].UnionExternalId; - var condition = Expression.NotEqual(union, QueryBinder.NullId(union.ValueType)); + var condition = Expression.NotEqual(union, QueryBinder.NullId(union!.ValueType)); if (kvp.Value is Expression exp) { @@ -3077,7 +3096,7 @@ object GetNominableExpression(Type type, Expression exp) if (nominations.Contains(newExp)) return newExp; - return new DityExpression { projector = newExp, candidates = nominations }; + return new DityExpression(projector : newExp, candidates : nominations); } @@ -3085,14 +3104,26 @@ class DityExpression { public Expression projector; public HashSet candidates; + + public DityExpression(Expression projector, HashSet candidates) + { + this.projector = projector; + this.candidates = candidates; + } } } class UnionEntity { - public PrimaryKeyExpression UnionExternalId; + public PrimaryKeyExpression? UnionExternalId; public EntityExpression Entity; public TableExpression Table; + + public UnionEntity(EntityExpression entity, TableExpression table) + { + Entity = entity; + Table = table; + } } class QueryJoinExpander : DbExpressionVisitor @@ -3100,16 +3131,18 @@ class QueryJoinExpander : DbExpressionVisitor Dictionary> requests; AliasGenerator aliasGenerator; + public QueryJoinExpander(Dictionary> requests, AliasGenerator aliasGenerator) + { + this.requests = requests; + this.aliasGenerator = aliasGenerator; + } + public static Expression ExpandJoins(Expression expression, QueryBinder binder, bool cleanRequests) { if (binder.requests.IsEmpty()) return expression; - QueryJoinExpander expander = new QueryJoinExpander - { - requests = binder.requests, - aliasGenerator = binder.aliasGenerator, - }; + QueryJoinExpander expander = new QueryJoinExpander(binder.requests, binder.aliasGenerator); var result = expander.Visit(expression); @@ -3127,9 +3160,6 @@ public static Expression ExpandJoins(Expression expression, QueryBinder binder, protected internal override SourceExpression VisitSource(SourceExpression source) { - if (source == null) - return null; - var reqs = requests.TryGetC(source); //if (reqs != null) @@ -3147,40 +3177,34 @@ SourceExpression ApplyExpansions(SourceExpression source, List { foreach (var r in expansions) { - if (r is TableRequest) + if (r is TableRequest tr) { - TableRequest tr = r as TableRequest; - var eq = SmartEqualizer.EqualNullable(tr.CompleteEntity.ExternalId, tr.CompleteEntity.GetBinding(EntityExpression.IdField)) .And(tr.CompleteEntity.ExternalPeriod.Overlaps(tr.CompleteEntity.TablePeriod)); - Expression equal = DbExpressionNominator.FullNominate(eq); + Expression equal = DbExpressionNominator.FullNominate(eq)!; source = new JoinExpression(JoinType.SingleRowLeftOuterJoin, source, tr.Table, equal); } - else if (r is UniqueRequest) + else if (r is UniqueRequest ur) { - UniqueRequest ur = (UniqueRequest)r; - - var newSelect = (SourceExpression)VisitSource(ur.Select); + var newSelect = VisitSource(ur.Select); source = new JoinExpression(ur.OuterApply ? JoinType.OuterApply : JoinType.CrossApply, source, newSelect, null); } - else + else if(r is UnionAllRequest ua) { - UnionAllRequest ur = (UnionAllRequest)r; - - var unionAll = ur.Implementations.Select(ue => + var unionAll = ua.Implementations.Select(ue => { - var table = (SourceExpression)VisitSource(ue.Value.Table); + var table = VisitSource(ue.Value.Table)!; - var columns = ur.GetDeclarations(ue.Key); + var columns = ua.GetDeclarations(ue.Key); return new SelectExpression(aliasGenerator.NextSelectAlias(), false, null, columns, table, null, null, null, 0); - }).Aggregate((a, b) => new SetOperatorExpression(SetOperator.UnionAll, a, b, ur.UnionAlias)); + }).Aggregate((a, b) => new SetOperatorExpression(SetOperator.UnionAll, a, b, ua.UnionAlias)); - var condition = (from imp in ur.Implementations + var condition = (from imp in ua.Implementations let uid = imp.Value.UnionExternalId - let eid = ur.OriginalImplementedBy.Implementations[imp.Key].ExternalId + let eid = ua.OriginalImplementedBy.Implementations[imp.Key].ExternalId select Expression.Or( SmartEqualizer.EqualNullable(uid, eid), Expression.And(new IsNullExpression(uid), new IsNullExpression(eid)))) @@ -3189,14 +3213,14 @@ select Expression.Or( source = new JoinExpression(JoinType.SingleRowLeftOuterJoin, source, unionAll, condition); } - r.Consumed = true; + r!/*CSBUG*/.Consumed = true; } return source; } protected internal override Expression VisitProjection(ProjectionExpression proj) { - SourceExpression source = (SourceExpression)this.VisitSource(proj.Select); + SourceExpression source = this.VisitSource(proj.Select); Expression projector = this.Visit(proj.Projector); if (source == proj.Select && projector == proj.Projector) @@ -3228,7 +3252,7 @@ protected internal override Expression VisitUpdate(UpdateExpression update) protected internal override Expression VisitInsertSelect(InsertSelectExpression insertSelect) { - var source = VisitSource(insertSelect.Source); + var source = VisitSource(insertSelect.Source)!; var assigments = Visit(insertSelect.Assigments, VisitColumnAssigment); if (source != insertSelect.Source || assigments != insertSelect.Assigments) { @@ -3251,9 +3275,14 @@ class AssignAdapterExpander : DbExpressionVisitor { Expression colExpression; + public AssignAdapterExpander(Expression colExpression) + { + this.colExpression = colExpression; + } + public static Expression Adapt(Expression exp, Expression colExpression) { - return new AssignAdapterExpander { colExpression = colExpression }.Visit(exp); + return new AssignAdapterExpander (colExpression).Visit(exp); } protected override Expression VisitConditional(ConditionalExpression c) @@ -3268,7 +3297,7 @@ protected override Expression VisitConditional(ConditionalExpression c) { using (this.OverrideColExpression(col.Reference)) { - var entity = CombineConditional(test, l.Reference, r.Reference); + var entity = CombineConditional(test, l.Reference, r.Reference)!; return new LiteReferenceExpression(Lite.Generate(entity.Type), entity, null, false, false); } }); @@ -3277,7 +3306,7 @@ protected override Expression VisitConditional(ConditionalExpression c) return CombineConditional(test, ifTrue, ifFalse) ?? c; } - private Expression CombineConditional(Expression test, Expression ifTrue, Expression ifFalse) + private Expression? CombineConditional(Expression test, Expression ifTrue, Expression ifFalse) { if (colExpression is EntityExpression) return Combiner(ifTrue, ifFalse, (col, t, f) => @@ -3327,8 +3356,8 @@ protected override Expression VisitBinary(BinaryExpression b) { using (this.OverrideColExpression(col.Reference)) { - var entity = CombineCoalesce(l.Reference, r.Reference); - return new LiteReferenceExpression(Lite.Generate(entity.Type), entity, null, false, false); + var entity = CombineCoalesce(l.Reference, r.Reference)!; + return new LiteReferenceExpression(Lite.Generate(entity!.Type), entity, null, false, false); } }); } @@ -3385,7 +3414,7 @@ protected override Expression VisitUnary(UnaryExpression node) } } - private Expression CombineCoalesce(Expression left, Expression right) + private Expression? CombineCoalesce(Expression left, Expression right) { if (colExpression is EntityExpression) return Combiner(left, right, (col, l, r) => @@ -3589,7 +3618,7 @@ internal EmbeddedEntityExpression EmbeddedFromConstant(ConstantExpression contan var embedded = (EmbeddedEntityExpression)colExpression; - var bindings = (from kvp in embedded.FieldEmbedded.EmbeddedFields + var bindings = (from kvp in embedded.FieldEmbedded!.EmbeddedFields let fi = kvp.Value.FieldInfo let bind = embedded.GetBinding(fi) select GetBinding(fi, value == null ? @@ -3611,7 +3640,7 @@ protected override Expression VisitMemberInit(MemberInitExpression init) var embedded = (EmbeddedEntityExpression)colExpression; - var bindings = (from kvp in embedded.FieldEmbedded.EmbeddedFields + var bindings = (from kvp in embedded.FieldEmbedded!.EmbeddedFields let fi = kvp.Value.FieldInfo select new FieldBinding(fi, fi.FieldType.IsValueType && !fi.FieldType.IsNullable() ? dic.GetOrThrow(fi.Name, "No value defined for non-nullable field {0}") : diff --git a/Signum.Engine/Linq/ExpressionVisitor/QueryFilterer.cs b/Signum.Engine/Linq/ExpressionVisitor/QueryFilterer.cs index 5c37114a59..5d61ea352d 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/QueryFilterer.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/QueryFilterer.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using Signum.Utilities.ExpressionTrees; using System.Linq.Expressions; @@ -95,7 +95,7 @@ protected override Expression VisitMethodCall(MethodCallExpression m) } - internal static Expression Filter(Expression expression, bool filter) + internal static Expression? Filter(Expression? expression, bool filter) { return new QueryFilterer { filter = filter }.Visit(expression); } diff --git a/Signum.Engine/Patterns/VirtualMList.cs b/Signum.Engine/Patterns/VirtualMList.cs index 8a4981331d..c35f6548f7 100644 --- a/Signum.Engine/Patterns/VirtualMList.cs +++ b/Signum.Engine/Patterns/VirtualMList.cs @@ -1,4 +1,4 @@ -using Signum.Engine.Maps; +using Signum.Engine.Maps; using Signum.Engine.Operations; using Signum.Entities; using Signum.Entities.Reflection; @@ -22,7 +22,7 @@ public static class VirtualMList public static bool ShouldAvoidMListType(Type elementType) { var stack = avoidTypes.Value; - return (stack != null && (stack.Contains(elementType) || stack.Contains(null))); + return (stack != null && (stack.Contains(elementType) || stack.Contains(typeof(object)))); } public static bool IsVirtualMList(this PropertyRoute pr) @@ -43,7 +43,7 @@ public static IDisposable AvoidMListType(Type elementType) public static bool ShouldConsiderNew(Type parentType) { var stack = considerNewTypes.Value; - return (stack != null && (stack.Contains(parentType) || stack.Contains(null))); + return (stack != null && (stack.Contains(parentType) || stack.Contains(typeof(object)))); } /// Use null for every type @@ -77,8 +77,8 @@ public static FluentInclude WithVirtualMList(this FluentInclude fi, public static FluentInclude WithVirtualMList(this FluentInclude fi, Expression>> mListField, Expression>> backReference, - Action onSave = null, - Action onRemove = null, + Action? onSave = null, + Action? onRemove = null, bool? lazyRetrieve = null, bool? lazyDelete = null) //To avoid StackOverflows where T : Entity @@ -94,7 +94,7 @@ public static FluentInclude WithVirtualMList(this FluentInclude fi, lazyDelete = (typeof(L) == typeof(T)); Func> getMList = GetAccessor(mListField); - Action> setter = null; + Action>? setter = null; bool preserveOrder = fi.SchemaBuilder.Settings.FieldAttributes(mListPropertRoute) .OfType() .Any(); @@ -204,7 +204,7 @@ public static FluentInclude WithVirtualMList(this FluentInclude fi, if(onRemove == null) query.Where(p => !oldElements.Contains(p)).UnsafeDelete(); else - query.Where(p => !oldElements.Contains(p)).ToList().ForEach(line => onRemove(line, e)); + query.Where(p => !oldElements.Contains(p)).ToList().ForEach(line => onRemove!(line, e)); } if (mlist != null) @@ -218,7 +218,7 @@ public static FluentInclude WithVirtualMList(this FluentInclude fi, if (onSave == null) mlist.SaveList(); else - mlist.ForEach(line => { if (GraphExplorer.IsGraphModified(line)) onSave(line, e); }); + mlist.ForEach(line => { if (GraphExplorer.IsGraphModified(line)) onSave!(line, e); }); var priv = (IMListPrivate)mlist; for (int i = 0; i < mlist.Count; i++) @@ -257,12 +257,12 @@ public static FluentInclude WithVirtualMList(this FluentInclude fi, public static FluentInclude WithVirtualMListInitializeOnly(this FluentInclude fi, Expression>> mListField, Expression>> backReference, - Action onSave = null) + Action? onSave = null) where T : Entity where L : Entity { Func> getMList = GetAccessor(mListField); - Action> setter = null; + Action>? setter = null; var sb = fi.SchemaBuilder; sb.Schema.EntityEvents().RegisterBinding(mListField, @@ -302,7 +302,11 @@ public static FluentInclude WithVirtualMListInitializeOnly(this FluentI if (onSave == null) mlist.SaveList(); else - mlist.ForEach(line => { if (GraphExplorer.IsGraphModified(line)) onSave(line, e); }); + mlist.ForEach(line => + { + if (GraphExplorer.IsGraphModified(line)) + onSave!(line, e); + }); var priv = (IMListPrivate)mlist; for (int i = 0; i < mlist.Count; i++) { @@ -338,7 +342,7 @@ private static Expression SafeAccess(ParameterExpression param, MemberExpression ); } - public static Action> CreateSetter(Expression>> getBackReference) + public static Action>? CreateSetter(Expression>> getBackReference) where T : Entity where L : Entity { diff --git a/Signum.Engine/Schema/EntityEvents.cs b/Signum.Engine/Schema/EntityEvents.cs index b0a610a85e..a7b2047402 100644 --- a/Signum.Engine/Schema/EntityEvents.cs +++ b/Signum.Engine/Schema/EntityEvents.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -19,7 +19,7 @@ public class EntityEvents : IEntityEvents public event AlternativeRetriveEventHandler AlternativeRetrive; public event RetrievedEventHandler Retrieved; - public CacheControllerBase CacheController { get; set; } + public CacheControllerBase? CacheController { get; set; } public event FilterQueryEventHandler FilterQuery; @@ -31,10 +31,10 @@ public class EntityEvents : IEntityEvents public event PreUnsafeInsertHandler PreUnsafeInsert; public event BulkInsetHandler PreBulkInsert; - public Dictionary AdditionalBindings { get; private set; } + public Dictionary? AdditionalBindings { get; private set; } /// For Caching scenarios - public void RegisterBinding(Expression> field, Func shouldSet, Expression> valueExpression, Func valueFunction = null) + public void RegisterBinding(Expression> field, Func shouldSet, Expression> valueExpression, Func? valueFunction = null) { if (AdditionalBindings == null) AdditionalBindings = new Dictionary(); @@ -43,13 +43,7 @@ public void RegisterBinding(Expression> field, Func shouldSe var pr = PropertyRoute.Construct(field); - AdditionalBindings.Add(pr, new AdditionalBinding - { - PropertyRoute = pr, - ShouldSet = shouldSet, - ValueExpression = valueExpression, - ValueFunction = valueFunction, - }); + AdditionalBindings.Add(pr, new AdditionalBinding(pr, shouldSet, valueExpression, valueFunction)); } @@ -62,9 +56,9 @@ internal IEnumerable> OnFilterQuery() return FilterQuery.GetInvocationListTyped().Select(f => f()).ToList(); } - internal IDisposable OnPreUnsafeDelete(IQueryable entityQuery) + internal IDisposable? OnPreUnsafeDelete(IQueryable entityQuery) { - IDisposable result = null; + IDisposable? result = null; if (PreUnsafeDelete != null) foreach (var action in PreUnsafeDelete.GetInvocationListTyped().Reverse()) result = Disposable.Combine(result, action(entityQuery)); @@ -72,9 +66,9 @@ internal IDisposable OnPreUnsafeDelete(IQueryable entityQuery) return result; } - internal IDisposable OnPreUnsafeMListDelete(IQueryable mlistQuery, IQueryable entityQuery) + internal IDisposable? OnPreUnsafeMListDelete(IQueryable mlistQuery, IQueryable entityQuery) { - IDisposable result = null; + IDisposable? result = null; if (PreUnsafeMListDelete != null) foreach (var action in PreUnsafeMListDelete.GetInvocationListTyped().Reverse()) result = Disposable.Combine(result, action(mlistQuery, entityQuery)); @@ -82,9 +76,9 @@ internal IDisposable OnPreUnsafeMListDelete(IQueryable mlistQuery, IQueryable return result; } - IDisposable IEntityEvents.OnPreUnsafeUpdate(IUpdateable update) + IDisposable? IEntityEvents.OnPreUnsafeUpdate(IUpdateable update) { - IDisposable result = null; + IDisposable? result = null; if (PreUnsafeUpdate != null) { var query = update.EntityQuery(); @@ -133,7 +127,7 @@ void IEntityEvents.OnRetrieved(Entity entity) Retrieved?.Invoke((T)entity); } - public Entity OnAlternativeRetriving(PrimaryKey id) + public Entity? OnAlternativeRetriving(PrimaryKey id) { if (AlternativeRetrive == null) return null; @@ -142,7 +136,6 @@ public Entity OnAlternativeRetriving(PrimaryKey id) AlternativeRetrive(id, args); - if (args.Entity == null) throw new EntityNotFoundException(typeof(T), id); @@ -158,7 +151,7 @@ public Entity OnAlternativeRetriving(PrimaryKey id) } - ICacheController IEntityEvents.CacheController + ICacheController? IEntityEvents.CacheController { get { return CacheController; } } @@ -178,10 +171,18 @@ public class AdditionalBinding : IAdditionalBinding public PropertyRoute PropertyRoute { get; set; } public Func ShouldSet { get; set; } public Expression> ValueExpression { get; set; } - public Func ValueFunction { get; set; } + public Func? ValueFunction { get; set; } LambdaExpression IAdditionalBinding.ValueExpression => ValueExpression; - Action _setter; + Action? _setter; + + public AdditionalBinding(PropertyRoute propertyRoute, Func shouldSet, Expression> valueExpression, Func? valueFunction) + { + PropertyRoute = propertyRoute; + ShouldSet = shouldSet; + ValueExpression = valueExpression; + ValueFunction = valueFunction; + } public void SetInMemory(Entity entity, IRetriever retriever) => SetInMemory((T)entity, retriever); void SetInMemory(T entity, IRetriever retriever) @@ -217,17 +218,17 @@ Action CreateSetter() retriever.ModifiablePostRetrieving((Modifiable)(object)mlist); }; } - else if (PropertyRoute.Parent.PropertyRouteType == PropertyRouteType.Root) + else if (PropertyRoute.Parent!.PropertyRouteType == PropertyRouteType.Root) { - var setter = ReflectionTools.CreateSetter(PropertyRoute.PropertyInfo); + var setter = ReflectionTools.CreateSetter(PropertyRoute.PropertyInfo!); return (e, value, retriever) => setter(e, value); } else { - var partGetter = PropertyRoute.Parent.GetLambdaExpression(true).Compile(); + var partGetter = PropertyRoute.Parent!.GetLambdaExpression(true).Compile(); - var setter = ReflectionTools.CreateSetter(PropertyRoute.PropertyInfo); + var setter = ReflectionTools.CreateSetter(PropertyRoute.PropertyInfo!); return (e, value, retriever) => { @@ -248,9 +249,9 @@ Action CreateSetter() public delegate FilterQueryResult FilterQueryEventHandler() where T : Entity; public delegate void AlternativeRetriveEventHandler(PrimaryKey id, AlternativeRetrieveArgs args) where T : Entity; - public delegate IDisposable PreUnsafeDeleteHandler(IQueryable entityQuery); - public delegate IDisposable PreUnsafeMListDeleteHandler(IQueryable mlistQuery, IQueryable entityQuery); - public delegate IDisposable PreUnsafeUpdateHandler(IUpdateable update, IQueryable entityQuery); + public delegate IDisposable? PreUnsafeDeleteHandler(IQueryable entityQuery); + public delegate IDisposable? PreUnsafeMListDeleteHandler(IQueryable mlistQuery, IQueryable entityQuery); + public delegate IDisposable? PreUnsafeUpdateHandler(IUpdateable update, IQueryable entityQuery); public delegate LambdaExpression PreUnsafeInsertHandler(IQueryable query, LambdaExpression constructor, IQueryable entityQuery); public delegate void BulkInsetHandler(bool inMListTable); @@ -258,7 +259,7 @@ Action CreateSetter() public class AlternativeRetrieveArgs where T : Entity { public bool AvoidAccesVerify { get; set; } - public T Entity { get; set; } + public T? Entity { get; set; } } public class SavedEventArgs @@ -289,19 +290,19 @@ public FilterQueryResult(Expression> inDatabaseExpression, Func AdditionalBindings { get; } + Dictionary? AdditionalBindings { get; } } } diff --git a/Signum.Engine/Schema/FluentInclude.cs b/Signum.Engine/Schema/FluentInclude.cs index 5ae110e045..056880f8fb 100644 --- a/Signum.Engine/Schema/FluentInclude.cs +++ b/Signum.Engine/Schema/FluentInclude.cs @@ -1,4 +1,4 @@ -using Signum.Entities; +using Signum.Entities; using System; using System.Linq.Expressions; @@ -15,19 +15,24 @@ public FluentInclude(Table table, SchemaBuilder schemaBuilder) SchemaBuilder = schemaBuilder; } - public FluentInclude WithUniqueIndex(Expression> fields, Expression> where = null, Expression> includeFields = null) + public FluentInclude WithUniqueIndex(Expression> fields, Expression>? where = null, Expression>? includeFields = null) { this.SchemaBuilder.AddUniqueIndex(fields, where, includeFields); return this; } - public FluentInclude WithIndex(Expression> fields, Expression> where = null, Expression> includeFields = null) + public FluentInclude WithIndex(Expression> fields, + Expression>? where = null, + Expression>? includeFields = null) { this.SchemaBuilder.AddIndex(fields, where, includeFields); return this; } - public FluentInclude WithUniqueIndexMList(Expression>> mlist, Expression, object>> fields = null, Expression, bool>> where = null, Expression, object>> includeFields = null) + public FluentInclude WithUniqueIndexMList(Expression>> mlist, + Expression, object>>? fields = null, + Expression, bool>>? where = null, + Expression, object>>? includeFields = null) { if (fields == null) fields = mle => new { mle.Parent, mle.Element }; @@ -36,7 +41,10 @@ public FluentInclude WithUniqueIndexMList(Expression>> ml return this; } - public FluentInclude WithIndexMList(Expression>> mlist, Expression, object>> fields, Expression, bool>> where = null, Expression, object>> includeFields = null) + public FluentInclude WithIndexMList(Expression>> mlist, + Expression, object>> fields, + Expression, bool>>? where = null, + Expression, object>>? includeFields = null) { this.SchemaBuilder.AddIndexMList(mlist, fields, where, includeFields); return this; diff --git a/Signum.Engine/Schema/ObjectName.cs b/Signum.Engine/Schema/ObjectName.cs index 01949be6f0..5ac881516a 100644 --- a/Signum.Engine/Schema/ObjectName.cs +++ b/Signum.Engine/Schema/ObjectName.cs @@ -1,4 +1,4 @@ -using System; +using System; using Signum.Utilities; namespace Signum.Engine.Maps @@ -48,7 +48,7 @@ public override int GetHashCode() return Name.GetHashCode(); } - public static ServerName Parse(string name) + public static ServerName? Parse(string? name) { if (string.IsNullOrEmpty(name)) return null; @@ -61,9 +61,9 @@ public class DatabaseName : IEquatable { public string Name { get; private set; } - public ServerName Server { get; private set; } + public ServerName? Server { get; private set; } - public DatabaseName(ServerName server, string name) + public DatabaseName(ServerName? server, string name) { if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); @@ -101,7 +101,7 @@ public override int GetHashCode() return Name.GetHashCode() ^ (Server == null ? 0 : Server.GetHashCode()); } - public static DatabaseName Parse(string name) + public static DatabaseName? Parse(string? name) { if (string.IsNullOrEmpty(name)) return null; @@ -116,9 +116,9 @@ public class SchemaName : IEquatable { public string Name { get; private set; } - readonly DatabaseName database; + readonly DatabaseName? database; - public DatabaseName Database + public DatabaseName? Database { get { @@ -136,7 +136,7 @@ public bool IsDefault() return Name == "dbo" && Database == null; } - public SchemaName(DatabaseName database, string name) + public SchemaName(DatabaseName? database, string name) { if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); @@ -172,7 +172,7 @@ public override int GetHashCode() return Name.GetHashCode() ^ (Database == null ? 0 : Database.GetHashCode()); } - public static SchemaName Parse(string name) + public static SchemaName Parse(string? name) { if (string.IsNullOrEmpty(name)) return SchemaName.Default; @@ -218,7 +218,7 @@ public override int GetHashCode() return Name.GetHashCode() ^ Schema.GetHashCode(); } - public static ObjectName Parse(string name) + public static ObjectName Parse(string? name) { if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); @@ -230,7 +230,7 @@ public static ObjectName Parse(string name) //FROM "[a.b.c].[d.e.f].[a.b.c].[c.d.f]" //TO ("[a.b.c].[d.e.f].[a.b.c]", "c.d.f") - internal static (string prefix, string name) SplitLast(string str) + internal static (string? prefix, string name) SplitLast(string str) { if (!str.EndsWith("]")) { @@ -247,7 +247,7 @@ internal static (string prefix, string name) SplitLast(string str) ); } - public ObjectName OnDatabase(DatabaseName databaseName) + public ObjectName OnDatabase(DatabaseName? databaseName) { return new ObjectName(new SchemaName(databaseName, Schema.Name), Name); } diff --git a/Signum.Engine/Schema/Schema.Basics.cs b/Signum.Engine/Schema/Schema.Basics.cs index 5ef9a142fa..f1355d08d9 100644 --- a/Signum.Engine/Schema/Schema.Basics.cs +++ b/Signum.Engine/Schema/Schema.Basics.cs @@ -17,7 +17,7 @@ namespace Signum.Engine.Maps public interface IFieldFinder { Field GetField(MemberInfo value); - Field TryGetField(MemberInfo value); + Field? TryGetField(MemberInfo value); } public interface ITable @@ -28,13 +28,13 @@ public interface ITable Dictionary Columns { get; } - List MultiColumnIndexes { get; set; } + List? MultiColumnIndexes { get; set; } List GeneratAllIndexes(); void GenerateColumns(); - SystemVersionedInfo SystemVersioned { get; } + SystemVersionedInfo? SystemVersioned { get; } } public class SystemVersionedInfo @@ -43,6 +43,13 @@ public class SystemVersionedInfo public string StartColumnName; public string EndColumnName; + public SystemVersionedInfo(ObjectName tableName, string startColumnName, string endColumnName) + { + TableName = tableName; + StartColumnName = startColumnName; + EndColumnName = endColumnName; + } + internal IEnumerable Columns() { return new[] @@ -72,15 +79,15 @@ public Column(string name, ColumnType systemVersionColumnType) public IsNullable Nullable => IsNullable.No; public SqlDbType SqlDbType => SqlDbType.DateTime2; public Type Type => typeof(DateTime); - public string UserDefinedTypeName => null; + public string? UserDefinedTypeName => null; public bool PrimaryKey => false; public bool IdentityBehaviour => false; public bool Identity => false; - public string Default { get; set; } + public string? Default { get; set; } public int? Size => null; public int? Scale => null; - public string Collation => null; - public Table ReferenceTable => null; + public string? Collation => null; + public Table? ReferenceTable => null; public bool AvoidForeignKey => false; } @@ -101,20 +108,22 @@ public partial class Table : IFieldFinder, ITable, ITablePrivate public bool IsView { get; internal set; } public string CleanTypeName { get; set; } - public SystemVersionedInfo SystemVersioned { get; set; } + public SystemVersionedInfo? SystemVersioned { get; set; } public Dictionary Fields { get; set; } - public Dictionary Mixins { get; set; } + public Dictionary? Mixins { get; set; } public Dictionary Columns { get; set; } - public List MultiColumnIndexes { get; set; } + public List? MultiColumnIndexes { get; set; } +#pragma warning disable CS8618 // Non-nullable field is uninitialized. public Table(Type type) { this.Type = type; } +#pragma warning restore CS8618 // Non-nullable field is uninitialized. public override string ToString() { @@ -154,6 +163,8 @@ public Field GetField(MemberInfo member) } } + member = member! /*CSBUG*/; + FieldInfo fi = member as FieldInfo ?? Reflector.FindFieldInfo(Type, (PropertyInfo)member); if (fi == null) @@ -164,7 +175,7 @@ public Field GetField(MemberInfo member) return field.Field; } - public Field TryGetField(MemberInfo member) + public Field? TryGetField(MemberInfo member) { if (member is MethodInfo mi) { @@ -181,12 +192,14 @@ public Field TryGetField(MemberInfo member) return Mixins?.TryGetC((Type)member); } - FieldInfo fi = member as FieldInfo ?? Reflector.TryFindFieldInfo(Type, (PropertyInfo)member); + member = member!; /*CSBUG*/ + + FieldInfo fi = member as FieldInfo ?? Reflector.TryFindFieldInfo(Type, (PropertyInfo)member)!; if (fi == null) return null; - EntityField field = Fields.TryGetC(fi.Name); + EntityField? field = Fields.TryGetC(fi.Name); if (field == null) return null; @@ -273,13 +286,14 @@ public class EntityField public FieldInfo FieldInfo { get; private set; } Type type; - Func getter; - public Func Getter => getter ?? (getter = ReflectionTools.CreateGetterUntyped(type, FieldInfo)); + Func? getter; + public Func Getter => getter ?? (getter = ReflectionTools.CreateGetterUntyped(type, FieldInfo)!); - public EntityField(Type type, FieldInfo fi) + public EntityField(Type type, FieldInfo fi, Field field) { - FieldInfo = fi; + this.FieldInfo = fi; this.type = type; + this.Field = field; } public override string ToString() @@ -292,9 +306,9 @@ public abstract partial class Field { public Type FieldType { get; private set; } public PropertyRoute Route { get; private set; } - public UniqueIndex UniqueIndex { get; set; } + public UniqueIndex? UniqueIndex { get; set; } - public Field(PropertyRoute route, Type fieldType = null) + public Field(PropertyRoute route, Type? fieldType = null) { this.Route = route; this.FieldType = fieldType ?? route.Type; @@ -311,7 +325,7 @@ public virtual IEnumerable GenerateIndexes(ITable table) return new[] { UniqueIndex }; } - public virtual UniqueIndex GenerateUniqueIndex(ITable table, UniqueIndexAttribute attribute) + public virtual UniqueIndex? GenerateUniqueIndex(ITable table, UniqueIndexAttribute attribute) { if (attribute == null) return null; @@ -366,15 +380,15 @@ public partial interface IColumn IsNullable Nullable { get; } SqlDbType SqlDbType { get; } Type Type { get; } - string UserDefinedTypeName { get; } + string? UserDefinedTypeName { get; } bool PrimaryKey { get; } bool IdentityBehaviour { get; } bool Identity { get; } - string Default { get; } + string? Default { get; } int? Size { get; } int? Scale { get; } - string Collation { get; } - Table ReferenceTable { get; } + string? Collation { get; } + Table? ReferenceTable { get; } bool AvoidForeignKey { get; } } @@ -420,23 +434,25 @@ public partial class FieldPrimaryKey : Field, IColumn public string Name { get; set; } IsNullable IColumn.Nullable { get { return IsNullable.No; } } public SqlDbType SqlDbType { get; set; } - public string UserDefinedTypeName { get; set; } + public string? UserDefinedTypeName { get; set; } bool IColumn.PrimaryKey { get { return true; } } public bool Identity { get; set; } bool IColumn.IdentityBehaviour { get { return table.IdentityBehaviour; } } int? IColumn.Size { get { return null; } } int? IColumn.Scale { get { return null; } } - public string Collation { get; set; } - Table IColumn.ReferenceTable { get { return null; } } + public string? Collation { get; set; } + Table? IColumn.ReferenceTable { get { return null; } } public Type Type { get; set; } public bool AvoidForeignKey { get { return false; } } - public string Default { get; set; } + public string? Default { get; set; } Table table; - public FieldPrimaryKey(PropertyRoute route, Table table) + public FieldPrimaryKey(PropertyRoute route, Table table, string name, Type type) : base(route) { this.table = table; + this.Name = name; + this.Type = type; } public override string ToString() @@ -473,20 +489,21 @@ public partial class FieldValue : Field, IColumn public string Name { get; set; } public IsNullable Nullable { get; set; } public SqlDbType SqlDbType { get; set; } - public string UserDefinedTypeName { get; set; } + public string? UserDefinedTypeName { get; set; } public bool PrimaryKey { get; set; } bool IColumn.Identity { get { return false; } } bool IColumn.IdentityBehaviour { get { return false; } } public int? Size { get; set; } - public string Collation { get; set; } + public string? Collation { get; set; } public int? Scale { get; set; } - Table IColumn.ReferenceTable { get { return null; } } + Table? IColumn.ReferenceTable { get { return null; } } public bool AvoidForeignKey { get { return false; } } - public string Default { get; set; } + public string? Default { get; set; } - public FieldValue(PropertyRoute route, Type fieldType = null) + public FieldValue(PropertyRoute route, Type? fieldType, string name) : base(route, fieldType) { + this.Name = name; } public override string ToString() @@ -524,9 +541,10 @@ public partial class FieldTicks : FieldValue { public new Type Type { get; set; } - public FieldTicks(PropertyRoute route) - : base(route) + public FieldTicks(PropertyRoute route, Type type, string name) + : base(route, null, name) { + this.Type = type; } } @@ -537,29 +555,33 @@ public partial class EmbeddedHasValueColumn : IColumn public string Name { get; set; } public IsNullable Nullable { get { return IsNullable.No; } } //even on neasted embeddeds public SqlDbType SqlDbType { get { return SqlDbType.Bit; } } - string IColumn.UserDefinedTypeName { get { return null; } } + string? IColumn.UserDefinedTypeName { get { return null; } } bool IColumn.PrimaryKey { get { return false; } } bool IColumn.Identity { get { return false; } } bool IColumn.IdentityBehaviour { get { return false; } } int? IColumn.Size { get { return null; } } int? IColumn.Scale { get { return null; } } - string IColumn.Collation { get { return null; } } - public Table ReferenceTable { get { return null; } } + string? IColumn.Collation { get { return null; } } + public Table? ReferenceTable { get { return null; } } Type IColumn.Type { get { return typeof(bool); } } public bool AvoidForeignKey { get { return false; } } - public string Default { get; set; } + public string? Default { get; set; } + public EmbeddedHasValueColumn(string name) + { + Name = name; + } } - public EmbeddedHasValueColumn HasValue { get; set; } + public EmbeddedHasValueColumn? HasValue { get; set; } public Dictionary EmbeddedFields { get; set; } - - public Func Constructor { get; private set; } - - public FieldEmbedded(PropertyRoute route) + + public FieldEmbedded(PropertyRoute route, EmbeddedHasValueColumn? hasValue, Dictionary embeddedFields) : base(route) { + this.HasValue = hasValue; + this.EmbeddedFields = embeddedFields; } public override string ToString() @@ -579,14 +601,14 @@ public Field GetField(MemberInfo member) return field.Field; } - public Field TryGetField(MemberInfo value) + public Field? TryGetField(MemberInfo value) { - FieldInfo fi = value as FieldInfo ?? Reflector.TryFindFieldInfo(FieldType, (PropertyInfo)value); + FieldInfo fi = value as FieldInfo ?? Reflector.TryFindFieldInfo(FieldType, (PropertyInfo)value)!; if (fi == null) return null; - EntityField field = EmbeddedFields.TryGetC(fi.Name); + EntityField? field = EmbeddedFields.TryGetC(fi.Name); if (field == null) return null; @@ -634,10 +656,11 @@ public partial class FieldMixin : Field, IFieldFinder public Table MainEntityTable; - public FieldMixin(PropertyRoute route, Table mainEntityTable) + public FieldMixin(PropertyRoute route, Table mainEntityTable, Dictionary fields) : base(route) { this.MainEntityTable = mainEntityTable; + this.Fields = fields; } public override string ToString() @@ -657,14 +680,14 @@ public Field GetField(MemberInfo member) return field.Field; } - public Field TryGetField(MemberInfo value) + public Field? TryGetField(MemberInfo value) { - FieldInfo fi = value as FieldInfo ?? Reflector.TryFindFieldInfo(FieldType, (PropertyInfo)value); + FieldInfo fi = value as FieldInfo ?? Reflector.TryFindFieldInfo(FieldType, (PropertyInfo)value)!; if (fi == null) return null; - EntityField field = Fields.TryGetC(fi.Name); + EntityField? field = Fields.TryGetC(fi.Name); if (field == null) return null; @@ -719,18 +742,23 @@ public partial class FieldReference : Field, IColumn, IFieldReference int? IColumn.Size { get { return null; } } int? IColumn.Scale { get { return null; } } public Table ReferenceTable { get; set; } + Table? IColumn.ReferenceTable => ReferenceTable; public SqlDbType SqlDbType { get { return ReferenceTable.PrimaryKey.SqlDbType; } } - public string Collation { get { return ReferenceTable.PrimaryKey.Collation; } } - public string UserDefinedTypeName { get { return ReferenceTable.PrimaryKey.UserDefinedTypeName; } } + public string? Collation { get { return ReferenceTable.PrimaryKey.Collation; } } + public string? UserDefinedTypeName { get { return ReferenceTable.PrimaryKey.UserDefinedTypeName; } } public virtual Type Type { get { return this.Nullable.ToBool() ? ReferenceTable.PrimaryKey.Type.Nullify() : ReferenceTable.PrimaryKey.Type; } } public bool AvoidForeignKey { get; set; } public bool IsLite { get; internal set; } public bool AvoidExpandOnRetrieving { get; set; } - public string Default { get; set; } + public string? Default { get; set; } - public FieldReference(PropertyRoute route, Type fieldType = null) : base(route, fieldType) { } + public FieldReference(PropertyRoute route, Type? fieldType, string name, Table referenceTable) : base(route, fieldType) + { + this.Name = name; + this.ReferenceTable = referenceTable; + } public override string ToString() { @@ -800,7 +828,7 @@ public override Type Type } } - public FieldEnum(PropertyRoute route) : base(route) { } + public FieldEnum(PropertyRoute route, string name, Table referenceTable) : base(route, null, name, referenceTable) { } public override string ToString() { @@ -838,7 +866,10 @@ public partial class FieldImplementedBy : Field, IFieldReference public Dictionary ImplementationColumns { get; set; } - public FieldImplementedBy(PropertyRoute route) : base(route) { } + public FieldImplementedBy(PropertyRoute route, Dictionary implementations) : base(route, null) + { + this.ImplementationColumns = implementations; + } public override string ToString() { @@ -895,7 +926,11 @@ public partial class FieldImplementedByAll : Field, IFieldReference public ImplementationStringColumn Column { get; set; } public ImplementationColumn ColumnType { get; set; } - public FieldImplementedByAll(PropertyRoute route) : base(route) { } + public FieldImplementedByAll(PropertyRoute route, ImplementationStringColumn column, ImplementationColumn columnType) : base(route) + { + this.Column = column; + this.ColumnType = columnType; + } public override IEnumerable Columns() { @@ -950,38 +985,53 @@ public partial class ImplementationColumn : IColumn bool IColumn.IdentityBehaviour { get { return false; } } int? IColumn.Size { get { return null; } } int? IColumn.Scale { get { return null; } } - public Table ReferenceTable { get; set; } + public Table ReferenceTable { get; private set; } + Table? IColumn.ReferenceTable => ReferenceTable; public SqlDbType SqlDbType { get { return ReferenceTable.PrimaryKey.SqlDbType; } } - public string Collation { get { return ReferenceTable.PrimaryKey.Collation; } } - public string UserDefinedTypeName { get { return ReferenceTable.PrimaryKey.UserDefinedTypeName; } } + public string? Collation { get { return ReferenceTable.PrimaryKey.Collation; } } + public string? UserDefinedTypeName { get { return ReferenceTable.PrimaryKey.UserDefinedTypeName; } } public Type Type { get { return this.Nullable.ToBool() ? ReferenceTable.PrimaryKey.Type.Nullify() : ReferenceTable.PrimaryKey.Type; } } public bool AvoidForeignKey { get; set; } - public string Default { get; set; } + public string? Default { get; set; } + + public ImplementationColumn(string name, Table referenceTable) + { + Name = name; + ReferenceTable = referenceTable; + } } public partial class ImplementationStringColumn : IColumn { public string Name { get; set; } public IsNullable Nullable { get; set; } - string IColumn.UserDefinedTypeName { get { return null; } } + string? IColumn.UserDefinedTypeName { get { return null; } } bool IColumn.PrimaryKey { get { return false; } } bool IColumn.Identity { get { return false; } } bool IColumn.IdentityBehaviour { get { return false; } } public int? Size { get; set; } int? IColumn.Scale { get { return null; } } - public string Collation { get; set; } - public Table ReferenceTable { get { return null; } } + public string? Collation { get; set; } + public Table? ReferenceTable { get { return null; } } public SqlDbType SqlDbType { get { return SqlDbType.NVarChar; } } public Type Type { get { return typeof(string); } } public bool AvoidForeignKey { get { return false; } } - public string Default { get; set; } + public string? Default { get; set; } + + public ImplementationStringColumn(string name) + { + Name = name; + } } public partial class FieldMList : Field, IFieldFinder { public TableMList TableMList { get; set; } - public FieldMList(PropertyRoute route) : base(route) { } + public FieldMList(PropertyRoute route, TableMList tableMList) : base(route) + { + this.TableMList = tableMList; + } public override string ToString() { @@ -996,7 +1046,7 @@ public Field GetField(MemberInfo member) throw new InvalidOperationException("{0} not supported by MList field".FormatWith(member.Name)); } - public Field TryGetField(MemberInfo member) + public Field? TryGetField(MemberInfo member) { if (member.Name == "Item") return TableMList.Field; @@ -1039,42 +1089,52 @@ public class PrimaryKeyColumn : IColumn public string Name { get; set; } IsNullable IColumn.Nullable { get { return IsNullable.No; } } public SqlDbType SqlDbType { get; set; } - public string Collation { get; set; } - public string UserDefinedTypeName { get; set; } + public string? Collation { get; set; } + public string? UserDefinedTypeName { get; set; } bool IColumn.PrimaryKey { get { return true; } } public bool Identity { get; set; } bool IColumn.IdentityBehaviour { get { return true; } } int? IColumn.Size { get { return null; } } int? IColumn.Scale { get { return null; } } - Table IColumn.ReferenceTable { get { return null; } } + Table? IColumn.ReferenceTable { get { return null; } } public Type Type { get; set; } public bool AvoidForeignKey { get { return false; } } - public string Default { get; set; } + public string? Default { get; set; } + + public PrimaryKeyColumn(Type type, string name) + { + Type = type; + Name = name; + } } public Dictionary Columns { get; set; } - public List MultiColumnIndexes { get; set; } + public List? MultiColumnIndexes { get; set; } public ObjectName Name { get; set; } public PrimaryKeyColumn PrimaryKey { get; set; } public FieldReference BackReference { get; set; } - public FieldValue Order { get; set; } + public FieldValue? Order { get; set; } public Field Field { get; set; } - public SystemVersionedInfo SystemVersioned { get; set; } + public SystemVersionedInfo? SystemVersioned { get; set; } public Type CollectionType { get; private set; } - public Func Constructor { get; private set; } public PropertyRoute PropertyRoute { get; internal set; } - Func getter; + Func? getter; public Func Getter => getter ?? (getter = PropertyRoute.GetLambdaExpression(true).Compile()); - public TableMList(Type collectionType) +#pragma warning disable CS8618 // Non-nullable field is uninitialized. + public TableMList(Type collectionType, ObjectName name, PrimaryKeyColumn primaryKey, FieldReference backReference) { + this.Name = name; + this.PrimaryKey = primaryKey; + this.BackReference = backReference; this.CollectionType = collectionType; this.cache = new Lazy(() => (IMListCache)giCreateCache.GetInvoker(this.Field.FieldType)(this)); } +#pragma warning restore CS8618 // Non-nullable field is uninitialized. public override string ToString() { @@ -1110,7 +1170,7 @@ public List GeneratAllIndexes() public Field GetField(MemberInfo member) { - Field result = TryGetField(member); + Field? result = TryGetField(member); if(result == null) throw new InvalidOperationException("'{0}' not found".FormatWith(member.Name)); @@ -1118,7 +1178,7 @@ public Field GetField(MemberInfo member) return result; } - public Field TryGetField(MemberInfo mi) + public Field? TryGetField(MemberInfo mi) { if (mi.Name == "Parent") return this.BackReference; diff --git a/Signum.Engine/Schema/Schema.Delete.cs b/Signum.Engine/Schema/Schema.Delete.cs index bbad01f8d1..8858582858 100644 --- a/Signum.Engine/Schema/Schema.Delete.cs +++ b/Signum.Engine/Schema/Schema.Delete.cs @@ -9,7 +9,7 @@ namespace Signum.Engine.Maps { public partial class Table { - public SqlPreCommand DeleteSqlSync(T entity, Expression> where, string comment = null) + public SqlPreCommand DeleteSqlSync(T entity, Expression>? where, string? comment = null) where T : Entity { if (typeof(T) != Type && where != null) diff --git a/Signum.Engine/Schema/Schema.Save.cs b/Signum.Engine/Schema/Schema.Save.cs index 8f5396ce5f..97d3be8376 100644 --- a/Signum.Engine/Schema/Schema.Save.cs +++ b/Signum.Engine/Schema/Schema.Save.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Signum.Entities; @@ -19,7 +19,7 @@ namespace Signum.Engine.Maps { public struct Forbidden { - public Forbidden(HashSet set) + public Forbidden(HashSet? set) { this.set = set; } @@ -29,7 +29,7 @@ public Forbidden(DirectedGraph graph, Entity entity) this.set = graph?.TryRelatedTo(entity); } - readonly HashSet set; + readonly HashSet? set; public bool IsEmpty { @@ -99,8 +99,14 @@ class InsertCacheDisableIdentity public Func> InsertParameters; ConcurrentDictionary, DirectedGraph>> insertDisableIdentityCache = - new ConcurrentDictionary, DirectedGraph>>(); - + new ConcurrentDictionary, DirectedGraph>>(); + + public InsertCacheDisableIdentity(Table table, Func sqlInsertPattern, Func> insertParameters) + { + this.table = table; + SqlInsertPattern = sqlInsertPattern; + InsertParameters = insertParameters; + } internal Action, DirectedGraph> GetInserter(int numElements) { @@ -114,22 +120,21 @@ Action, DirectedGraph> GetInsertDisableIdentity() return (list, graph) => { - Entity etity = list.Single(); + Entity entity = list.Single(); - AssertHasId(etity); - - if (etity is Entity entity) - entity.Ticks = TimeZoneManager.Now.Ticks; + AssertHasId(entity); + + entity.Ticks = TimeZoneManager.Now.Ticks; - table.SetToStrField(etity); + table.SetToStrField(entity); - var forbidden = new Forbidden(graph, etity); + var forbidden = new Forbidden(graph, entity); - new SqlPreCommandSimple(sqlSingle, InsertParameters(etity, forbidden, "")).ExecuteNonQuery(); + new SqlPreCommandSimple(sqlSingle, InsertParameters(entity, forbidden, "")).ExecuteNonQuery(); - etity.IsNew = false; + entity.IsNew = false; if (table.saveCollections.Value != null) - table.saveCollections.Value.InsertCollections(new List { new EntityForbidden(etity, forbidden) }); + table.saveCollections.Value.InsertCollections(new List { new EntityForbidden(entity, forbidden) }); }; } @@ -139,33 +144,32 @@ Action, DirectedGraph> GetInsertMultiDisableIdentity(int nu { string sqlMulti = Enumerable.Range(0, num).ToString(i => SqlInsertPattern(i.ToString()), ";\r\n"); - return (idents, graph) => + return (entities, graph) => { for (int i = 0; i < num; i++) { - var ident = idents[i]; - AssertHasId(ident); + var entity = entities[i]; + AssertHasId(entity); - if (ident is Entity entity) - entity.Ticks = TimeZoneManager.Now.Ticks; + entity.Ticks = TimeZoneManager.Now.Ticks; - table.SetToStrField(ident); + table.SetToStrField(entity); } List result = new List(); - for (int i = 0; i < idents.Count; i++) - result.AddRange(InsertParameters(idents[i], new Forbidden(graph, idents[i]), i.ToString())); + for (int i = 0; i < entities.Count; i++) + result.AddRange(InsertParameters(entities[i], new Forbidden(graph, entities[i]), i.ToString())); new SqlPreCommandSimple(sqlMulti, result).ExecuteNonQuery(); for (int i = 0; i < num; i++) { - Entity ident = idents[i]; + Entity ident = entities[i]; ident.IsNew = false; } if (table.saveCollections.Value != null) - table.saveCollections.Value.InsertCollections(idents.Select(e => new EntityForbidden(e, graph)).ToList()); + table.saveCollections.Value.InsertCollections(entities.Select(e => new EntityForbidden(e, graph)).ToList()); }; } @@ -173,8 +177,6 @@ internal static InsertCacheDisableIdentity InitializeInsertDisableIdentity(Table { using (HeavyProfiler.LogNoStackTrace("InitializeInsertDisableIdentity", () => table.Type.TypeName())) { - InsertCacheDisableIdentity result = new InsertCacheDisableIdentity { table = table }; - var trios = new List(); var assigments = new List(); var paramIdent = Expression.Parameter(typeof(object) /*Entity*/, "ident"); @@ -191,7 +193,7 @@ internal static InsertCacheDisableIdentity InitializeInsertDisableIdentity(Table foreach (var item in table.Mixins.Values) item.CreateParameter(trios, assigments, cast, paramForbidden, paramSuffix); - result.SqlInsertPattern = (suffix) => + Func insertPattern = (suffix) => "INSERT {0} ({1})\r\n VALUES ({2})".FormatWith(table.Name, trios.ToString(p => p.SourceColumn.SqlEscape(), ", "), trios.ToString(p => p.ParameterName + suffix, ", ")); @@ -199,9 +201,8 @@ internal static InsertCacheDisableIdentity InitializeInsertDisableIdentity(Table var expr = Expression.Lambda>>( CreateBlock(trios.Select(a => a.ParameterBuilder), assigments), paramIdent, paramForbidden, paramSuffix); - result.InsertParameters = expr.Compile(); - - return result; + + return new InsertCacheDisableIdentity(table, insertPattern, expr.Compile()); } } } @@ -214,8 +215,15 @@ class InsertCacheIdentity public Func> InsertParameters; ConcurrentDictionary, DirectedGraph>> insertIdentityCache = - new ConcurrentDictionary, DirectedGraph>>(); - + new ConcurrentDictionary, DirectedGraph>>(); + + public InsertCacheIdentity(Table table, Func sqlInsertPattern, Func> insertParameters) + { + this.table = table; + SqlInsertPattern = sqlInsertPattern; + InsertParameters = insertParameters; + } + internal Action, DirectedGraph> GetInserter(int numElements) { return insertIdentityCache.GetOrAdd(numElements, (int num) => GetInsertMultiIdentity(num)); @@ -228,35 +236,34 @@ Action, DirectedGraph> GetInsertMultiIdentity(int num) .AppendLines(Enumerable.Range(0, num).Select(i => SqlInsertPattern(i.ToString(), true))) .AppendLine("SELECT Id from @MyTable").ToString(); - return (idents, graph) => + return (entities, graph) => { for (int i = 0; i < num; i++) { - var ident = idents[i]; - AssertNoId(ident); + var entity = entities[i]; + AssertNoId(entity); - if (ident is Entity entity) - entity.Ticks = TimeZoneManager.Now.Ticks; + entity.Ticks = TimeZoneManager.Now.Ticks; - table.SetToStrField(ident); + table.SetToStrField(entity); } List result = new List(); - for (int i = 0; i < idents.Count; i++) - result.AddRange(InsertParameters(idents[i], new Forbidden(graph, idents[i]), i.ToString())); + for (int i = 0; i < entities.Count; i++) + result.AddRange(InsertParameters(entities[i], new Forbidden(graph, entities[i]), i.ToString())); DataTable dt = new SqlPreCommandSimple(sqlMulti, result).ExecuteDataTable(); for (int i = 0; i < num; i++) { - Entity ident = idents[i]; + Entity ident = entities[i]; ident.id = new PrimaryKey((IComparable)dt.Rows[i][0]); ident.IsNew = false; } if (table.saveCollections.Value != null) - table.saveCollections.Value.InsertCollections(idents.Select(e => new EntityForbidden(e, graph)).ToList()); + table.saveCollections.Value.InsertCollections(entities.Select(e => new EntityForbidden(e, graph)).ToList()); }; } @@ -265,8 +272,6 @@ internal static InsertCacheIdentity InitializeInsertIdentity(Table table) { using (HeavyProfiler.LogNoStackTrace("InitializeInsertIdentity", () => table.Type.TypeName())) { - InsertCacheIdentity result = new InsertCacheIdentity { table = table }; - var trios = new List(); var assigments = new List(); var paramIdent = Expression.Parameter(typeof(Entity), "ident"); @@ -283,7 +288,7 @@ internal static InsertCacheIdentity InitializeInsertIdentity(Table table) foreach (var item in table.Mixins.Values) item.CreateParameter(trios, assigments, cast, paramForbidden, paramSuffix); - result.SqlInsertPattern = (suffix, output) => + Func sqlInsertPattern = (suffix, output) => "INSERT {0} ({1})\r\n{2} VALUES ({3})".FormatWith(table.Name, trios.ToString(p => p.SourceColumn.SqlEscape(), ", "), output ? "OUTPUT INSERTED.Id into @MyTable \r\n" : null, @@ -292,14 +297,11 @@ internal static InsertCacheIdentity InitializeInsertIdentity(Table table) var expr = Expression.Lambda>>( CreateBlock(trios.Select(a => a.ParameterBuilder), assigments), paramIdent, paramForbidden, paramSuffix); - - result.InsertParameters = expr.Compile(); - - return result; + + return new InsertCacheIdentity(table, sqlInsertPattern, expr.Compile()); } } - } - + } static void AssertHasId(Entity ident) { @@ -314,7 +316,7 @@ static void AssertNoId(Entity ident) } - public IColumn ToStrColumn + public IColumn? ToStrColumn { get { @@ -343,7 +345,6 @@ internal bool SetToStrField(Entity entity) entity.toStr = newStr; return true; } - } return false; @@ -369,8 +370,14 @@ class UpdateCache public Func> UpdateParameters; ConcurrentDictionary, DirectedGraph>> updateCache = - new ConcurrentDictionary, DirectedGraph>>(); - + new ConcurrentDictionary, DirectedGraph>>(); + + public UpdateCache(Table table, Func sqlUpdatePattern, Func> updateParameters) + { + this.table = table; + SqlUpdatePattern = sqlUpdatePattern; + UpdateParameters = updateParameters; + } public Action, DirectedGraph> GetUpdater(int numElements) { @@ -482,8 +489,6 @@ internal static UpdateCache InitializeUpdate(Table table) { using (HeavyProfiler.LogNoStackTrace("InitializeUpdate", () => table.Type.TypeName())) { - UpdateCache result = new UpdateCache { table = table }; - var trios = new List(); var assigments = new List(); var paramIdent = Expression.Parameter(typeof(Entity), "ident"); @@ -507,7 +512,7 @@ internal static UpdateCache InitializeUpdate(Table table) string oldTicksParamName = ParameterBuilder.GetParameterName("old_ticks"); - result.SqlUpdatePattern = (suffix, output) => + Func sqlUpdatePattern = (suffix, output) => { string update = "UPDATE {0} SET \r\n{1}\r\n WHERE {2} = {3}".FormatWith( table.Name, @@ -540,9 +545,8 @@ internal static UpdateCache InitializeUpdate(Table table) var expr = Expression.Lambda>>( CreateBlock(parameters, assigments), paramIdent, paramOldTicks, paramForbidden, paramSuffix); - result.UpdateParameters = expr.Compile(); - - return result; + + return new UpdateCache(table, sqlUpdatePattern, expr.Compile()); } } @@ -556,9 +560,18 @@ class CollectionsCache public Func InsertCollectionsSync; public Action> InsertCollections; - public Action> UpdateCollections; - - internal static CollectionsCache InitializeCollections(Table table) + public Action> UpdateCollections; + + public CollectionsCache(Func insertCollectionsSync, + Action> insertCollections, + Action> updateCollections) + { + InsertCollectionsSync = insertCollectionsSync; + InsertCollections = insertCollections; + UpdateCollections = updateCollections; + } + + internal static CollectionsCache? InitializeCollections(Table table) { using (HeavyProfiler.LogNoStackTrace("InitializeCollections", () => table.Type.TypeName())) { @@ -570,23 +583,20 @@ internal static CollectionsCache InitializeCollections(Table table) return null; else { - return new CollectionsCache - { - InsertCollections = (entities) => + return new CollectionsCache( + insertCollections: (entities) => { foreach (var rc in caches) rc.RelationalInserts(entities); - }, - - UpdateCollections = (entities) => - { - foreach (var rc in caches) - rc.RelationalUpdates(entities); - }, - - InsertCollectionsSync = (ident, suffix, replaceParameter) => - caches.Select((rc, i) => rc.RelationalUpdateSync(ident, suffix + "_" + i.ToString(), replaceParameter)).Combine(Spacing.Double) - }; + }, + updateCollections: (entities) => + { + foreach (var rc in caches) + rc.RelationalUpdates(entities); + }, + insertCollectionsSync: (ident, suffix, replaceParameter) => + caches.Select((rc, i) => rc.RelationalUpdateSync(ident, suffix + "_" + i.ToString(), replaceParameter)).Combine(Spacing.Double)! + ); } } } @@ -595,7 +605,7 @@ internal static CollectionsCache InitializeCollections(Table table) ResetLazy saveCollections; - public SqlPreCommand InsertSqlSync(Entity ident, bool includeCollections = true, string comment = null, string suffix = "") + public SqlPreCommand InsertSqlSync(Entity ident, bool includeCollections = true, string? comment = null, string suffix = "") { PrepareEntitySync(ident); SetToStrField(ident); @@ -624,10 +634,10 @@ public SqlPreCommand InsertSqlSync(Entity ident, bool includeCollections = true, SqlPreCommand setParent = new SqlPreCommandSimple("SET @parentId = @@Identity"); - return SqlPreCommand.Combine(Spacing.Simple, declareParent, insert, setParent, collections); + return SqlPreCommand.Combine(Spacing.Simple, declareParent, insert, setParent, collections)!; } - public SqlPreCommand UpdateSqlSync(T entity, Expression> where, bool includeCollections = true, string comment = null, string suffix = "") + public SqlPreCommand? UpdateSqlSync(T entity, Expression> where, bool includeCollections = true, string? comment = null, string suffix = "") where T : Entity { if (typeof(T) != Type && where != null) @@ -645,7 +655,7 @@ public SqlPreCommand UpdateSqlSync(T entity, Expression> where, var sql = uc.SqlUpdatePattern(suffix, false); var parameters = uc.UpdateParameters(entity, (entity as Entity)?.Ticks ?? -1, new Forbidden(), suffix); - SqlPreCommand update; + SqlPreCommand? update; if (where != null) { update = SqlPreCommand.Combine(Spacing.Simple, @@ -728,14 +738,16 @@ public partial class TableMList { internal interface IMListCache { - SqlPreCommand RelationalUpdateSync(Entity parent, string suffix, bool replaceParameter); + SqlPreCommand? RelationalUpdateSync(Entity parent, string suffix, bool replaceParameter); void RelationalInserts(List entities); void RelationalUpdates(List entities); object[] BulkInsertDataRow(Entity entity, object value, int order); - } - - internal class TableMListCache : IMListCache + } + +#pragma warning disable CS8618 // Non-nullable field is uninitialized. + internal class TableMListCache : IMListCache +#pragma warning restore CS8618 // Non-nullable field is uninitialized. { internal TableMList table; @@ -961,7 +973,7 @@ public void RelationalUpdates(List idents) if (row.RowId.HasValue) { if (hasOrder && row.OldIndex != i || - isEmbeddedEntity && ((ModifiableEntity)(object)row.Element).IsGraphModified) + isEmbeddedEntity && ((ModifiableEntity)(object)row.Element!).IsGraphModified) { toUpdate.Add(new MListUpdate(ef, collection, i)); } @@ -984,7 +996,7 @@ public void RelationalUpdates(List idents) toInsert.SplitStatements(this.table.Columns.Count, listPairs => GetInsert(listPairs.Count)(listPairs)); } - public SqlPreCommand RelationalUpdateSync(Entity parent, string suffix, bool replaceParameter) + public SqlPreCommand? RelationalUpdateSync(Entity parent, string suffix, bool replaceParameter) { MList collection = Getter(parent); @@ -1009,7 +1021,7 @@ public SqlPreCommand RelationalUpdateSync(Entity parent, string suffix, bool rep parameters.RemoveAt(0); string script = sqlInsert(suffix + "_" + i, false); script = script.Replace(parentId.ParameterName, "@parentId"); - return new SqlPreCommandSimple(script, parameters).AddComment(e.ToString()); + return new SqlPreCommandSimple(script, parameters).AddComment(e?.ToString()); }).Combine(Spacing.Simple); } else @@ -1017,7 +1029,7 @@ public SqlPreCommand RelationalUpdateSync(Entity parent, string suffix, bool rep return SqlPreCommand.Combine(Spacing.Simple, new SqlPreCommandSimple(sqlDelete(suffix), new List { DeleteParameter(parent, suffix) }).ReplaceFirstParameter(replaceParameter ? parent.Id.VariableName : null), collection.Select((e, i) => new SqlPreCommandSimple(sqlInsert(suffix + "_" + i, false), InsertParameters(parent, e, i, new Forbidden(), suffix + "_" + i)) - .AddComment(e.ToString()) + .AddComment(e?.ToString()) .ReplaceFirstParameter(replaceParameter ? parent.Id.VariableName : null) ).Combine(Spacing.Simple)); } @@ -1033,7 +1045,7 @@ TableMListCache CreateCache() { var pb = Connector.Current.ParameterBuilder; - TableMListCache result = new TableMListCache() + TableMListCache result = new TableMListCache { table = this, Getter = entity => (MList)Getter(entity), @@ -1294,7 +1306,7 @@ public static Expression GetTypeFactory(this IFieldReference fr, Expression valu return Expression.Call(fr.IsLite ? miGetTypeForLite : miGetTypeForEntity, value, forbidden); } - static Type GetTypeForLite(Lite value, Forbidden forbidden) + static Type? GetTypeForLite(Lite value, Forbidden forbidden) { if (value == null) return null; @@ -1305,7 +1317,7 @@ static Type GetTypeForLite(Lite value, Forbidden forbidden) l.EntityType; } - static Type GetTypeForEntity(IEntity value, Forbidden forbidden) + static Type? GetTypeForEntity(IEntity value, Forbidden forbidden) { if (value == null) return null; @@ -1383,7 +1395,7 @@ protected internal override void CreateParameter(List trios, List PrimaryKey.UnwrapToString(null)); static MethodInfo miConvertType = ReflectionTools.GetMethodInfo(() => ConvertType(null)); - static IComparable ConvertType(Type type) + static IComparable? ConvertType(Type type) { if (type == null) return null; diff --git a/Signum.Engine/Schema/Schema.cs b/Signum.Engine/Schema/Schema.cs index e45f10b809..ffe4af0a39 100644 --- a/Signum.Engine/Schema/Schema.cs +++ b/Signum.Engine/Schema/Schema.cs @@ -19,11 +19,11 @@ namespace Signum.Engine.Maps { public class Schema : IImplementationsFinder { - public CultureInfo ForceCultureInfo { get; set; } + public CultureInfo? ForceCultureInfo { get; set; } public TimeZoneMode TimeZoneMode { get; set; } - Version version; + Version? version; public Version Version { get @@ -42,7 +42,7 @@ public void InvalidateMetadata() this.OnMetadataInvalidated?.Invoke(); } - string applicationName; + string? applicationName; public string ApplicationName { get { return applicationName ?? (applicationName = AppDomain.CurrentDomain.FriendlyName); } @@ -68,7 +68,7 @@ public Dictionary Tables public event Func IsAllowedCallback; - public string IsAllowed(Type type, bool inUserInterface) + public string? IsAllowed(Type type, bool inUserInterface) { foreach (var f in IsAllowedCallback.GetInvocationListTyped()) { @@ -88,7 +88,7 @@ public string IsAllowed(Type type, bool inUserInterface) public void AssertAllowed(Type type, bool inUserInterface) { - string error = IsAllowed(type, inUserInterface); + string? error = IsAllowed(type, inUserInterface); if (error != null) throw new UnauthorizedAccessException(EngineMessage.UnauthorizedAccessTo0Because1.NiceToString().FormatWith(type.NiceName(), error)); @@ -112,7 +112,7 @@ internal void OnPreSaving(Entity entity, PreSavingContext ctx) { AssertAllowed(entity.GetType(), inUserInterface: false); - IEntityEvents ee = entityEvents.TryGetC(entity.GetType()); + IEntityEvents? ee = entityEvents.TryGetC(entity.GetType()); if (ee != null) ee.OnPreSaving(entity, ctx); @@ -120,11 +120,11 @@ internal void OnPreSaving(Entity entity, PreSavingContext ctx) entityEventsGlobal.OnPreSaving(entity, ctx); } - internal Entity OnAlternativeRetriving(Type entityType, PrimaryKey id) + internal Entity? OnAlternativeRetriving(Type entityType, PrimaryKey id) { AssertAllowed(entityType, inUserInterface: false); - IEntityEvents ee = entityEvents.TryGetC(entityType); + IEntityEvents? ee = entityEvents.TryGetC(entityType); if (ee == null) return null; @@ -136,7 +136,7 @@ internal void OnSaving(Entity entity) { AssertAllowed(entity.GetType(), inUserInterface: false); - IEntityEvents ee = entityEvents.TryGetC(entity.GetType()); + IEntityEvents? ee = entityEvents.TryGetC(entity.GetType()); if (ee != null) ee.OnSaving(entity); @@ -149,7 +149,7 @@ internal void OnSaved(Entity entity, SavedEventArgs args) { AssertAllowed(entity.GetType(), inUserInterface: false); - IEntityEvents ee = entityEvents.TryGetC(entity.GetType()); + IEntityEvents? ee = entityEvents.TryGetC(entity.GetType()); if (ee != null) ee.OnSaved(entity, args); @@ -161,7 +161,7 @@ internal void OnRetrieved(Entity entity) { AssertAllowed(entity.GetType(), inUserInterface: false); - IEntityEvents ee = entityEvents.TryGetC(entity.GetType()); + IEntityEvents? ee = entityEvents.TryGetC(entity.GetType()); if (ee != null) ee.OnRetrieved(entity); @@ -169,11 +169,11 @@ internal void OnRetrieved(Entity entity) entityEventsGlobal.OnRetrieved(entity); } - internal IDisposable OnPreUnsafeDelete(IQueryable entityQuery) where T : Entity + internal IDisposable? OnPreUnsafeDelete(IQueryable entityQuery) where T : Entity { AssertAllowed(typeof(T), inUserInterface: false); - EntityEvents ee = (EntityEvents)entityEvents.TryGetC(typeof(T)); + EntityEvents? ee = (EntityEvents?)entityEvents.TryGetC(typeof(T)); if (ee == null) return null; @@ -181,11 +181,11 @@ internal IDisposable OnPreUnsafeDelete(IQueryable entityQuery) where T : E return ee.OnPreUnsafeDelete(entityQuery); } - internal IDisposable OnPreUnsafeMListDelete(IQueryable mlistQuery, IQueryable entityQuery) where T : Entity + internal IDisposable? OnPreUnsafeMListDelete(IQueryable mlistQuery, IQueryable entityQuery) where T : Entity { AssertAllowed(typeof(T), inUserInterface: false); - EntityEvents ee = (EntityEvents)entityEvents.TryGetC(typeof(T)); + EntityEvents? ee = (EntityEvents?)entityEvents.TryGetC(typeof(T)); if (ee == null) return null; @@ -193,7 +193,7 @@ internal IDisposable OnPreUnsafeMListDelete(IQueryable mlistQuery, IQueryable return ee.OnPreUnsafeMListDelete(mlistQuery, entityQuery); } - internal IDisposable OnPreUnsafeUpdate(IUpdateable update) + internal IDisposable? OnPreUnsafeUpdate(IUpdateable update) { var type = update.EntityType; if (type.IsInstantiationOf(typeof(MListElement<,>))) @@ -231,9 +231,9 @@ internal void OnPreBulkInsert(Type type, bool inMListTable) ee.OnPreBulkInsert(inMListTable); } - public ICacheController CacheController(Type type) + public ICacheController? CacheController(Type type) { - IEntityEvents ee = entityEvents.TryGetC(type); + IEntityEvents? ee = entityEvents.TryGetC(type); if (ee == null) return null; @@ -250,12 +250,12 @@ internal IEnumerable GetAdditionalQueryBindings(PropertyRoute pare return Enumerable.Empty(); return ee.AdditionalBindings - .Where(kvp => kvp.Key.Parent.Equals(parent)) - .Select(kvp => new FieldBinding(kvp.Key.FieldInfo, new AdditionalFieldExpression(kvp.Key.FieldInfo.FieldType, (PrimaryKeyExpression)id, period, kvp.Key))) + .Where(kvp => kvp.Key.Parent!.Equals(parent)) + .Select(kvp => new FieldBinding(kvp.Key.FieldInfo!, new AdditionalFieldExpression(kvp.Key.FieldInfo!.FieldType, id, period, kvp.Key))) .ToList(); } - public List GetAdditionalBindings(Type rootType) + public List? GetAdditionalBindings(Type rootType) { var ee = entityEvents.TryGetC(rootType); if (ee == null || ee.AdditionalBindings == null) @@ -264,13 +264,13 @@ public List GetAdditionalBindings(Type rootType) return ee.AdditionalBindings.Values.ToList(); } - internal LambdaExpression GetAdditionalQueryBinding(PropertyRoute pr, bool entityCompleter) + internal LambdaExpression? GetAdditionalQueryBinding(PropertyRoute pr, bool entityCompleter) { //AssertAllowed(pr.Type, inUserInterface: false); var ee = entityEvents.GetOrThrow(pr.RootType); - var ab = ee.AdditionalBindings.GetOrThrow(pr); + var ab = ee.AdditionalBindings!.GetOrThrow(pr); if (entityCompleter && !ab.ShouldSet()) return null; @@ -278,9 +278,9 @@ internal LambdaExpression GetAdditionalQueryBinding(PropertyRoute pr, bool entit return ab.ValueExpression; } - internal CacheControllerBase CacheController() where T : Entity + internal CacheControllerBase? CacheController() where T : Entity { - EntityEvents ee = (EntityEvents)entityEvents.TryGetC(typeof(T)); + EntityEvents? ee = (EntityEvents?)entityEvents.TryGetC(typeof(T)); if (ee == null) return null; @@ -288,16 +288,16 @@ internal CacheControllerBase CacheController() where T : Entity return ee.CacheController; } - internal FilterQueryResult OnFilterQuery() + internal FilterQueryResult? OnFilterQuery() where T : Entity { AssertAllowed(typeof(T), inUserInterface: false); - EntityEvents ee = (EntityEvents)entityEvents.TryGetC(typeof(T)); + EntityEvents? ee = (EntityEvents?)entityEvents.TryGetC(typeof(T)); if (ee == null) return null; - FilterQueryResult result = null; + FilterQueryResult? result = null; foreach (var item in ee.OnFilterQuery()) result = CombineFilterResult(result, item); @@ -306,21 +306,18 @@ internal FilterQueryResult OnFilterQuery() - FilterQueryResult CombineFilterResult(FilterQueryResult result, FilterQueryResult expression) + FilterQueryResult? CombineFilterResult(FilterQueryResult? one, FilterQueryResult two) where T : Entity { - if (result == null) - return expression; - - if (expression == null) - return result; - - if (result.InMemoryFunction == null || expression.InMemoryFunction == null) - return new FilterQueryResult(a => result.InDatabaseExpresson.Evaluate(a) && expression.InDatabaseExpresson.Evaluate(a), null); + if (one == null) + return two; + if (two == null) + return one; + return new FilterQueryResult( - a => result.InDatabaseExpresson.Evaluate(a) && expression.InDatabaseExpresson.Evaluate(a), - a => result.InMemoryFunction(a) && expression.InMemoryFunction(a)); + a => one!.InDatabaseExpresson.Evaluate(a) && two.InDatabaseExpresson.Evaluate(a), + a => one!.InMemoryFunction(a) && two!.InMemoryFunction(a)); } public Func GetInMemoryFilter(bool userInterface) @@ -328,11 +325,11 @@ public Func GetInMemoryFilter(bool userInterface) { using (userInterface ? ExecutionMode.UserInterface() : null) { - EntityEvents ee = (EntityEvents)entityEvents.TryGetC(typeof(T)); + EntityEvents? ee = (EntityEvents?)entityEvents.TryGetC(typeof(T)); if (ee == null) return a => true; - Func result = null; + Func? result = null; foreach (var item in ee.OnFilterQuery().NotNull()) { if (item.InMemoryFunction == null) @@ -349,25 +346,25 @@ public Func GetInMemoryFilter(bool userInterface) } } - private Func CombineFunc(Func result, Func func) where T : Entity + private Func? CombineFunc(Func? one, Func? two) where T : Entity { - if (result == null) - return func; + if (one == null) + return two; - if (func == null) - return result; + if (two == null) + return one; - return a => result(a) && func(a); + return a => one!(a) && two!(a); } - public Expression> GetInDatabaseFilter() + public Expression>? GetInDatabaseFilter() where T : Entity { - EntityEvents ee = (EntityEvents)entityEvents.TryGetC(typeof(T)); + EntityEvents? ee = (EntityEvents?)entityEvents.TryGetC(typeof(T)); if (ee == null) return null; - Expression> result = null; + Expression>? result = null; foreach (var item in ee.OnFilterQuery().NotNull()) { result = CombineExpr(result, item.InDatabaseExpresson); @@ -379,19 +376,19 @@ public Expression> GetInDatabaseFilter() return result; } - private Expression> CombineExpr(Expression> result, Expression> func) where T : Entity + private Expression>? CombineExpr(Expression>? one, Expression>? two) where T : Entity { - if (result == null) - return func; + if (one == null) + return two; - if (func == null) - return result; + if (two == null) + return one; - return a => result.Evaluate(a) && func.Evaluate(a); + return a => one!.Evaluate(a) && two!.Evaluate(a); } - public event Func Synchronizing; - public SqlPreCommand SynchronizationScript(bool interactive = true, bool schemaOnly = false, string replaceDatabaseName = null) + public event Func Synchronizing; + public SqlPreCommand? SynchronizationScript(bool interactive = true, bool schemaOnly = false, string? replaceDatabaseName = null) { OnBeforeDatabaseAccess(); @@ -401,8 +398,13 @@ public SqlPreCommand SynchronizationScript(bool interactive = true, bool schemaO using (CultureInfoUtils.ChangeBothCultures(ForceCultureInfo)) using (ExecutionMode.Global()) { - Replacements replacements = new Replacements() { Interactive = interactive, ReplaceDatabaseName = replaceDatabaseName, SchemaOnly = schemaOnly }; - SqlPreCommand command = Synchronizing + Replacements replacements = new Replacements() + { + Interactive = interactive, + ReplaceDatabaseName = replaceDatabaseName, + SchemaOnly = schemaOnly + }; + SqlPreCommand? command = Synchronizing .GetInvocationListTyped() .Select(e => { @@ -453,8 +455,8 @@ public Table View(Type viewType) return Views.GetOrCreate(viewType, ViewBuilder.NewView(viewType)); } - public event Func Generating; - internal SqlPreCommand GenerationScipt() + public event Func Generating; + internal SqlPreCommand? GenerationScipt() { OnBeforeDatabaseAccess(); @@ -473,7 +475,7 @@ internal SqlPreCommand GenerationScipt() - public event Action SchemaCompleted; + public event Action? SchemaCompleted; public void OnSchemaCompleted() { @@ -496,7 +498,7 @@ public void WhenIncluded(Action action) where T : Entity }; } - public event Action BeforeDatabaseAccess; + public event Action? BeforeDatabaseAccess; public void OnBeforeDatabaseAccess() { @@ -513,7 +515,7 @@ public void OnBeforeDatabaseAccess() BeforeDatabaseAccess = null; } - public event Action Initializing; + public event Action? Initializing; public void Initialize() { @@ -540,6 +542,7 @@ static Schema() internal Schema(SchemaSettings settings) { + this.typeCachesLazy = null!; this.Settings = settings; this.Assets = new SchemaAssets(); this.ViewBuilder = new Maps.ViewBuilder(this); @@ -584,8 +587,8 @@ public Table Table(Type type) internal static Field FindField(IFieldFinder fieldFinder, MemberInfo[] members) { - IFieldFinder current = fieldFinder; - Field result = null; + IFieldFinder? current = fieldFinder; + Field? result = null; foreach (var mi in members) { if (current == null) @@ -596,13 +599,13 @@ internal static Field FindField(IFieldFinder fieldFinder, MemberInfo[] members) current = result as IFieldFinder; } - return result; + return result!; } - internal static Field TryFindField(IFieldFinder fieldFinder, MemberInfo[] members) + internal static Field? TryFindField(IFieldFinder fieldFinder, MemberInfo[] members) { - IFieldFinder current = fieldFinder; - Field result = null; + IFieldFinder? current = fieldFinder; + Field? result = null; foreach (var mi in members) { if (current == null) @@ -619,7 +622,7 @@ internal static Field TryFindField(IFieldFinder fieldFinder, MemberInfo[] member return result; } - public Dictionary FindAllImplementations(Type root) + public Dictionary? FindAllImplementations(Type root) { try { @@ -643,14 +646,14 @@ public Dictionary FindAllImplementations(Type ro public Implementations FindImplementations(PropertyRoute route) { if (route.PropertyRouteType == PropertyRouteType.LiteEntity) - route = route.Parent; + route = route.Parent!; Type type = route.RootType; if (!Tables.ContainsKey(type)) return Schema.Current.Settings.GetImplementations(route); - Field field = TryFindField(Table(type), route.Members); + Field? field = TryFindField(Table(type), route.Members); //if (field == null) // return Implementations.ByAll; @@ -687,13 +690,13 @@ public Implementations FindImplementations(PropertyRoute route) if (route.PropertyRouteType != PropertyRouteType.FieldOrProperty) return null; - var lambda = ExpressionCleaner.GetFieldExpansion(route.Parent.Type, route.PropertyInfo); + var lambda = ExpressionCleaner.GetFieldExpansion(route.Parent!.Type, route.PropertyInfo!); if (lambda == null) return null; - Expression e = MetadataVisitor.JustVisit(lambda, new MetaExpression(route.Parent.Type, new CleanMeta(route.Parent.TryGetImplementations(), new[] { route.Parent }))); + Expression e = MetadataVisitor.JustVisit(lambda, new MetaExpression(route.Parent!.Type, new CleanMeta(route.Parent!.TryGetImplementations(), new[] { route.Parent! }))); - MetaExpression me = e as MetaExpression; + MetaExpression? me = e as MetaExpression; if (me == null) return null; @@ -714,7 +717,7 @@ public Field Field(PropertyRoute route) return FindField(Table(route.RootType), route.Members); } - public Field TryField(PropertyRoute route) + public Field? TryField(PropertyRoute route) { return TryFindField(Table(route.RootType), route.Members); } @@ -738,9 +741,9 @@ public bool HasSomeIndex(PropertyRoute route) ITable table = mlistPr == null ? (ITable)Table(route.RootType) : - (ITable)((FieldMList)Field(mlistPr.Parent)).TableMList; + (ITable)((FieldMList)Field(mlistPr.Parent!)).TableMList; - return table.MultiColumnIndexes != null && table.MultiColumnIndexes.Any(index => index.Columns.Any(cols.Contains)); + return table.MultiColumnIndexes != null && table.MultiColumnIndexes.Any(index => index.Columns.Any(c => cols.Contains(c))); } public override string ToString() @@ -759,9 +762,9 @@ public IEnumerable GetDatabaseTables() } } - public Func IsExternalDatabase = db => false; + public Func IsExternalDatabase = db => false; - public List DatabaseNames() + public List DatabaseNames() { return GetDatabaseTables().Select(a => a.Name.Schema?.Database).Where(a => !IsExternalDatabase(a)).Distinct().ToList(); } diff --git a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs index 9d69dee8fa..31097591f2 100644 --- a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs +++ b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs @@ -66,7 +66,7 @@ public Schema Schema } - public UniqueIndex AddUniqueIndex(Expression> fields, Expression> where = null, Expression> includeFields = null) where T : Entity + public UniqueIndex AddUniqueIndex(Expression> fields, Expression>? where = null, Expression>? includeFields = null) where T : Entity { var table = Schema.Table(); @@ -89,7 +89,9 @@ public UniqueIndex AddUniqueIndex(Expression> fields, Express return index; } - public Index AddIndex(Expression> fields, Expression> where = null, Expression> includeFields = null) where T : Entity + public Index AddIndex(Expression> fields, + Expression>? where = null, + Expression>? includeFields = null) where T : Entity { var table = Schema.Table(); @@ -116,8 +118,8 @@ public Index AddIndex(Expression> fields, Expression(Expression>> toMList, Expression, object>> fields, - Expression, bool>> where = null, - Expression, object>> includeFields = null) + Expression, bool>>? where = null, + Expression, object>>? includeFields = null) where T : Entity { TableMList table = ((FieldMList)Schema.FindField(Schema.Table(typeof(T)), Reflector.GetMemberList(toMList))).TableMList; @@ -146,8 +148,8 @@ public UniqueIndex AddUniqueIndexMList(Expression>> toMLi public Index AddIndexMList(Expression>> toMList, Expression, object>> fields, - Expression, bool>> where = null, - Expression, object>> includeFields = null) + Expression, bool>>? where = null, + Expression, object>>? includeFields = null) where T : Entity { TableMList table = ((FieldMList)Schema.FindField(Schema.Table(typeof(T)), Reflector.GetMemberList(toMList))).TableMList; @@ -223,7 +225,7 @@ public virtual Table Include(Type type) - internal protected virtual Table Include(Type type, PropertyRoute route) + internal protected virtual Table Include(Type type, PropertyRoute? route) { if (schema.Tables.TryGetValue(type, out Table result)) return result; @@ -290,25 +292,20 @@ void Complete(Table table) } } - public SystemVersionedInfo ToSystemVersionedInfo(SystemVersionedAttribute att, ObjectName tableName) + public SystemVersionedInfo? ToSystemVersionedInfo(SystemVersionedAttribute att, ObjectName tableName) { if (att == null) return null; - return new SystemVersionedInfo - { - TableName = att.TemporalTableName != null ? - ObjectName.Parse(att.TemporalTableName) : - new ObjectName(tableName.Schema, tableName.Name + "_History"), + var tn = att.TemporalTableName != null ? ObjectName.Parse(att.TemporalTableName) : + new ObjectName(tableName.Schema, tableName.Name + "_History"); - StartColumnName = att.StartDateColumnName, - EndColumnName = att.EndDateColumnName, - }; + return new SystemVersionedInfo(tn, att.StartDateColumnName, att.EndDateColumnName); } - private Dictionary GenerateMixins(PropertyRoute propertyRoute, Table table, NameSequence nameSequence) + private Dictionary? GenerateMixins(PropertyRoute propertyRoute, Table table, NameSequence nameSequence) { - Dictionary mixins = null; + Dictionary? mixins = null; foreach (var t in MixinDeclarations.GetMixinDeclarations(table.Type)) { if (mixins == null) @@ -320,7 +317,7 @@ private Dictionary GenerateMixins(PropertyRoute propertyRoute, return mixins; } - public HeavyProfiler.Tracer Tracer { get; set; } + public HeavyProfiler.Tracer? Tracer { get; set; } public HashSet<(Type type, string method)> LoadedModules = new HashSet<(Type type, string method)>(); @@ -371,7 +368,7 @@ protected Dictionary GenerateFields(PropertyRoute root, ITa Field field = GenerateField(table, route, preName, forceNull, inMList); - result.Add(fiId.Name, new EntityField(type, fiId) { Field = field }); + result.Add(fiId.Name, new EntityField(type, fiId, field)); } TicksColumnAttribute t = type.GetCustomAttribute(); @@ -381,11 +378,10 @@ protected Dictionary GenerateFields(PropertyRoute root, ITa Field field = GenerateField(table, route, preName, forceNull, inMList); - result.Add(fiTicks.Name, new EntityField(type, fiTicks) { Field = field }); + result.Add(fiTicks.Name, new EntityField(type, fiTicks, field)); } - Expression exp = ExpressionCleaner.GetFieldExpansion(type, EntityExpression.ToStringMethod); - + Expression? exp = ExpressionCleaner.GetFieldExpansion(type, EntityExpression.ToStringMethod); if (exp == null) { PropertyRoute route = root.Add(fiToStr); @@ -395,7 +391,7 @@ protected Dictionary GenerateFields(PropertyRoute root, ITa if (result.ContainsKey(fiToStr.Name)) throw new InvalidOperationException("Duplicated field with name {0} on {1}, shadowing not supported".FormatWith(fiToStr.Name, type.TypeName())); - result.Add(fiToStr.Name, new EntityField(type, fiToStr) { Field = field }); + result.Add(fiToStr.Name, new EntityField(type, fiToStr, field)); } } @@ -413,7 +409,7 @@ protected Dictionary GenerateFields(PropertyRoute root, ITa if (result.ContainsKey(fi.Name)) throw new InvalidOperationException("Duplicated field with name '{0}' on '{1}', shadowing not supported".FormatWith(fi.Name, type.TypeName())); - var ef = new EntityField(type, fi) { Field = field }; + var ef = new EntityField(type, fi, field); if (field is FieldMList fml) fml.TableMList.PropertyRoute = route; @@ -526,10 +522,8 @@ protected virtual Field GenerateFieldPrimaryKey(Table table, PropertyRoute route SqlDbTypePair pair = Settings.GetSqlDbType(attr, attr.Type); - return table.PrimaryKey = new FieldPrimaryKey(route, table) + return table.PrimaryKey = new FieldPrimaryKey(route, table, attr.Name, attr.Type) { - Name = attr.Name, - Type = attr.Type, SqlDbType = pair.SqlDbType, Collation = Settings.GetCollate(attr), UserDefinedTypeName = pair.UserDefinedTypeName, @@ -562,10 +556,10 @@ protected virtual FieldValue GenerateFieldTicks(Table table, PropertyRoute route SqlDbTypePair pair = Settings.GetSqlDbType(ticksAttr, type); - return table.Ticks = new FieldTicks(route) + string ticksName = ticksAttr?.Name ?? name.ToString(); + + return table.Ticks = new FieldTicks(route, type, ticksName) { - Type = type, - Name = ticksAttr?.Name ?? name.ToString(), SqlDbType = pair.SqlDbType, Collation = Settings.GetCollate(ticksAttr), UserDefinedTypeName = pair.UserDefinedTypeName, @@ -582,9 +576,8 @@ protected virtual FieldValue GenerateFieldValue(ITable table, PropertyRoute rout SqlDbTypePair pair = Settings.GetSqlDbType(att, route.Type); - return new FieldValue(route) + return new FieldValue(route, null, name.ToString()) { - Name = name.ToString(), SqlDbType = pair.SqlDbType, Collation = Settings.GetCollate(att), UserDefinedTypeName = pair.UserDefinedTypeName, @@ -603,12 +596,10 @@ protected virtual FieldEnum GenerateFieldEnum(ITable table, PropertyRoute route, var referenceTable = Include(EnumEntity.Generate(cleanEnum), route); - return new FieldEnum(route) + return new FieldEnum(route, name.ToString(), referenceTable) { - Name = name.ToString(), Nullable = Settings.GetIsNullable(route, forceNull), IsLite = false, - ReferenceTable = referenceTable, AvoidForeignKey = Settings.FieldAttribute(route) != null, Default = att?.Default, }.Do(f => f.UniqueIndex = f.GenerateUniqueIndex(table, Settings.FieldAttribute(route))); @@ -620,12 +611,10 @@ protected virtual FieldReference GenerateFieldReference(ITable table, PropertyRo var nullable = Settings.GetIsNullable(route, forceNull); - return new FieldReference(route) + return new FieldReference(route, null, name.ToString(), referenceTable) { - Name = name.ToString(), Nullable = nullable, IsLite = route.Type.IsLite(), - ReferenceTable = referenceTable, AvoidForeignKey = Settings.FieldAttribute(route) != null, AvoidExpandOnRetrieving = Settings.FieldAttribute(route) != null, Default = Settings.FieldAttribute(route)?.Default @@ -648,16 +637,18 @@ protected virtual FieldImplementedBy GenerateFieldImplementedBy(ITable table, Pr bool avoidForeignKey = Settings.FieldAttribute(route) != null; - return new FieldImplementedBy(route) + var implementations = types.ToDictionary(t => t, t => new ImplementationColumn( + name: name.Add(TypeLogic.GetCleanName(t)).ToString(), + referenceTable: Include(t, route) + ) + { + Nullable = nullable, + AvoidForeignKey = avoidForeignKey, + }); + + return new FieldImplementedBy(route, implementations) { SplitStrategy = strategy, - ImplementationColumns = types.ToDictionary(t => t, t => new ImplementationColumn - { - ReferenceTable = Include(t, route), - Name = name.Add(TypeLogic.GetCleanName(t)).ToString(), - Nullable = nullable, - AvoidForeignKey = avoidForeignKey, - }), IsLite = route.Type.IsLite(), AvoidExpandOnRetrieving = Settings.FieldAttribute(route) != null }.Do(f => f.UniqueIndex = f.GenerateUniqueIndex(table, Settings.FieldAttribute(route))); @@ -667,21 +658,20 @@ protected virtual FieldImplementedByAll GenerateFieldImplementedByAll(PropertyRo { var nullable = Settings.GetIsNullable(route, forceNull); - return new FieldImplementedByAll(route) + var column = new ImplementationStringColumn(preName.ToString()) + { + Nullable = nullable, + Size = Settings.DefaultImplementedBySize, + }; + + var columnType = new ImplementationColumn(preName.Add("Type").ToString(), Include(typeof(TypeEntity), route)) + { + Nullable = nullable, + AvoidForeignKey = Settings.FieldAttribute(route) != null, + }; + + return new FieldImplementedByAll(route, column, columnType) { - Column = new ImplementationStringColumn - { - Name = preName.ToString(), - Nullable = nullable, - Size = Settings.DefaultImplementedBySize, - }, - ColumnType = new ImplementationColumn - { - Name = preName.Add("Type").ToString(), - Nullable = nullable, - ReferenceTable = Include(typeof(TypeEntity), route), - AvoidForeignKey = Settings.FieldAttribute(route) != null, - }, IsLite = route.Type.IsLite(), AvoidExpandOnRetrieving = Settings.FieldAttribute(route) != null }.Do(f => f.UniqueIndex = f.GenerateUniqueIndex(table, Settings.FieldAttribute(route))); @@ -692,18 +682,17 @@ protected virtual FieldMList GenerateFieldMList(Table table, PropertyRoute route Type elementType = route.Type.ElementType(); if (table.Ticks == null) - throw new InvalidOperationException("Type '{0}' has field '{1}' but does not Ticks. MList requires concurrency control.".FormatWith(route.Parent.Type.TypeName(), route.FieldInfo.FieldName())); + throw new InvalidOperationException("Type '{0}' has field '{1}' but does not Ticks. MList requires concurrency control.".FormatWith(route.Parent!.Type.TypeName(), route.FieldInfo!.FieldName())); var orderAttr = Settings.FieldAttribute(route); - FieldValue order = null; + FieldValue? order = null; if (orderAttr != null) { var pair = Settings.GetSqlDbTypePair(typeof(int)); - order = new FieldValue(route: null, fieldType: typeof(int)) + order = new FieldValue(route: null!, fieldType: typeof(int), orderAttr.Name ?? "Order") { - Name = orderAttr.Name ?? "Order", SqlDbType = pair.SqlDbType, Collation = Settings.GetCollate(orderAttr), UserDefinedTypeName = pair.UserDefinedTypeName, @@ -718,10 +707,8 @@ protected virtual FieldMList GenerateFieldMList(Table table, PropertyRoute route { var pair = Settings.GetSqlDbType(keyAttr, keyAttr.Type); - primaryKey = new TableMList.PrimaryKeyColumn + primaryKey = new TableMList.PrimaryKeyColumn(keyAttr.Type, keyAttr.Name) { - Name = keyAttr.Name, - Type = keyAttr.Type, SqlDbType = pair.SqlDbType, Collation = Settings.GetCollate(orderAttr), UserDefinedTypeName = pair.UserDefinedTypeName, @@ -730,36 +717,33 @@ protected virtual FieldMList GenerateFieldMList(Table table, PropertyRoute route }; } - TableMList relationalTable = new TableMList(route.Type) + var tableName = GenerateTableNameCollection(table, name, Settings.FieldAttribute(route)); + + var backReference = new FieldReference(route: null!, fieldType: table.Type, + name: GenerateBackReferenceName(table.Type, Settings.FieldAttribute(route)), + referenceTable: table + ) { - Name = GenerateTableNameCollection(table, name, Settings.FieldAttribute(route)), - PrimaryKey = primaryKey, - BackReference = new FieldReference(route: null, fieldType: table.Type) - { - Name = GenerateBackReferenceName(table.Type, Settings.FieldAttribute(route)), - ReferenceTable = table, - AvoidForeignKey = Settings.FieldAttribute(route) != null, - }, - Order = order, + AvoidForeignKey = Settings.FieldAttribute(route) != null, }; - relationalTable.Field = GenerateField(relationalTable, route.Add("Item"), NameSequence.Void, forceNull: false, inMList: true); - - if(relationalTable.Field is FieldEmbedded fe && fe.HasValue != null) + TableMList mlistTable = new TableMList(route.Type, tableName, primaryKey, backReference) { + Order = order, + }; - } - + mlistTable.Field = GenerateField(mlistTable, route.Add("Item"), NameSequence.Void, forceNull: false, inMList: true); + var sysAttribute = Settings.FieldAttribute(route) ?? (Settings.TypeAttribute(table.Type) != null ? new SystemVersionedAttribute() : null); - relationalTable.SystemVersioned = ToSystemVersionedInfo(sysAttribute, relationalTable.Name); + mlistTable.SystemVersioned = ToSystemVersionedInfo(sysAttribute, mlistTable.Name); - relationalTable.GenerateColumns(); + mlistTable.GenerateColumns(); - return new FieldMList(route) + return new FieldMList(route, mlistTable) { - TableMList = relationalTable, + TableMList = mlistTable, }; } @@ -767,19 +751,16 @@ protected virtual FieldEmbedded GenerateFieldEmbedded(ITable table, PropertyRout { var nullable = Settings.GetIsNullable(route, false); - return new FieldEmbedded(route) - { - HasValue = nullable.ToBool() ? new FieldEmbedded.EmbeddedHasValueColumn() { Name = name.Add("HasValue").ToString() } : null, - EmbeddedFields = GenerateFields(route, table, name, forceNull: nullable.ToBool() || forceNull, inMList: inMList) - }; + var hasValue = nullable.ToBool() ? new FieldEmbedded.EmbeddedHasValueColumn(name.Add("HasValue").ToString()) : null; + + var embeddedFields = GenerateFields(route, table, name, forceNull: nullable.ToBool() || forceNull, inMList: inMList); + + return new FieldEmbedded(route, hasValue, embeddedFields); } protected virtual FieldMixin GenerateFieldMixin(PropertyRoute route, NameSequence name, Table table) { - return new FieldMixin(route, table) - { - Fields = GenerateFields(route, table, name, forceNull: false, inMList: false) - }; + return new FieldMixin(route, table, GenerateFields(route, table, name, forceNull: false, inMList: false)); } #endregion @@ -814,8 +795,8 @@ public virtual ObjectName GenerateTableName(Type type, TableNameAttribute tn) private SchemaName GetSchemaName(TableNameAttribute tn) { - ServerName server = tn.ServerName == null ? null : new ServerName(tn.ServerName); - DatabaseName dataBase = tn.DatabaseName == null && server == null ? null : new DatabaseName(server, tn.DatabaseName); + ServerName? server = tn.ServerName == null ? null : new ServerName(tn.ServerName); + DatabaseName? dataBase = tn.DatabaseName == null && server == null ? null : new DatabaseName(server, tn.DatabaseName); SchemaName schema = tn.SchemaName == null && dataBase == null ? SchemaName.Default : new SchemaName(dataBase, tn.SchemaName); return schema; } @@ -847,7 +828,7 @@ public virtual string GenerateMListFieldName(PropertyRoute route, KindOfField ki public virtual string GenerateFieldName(PropertyRoute route, KindOfField kindOfField) { string name = route.PropertyInfo != null ? (route.PropertyInfo.Name.TryAfterLast('.') ?? route.PropertyInfo.Name) - : route.FieldInfo.Name.FirstUpper(); + : route.FieldInfo!.Name.FirstUpper(); switch (kindOfField) { @@ -861,7 +842,7 @@ public virtual string GenerateFieldName(PropertyRoute route, KindOfField kindOfF case KindOfField.Enum: return name + "ID"; default: - throw new InvalidOperationException("No name for {0} defined".FormatWith(route.FieldInfo.Name)); + throw new InvalidOperationException("No name for {0} defined".FormatWith(route.FieldInfo!.Name)); } } @@ -879,7 +860,9 @@ public void SwitchGlobalLazyManager(GlobalLazyManager manager) GlobalLazyManager = manager; } - public ResetLazy GlobalLazy(Func func, InvalidateWith invalidateWith, Action onInvalidated = null, LazyThreadSafetyMode mode = LazyThreadSafetyMode.ExecutionAndPublication) where T : class + public ResetLazy GlobalLazy(Func func, InvalidateWith invalidateWith, + Action? onInvalidated = null, + LazyThreadSafetyMode mode = LazyThreadSafetyMode.ExecutionAndPublication) where T : class { var result = Signum.Engine.GlobalLazy.WithoutInvalidations(() => { @@ -1007,7 +990,7 @@ public override ObjectName GenerateTableName(Type type, TableNameAttribute tn) { if (tn.SchemaName == "sys") { - DatabaseName db = Administrator.sysViewDatabase.Value; + DatabaseName? db = Administrator.sysViewDatabase.Value; return new ObjectName(new SchemaName(db, tn.SchemaName ?? "dbo"), tn.Name); } @@ -1045,12 +1028,10 @@ protected override FieldEnum GenerateFieldEnum(ITable table, PropertyRoute route //var referenceTable = Include(EnumEntity.Generate(cleanEnum), route); - return new FieldEnum(route) + return new FieldEnum(route, name.ToString(), null! /*referenceTable*/) { - Name = name.ToString(), Nullable = Settings.GetIsNullable(route, forceNull), IsLite = false, - ReferenceTable = null,//referenceTable, AvoidForeignKey = Settings.FieldAttribute(route) != null, Default = att?.Default, }.Do(f => f.UniqueIndex = f.GenerateUniqueIndex(table, Settings.FieldAttribute(route))); diff --git a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs index add74e7c0c..3fe6d3da44 100644 --- a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs +++ b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs @@ -276,7 +276,7 @@ internal SqlDbTypePair GetSqlDbType(SqlDbTypeAttribute att, Type type) return GetSqlDbTypePair(type.UnNullify()); } - internal int? GetSqlSize(SqlDbTypeAttribute att, PropertyRoute route, SqlDbType sqlDbType) + internal int? GetSqlSize(SqlDbTypeAttribute att, PropertyRoute? route, SqlDbType sqlDbType) { if (att != null && att.HasSize) return att.Size; diff --git a/Signum.Engine/Signum.Engine.csproj b/Signum.Engine/Signum.Engine.csproj index 9c02d6cd47..b309f217c9 100644 --- a/Signum.Engine/Signum.Engine.csproj +++ b/Signum.Engine/Signum.Engine.csproj @@ -2,8 +2,10 @@ netcoreapp2.2 - latest + 8.0 true + true + true x64 diff --git a/Signum.Entities/Basics/Type.cs b/Signum.Entities/Basics/Type.cs index 7d05422b92..465fe3549f 100644 --- a/Signum.Entities/Basics/Type.cs +++ b/Signum.Entities/Basics/Type.cs @@ -43,13 +43,13 @@ public bool IsType(Type type) return ClassName == type.Name && Namespace == type.Namespace; } - public static Func ToTypeEntityFunc = t => { throw new InvalidOperationException("Lite.ToTypeDNFunc is not set"); }; - public static Func ToTypeFunc = t => { throw new InvalidOperationException("Lite.ToTypeFunc is not set"); }; - public static Func TryGetType = s => { throw new InvalidOperationException("Lite.TryGetType is not set"); }; - public static Func GetCleanName = s => { throw new InvalidOperationException("Lite.GetCleanName is not set"); }; + public static Func ToTypeEntityFunc = t => { throw new InvalidOperationException("TypeEntity.ToTypeEntityFunc is not set"); }; + public static Func ToTypeFunc = t => { throw new InvalidOperationException("TypeEntity.ToTypeFunc is not set"); }; + public static Func TryGetType = s => { throw new InvalidOperationException("TypeEntity.TryGetType is not set"); }; + public static Func GetCleanName = s => { throw new InvalidOperationException("TypeEntity.GetCleanName is not set"); }; public static bool AlreadySet { get; private set; } - public static void SetTypeNameCallbacks(Func getCleanName, Func tryGetType) + public static void SetTypeNameCallbacks(Func getCleanName, Func tryGetType) { TypeEntity.GetCleanName = getCleanName; TypeEntity.TryGetType = tryGetType; diff --git a/Signum.Entities/DynamicQuery/Tokens/ExtensionDictionaryToken.cs b/Signum.Entities/DynamicQuery/Tokens/ExtensionDictionaryToken.cs index ac0dc0d7a0..d2b329a907 100644 --- a/Signum.Entities/DynamicQuery/Tokens/ExtensionDictionaryToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/ExtensionDictionaryToken.cs @@ -8,15 +8,16 @@ namespace Signum.Entities.DynamicQuery { [Serializable] public class ExtensionDictionaryToken : QueryToken - where K : Object + where K : object { QueryToken parent; public override QueryToken? Parent => parent; public ExtensionDictionaryToken(QueryToken parent, K key, - string unit, string format, + string? unit, + string? format, Implementations? implementations, - PropertyRoute propertyRoute, + PropertyRoute? propertyRoute, Expression> lambda) { this.keyValue= key; @@ -44,10 +45,10 @@ public override string NiceName() K keyValue; public override string Key => "[" + keyValue.ToString() + "]"; - string format; + string? format; public override string? Format => format; - string unit; + string? unit; public override string? Unit => unit; protected override List SubTokensOverride(SubTokensOptions options) @@ -63,10 +64,10 @@ protected override Expression BuildExpressionInternal(BuildExpressionContext con var result = Expression.Invoke(Lambda, parentExpression); - return result.BuildLiteNulifyUnwrapPrimaryKey(new[] { this.propertyRoute }); + return result.BuildLiteNulifyUnwrapPrimaryKey(new[] { this.propertyRoute! }); } - public PropertyRoute propertyRoute; + public PropertyRoute? propertyRoute; public override PropertyRoute? GetPropertyRoute() => this.propertyRoute; public Implementations? implementations; diff --git a/Signum.Entities/DynamicQuery/Tokens/ExtensionToken.cs b/Signum.Entities/DynamicQuery/Tokens/ExtensionToken.cs index b3c64cd87f..8b1f462646 100644 --- a/Signum.Entities/DynamicQuery/Tokens/ExtensionToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/ExtensionToken.cs @@ -15,7 +15,7 @@ public class ExtensionToken : QueryToken public ExtensionToken(QueryToken parent, string key, Type type, bool isProjection, string? unit, string? format, Implementations? implementations, - string? isAllowed, PropertyRoute propertyRoute, string displayName) + string? isAllowed, PropertyRoute? propertyRoute, string displayName) { this.parent = parent ?? throw new ArgumentNullException(nameof(parent)); @@ -81,10 +81,10 @@ protected override Expression BuildExpressionInternal(BuildExpressionContext con var result = BuildExtension(parent.Type.CleanType().UnNullify(), Key, parentExpression); - return result.BuildLiteNulifyUnwrapPrimaryKey(new[] { this.propertyRoute }); + return result.BuildLiteNulifyUnwrapPrimaryKey(new[] { this.propertyRoute! }); } - public PropertyRoute propertyRoute; + public PropertyRoute? propertyRoute; public override PropertyRoute? GetPropertyRoute() { return isProjection ? null : propertyRoute; diff --git a/Signum.Entities/SystemTime.cs b/Signum.Entities/SystemTime.cs index 5eb56edf23..ef33aaa475 100644 --- a/Signum.Entities/SystemTime.cs +++ b/Signum.Entities/SystemTime.cs @@ -111,7 +111,7 @@ public static Interval SystemPeriod(this MListElement mlis static MethodInfo miOverlaps = ReflectionTools.GetMethodInfo((Interval pair) => pair.Overlaps(new Interval())); - internal static Expression? Overlaps(this NewExpression interval1, NewExpression interval2) + internal static Expression? Overlaps(this NewExpression? interval1, NewExpression? interval2) { if (interval1 == null) return null; @@ -133,7 +133,7 @@ public static Interval SystemPeriod(this MListElement mlis static ConstructorInfo ciInterval = ReflectionTools.GetConstuctorInfo(() => new Interval(new DateTime(), new DateTime())); - internal static Expression Intesection(this NewExpression interval1, NewExpression interval2) + internal static Expression Intesection(this NewExpression? interval1, NewExpression? interval2) { if (interval1 == null) return interval2; @@ -151,7 +151,7 @@ internal static Expression Intesection(this NewExpression interval1, NewExpressi Expression.Condition(Expression.GreaterThan(max1, max2), max1, max2)); } - public static Expression And(this Expression expression, Expression other) + public static Expression And(this Expression expression, Expression? other) { if (other == null) return expression; diff --git a/Signum.Utilities/DataStructures/ImmutableStack.cs b/Signum.Utilities/DataStructures/ImmutableStack.cs index 5341af2f76..077b696ea7 100644 --- a/Signum.Utilities/DataStructures/ImmutableStack.cs +++ b/Signum.Utilities/DataStructures/ImmutableStack.cs @@ -8,7 +8,7 @@ namespace Signum.Utilities.DataStructures public class ImmutableStack : IEnumerable - where T : object + where T : object /*CSBUG*/ { class ImmutableFullStack : ImmutableStack { diff --git a/Signum.Utilities/Disposable.cs b/Signum.Utilities/Disposable.cs index 0a7700116a..cddf772f89 100644 --- a/Signum.Utilities/Disposable.cs +++ b/Signum.Utilities/Disposable.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.Serialization; namespace Signum.Utilities @@ -19,7 +19,7 @@ public void Dispose() action?.Invoke(); } - public static IDisposable Combine(IDisposable first, IDisposable second) + public static IDisposable? Combine(IDisposable? first, IDisposable? second) { if (first == null || second == null) return first ?? second; diff --git a/Signum.Utilities/ExpressionTrees/ExpressionCleaner.cs b/Signum.Utilities/ExpressionTrees/ExpressionCleaner.cs index 1c0557ba12..d5c645c6fe 100644 --- a/Signum.Utilities/ExpressionTrees/ExpressionCleaner.cs +++ b/Signum.Utilities/ExpressionTrees/ExpressionCleaner.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using System.Linq.Expressions; using System.Reflection; @@ -20,7 +20,7 @@ public class ExpressionCleaner : ExpressionVisitor bool shortCircuit; - public static Expression Clean(Expression expr) + public static Expression? Clean(Expression? expr) { return Clean(expr, ExpressionEvaluator.PartialEval, true); } @@ -48,15 +48,14 @@ protected override Expression VisitMethodCall(MethodCallExpression m) { MethodCallExpression expr = (MethodCallExpression)base.VisitMethodCall(m); - Expression binded = BindMethodExpression(expr, false); - + Expression? binded = BindMethodExpression(expr, false); if (binded != null) return Visit(binded); return expr; } - public static Expression BindMethodExpression(MethodCallExpression m, bool allowPolymorphics) + public static Expression? BindMethodExpression(MethodCallExpression m, bool allowPolymorphics) { if (m.Method.DeclaringType == typeof(ExpressionExtensions) && m.Method.Name == "Evaluate") { @@ -79,7 +78,7 @@ public static Expression BindMethodExpression(MethodCallExpression m, bool allow Expression[] args = m.Object == null ? m.Arguments.ToArray() : m.Arguments.PreAnd(m.Object).ToArray(); var type = attribute.ExpanderType.MakeGenericType(m.Method.GetGenericArguments()); - GenericMethodExpander expander = Activator.CreateInstance(type) as GenericMethodExpander; + GenericMethodExpander expander = (GenericMethodExpander)Activator.CreateInstance(type); return Expression.Invoke(expander.GenericLambdaExpression, args); } else @@ -98,7 +97,7 @@ public static Expression BindMethodExpression(MethodCallExpression m, bool allow } } - LambdaExpression lambdaExpression = GetFieldExpansion(m.Object?.Type, m.Method); + LambdaExpression? lambdaExpression = GetFieldExpansion(m.Object?.Type, m.Method); if (lambdaExpression != null) { Expression[] args = m.Object == null ? m.Arguments.ToArray() : m.Arguments.PreAnd(m.Object).ToArray(); @@ -114,24 +113,23 @@ protected override Expression VisitMember(MemberExpression m) { MemberExpression exp = (MemberExpression)base.VisitMember(m); - Expression binded = BindMemberExpression(exp, false); - + Expression? binded = BindMemberExpression(exp, false); if (binded != null) return Visit(binded); return exp; } - public static Expression BindMemberExpression(MemberExpression m, bool allowPolymorphics) + public static Expression? BindMemberExpression(MemberExpression m, bool allowPolymorphics) { - PropertyInfo pi = m.Member as PropertyInfo; + PropertyInfo? pi = m.Member as PropertyInfo; if (pi == null) return null; if (pi.HasAttributeInherit() && !allowPolymorphics) return null; - LambdaExpression lambda = GetFieldExpansion(m.Expression?.Type, pi); + LambdaExpression? lambda = GetFieldExpansion(m.Expression?.Type, pi); if (lambda == null) return null; @@ -146,13 +144,13 @@ public static bool HasExpansions(Type type, MemberInfo mi) return GetFieldExpansion(type, mi) != null || mi is MethodInfo && mi.HasAttribute(); } - public static LambdaExpression GetFieldExpansion(Type decType, MemberInfo mi) + public static LambdaExpression? GetFieldExpansion(Type decType, MemberInfo mi) { if (decType == null || decType == mi.DeclaringType || IsStatic(mi)) return GetExpansion(mi); else { - for (MemberInfo m = GetMember(decType, mi); m != null; m = BaseMember(m)) + for (MemberInfo? m = GetMember(decType, mi); m != null; m = BaseMember(m)) { var result = GetExpansion(m); if (result != null) @@ -174,7 +172,7 @@ static bool IsStatic(MemberInfo mi) return false; } - static LambdaExpression GetExpansion(MemberInfo mi) + static LambdaExpression? GetExpansion(MemberInfo mi) { ExpressionFieldAttribute efa = mi.GetCustomAttribute(); if (efa == null) @@ -203,7 +201,7 @@ static LambdaExpression GetExpansion(MemberInfo mi) static BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; - static MemberInfo GetMember(Type decType, MemberInfo mi) + static MemberInfo? GetMember(Type decType, MemberInfo mi) { if (mi is MethodInfo) { @@ -235,7 +233,7 @@ static MemberInfo GetMember(Type decType, MemberInfo mi) throw new InvalidOperationException("Invalid Member type"); } - static MemberInfo BaseMember(MemberInfo mi) + static MemberInfo? BaseMember(MemberInfo mi) { MemberInfo result; if (mi is MethodInfo mti) diff --git a/Signum.Utilities/Extensions/DateTimeExtensions.cs b/Signum.Utilities/Extensions/DateTimeExtensions.cs index a046e2d3ec..d92f5856e3 100644 --- a/Signum.Utilities/Extensions/DateTimeExtensions.cs +++ b/Signum.Utilities/Extensions/DateTimeExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.ComponentModel; using System.Globalization; using System.Linq.Expressions; @@ -349,7 +349,7 @@ public static string ToAgoString(this DateTime dateTime) public static string ToAgoString(this DateTime dateTime, DateTime now) { TimeSpan ts = now.Subtract(dateTime); - string resource = null; + string? resource = null; if (ts.TotalMilliseconds < 0) resource = DateTimeMessage.In0.NiceToString(); else @@ -524,7 +524,7 @@ public DateSpan Invert() public override string ToString() { - string result = ", ".Combine( + string result = ", ".CombineIfNotEmpty( Years == 0 ? null : Years == 1 ? DateTimeMessage._0Year.NiceToString().FormatWith(Years) : DateTimeMessage._0Years.NiceToString().FormatWith(Years), diff --git a/Signum.Utilities/Extensions/EnumerableExtensions.cs b/Signum.Utilities/Extensions/EnumerableExtensions.cs index 696f25648d..e54f876e11 100644 --- a/Signum.Utilities/Extensions/EnumerableExtensions.cs +++ b/Signum.Utilities/Extensions/EnumerableExtensions.cs @@ -372,7 +372,7 @@ public static T Only(this IEnumerable collection) public static class EnumerableExtensions { - public static IEnumerable EmptyIfNull(this IEnumerable collection) + public static IEnumerable EmptyIfNull(this IEnumerable? collection) { if (collection == null) return Enumerable.Empty(); @@ -399,12 +399,12 @@ public Expression Expand(Expression instance, Expression[] arguments, MethodInfo } } - public static bool IsNullOrEmpty(this IEnumerable collection) + public static bool IsNullOrEmpty(this IEnumerable? collection) { return collection == null || collection.IsEmpty(); } - public static bool HasItems(this IEnumerable collection) + public static bool HasItems(this IEnumerable? collection) { return collection != null && collection.Any(); } @@ -1117,7 +1117,7 @@ static bool AssertoTwo(bool nextA, bool nextB) #region Conversions - public static ReadOnlyCollection ToReadOnly(this IEnumerable collection) + public static ReadOnlyCollection ToReadOnly(this IEnumerable? collection) { return collection == null ? EmptyReadOnlyCollection.Instance : collection as ReadOnlyCollection ?? diff --git a/Signum.Utilities/Extensions/StreamExtensions.cs b/Signum.Utilities/Extensions/StreamExtensions.cs index 6f2fb6c76b..7ae5153457 100644 --- a/Signum.Utilities/Extensions/StreamExtensions.cs +++ b/Signum.Utilities/Extensions/StreamExtensions.cs @@ -82,7 +82,7 @@ public static bool FilesAreEqual(FileInfo first, FileInfo second) [DebuggerStepThrough] public static R Using(this T disposable, Func function) - where T : IDisposable + where T : IDisposable? { //using (disposable) // return function(disposable); @@ -108,7 +108,7 @@ public static R Using(this T disposable, Func function) [DebuggerStepThrough] public static void EndUsing(this T disposable, Action action) - where T : IDisposable + where T : IDisposable? { try { diff --git a/Signum.Utilities/Profiler/HeavyProfiler.cs b/Signum.Utilities/Profiler/HeavyProfiler.cs index 318656564b..556f5e2d16 100644 --- a/Signum.Utilities/Profiler/HeavyProfiler.cs +++ b/Signum.Utilities/Profiler/HeavyProfiler.cs @@ -35,7 +35,7 @@ public static bool Enabled } } - static readonly Variable current = Statics.ThreadVariable("heavy"); + static readonly Variable current = Statics.ThreadVariable("heavy"); public static readonly List Entries = new List(); @@ -180,12 +180,12 @@ public void Dispose() } } - public static void Switch(this Tracer tracer, string role, Func? additionalData = null) + public static void Switch(this Tracer? tracer, string role, Func? additionalData = null) { if (tracer == null) return; - bool hasStackTrace = current.Value.StackTrace != null; + bool hasStackTrace = current.Value!.StackTrace != null; tracer.Dispose(); @@ -261,7 +261,7 @@ public static XDocument SqlStatisticsXDocument() public static IOrderedEnumerable SqlStatistics() { - var statistics = AllEntries().Where(a => a.Role == "SQL").GroupBy(a => (string)a.AdditionalData).Select(gr => + var statistics = AllEntries().Where(a => a.Role == "SQL").GroupBy(a => a.AdditionalData!).Select(gr => new SqlProfileResume { Query = gr.Key, @@ -408,8 +408,8 @@ public XElement ExportXml(bool includeStackTrace) private XElement StackTraceToXml(StackTrace stackTrace) { - var frames = (from i in 0.To(StackTrace.FrameCount) - let sf = StackTrace.GetFrame(i) + var frames = (from i in 0.To(StackTrace!.FrameCount) + let sf = StackTrace!.GetFrame(i) let mi = sf.GetMethod() select new XElement("StackFrame", new XAttribute("Method", mi.DeclaringType?.FullName + "." + mi.Name), diff --git a/Signum.Utilities/Synchronization/CultureInfoUtils.cs b/Signum.Utilities/Synchronization/CultureInfoUtils.cs index f67b85d500..f860657b1a 100644 --- a/Signum.Utilities/Synchronization/CultureInfoUtils.cs +++ b/Signum.Utilities/Synchronization/CultureInfoUtils.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading; using System.Globalization; @@ -6,7 +6,7 @@ namespace Signum.Utilities { public static class CultureInfoUtils { - public static IDisposable ChangeBothCultures(string cultureName) + public static IDisposable? ChangeBothCultures(string cultureName) { if (string.IsNullOrEmpty(cultureName)) return null; @@ -14,7 +14,7 @@ public static IDisposable ChangeBothCultures(string cultureName) return ChangeBothCultures(CultureInfo.GetCultureInfo(cultureName)); } - public static IDisposable ChangeBothCultures(CultureInfo ci) + public static IDisposable? ChangeBothCultures(CultureInfo? ci) { if (ci == null) return null; @@ -31,7 +31,7 @@ public static IDisposable ChangeBothCultures(CultureInfo ci) }); } - public static IDisposable ChangeCulture(string cultureName) + public static IDisposable? ChangeCulture(string cultureName) { if (string.IsNullOrEmpty(cultureName)) return null; @@ -39,7 +39,7 @@ public static IDisposable ChangeCulture(string cultureName) return ChangeCulture(CultureInfo.GetCultureInfo(cultureName)); } - public static IDisposable ChangeCulture(CultureInfo ci) + public static IDisposable? ChangeCulture(CultureInfo ci) { if (ci == null) return null; @@ -50,7 +50,7 @@ public static IDisposable ChangeCulture(CultureInfo ci) return new Disposable(() => t.CurrentCulture = old); } - public static IDisposable ChangeCultureUI(string cultureName) + public static IDisposable? ChangeCultureUI(string cultureName) { if (string.IsNullOrEmpty(cultureName)) return null; @@ -58,7 +58,7 @@ public static IDisposable ChangeCultureUI(string cultureName) return ChangeCultureUI(CultureInfo.GetCultureInfo(cultureName)); } - public static IDisposable ChangeCultureUI(CultureInfo ci) + public static IDisposable? ChangeCultureUI(CultureInfo? ci) { if (ci == null) return null; From 258c508cd681be443dbb5e7c726ac5ed28c66cb5 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Thu, 24 Jan 2019 09:05:48 +0100 Subject: [PATCH 09/25] more on Signum.Engine nullable --- Signum.Engine/Basics/ExceptionLogic.cs | 2 +- Signum.Engine/BulkInserter.cs | 748 +++++++++--------- Signum.Engine/CodeGeneration/CodeGenerator.cs | 24 +- .../CodeGeneration/EntityCodeGenerator.cs | 100 ++- .../CodeGeneration/LogicCodeGenerator.cs | 52 +- Signum.Engine/Connection/Executor.cs | 7 +- Signum.Engine/Connection/FieldReader.cs | 20 +- Signum.Engine/Connection/Transaction.cs | 135 ++-- Signum.Engine/Database.cs | 48 +- .../DynamicQuery/AutoDynamicQuery.cs | 16 +- .../DynamicQuery/ColumnDescriptionFactory.cs | 4 +- Signum.Engine/DynamicQuery/DynamicQuery.cs | 127 ++- .../DynamicQuery/DynamicQueryContainer.cs | 24 +- .../DynamicQuery/DynamicQueryFluentInclude.cs | 4 +- .../DynamicQuery/ExpressionContainer.cs | 4 +- .../DynamicQuery/ManualDynamicQuery.cs | 12 +- Signum.Engine/Engine/Saver.cs | 4 +- Signum.Engine/Engine/SchemaSynchronizer.cs | 18 +- Signum.Engine/Engine/SqlBuilder.cs | 2 +- Signum.Engine/Engine/Sys.Tables.cs | 3 +- Signum.Engine/EntityCache.cs | 31 +- Signum.Engine/Exceptions.cs | 32 +- Signum.Engine/ExecutionContext.cs | 7 +- Signum.Engine/Linq/AliasGenerator.cs | 16 +- Signum.Engine/Linq/DbExpressions.Signum.cs | 18 +- Signum.Engine/Linq/DbExpressions.Sql.cs | 8 +- Signum.Engine/Linq/DbQueryProvider.cs | 6 +- .../AliasProjectionReplacer.cs | 19 +- .../Linq/ExpressionVisitor/AliasReplacer.cs | 16 +- .../ChildProjectionFlattener.cs | 72 +- .../Linq/ExpressionVisitor/ColumnProjector.cs | 45 +- .../ExpressionVisitor/ConditionsRewriter.cs | 22 +- .../ExpressionVisitor/DbExpressionComparer.cs | 10 +- .../DbExpressionNominator.cs | 32 +- .../ExpressionVisitor/DbExpressionVisitor.cs | 14 +- .../Linq/ExpressionVisitor/EntityCompleter.cs | 17 +- .../Linq/ExpressionVisitor/QueryBinder.cs | 34 +- .../Linq/ExpressionVisitor/QueryFormatter.cs | 44 +- .../Linq/ExpressionVisitor/QueryRebinder.cs | 22 +- .../Linq/ExpressionVisitor/Replacer.cs | 14 +- .../ScalarSubqueryRewriter.cs | 17 +- .../Linq/ExpressionVisitor/SubqueryRemover.cs | 18 +- .../ExpressionVisitor/TranslatorBuilder.cs | 128 ++- .../UpdateDeleteSimplifier.cs | 17 +- Signum.Engine/Linq/Meta/MetaEvaluator.cs | 10 +- Signum.Engine/Linq/Meta/MetaExpression.cs | 4 +- Signum.Engine/Linq/Meta/MetadataVisitor.cs | 40 +- Signum.Engine/Linq/TranslateResult.cs | 68 +- Signum.Engine/Operations/Graph.cs | 124 +-- Signum.Engine/Operations/GraphState.cs | 60 +- Signum.Engine/Operations/Internal.cs | 20 +- Signum.Engine/Operations/OperationLogic.cs | 74 +- Signum.Engine/Patterns/DeletePart.cs | 8 +- Signum.Engine/Retriever.cs | 78 +- Signum.Engine/Schema/Schema.Expressions.cs | 73 +- Signum.Engine/Schema/Schema.Save.cs | 26 +- Signum.Engine/Schema/Schema.cs | 2 +- .../Schema/SchemaBuilder/NameSequence.cs | 5 +- .../Schema/SchemaBuilder/SchemaBuilder.cs | 4 +- .../SchemaBuilder/SchemaBuilderSettings.cs | 73 +- Signum.Engine/Schema/UniqueIndex.cs | 2 +- Signum.Entities/DynamicQuery/Filter.cs | 17 +- Signum.Entities/DynamicQuery/QueryUtils.cs | 18 +- Signum.Entities/DynamicQuery/ResultTable.cs | 6 +- .../DynamicQuery/Tokens/AggregateToken.cs | 4 +- .../DynamicQuery/Tokens/AsTypeToken.cs | 2 +- .../Tokens/CollectionAnyAllToken.cs | 16 +- .../Tokens/CollectionElementToken.cs | 7 +- .../Tokens/DecimalSpecialTokens.cs | 2 +- .../Tokens/EntityToStringToken.cs | 18 +- .../DynamicQuery/Tokens/ExtensionToken.cs | 2 +- .../DynamicQuery/Tokens/QueryToken.cs | 2 +- Signum.Entities/FieldAttributes.cs | 4 +- .../FieldNotificationAttributes.cs | 8 +- Signum.Entities/Lite.cs | 4 +- Signum.Entities/MList.cs | 10 +- Signum.Entities/MixinEntity.cs | 4 +- Signum.Entities/ModifiableEntity.cs | 8 +- Signum.Entities/Patterns/CorruptEntity.cs | 12 +- Signum.Entities/Patterns/LockeableEntity.cs | 2 +- Signum.Entities/PropertyAttributes.cs | 2 +- Signum.Entities/PropertyRoute.cs | 10 +- Signum.Entities/Reflection/GraphExplorer.cs | 4 +- Signum.Entities/Reflection/ModifyInspector.cs | 20 +- Signum.Entities/Services/Security.cs | 7 +- Signum.Entities/SystemTime.cs | 2 +- .../Scripts/Signum.Entities.Basics.ts | 16 +- Signum.React/Scripts/Signum.Entities.ts | 3 +- .../DataStructures/DirectedEdgedGraph.cs | 13 +- .../DataStructures/DirectedGraph.cs | 11 +- .../IntervalDictionaries/CubeDictionary.cs | 2 +- .../IntervalDictionaries/Interval.cs | 4 +- .../IntervalDictionary.cs | 10 +- .../IntervalDictionaries/SquareDictionary.cs | 4 +- .../DataStructures/RecentsDictionary.cs | 10 +- Signum.Utilities/DescriptionManager.cs | 75 +- Signum.Utilities/Disposable.cs | 8 +- Signum.Utilities/ExpressionExpanderSamples.cs | 25 +- .../ExpressionTrees/CSharpRenderer.cs | 7 +- .../ExpandableQueryProvider.cs | 12 +- .../ExpressionTrees/ExpressionCleaner.cs | 13 +- .../ExpressionTrees/ExpressionComparer.cs | 6 +- .../ExpressionTrees/ExpressionEvaluator.cs | 59 +- .../ExpressionTrees/ExpressionHelper.cs | 12 +- .../ExpressionTrees/ExpressionReplacer.cs | 21 +- Signum.Utilities/ExpressionTrees/Query.cs | 4 +- .../ExpressionTrees/QueryProvider.cs | 4 +- .../QueryableAsyncExtensions.cs | 12 +- Signum.Utilities/Extensions/ArgsExtensions.cs | 12 +- .../Extensions/ColorExtensions.cs | 10 +- .../Extensions/DateTimeExtensions.cs | 2 +- Signum.Utilities/Extensions/EnumExtensions.cs | 4 +- .../Extensions/EnumerableExtensions.cs | 8 +- Signum.Utilities/Extensions/Extensions.cs | 9 +- .../Extensions/GroupExtensions.cs | 12 +- .../Extensions/ReflectionExtensions.cs | 19 +- .../Extensions/RegexExtensions.cs | 10 +- .../Extensions/StringExtensions.cs | 39 +- .../Extensions/StringExtensions.md | 8 +- .../Extensions/TimeSpanExtensions.cs | 2 +- Signum.Utilities/Extensions/TreeHelper.cs | 24 +- Signum.Utilities/NaturalLanguage/German.cs | 21 +- Signum.Utilities/NaturalLanguage/Spanish.cs | 22 +- Signum.Utilities/NotNullAttributes.cs | 33 + Signum.Utilities/ProgressProxy.cs | 6 +- .../Reflection/ReflectionTools.cs | 17 +- .../Reflection/TupleExtensions.cs | 4 +- Signum.Utilities/Statics.cs | 17 +- .../Synchronization/ThreadSafeEnumerator.cs | 6 +- Signum.Utilities/Tsv.cs | 6 +- 130 files changed, 1751 insertions(+), 1746 deletions(-) create mode 100644 Signum.Utilities/NotNullAttributes.cs diff --git a/Signum.Engine/Basics/ExceptionLogic.cs b/Signum.Engine/Basics/ExceptionLogic.cs index 6111780b9e..76647c935d 100644 --- a/Signum.Engine/Basics/ExceptionLogic.cs +++ b/Signum.Engine/Basics/ExceptionLogic.cs @@ -50,7 +50,7 @@ public static ExceptionEntity LogException(this Exception ex) return entity.SaveForceNew(); } - public static ExceptionEntity GetExceptionEntity(this Exception ex) + public static ExceptionEntity? GetExceptionEntity(this Exception ex) { var exEntity = ex.Data[ExceptionEntity.ExceptionDataKey] as ExceptionEntity; diff --git a/Signum.Engine/BulkInserter.cs b/Signum.Engine/BulkInserter.cs index 493552bc2d..daefa1eef8 100644 --- a/Signum.Engine/BulkInserter.cs +++ b/Signum.Engine/BulkInserter.cs @@ -1,375 +1,375 @@ -using Signum.Engine.Maps; -using Signum.Entities; -using Signum.Entities.Reflection; -using Signum.Utilities; -using Signum.Utilities.ExpressionTrees; -using Signum.Utilities.Reflection; -using System; -using System.Collections; -using System.Collections.Generic; -using System.Data; -using System.Data.SqlClient; -using System.Linq; -using System.Linq.Expressions; - -namespace Signum.Engine -{ - public static class BulkInserter - { - public static int BulkInsert(this IEnumerable entities, - SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, - bool preSaving = true, - bool validateFirst = true, - bool disableIdentity = false, - int? timeout = null, - string? message = null) - where T : Entity - { - using (HeavyProfiler.Log(nameof(BulkInsert), () => typeof(T).TypeName())) - using (Transaction tr = new Transaction()) - { - - var table = Schema.Current.Table(typeof(T)); - - if (!disableIdentity && table.IdentityBehaviour && table.TablesMList().Any()) - throw new InvalidOperationException($@"Table {typeof(T)} contains MList but the entities have no IDs. Consider: -* Using BulkInsertQueryIds, that queries the inserted rows and uses the IDs to insert the MList elements. -* Set {nameof(disableIdentity)} = true, and set manually the Ids of the entities before inseting using {nameof(UnsafeEntityExtensions.SetId)}. -* If you know what you doing, call ${nameof(BulkInsertTable)} manually (MList wont be saved)." - ); - - var list = entities.ToList(); - - var rowNum = BulkInsertTable(list, copyOptions, preSaving, validateFirst, disableIdentity, timeout, message); - - BulkInsertMLists(list, copyOptions, timeout, message); - - return tr.Commit(rowNum); - } - } - - /// Unique key to retrieve ids - /// Optional filter to query only the recently inseted entities - public static int BulkInsertQueryIds(this IEnumerable entities, - Expression> keySelector, - Expression>? isNewPredicate = null, - SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, - bool preSaving = true, - bool validateFirst = true, - int? timeout = null, - string? message = null) +using Signum.Engine.Maps; +using Signum.Entities; +using Signum.Entities.Reflection; +using Signum.Utilities; +using Signum.Utilities.ExpressionTrees; +using Signum.Utilities.Reflection; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Data.SqlClient; +using System.Linq; +using System.Linq.Expressions; + +namespace Signum.Engine +{ + public static class BulkInserter + { + public static int BulkInsert(this IEnumerable entities, + SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, + bool preSaving = true, + bool validateFirst = true, + bool disableIdentity = false, + int? timeout = null, + string? message = null) where T : Entity - where K : object - { - using (HeavyProfiler.Log(nameof(BulkInsertQueryIds), () => typeof(T).TypeName())) - using (Transaction tr = new Transaction()) - { - var t = Schema.Current.Table(typeof(T)); - - var list = entities.ToList(); - - if (isNewPredicate == null) - isNewPredicate = GetFilterAutomatic(t); - - var rowNum = BulkInsertTable(list, copyOptions, preSaving, validateFirst, false, timeout, message); - - var dictionary = Database.Query().Where(isNewPredicate).Select(a => KVP.Create(keySelector.Evaluate(a), a.Id)).ToDictionaryEx(); - - var getKeyFunc = keySelector.Compile(); - - list.ForEach(e => - { - e.SetId(dictionary.GetOrThrow(getKeyFunc(e))); - e.SetIsNew(false); - }); - - BulkInsertMLists(list, copyOptions, timeout, message); - - GraphExplorer.CleanModifications(GraphExplorer.FromRoots(list)); - - return tr.Commit(rowNum); - } - } - - static void BulkInsertMLists(List list, SqlBulkCopyOptions options, int? timeout, string? message) where T : Entity - { - var mlistPrs = PropertyRoute.GenerateRoutes(typeof(T), includeIgnored: false).Where(a => a.PropertyRouteType == PropertyRouteType.FieldOrProperty && a.Type.IsMList()).ToList(); - foreach (var pr in mlistPrs) - { - giBulkInsertMListFromEntities.GetInvoker(typeof(T), pr.Type.ElementType())(list, pr, options, timeout, message); - } - } - - static Expression> GetFilterAutomatic(Table table) where T : Entity - { - if (table.PrimaryKey.Identity) - { - var max = ExecutionMode.Global().Using(_ => Database.Query().Max(a => (PrimaryKey?)a.Id)); - if (max == null) - return a => true; - - return a => a.Id > max; - } - - var count = ExecutionMode.Global().Using(_ => Database.Query().Count()); - - if (count == 0) - return a => true; - - throw new InvalidOperationException($"Impossible to determine the filter for the IDs query automatically because the table is not Identity and has rows"); - } - - public static int BulkInsertTable(IEnumerable entities, - SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, - bool preSaving = true, - bool validateFirst = true, - bool disableIdentity = false, - int? timeout = null, - string? message = null) - where T : Entity - { - using (HeavyProfiler.Log(nameof(BulkInsertTable), () => typeof(T).TypeName())) - { - - if (message != null) - return SafeConsole.WaitRows(message == "auto" ? $"BulkInsering {entities.Count()} {typeof(T).TypeName()}" : message, - () => BulkInsertTable(entities, copyOptions, preSaving, validateFirst, disableIdentity, timeout, message: null)); - - if (disableIdentity) - copyOptions |= SqlBulkCopyOptions.KeepIdentity; - - if (copyOptions.HasFlag(SqlBulkCopyOptions.UseInternalTransaction)) - throw new InvalidOperationException("BulkInsertDisableIdentity not compatible with UseInternalTransaction"); - - var list = entities.ToList(); - - if (preSaving) - { - Saver.PreSaving(() => GraphExplorer.FromRoots(list)); - } - - if (validateFirst) - { - Validate(list); - } - - var t = Schema.Current.Table(); - bool disableIdentityBehaviour = copyOptions.HasFlag(SqlBulkCopyOptions.KeepIdentity); - bool oldIdentityBehaviour = t.IdentityBehaviour; - - DataTable dt = new DataTable(); - foreach (var c in t.Columns.Values.Where(c => !(c is SystemVersionedInfo.Column) && (disableIdentityBehaviour || !c.IdentityBehaviour))) - dt.Columns.Add(new DataColumn(c.Name, c.Type.UnNullify())); - - if (disableIdentityBehaviour) t.IdentityBehaviour = false; - foreach (var e in list) - { - if (!e.IsNew) - throw new InvalidOperationException("Entites should be new"); - t.SetToStrField(e); - dt.Rows.Add(t.BulkInsertDataRow(e)); - } - if (disableIdentityBehaviour) t.IdentityBehaviour = oldIdentityBehaviour; - - using (Transaction tr = new Transaction()) - { - Schema.Current.OnPreBulkInsert(typeof(T), inMListTable: false); - - Executor.BulkCopy(dt, t.Name, copyOptions, timeout); - - foreach (var item in list) - item.SetNotModified(); - - return tr.Commit(list.Count); - } - } - } - - static void Validate(IEnumerable entities) where T : Entity - { - foreach (var e in entities) - { - var ic = e.FullIntegrityCheck(); - - if (ic != null) - { -#if DEBUG - throw new IntegrityCheckException(ic.WithEntities(GraphExplorer.FromRoots(entities))); -#else - throw new IntegrityCheckException(ic); -#endif - } - } - } - - static GenericInvoker> giBulkInsertMListFromEntities = - new GenericInvoker>((entities, propertyRoute, options, timeout, message) => - BulkInsertMListTablePropertyRoute((List)entities, propertyRoute, options, timeout, message)); - - static int BulkInsertMListTablePropertyRoute(List entities, PropertyRoute route, SqlBulkCopyOptions copyOptions, int? timeout, string? message) - where E : Entity - { - return BulkInsertMListTable(entities, route.GetLambdaExpression>(safeNullAccess: false), copyOptions, timeout, message); - } - - public static int BulkInsertMListTable( - List entities, - Expression>> mListProperty, - SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, - int? timeout = null, - string? message = null) - where E : Entity - { - using (HeavyProfiler.Log(nameof(BulkInsertMListTable), () => $"{mListProperty} ({typeof(E).TypeName()})")) - { - try - { - var func = mListProperty.Compile(); - - var mlistElements = (from e in entities - from mle in func(e).Select((iw, i) => new MListElement - { - Order = i, - Element = iw, - Parent = e, - }) - select mle).ToList(); - - return BulkInsertMListTable(mlistElements, mListProperty, copyOptions, timeout, updateParentTicks: false, message: message); - } - catch (InvalidOperationException e) when (e.Message.Contains("has no Id")) - { - throw new InvalidOperationException($"{nameof(BulkInsertMListTable)} requires that you set the Id of the entities manually using {nameof(UnsafeEntityExtensions.SetId)}"); - - throw; - } - } - } - - public static int BulkInsertMListTable( - this IEnumerable> mlistElements, - Expression>> mListProperty, - SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, - int? timeout = null, - bool? updateParentTicks = null, /*Needed for concurrency and Temporal tables*/ - string? message = null) - where E : Entity - { - using (HeavyProfiler.Log(nameof(BulkInsertMListTable), () => $"{mListProperty} ({typeof(MListElement).TypeName()})")) - { - if (message != null) - return SafeConsole.WaitRows(message == "auto" ? $"BulkInsering MList<{ typeof(V).TypeName()}> in { typeof(E).TypeName()}" : message, - () => BulkInsertMListTable(mlistElements, mListProperty, copyOptions, timeout, updateParentTicks, message: null)); - - if (copyOptions.HasFlag(SqlBulkCopyOptions.UseInternalTransaction)) - throw new InvalidOperationException("BulkInsertDisableIdentity not compatible with UseInternalTransaction"); - - var mlistTable = ((FieldMList)Schema.Current.Field(mListProperty)).TableMList; - - if (updateParentTicks == null) - { - updateParentTicks = mlistTable.PrimaryKey.Type != typeof(Guid) && mlistTable.BackReference.ReferenceTable.Ticks != null; - } - - var maxRowId = updateParentTicks.Value ? Database.MListQuery(mListProperty).Max(a => (PrimaryKey?)a.RowId) : null; - - DataTable dt = new DataTable(); - - foreach (var c in mlistTable.Columns.Values.Where(c => !(c is SystemVersionedInfo.Column) && !c.IdentityBehaviour)) - dt.Columns.Add(new DataColumn(c.Name, c.Type.UnNullify())); - - var list = mlistElements.ToList(); - - foreach (var e in list) - { - dt.Rows.Add(mlistTable.BulkInsertDataRow(e.Parent, e.Element, e.Order)); - } - - using (Transaction tr = new Transaction()) - { - Schema.Current.OnPreBulkInsert(typeof(E), inMListTable: true); - - Executor.BulkCopy(dt, mlistTable.Name, copyOptions, timeout); - - var result = list.Count; - - if (updateParentTicks.Value) - { - Database.MListQuery(mListProperty) - .Where(a => maxRowId == null || a.RowId > maxRowId) - .Select(a => a.Parent) - .UnsafeUpdate() - .Set(e => e.Ticks, a => TimeZoneManager.Now.Ticks) - .Execute(); - } - - return tr.Commit(result); - } - } - } - - public static int BulkInsertView(this IEnumerable entities, - SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, - int? timeout = null, - string? message = null) - where T : IView - { - using (HeavyProfiler.Log(nameof(BulkInsertView), () => typeof(T).Name)) - { - if (message != null) - return SafeConsole.WaitRows(message == "auto" ? $"BulkInsering {entities.Count()} {typeof(T).TypeName()}" : message, - () => BulkInsertView(entities, copyOptions, timeout, message: null)); - - if (copyOptions.HasFlag(SqlBulkCopyOptions.UseInternalTransaction)) - throw new InvalidOperationException("BulkInsertDisableIdentity not compatible with UseInternalTransaction"); - - var t = Schema.Current.View(); - - var list = entities.ToList(); - - bool disableIdentityBehaviour = copyOptions.HasFlag(SqlBulkCopyOptions.KeepIdentity); - - DataTable dt = new DataTable(); - foreach (var c in t.Columns.Values) - dt.Columns.Add(new DataColumn(c.Name, c.Type.UnNullify())); - - foreach (var e in entities) - { - dt.Rows.Add(t.BulkInsertDataRow(e)); - } - - using (Transaction tr = new Transaction()) - { - Schema.Current.OnPreBulkInsert(typeof(T), inMListTable: false); - - Executor.BulkCopy(dt, t.Name, copyOptions, timeout); - - return tr.Commit(list.Count); - } - } - } - } - - public class BulkSetterOptions - { - public SqlBulkCopyOptions CopyOptions = SqlBulkCopyOptions.Default; - public bool ValidateFirst = false; - public bool DisableIdentity = false; - public int? Timeout = null; - } - - - public class BulkSetterTableOptionsT - { - public SqlBulkCopyOptions CopyOptions = SqlBulkCopyOptions.Default; - public bool ValidateFirst = false; - public bool DisableIdentity = false; - public int? Timeout = null; - } - - public class BulkSetterMListOptions - { - public SqlBulkCopyOptions CopyOptions = SqlBulkCopyOptions.Default; - public int? Timeout = null; - } -} + { + using (HeavyProfiler.Log(nameof(BulkInsert), () => typeof(T).TypeName())) + using (Transaction tr = new Transaction()) + { + + var table = Schema.Current.Table(typeof(T)); + + if (!disableIdentity && table.IdentityBehaviour && table.TablesMList().Any()) + throw new InvalidOperationException($@"Table {typeof(T)} contains MList but the entities have no IDs. Consider: +* Using BulkInsertQueryIds, that queries the inserted rows and uses the IDs to insert the MList elements. +* Set {nameof(disableIdentity)} = true, and set manually the Ids of the entities before inseting using {nameof(UnsafeEntityExtensions.SetId)}. +* If you know what you doing, call ${nameof(BulkInsertTable)} manually (MList wont be saved)." + ); + + var list = entities.ToList(); + + var rowNum = BulkInsertTable(list, copyOptions, preSaving, validateFirst, disableIdentity, timeout, message); + + BulkInsertMLists(list, copyOptions, timeout, message); + + return tr.Commit(rowNum); + } + } + + /// Unique key to retrieve ids + /// Optional filter to query only the recently inseted entities + public static int BulkInsertQueryIds(this IEnumerable entities, + Expression> keySelector, + Expression>? isNewPredicate = null, + SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, + bool preSaving = true, + bool validateFirst = true, + int? timeout = null, + string? message = null) + where T : Entity + where K : object + { + using (HeavyProfiler.Log(nameof(BulkInsertQueryIds), () => typeof(T).TypeName())) + using (Transaction tr = new Transaction()) + { + var t = Schema.Current.Table(typeof(T)); + + var list = entities.ToList(); + + if (isNewPredicate == null) + isNewPredicate = GetFilterAutomatic(t); + + var rowNum = BulkInsertTable(list, copyOptions, preSaving, validateFirst, false, timeout, message); + + var dictionary = Database.Query().Where(isNewPredicate).Select(a => KVP.Create(keySelector.Evaluate(a), a.Id)).ToDictionaryEx(); + + var getKeyFunc = keySelector.Compile(); + + list.ForEach(e => + { + e.SetId(dictionary.GetOrThrow(getKeyFunc(e))); + e.SetIsNew(false); + }); + + BulkInsertMLists(list, copyOptions, timeout, message); + + GraphExplorer.CleanModifications(GraphExplorer.FromRoots(list)); + + return tr.Commit(rowNum); + } + } + + static void BulkInsertMLists(List list, SqlBulkCopyOptions options, int? timeout, string? message) where T : Entity + { + var mlistPrs = PropertyRoute.GenerateRoutes(typeof(T), includeIgnored: false).Where(a => a.PropertyRouteType == PropertyRouteType.FieldOrProperty && a.Type.IsMList()).ToList(); + foreach (var pr in mlistPrs) + { + giBulkInsertMListFromEntities.GetInvoker(typeof(T), pr.Type.ElementType()!)(list, pr, options, timeout, message); + } + } + + static Expression> GetFilterAutomatic(Table table) where T : Entity + { + if (table.PrimaryKey.Identity) + { + var max = ExecutionMode.Global().Using(_ => Database.Query().Max(a => (PrimaryKey?)a.Id)); + if (max == null) + return a => true; + + return a => a.Id > max; + } + + var count = ExecutionMode.Global().Using(_ => Database.Query().Count()); + + if (count == 0) + return a => true; + + throw new InvalidOperationException($"Impossible to determine the filter for the IDs query automatically because the table is not Identity and has rows"); + } + + public static int BulkInsertTable(IEnumerable entities, + SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, + bool preSaving = true, + bool validateFirst = true, + bool disableIdentity = false, + int? timeout = null, + string? message = null) + where T : Entity + { + using (HeavyProfiler.Log(nameof(BulkInsertTable), () => typeof(T).TypeName())) + { + + if (message != null) + return SafeConsole.WaitRows(message == "auto" ? $"BulkInsering {entities.Count()} {typeof(T).TypeName()}" : message, + () => BulkInsertTable(entities, copyOptions, preSaving, validateFirst, disableIdentity, timeout, message: null)); + + if (disableIdentity) + copyOptions |= SqlBulkCopyOptions.KeepIdentity; + + if (copyOptions.HasFlag(SqlBulkCopyOptions.UseInternalTransaction)) + throw new InvalidOperationException("BulkInsertDisableIdentity not compatible with UseInternalTransaction"); + + var list = entities.ToList(); + + if (preSaving) + { + Saver.PreSaving(() => GraphExplorer.FromRoots(list)); + } + + if (validateFirst) + { + Validate(list); + } + + var t = Schema.Current.Table(); + bool disableIdentityBehaviour = copyOptions.HasFlag(SqlBulkCopyOptions.KeepIdentity); + bool oldIdentityBehaviour = t.IdentityBehaviour; + + DataTable dt = new DataTable(); + foreach (var c in t.Columns.Values.Where(c => !(c is SystemVersionedInfo.Column) && (disableIdentityBehaviour || !c.IdentityBehaviour))) + dt.Columns.Add(new DataColumn(c.Name, c.Type.UnNullify())); + + if (disableIdentityBehaviour) t.IdentityBehaviour = false; + foreach (var e in list) + { + if (!e.IsNew) + throw new InvalidOperationException("Entites should be new"); + t.SetToStrField(e); + dt.Rows.Add(t.BulkInsertDataRow(e)); + } + if (disableIdentityBehaviour) t.IdentityBehaviour = oldIdentityBehaviour; + + using (Transaction tr = new Transaction()) + { + Schema.Current.OnPreBulkInsert(typeof(T), inMListTable: false); + + Executor.BulkCopy(dt, t.Name, copyOptions, timeout); + + foreach (var item in list) + item.SetNotModified(); + + return tr.Commit(list.Count); + } + } + } + + static void Validate(IEnumerable entities) where T : Entity + { + foreach (var e in entities) + { + var ic = e.FullIntegrityCheck(); + + if (ic != null) + { +#if DEBUG + throw new IntegrityCheckException(ic.WithEntities(GraphExplorer.FromRoots(entities))); +#else + throw new IntegrityCheckException(ic); +#endif + } + } + } + + static readonly GenericInvoker> giBulkInsertMListFromEntities = + new GenericInvoker>((entities, propertyRoute, options, timeout, message) => + BulkInsertMListTablePropertyRoute((List)entities, propertyRoute, options, timeout, message)); + + static int BulkInsertMListTablePropertyRoute(List entities, PropertyRoute route, SqlBulkCopyOptions copyOptions, int? timeout, string? message) + where E : Entity + { + return BulkInsertMListTable(entities, route.GetLambdaExpression>(safeNullAccess: false), copyOptions, timeout, message); + } + + public static int BulkInsertMListTable( + List entities, + Expression>> mListProperty, + SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, + int? timeout = null, + string? message = null) + where E : Entity + { + using (HeavyProfiler.Log(nameof(BulkInsertMListTable), () => $"{mListProperty} ({typeof(E).TypeName()})")) + { + try + { + var func = mListProperty.Compile(); + + var mlistElements = (from e in entities + from mle in func(e).Select((iw, i) => new MListElement + { + Order = i, + Element = iw, + Parent = e, + }) + select mle).ToList(); + + return BulkInsertMListTable(mlistElements, mListProperty, copyOptions, timeout, updateParentTicks: false, message: message); + } + catch (InvalidOperationException e) when (e.Message.Contains("has no Id")) + { + throw new InvalidOperationException($"{nameof(BulkInsertMListTable)} requires that you set the Id of the entities manually using {nameof(UnsafeEntityExtensions.SetId)}"); + + throw; + } + } + } + + public static int BulkInsertMListTable( + this IEnumerable> mlistElements, + Expression>> mListProperty, + SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, + int? timeout = null, + bool? updateParentTicks = null, /*Needed for concurrency and Temporal tables*/ + string? message = null) + where E : Entity + { + using (HeavyProfiler.Log(nameof(BulkInsertMListTable), () => $"{mListProperty} ({typeof(MListElement).TypeName()})")) + { + if (message != null) + return SafeConsole.WaitRows(message == "auto" ? $"BulkInsering MList<{ typeof(V).TypeName()}> in { typeof(E).TypeName()}" : message, + () => BulkInsertMListTable(mlistElements, mListProperty, copyOptions, timeout, updateParentTicks, message: null)); + + if (copyOptions.HasFlag(SqlBulkCopyOptions.UseInternalTransaction)) + throw new InvalidOperationException("BulkInsertDisableIdentity not compatible with UseInternalTransaction"); + + var mlistTable = ((FieldMList)Schema.Current.Field(mListProperty)).TableMList; + + if (updateParentTicks == null) + { + updateParentTicks = mlistTable.PrimaryKey.Type != typeof(Guid) && mlistTable.BackReference.ReferenceTable.Ticks != null; + } + + var maxRowId = updateParentTicks.Value ? Database.MListQuery(mListProperty).Max(a => (PrimaryKey?)a.RowId) : null; + + DataTable dt = new DataTable(); + + foreach (var c in mlistTable.Columns.Values.Where(c => !(c is SystemVersionedInfo.Column) && !c.IdentityBehaviour)) + dt.Columns.Add(new DataColumn(c.Name, c.Type.UnNullify())); + + var list = mlistElements.ToList(); + + foreach (var e in list) + { + dt.Rows.Add(mlistTable.BulkInsertDataRow(e.Parent, e.Element, e.Order)); + } + + using (Transaction tr = new Transaction()) + { + Schema.Current.OnPreBulkInsert(typeof(E), inMListTable: true); + + Executor.BulkCopy(dt, mlistTable.Name, copyOptions, timeout); + + var result = list.Count; + + if (updateParentTicks.Value) + { + Database.MListQuery(mListProperty) + .Where(a => maxRowId == null || a.RowId > maxRowId) + .Select(a => a.Parent) + .UnsafeUpdate() + .Set(e => e.Ticks, a => TimeZoneManager.Now.Ticks) + .Execute(); + } + + return tr.Commit(result); + } + } + } + + public static int BulkInsertView(this IEnumerable entities, + SqlBulkCopyOptions copyOptions = SqlBulkCopyOptions.Default, + int? timeout = null, + string? message = null) + where T : IView + { + using (HeavyProfiler.Log(nameof(BulkInsertView), () => typeof(T).Name)) + { + if (message != null) + return SafeConsole.WaitRows(message == "auto" ? $"BulkInsering {entities.Count()} {typeof(T).TypeName()}" : message, + () => BulkInsertView(entities, copyOptions, timeout, message: null)); + + if (copyOptions.HasFlag(SqlBulkCopyOptions.UseInternalTransaction)) + throw new InvalidOperationException("BulkInsertDisableIdentity not compatible with UseInternalTransaction"); + + var t = Schema.Current.View(); + + var list = entities.ToList(); + + bool disableIdentityBehaviour = copyOptions.HasFlag(SqlBulkCopyOptions.KeepIdentity); + + DataTable dt = new DataTable(); + foreach (var c in t.Columns.Values) + dt.Columns.Add(new DataColumn(c.Name, c.Type.UnNullify())); + + foreach (var e in entities) + { + dt.Rows.Add(t.BulkInsertDataRow(e)); + } + + using (Transaction tr = new Transaction()) + { + Schema.Current.OnPreBulkInsert(typeof(T), inMListTable: false); + + Executor.BulkCopy(dt, t.Name, copyOptions, timeout); + + return tr.Commit(list.Count); + } + } + } + } + + public class BulkSetterOptions + { + public SqlBulkCopyOptions CopyOptions = SqlBulkCopyOptions.Default; + public bool ValidateFirst = false; + public bool DisableIdentity = false; + public int? Timeout = null; + } + + + public class BulkSetterTableOptionsT + { + public SqlBulkCopyOptions CopyOptions = SqlBulkCopyOptions.Default; + public bool ValidateFirst = false; + public bool DisableIdentity = false; + public int? Timeout = null; + } + + public class BulkSetterMListOptions + { + public SqlBulkCopyOptions CopyOptions = SqlBulkCopyOptions.Default; + public int? Timeout = null; + } +} diff --git a/Signum.Engine/CodeGeneration/CodeGenerator.cs b/Signum.Engine/CodeGeneration/CodeGenerator.cs index b5fc250051..c97c2e15cf 100644 --- a/Signum.Engine/CodeGeneration/CodeGenerator.cs +++ b/Signum.Engine/CodeGeneration/CodeGenerator.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; @@ -63,27 +63,23 @@ public static IEnumerable GetModules(Dictionary types, strin if (selected.IsNullOrEmpty()) yield break; - string moduleName = GetDefaultModuleName(selected, solutionName); + string? moduleName = GetDefaultModuleName(selected, solutionName); SafeConsole.WriteColor(ConsoleColor.Gray, $"Module name? ([Enter] for '{moduleName}'):"); - moduleName = Console.ReadLine().DefaultText(moduleName); + moduleName = Console.ReadLine().DefaultText(moduleName!); - yield return new Module - { - ModuleName = moduleName, - Types = selected.ToList() - }; + yield return new Module(moduleName, selected.ToList()); types.SetRange(selected, a => a, a => true); } } - public static string GetDefaultModuleName(Type[] selected, string solutionName) + public static string? GetDefaultModuleName(Type[] selected, string solutionName) { StringDistance sd = new StringDistance(); - string name = null; + string? name = null; foreach (var item in selected) { if (name == null) @@ -99,7 +95,7 @@ public static string GetDefaultModuleName(Type[] selected, string solutionName) } } - return name.Trim('.'); + return name?.Trim('.'); } } @@ -107,5 +103,11 @@ public class Module { public string ModuleName; public List Types; + + public Module(string moduleName, List types) + { + ModuleName = moduleName; + Types = types; + } } } diff --git a/Signum.Engine/CodeGeneration/EntityCodeGenerator.cs b/Signum.Engine/CodeGeneration/EntityCodeGenerator.cs index e913aeb054..c8d9d4b39c 100644 --- a/Signum.Engine/CodeGeneration/EntityCodeGenerator.cs +++ b/Signum.Engine/CodeGeneration/EntityCodeGenerator.cs @@ -16,13 +16,13 @@ namespace Signum.Engine.CodeGeneration { public class EntityCodeGenerator { - public string SolutionName; - public string SolutionFolder; + public string SolutionName = null!; + public string SolutionFolder = null!; - public Dictionary Tables; - public DirectedGraph InverseGraph; + public Dictionary Tables = null!; + public DirectedGraph InverseGraph = null!; - public Schema CurrentSchema; + public Schema CurrentSchema = null!; public virtual void GenerateEntitiesFromDatabaseTables() { @@ -46,8 +46,7 @@ public virtual void GenerateEntitiesFromDatabaseTables() foreach (var gr in tables.GroupBy(t => GetFileName(t))) { - string str = WriteFile(gr.Key, gr); - + string? str = WriteFile(gr.Key, gr); if (str != null) { string fileName = Path.Combine(projectFolder, gr.Key); @@ -92,7 +91,7 @@ protected virtual string GetFileName(DiffTable t) return name + ".cs"; } - protected virtual string WriteFile(string fileName, IEnumerable tables) + protected virtual string? WriteFile(string fileName, IEnumerable tables) { StringBuilder sb = new StringBuilder(); foreach (var item in GetUsingNamespaces(fileName, tables)) @@ -164,7 +163,7 @@ protected virtual string GetNamespace(string fileName) { var result = SolutionName + ".Entities"; - string folder = fileName.TryBeforeLast('\\'); + string? folder = fileName.TryBeforeLast('\\'); if (folder != null) result += "." + folder.Replace('\\', '.'); @@ -180,7 +179,7 @@ protected virtual void WriteAttributeTag(StringBuilder sb, IEnumerable a } } - protected virtual string WriteTableEntity(string fileName, DiffTable table) + protected virtual string? WriteTableEntity(string fileName, DiffTable table) { var mListInfo = GetMListInfo(table); @@ -211,7 +210,7 @@ protected virtual string WriteEntity(string fileName, DiffTable table) sb.AppendLine("public class {0} : {1}".FormatWith(name, GetEntityBaseClass(table.Name))); sb.AppendLine("{"); - string multiColumnIndexComment = WriteMultiColumnIndexComment(table, name); + string? multiColumnIndexComment = WriteMultiColumnIndexComment(table, name); if (multiColumnIndexComment != null) { sb.Append(multiColumnIndexComment.Indent(4)); @@ -258,7 +257,7 @@ group col by GetEmbeddedField(table, col) into g } } - string toString = WriteToString(table); + string? toString = WriteToString(table); if (toString != null) { sb.Append(toString.Indent(4)); @@ -278,7 +277,7 @@ group col by GetEmbeddedField(table, col) into g } } - string operations = WriteOperations(table); + string? operations = WriteOperations(table); if (operations != null) { sb.Append(operations); @@ -287,7 +286,7 @@ group col by GetEmbeddedField(table, col) into g return sb.ToString(); } - protected virtual string GetEmbeddedField(DiffTable table, DiffColumn col) + protected virtual string? GetEmbeddedField(DiffTable table, DiffColumn col) { return null; } @@ -299,7 +298,7 @@ protected virtual string WriteEmbeddedEntity(string fileName, DiffTable table, s sb.AppendLine("public class {0} : {1}".FormatWith(name, typeof(EmbeddedEntity).Name)); sb.AppendLine("{"); - string multiColumnIndexComment = WriteMultiColumnIndexComment(table, name); + string? multiColumnIndexComment = WriteMultiColumnIndexComment(table, name); if (multiColumnIndexComment != null) { sb.Append(multiColumnIndexComment.Indent(4)); @@ -367,13 +366,11 @@ protected virtual List GetEnumAttributes(DiffTable table) { List atts = new List(); - string tableNameAttribute = GetTableNameAttribute(table.Name, null); - + string? tableNameAttribute = GetTableNameAttribute(table.Name, null); if (tableNameAttribute != null) atts.Add(tableNameAttribute); - string primaryKeyAttribute = GetPrimaryKeyAttribute(table); - + string? primaryKeyAttribute = GetPrimaryKeyAttribute(table); if (primaryKeyAttribute != null) atts.Add(primaryKeyAttribute); @@ -400,7 +397,7 @@ protected virtual bool IsEnum(DiffTable objectName) return false; } - protected virtual string WriteMultiColumnIndexComment(DiffTable table, string name) + protected virtual string? WriteMultiColumnIndexComment(DiffTable table, string name) { StringBuilder sb = new StringBuilder(); foreach (var ix in table.Indices.Values.Where(ix => ix.Columns.Count > 1 || ix.FilterDefinition.HasText() || ix.Columns.Any(ic => ic.IsIncluded))) @@ -413,13 +410,13 @@ protected virtual string WriteMultiColumnIndexComment(DiffTable table, string na sb.AppendLine("//Add to Logic class"); sb.AppendLine("//sb.AddUniqueIndex<{0}>({1});".FormatWith(name, - new object[] { columns, ix.FilterDefinition, incColumns }.NotNull().ToString(", "))); + new object?[] { columns, ix.FilterDefinition, incColumns }.NotNull().ToString(", "))); } - return sb.ToString().DefaultText(null); + return sb.ToString().DefaultText(null!); } - protected virtual string WriteOperations(DiffTable table) + protected virtual string? WriteOperations(DiffTable table) { var kind = GetEntityKind(table); if (!(kind == EntityKind.Main || kind == EntityKind.Shared || kind == EntityKind.String)) @@ -439,7 +436,7 @@ protected virtual string GetOperationName(DiffTable objectName) return GetEntityName(objectName).RemoveSuffix("Entity") + "Operation"; } - protected virtual MListInfo GetMListInfo(DiffTable table) + protected virtual MListInfo? GetMListInfo(DiffTable table) { if (this.InverseGraph.RelatedTo(table).Any()) return null; @@ -458,12 +455,12 @@ protected virtual MListInfo GetMListInfo(DiffTable table) }; } - protected virtual DiffColumn GetMListTrivialElementColumn(DiffTable table, DiffColumn parentColumn, DiffColumn orderColumn) + protected virtual DiffColumn GetMListTrivialElementColumn(DiffTable table, DiffColumn parentColumn, DiffColumn? orderColumn) { return table.Columns.Values.Where(c => c != parentColumn && c != orderColumn && !c.PrimaryKey).Only(); } - protected virtual DiffColumn GetMListOrderColumn(DiffTable table) + protected virtual DiffColumn? GetMListOrderColumn(DiffTable table) { return table.Columns.TryGetC("Order") ?? table.Columns.TryGetC("Row") ?? table.Columns.TryGetC("Index"); } @@ -478,15 +475,15 @@ protected virtual IEnumerable GetEntityAttributes(DiffTable table) atts.Add("EntityKind(EntityKind." + GetEntityKind(table) + ", EntityData." + GetEntityData(table) + ")"); - string tableNameAttribute = GetTableNameAttribute(table.Name, null); + string? tableNameAttribute = GetTableNameAttribute(table.Name, null); if (tableNameAttribute != null) atts.Add(tableNameAttribute); - string primaryKeyAttribute = GetPrimaryKeyAttribute(table); + string? primaryKeyAttribute = GetPrimaryKeyAttribute(table); if (primaryKeyAttribute != null) atts.Add(primaryKeyAttribute); - string ticksColumnAttribute = GetTicksColumnAttribute(table); + string? ticksColumnAttribute = GetTicksColumnAttribute(table); if (ticksColumnAttribute != null) atts.Add(ticksColumnAttribute); @@ -499,7 +496,7 @@ protected virtual string GetTicksColumnAttribute(DiffTable table) } - protected virtual string GetPrimaryKeyAttribute(DiffTable table) + protected virtual string? GetPrimaryKeyAttribute(DiffTable table) { DiffColumn primaryKey = GetPrimaryKeyColumn(table); @@ -537,7 +534,7 @@ protected virtual DiffColumn GetPrimaryKeyColumn(DiffTable table) return table.Columns.Values.SingleOrDefaultEx(a => a.PrimaryKey); } - protected virtual string GetTableNameAttribute(ObjectName objectName, MListInfo mListInfo) + protected virtual string? GetTableNameAttribute(ObjectName objectName, MListInfo? mListInfo) { StringBuilder sb = new StringBuilder(); sb.Append("TableName(\"" + objectName.Name + "\""); @@ -583,7 +580,7 @@ protected virtual string GetEntityBaseClass(ObjectName objectName) protected virtual string WriteField(string fileName, DiffTable table, DiffColumn col) { - string relatedEntity = GetRelatedEntity(table, col); + string? relatedEntity = GetRelatedEntity(table, col); string type = GetFieldType(table, col, relatedEntity); @@ -598,7 +595,7 @@ protected virtual string WriteField(string fileName, DiffTable table, DiffColumn return sb.ToString(); } - protected virtual string GetRelatedEntity(DiffTable table, DiffColumn col) + protected virtual string? GetRelatedEntity(DiffTable table, DiffColumn col) { if (col.ForeignKey == null) return null; @@ -611,21 +608,21 @@ protected virtual bool IsReadonly(DiffTable table, DiffColumn col) return false; } - protected virtual IEnumerable GetPropertyAttributes(DiffTable table, DiffColumn col, string relatedEntity) + protected virtual IEnumerable GetPropertyAttributes(DiffTable table, DiffColumn col, string? relatedEntity) { List attributes = new List(); if (RequiresNotNullableAttribute(col, relatedEntity) && GetValueType(col) != typeof(string)) attributes.Add("NotNullValidator"); - string stringLengthValidator = GetStringLengthValidator(table, col, relatedEntity); + string? stringLengthValidator = GetStringLengthValidator(table, col, relatedEntity); if(stringLengthValidator != null) attributes.Add(stringLengthValidator); return attributes; } - protected virtual string GetStringLengthValidator(DiffTable table, DiffColumn col, string relatedEntity) + protected virtual string? GetStringLengthValidator(DiffTable table, DiffColumn col, string? relatedEntity) { if (GetValueType(col) != typeof(string)) return null; @@ -649,7 +646,7 @@ protected virtual string GetStringLengthValidator(DiffTable table, DiffColumn co return 1; } - protected virtual bool RequiresNotNullableAttribute(DiffColumn col, string relatedEntity) + protected virtual bool RequiresNotNullableAttribute(DiffColumn col, string? relatedEntity) { return !col.Nullable && (relatedEntity != null || GetValueType(col).IsClass); } @@ -670,7 +667,7 @@ protected virtual string GetFieldName(DiffTable table, DiffColumn col) return name.FirstLower(); } - protected virtual IEnumerable GetFieldAttributes(DiffTable table, DiffColumn col, string relatedEntity, bool isMList) + protected virtual IEnumerable GetFieldAttributes(DiffTable table, DiffColumn col, string? relatedEntity, bool isMList) { List attributes = new List(); @@ -679,8 +676,7 @@ protected virtual IEnumerable GetFieldAttributes(DiffTable table, DiffCo if (col.ForeignKey == null) { - string sqlDbType = GetSqlTypeAttribute(table, col); - + string? sqlDbType = GetSqlTypeAttribute(table, col); if (sqlDbType != null) attributes.Add(sqlDbType); } @@ -723,7 +719,7 @@ protected virtual string DefaultColumnName(DiffTable table, DiffColumn col) return fieldName + "ID"; } - protected virtual string GetSqlTypeAttribute(DiffTable table, DiffColumn col) + protected virtual string? GetSqlTypeAttribute(DiffTable table, DiffColumn col) { Type type = GetValueType(col); List parts = GetSqlDbTypeParts(col, type); @@ -780,7 +776,7 @@ protected virtual string CleanDefault(string def) return def; } - protected virtual string GetFieldType(DiffTable table, DiffColumn col, string relatedEntity) + protected virtual string GetFieldType(DiffTable table, DiffColumn col, string? relatedEntity) { if (relatedEntity != null) { @@ -872,25 +868,25 @@ protected virtual string WriteFieldMList(string fileName, DiffTable table, MList } else { - string relatedEntity = GetRelatedEntity(relatedTable, mListInfo.TrivialElementColumn); + string relatedEntity = GetRelatedEntity(relatedTable, mListInfo.TrivialElementColumn)!; type = GetFieldType(relatedTable, mListInfo.TrivialElementColumn, relatedEntity); fieldAttributes = GetFieldAttributes(relatedTable, mListInfo.TrivialElementColumn, relatedEntity, isMList: true).ToList(); } - var preserveOrder = GetPreserveOrderAttribute(mListInfo); + string? preserveOrder = GetPreserveOrderAttribute(mListInfo); if (preserveOrder != null) fieldAttributes.Add(preserveOrder); - string primaryKey = GetPrimaryKeyAttribute(relatedTable); + string? primaryKey = GetPrimaryKeyAttribute(relatedTable); if (primaryKey != null) fieldAttributes.Add(primaryKey); - string tableName = GetTableNameAttribute(relatedTable.Name, mListInfo); + string? tableName = GetTableNameAttribute(relatedTable.Name, mListInfo); if (tableName != null) fieldAttributes.Add(tableName); - string backColumn = GetBackColumnNameAttribute(mListInfo.BackReferenceColumn); + string? backColumn = GetBackColumnNameAttribute(mListInfo.BackReferenceColumn); if (backColumn != null) fieldAttributes.AddRange(backColumn); @@ -904,7 +900,7 @@ protected virtual string WriteFieldMList(string fileName, DiffTable table, MList return sb.ToString(); } - protected virtual string GetPreserveOrderAttribute(MListInfo mListInfo) + protected virtual string? GetPreserveOrderAttribute(MListInfo mListInfo) { if(mListInfo.PreserveOrderColumn == null) return null; @@ -920,7 +916,7 @@ protected virtual string GetPreserveOrderAttribute(MListInfo mListInfo) return @"PreserveOrder({0})".FormatWith(parts.ToString(", ")); } - protected virtual string GetBackColumnNameAttribute(DiffColumn backReference) + protected virtual string? GetBackColumnNameAttribute(DiffColumn backReference) { if (backReference.Name == "ParentID") return null; @@ -933,7 +929,7 @@ protected virtual string GetFieldMListName(DiffTable table, DiffTable relatedTab return NaturalLanguageTools.Pluralize(relatedTable.Name.Name.RemovePrefix(table.Name.Name)); } - protected virtual string WriteToString(DiffTable table) + protected virtual string? WriteToString(DiffTable table) { var toStringColumn = GetToStringColumn(table); if (toStringColumn == null) @@ -972,7 +968,7 @@ public MListInfo(DiffColumn backReferenceColumn) } public readonly DiffColumn BackReferenceColumn; - public DiffColumn TrivialElementColumn; - public DiffColumn PreserveOrderColumn; + public DiffColumn? TrivialElementColumn; + public DiffColumn? PreserveOrderColumn; } } diff --git a/Signum.Engine/CodeGeneration/LogicCodeGenerator.cs b/Signum.Engine/CodeGeneration/LogicCodeGenerator.cs index 683d19bab6..b58f51cc8c 100644 --- a/Signum.Engine/CodeGeneration/LogicCodeGenerator.cs +++ b/Signum.Engine/CodeGeneration/LogicCodeGenerator.cs @@ -15,10 +15,10 @@ namespace Signum.Engine.CodeGeneration { public class LogicCodeGenerator { - public string SolutionName; - public string SolutionFolder; + public string SolutionName = null!; + public string SolutionFolder = null!; - public Schema CurrentSchema; + public Schema CurrentSchema = null!; protected bool? overwriteFiles = null; @@ -165,7 +165,7 @@ protected virtual string WriteStartMethod(Module mod, List expre sb.AppendLine(); } - string query = WriteQuery(item); + string? query = WriteQuery(item); if (query != null) { sb.Append(query.Indent(8)); @@ -234,7 +234,7 @@ private bool IsSimpleExpression(ExpressionInfo exp, Type type) return !exp.IsUnique && type == exp.ToType; } - protected virtual string WriteQuery(Type type) + protected virtual string? WriteQuery(Type type) { if (ShouldWriteSimpleQuery(type)) return null; @@ -276,9 +276,17 @@ protected internal class ExpressionInfo public Type FromType; public Type ToType; public PropertyInfo Property; - public string Name; - public string ExpressionName; public bool IsUnique; + public string? Name; + public string? ExpressionName; + + public ExpressionInfo(Type fromType, Type toType, PropertyInfo property, bool isUnique) + { + FromType = fromType; + ToType = toType; + Property = property; + IsUnique = isUnique; + } } protected virtual List GetExpressions(Type toType) @@ -289,20 +297,14 @@ where fromType.IsEntity() && !fromType.IsAbstract let fi = Reflector.TryFindFieldInfo(toType, pi) where fi != null let isUnique = fi.GetCustomAttribute() != null - select new ExpressionInfo - { - ToType = toType, - FromType = fromType, - Property = pi, - IsUnique = isUnique, - }).ToList(); + select new ExpressionInfo(fromType, toType, pi, isUnique)) + .ToList(); foreach (var ei in result) { ei.Name = GetExpressionName(ei); } - - + result = result.GroupBy(ei => new { ei.FromType, ei.ToType }).Where(g => g.Count() == 1).SelectMany(g => g).ToList(); result = result.Where(ShouldWriteExpression).ToList(); @@ -391,18 +393,18 @@ orderby p.Name.Contains("Name") ? 1 : 2 select p).Take(10); } - protected virtual string GetWithVirtualMLists(Type type) + protected virtual string? GetWithVirtualMLists(Type type) { return (from p in Reflector.PublicInstancePropertiesInOrder(type) let bp = GetVirtualMListBackReference(p) where bp != null - select GetWithVirtualMList(type, p, bp)).ToString("\r\n").DefaultText(null); + select GetWithVirtualMList(type, p, bp)).ToString("\r\n").DefaultText(null!); } protected virtual string GetWithVirtualMList(Type type, PropertyInfo p, PropertyInfo bp) { var p1 = GetVariableName(type); - var p2 = GetVariableName(p.PropertyType.ElementType()); + var p2 = GetVariableName(p.PropertyType.ElementType()!); if (p1 == p2) p2 += "2"; @@ -411,12 +413,12 @@ protected virtual string GetWithVirtualMList(Type type, PropertyInfo p, Property return $" .WithVirtualMList({p1} => {p1}.{p.Name}, {p2} => {cast}{p2}.{bp.Name})"; } - protected virtual PropertyInfo GetVirtualMListBackReference(PropertyInfo pi) + protected virtual PropertyInfo? GetVirtualMListBackReference(PropertyInfo pi) { if (!pi.PropertyType.IsMList()) return null; - if (!pi.PropertyType.ElementType().IsEntity()) + if (!pi.PropertyType.ElementType()!.IsEntity()) return null; if (!pi.HasAttribute()) @@ -445,7 +447,7 @@ protected virtual bool IsVirtualMListBackReference(PropertyInfo pi, Type targetT protected virtual bool IsSimpleValueType(Type type) { - var t = CurrentSchema.Settings.GetSqlDbTypePair(type.UnNullify()); + var t = CurrentSchema.Settings.TryGetSqlDbTypePair(type.UnNullify()); return t != null && t.UserDefinedTypeName == null && t.SqlDbType != SqlDbType.Image && t.SqlDbType != SqlDbType.VarBinary; } @@ -455,7 +457,7 @@ protected virtual string WriteOperations(Type type) StringBuilder sb = new StringBuilder(); foreach (var oper in GetOperationsSymbols(type)) { - string operation = WriteOperation(oper); + string? operation = WriteOperation(oper); if (operation != null) { sb.Append(operation); @@ -465,7 +467,7 @@ protected virtual string WriteOperations(Type type) return sb.ToString(); } - protected virtual string WriteOperation(IOperationSymbolContainer oper) + protected virtual string? WriteOperation(IOperationSymbolContainer oper) { switch (GetOperationType(oper)) @@ -538,7 +540,7 @@ protected virtual bool IsSave(IOperationSymbolContainer oper) return oper.ToString().Contains("Save"); ; } - protected virtual string WriteDeleteOperation(IOperationSymbolContainer oper) + protected virtual string? WriteDeleteOperation(IOperationSymbolContainer oper) { if (ShouldWriteSimpleOperations(oper)) return null; diff --git a/Signum.Engine/Connection/Executor.cs b/Signum.Engine/Connection/Executor.cs index a15d55a3b9..79d19dc694 100644 --- a/Signum.Engine/Connection/Executor.cs +++ b/Signum.Engine/Connection/Executor.cs @@ -10,17 +10,16 @@ namespace Signum.Engine { public static class Executor { - public static object ExecuteScalar(string sql, List? parameters = null, CommandType commandType = CommandType.Text) + public static object? ExecuteScalar(string sql, List? parameters = null, CommandType commandType = CommandType.Text) { return Connector.Current.ExecuteScalar(new SqlPreCommandSimple(sql, parameters), commandType); } - public static object ExecuteScalar(this SqlPreCommandSimple preCommand, CommandType commandType = CommandType.Text) + public static object? ExecuteScalar(this SqlPreCommandSimple preCommand, CommandType commandType = CommandType.Text) { return Connector.Current.ExecuteScalar(preCommand, commandType); } - - + public static int ExecuteNonQuery(string sql, List? parameters = null, CommandType commandType = CommandType.Text) { return Connector.Current.ExecuteNonQuery(new SqlPreCommandSimple(sql, parameters), commandType); diff --git a/Signum.Engine/Connection/FieldReader.cs b/Signum.Engine/Connection/FieldReader.cs index c6598efe38..92b1aeb482 100644 --- a/Signum.Engine/Connection/FieldReader.cs +++ b/Signum.Engine/Connection/FieldReader.cs @@ -61,7 +61,7 @@ public bool IsNull(int ordinal) return reader.IsDBNull(ordinal); } - public string GetString(int ordinal) + public string? GetString(int ordinal) { LastOrdinal = ordinal; if (reader.IsDBNull(ordinal)) @@ -96,7 +96,7 @@ public string GetString(int ordinal) } } - public byte[] GetByteArray(int ordinal) + public byte[]? GetByteArray(int ordinal) { LastOrdinal = ordinal; if (reader.IsDBNull(ordinal)) @@ -526,7 +526,7 @@ public T GetUdt(int ordinal) LastOrdinal = ordinal; if (reader.IsDBNull(ordinal)) { - return (T)(object)null; + return (T)(object)null!; } var udt = Activator.CreateInstance(); @@ -542,8 +542,7 @@ public T GetUdt(int ordinal) public static Expression GetExpression(Expression reader, int ordinal, Type type) { - MethodInfo mi = methods.TryGetC(type); - + MethodInfo? mi = methods.TryGetC(type); if (mi != null) return Expression.Call(reader, mi, Expression.Constant(ordinal)); @@ -579,7 +578,12 @@ internal FieldReaderException CreateFieldReaderException(Exception ex) [Serializable] public class FieldReaderException : SqlTypeException { - public FieldReaderException(Exception inner) : base(null, inner) { } + public FieldReaderException(Exception inner, int ordinal, string columnName, Type columnType) : base(null, inner) + { + this.Ordinal = ordinal; + this.ColumnName = columnName; + this.ColumnType = columnType; + } protected FieldReaderException( System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) @@ -609,7 +613,7 @@ public override string Message public string ColumnName { get; internal set; } public Type ColumnType { get; internal set; } public int Row { get; internal set; } - public SqlPreCommand Command { get; internal set; } - public LambdaExpression Projector { get; internal set; } + public SqlPreCommand? Command { get; internal set; } + public LambdaExpression? Projector { get; internal set; } } } diff --git a/Signum.Engine/Connection/Transaction.cs b/Signum.Engine/Connection/Transaction.cs index a7379564f8..7072f7482b 100644 --- a/Signum.Engine/Connection/Transaction.cs +++ b/Signum.Engine/Connection/Transaction.cs @@ -17,30 +17,30 @@ namespace Signum.Engine /// public class Transaction : IDisposableException { - static readonly Variable> currents = Statics.ThreadVariable>("transactions", avoidExportImport: true); + static readonly Variable?> currents = Statics.ThreadVariable?>("transactions", avoidExportImport: true); bool commited; ICoreTransaction coreTransaction; interface ICoreTransaction { - event Action> PostRealCommit; + event Action?> PostRealCommit; void CallPostRealCommit(); - event Action> PreRealCommit; - DbConnection Connection { get; } - DbTransaction Transaction { get; } + event Action?> PreRealCommit; + DbConnection? Connection { get; } + DbTransaction? Transaction { get; } bool Started { get; } - Exception IsRolledback { get; } + Exception? IsRolledback { get; } void Rollback(Exception ex); - event Action> Rolledback; + event Action?> Rolledback; void Commit(); void Finish(); void Start(); - ICoreTransaction Parent { get; } + ICoreTransaction? Parent { get; } Dictionary UserData { get; } } @@ -51,27 +51,30 @@ class FakedTransaction : ICoreTransaction public FakedTransaction(ICoreTransaction parent) { + if (parent == null) + throw new ArgumentNullException(nameof(parent)); + if (parent != null && parent.IsRolledback != null) throw new InvalidOperationException("The transaction can not be created because a parent transaction is rolled back. Exception:\r\n\t" + parent.IsRolledback.Message, parent.IsRolledback); this.parent = parent; } - public event Action> PostRealCommit + public event Action?> PostRealCommit { add { parent.PostRealCommit += value; } remove { parent.PostRealCommit -= value; } } - public event Action> PreRealCommit + public event Action?> PreRealCommit { add { parent.PreRealCommit += value; } remove { parent.PreRealCommit -= value; } } - public DbConnection Connection { get { return parent.Connection; } } - public DbTransaction Transaction { get { return parent.Transaction; } } - public Exception IsRolledback { get { return parent.IsRolledback; } } + public DbConnection? Connection { get { return parent.Connection; } } + public DbTransaction? Transaction { get { return parent.Transaction; } } + public Exception? IsRolledback { get { return parent.IsRolledback; } } public bool Started { get { return parent.Started; } } public void Start() { parent.Start(); } @@ -95,12 +98,12 @@ public void CallPostRealCommit() } - public ICoreTransaction Parent + public ICoreTransaction? Parent { get { return parent; } } - public event Action> Rolledback + public event Action?> Rolledback { add { parent.Rolledback += value; } remove { parent.Rolledback -= value; } @@ -109,19 +112,19 @@ public event Action> Rolledback class RealTransaction : ICoreTransaction { - ICoreTransaction parent; + ICoreTransaction? parent; - public DbConnection Connection { get; private set; } - public DbTransaction Transaction { get; private set; } - public Exception IsRolledback { get; private set; } + public DbConnection? Connection { get; private set; } + public DbTransaction? Transaction { get; private set; } + public Exception? IsRolledback { get; private set; } public bool Started { get; private set; } - public event Action> PostRealCommit; - public event Action> PreRealCommit; - public event Action> Rolledback; + public event Action?> PostRealCommit; + public event Action?> PreRealCommit; + public event Action?> Rolledback; IsolationLevel? IsolationLevel; - public RealTransaction(ICoreTransaction parent, IsolationLevel? isolationLevel) + public RealTransaction(ICoreTransaction? parent, IsolationLevel? isolationLevel) { IsolationLevel = isolationLevel; this.parent = parent; @@ -145,7 +148,7 @@ public virtual void Commit() { OnPreRealCommit(); - Transaction.Commit(); + Transaction!.Commit(); } } @@ -176,7 +179,7 @@ public void Rollback(Exception ex) { if (Started && IsRolledback == null) { - Transaction.Rollback(); + Transaction!.Rollback(); IsRolledback = ex; Rolledback?.Invoke(this.userData); } @@ -197,13 +200,13 @@ public virtual void Finish() } } - Dictionary userData; + Dictionary? userData; public Dictionary UserData { get { return userData ?? (userData = new Dictionary()); } } - public ICoreTransaction Parent + public ICoreTransaction? Parent { get { return parent; } } @@ -214,19 +217,19 @@ class NamedTransaction : ICoreTransaction { ICoreTransaction parent; string savePointName; - public Exception IsRolledback { get; private set; } + public Exception? IsRolledback { get; private set; } public bool Started { get; private set; } - public event Action> PostRealCommit; + public event Action?> PostRealCommit; - public event Action> PreRealCommit; - public event Action> Rolledback; + public event Action?> PreRealCommit; + public event Action?> Rolledback; public NamedTransaction(ICoreTransaction parent, string savePointName) { if (parent == null) throw new InvalidOperationException("Named transactions should be nested inside another transaction"); - if (parent != null && parent.IsRolledback != null) + if (parent.IsRolledback != null) throw new InvalidOperationException("The transaction can not be created because a parent transaction is rolled back. Exception:\r\n\t" + parent.IsRolledback.Message, parent.IsRolledback); this.parent = parent; @@ -234,15 +237,15 @@ public NamedTransaction(ICoreTransaction parent, string savePointName) } - public DbConnection Connection { get { return parent.Connection; } } - public DbTransaction Transaction { get { return parent.Transaction; } } + public DbConnection? Connection { get { return parent.Connection; } } + public DbTransaction? Transaction { get { return parent.Transaction; } } public void Start() { if (!Started) { parent.Start(); - Connector.Current.SaveTransactionPoint(Transaction, savePointName); + Connector.Current.SaveTransactionPoint(Transaction!, savePointName); Started = true; } } @@ -251,7 +254,7 @@ public void Rollback(Exception ex) { if (Started && IsRolledback == null) { - Connector.Current.RollbackTransactionPoint(Transaction, savePointName); + Connector.Current.RollbackTransactionPoint(Transaction!, savePointName); IsRolledback = ex; Rolledback?.Invoke(this.UserData); } @@ -274,13 +277,13 @@ public void CallPostRealCommit() public void Finish() { } - Dictionary userData; + Dictionary? userData; public Dictionary UserData { get { return userData ?? (userData = new Dictionary()); } } - public ICoreTransaction Parent + public ICoreTransaction? Parent { get { return parent; } } @@ -288,17 +291,17 @@ public ICoreTransaction Parent class NoneTransaction : ICoreTransaction { - ICoreTransaction parent; + ICoreTransaction? parent; - public DbConnection Connection { get; private set; } - public DbTransaction Transaction { get { return null; } } - public Exception IsRolledback { get; private set; } + public DbConnection? Connection { get; private set; } + public DbTransaction? Transaction { get { return null; } } + public Exception? IsRolledback { get; private set; } public bool Started { get; private set; } - public event Action> PostRealCommit; - public event Action> PreRealCommit; - public event Action> Rolledback; + public event Action?> PostRealCommit; + public event Action?> PreRealCommit; + public event Action?> Rolledback; - public NoneTransaction(ICoreTransaction parent) + public NoneTransaction(ICoreTransaction? parent) { this.parent = parent; } @@ -368,13 +371,13 @@ public void Finish() } } - Dictionary userData; + Dictionary? userData; public Dictionary UserData { get { return userData ?? (userData = new Dictionary()); } } - public ICoreTransaction Parent + public ICoreTransaction? Parent { get { return parent; } } @@ -390,7 +393,7 @@ public static bool InTestTransaction class TestTransaction : RealTransaction { bool oldTestTransaction; - public TestTransaction(ICoreTransaction parent, IsolationLevel? isolation) + public TestTransaction(ICoreTransaction? parent, IsolationLevel? isolation) : base(parent, isolation) { oldTestTransaction = inTestTransaction.Value; @@ -413,19 +416,18 @@ public Transaction() { } - Transaction(Func factory) + Transaction(Func factory) { - if (currents.Value == null) - currents.Value = new Dictionary(); + var dic = currents.Value ??= new Dictionary(); Connector bc = Connector.Current; if (bc == null) throw new InvalidOperationException("ConnectionScope.Current not established. Use ConnectionScope.Default to set it."); - ICoreTransaction parent = currents.Value.TryGetC(bc); + ICoreTransaction? parent = dic.TryGetC(bc); - currents.Value[bc] = coreTransaction = factory(parent); + dic[bc] = coreTransaction = factory(parent); } public static Transaction None() @@ -435,7 +437,7 @@ public static Transaction None() public static Transaction NamedSavePoint(string savePointName) { - return new Transaction(parent => new NamedTransaction(parent, savePointName)); + return new Transaction(parent => new NamedTransaction(parent!, savePointName)); } @@ -450,14 +452,14 @@ public static T ForceNew(Func func) public static Transaction ForceNew() { return new Transaction(parent => inTestTransaction.Value ? - (ICoreTransaction)new FakedTransaction(parent) : + (ICoreTransaction)new FakedTransaction(parent!) : (ICoreTransaction)new RealTransaction(parent, null)); } public static Transaction ForceNew(IsolationLevel? isolationLevel) { return new Transaction(parent => inTestTransaction.Value ? - (ICoreTransaction)new FakedTransaction(parent) : + (ICoreTransaction)new FakedTransaction(parent!) : (ICoreTransaction)new RealTransaction(parent, isolationLevel)); } @@ -473,7 +475,7 @@ public static Transaction Test(IsolationLevel? isolationLevel) static ICoreTransaction GetCurrent() { - return currents.Value.GetOrThrow(Connector.Current, "No Transaction created yet"); + return currents.Value!.GetOrThrow(Connector.Current, "No Transaction created yet"); } public static event Action> PostRealCommit @@ -506,10 +508,10 @@ public static Dictionary TopParentUserData() public static bool HasTransaction { - get { return currents.Value != null && currents.Value.ContainsKey(Connector.Current); } + get { return currents.Value != null && currents.Value!.ContainsKey(Connector.Current); } } - public static DbConnection CurrentConnection + public static DbConnection? CurrentConnection { get { @@ -519,7 +521,7 @@ public static DbConnection CurrentConnection } } - public static DbTransaction CurrentTransaccion + public static DbTransaction? CurrentTransaccion { get { @@ -536,7 +538,7 @@ public static string CurrentStatus() t.Started, t.IsRolledback, t.Connection == null ? "null" : (t.Connection.State.ToString() + " Hash " + t.Connection.GetHashCode()), - t.Transaction == null ? "null" : (" Hash " + t.Connection.GetHashCode())), "\r\n"); + t.Transaction == null ? "null" : (" Hash " + t.Transaction.GetHashCode())), "\r\n"); } public T Commit(T returnValue) @@ -580,14 +582,15 @@ public void Dispose() } finally { + var dic = currents.Value!; if (coreTransaction.Parent == null) { - currents.Value.Remove(Connector.Current); - if (currents.Value.Count == 0) + dic.Remove(Connector.Current); + if (dic.Count == 0) currents.Value = null; } else - currents.Value[Connector.Current] = coreTransaction.Parent; + dic[Connector.Current] = coreTransaction.Parent; } if (commited) @@ -599,7 +602,7 @@ public static void InvokePreRealCommit(Transaction tr) ((RealTransaction)tr.coreTransaction).OnPreRealCommit(); } - Exception savedException; + Exception? savedException; public void OnException(Exception ex) { diff --git a/Signum.Engine/Database.cs b/Signum.Engine/Database.cs index 0742be5554..46b0419365 100644 --- a/Signum.Engine/Database.cs +++ b/Signum.Engine/Database.cs @@ -116,7 +116,7 @@ public static async Task RetrieveAndForgetAsync(this Lite lite, Cancell return (T)(object)await RetrieveAsync(lite.EntityType, lite.Id, token); } - static GenericInvoker> giRetrieve = new GenericInvoker>(id => Retrieve(id)); + static readonly GenericInvoker> giRetrieve = new GenericInvoker>(id => Retrieve(id)); public static T Retrieve(PrimaryKey id) where T : Entity { using (HeavyProfiler.Log("DBRetrieve", () => typeof(T).TypeName())) @@ -164,7 +164,7 @@ public static T Retrieve(PrimaryKey id) where T : Entity } } - static GenericInvoker>> giRetrieveAsync = new GenericInvoker>>((id, token) => RetrieveAsync(id, token)); + static readonly GenericInvoker>> giRetrieveAsync = new GenericInvoker>>((id, token) => RetrieveAsync(id, token)); public static async Task RetrieveAsync(PrimaryKey id, CancellationToken token) where T : Entity { using (HeavyProfiler.Log("DBRetrieve", () => typeof(T).TypeName())) @@ -214,7 +214,7 @@ public static async Task RetrieveAsync(PrimaryKey id, CancellationToken to static CacheControllerBase? GetCacheController() where T : Entity { - CacheControllerBase cc = Schema.Current.CacheController(); + CacheControllerBase? cc = Schema.Current.CacheController(); if (cc == null || !cc.Enabled) return null; @@ -253,7 +253,7 @@ public static Task> RetrieveLiteAsync(Type type, PrimaryKey id, Can } - static GenericInvoker>> giRetrieveLite = new GenericInvoker>>(id => RetrieveLite(id)); + static readonly GenericInvoker>> giRetrieveLite = new GenericInvoker>>(id => RetrieveLite(id)); public static Lite RetrieveLite(PrimaryKey id) where T : Entity { @@ -283,7 +283,7 @@ public static Lite RetrieveLite(PrimaryKey id) } } - static GenericInvoker>>> giRetrieveLiteAsync = + static readonly GenericInvoker>>> giRetrieveLiteAsync = new GenericInvoker>>>((id, token) => RetrieveLiteAsync(id, token)); public static async Task> RetrieveLiteAsync(PrimaryKey id, CancellationToken token) where T : Entity @@ -333,7 +333,7 @@ public static async Task> FillToStringAsync(this Lite lite, Cancel public static string GetToStr(Type type, PrimaryKey id) => giGetToStr.GetInvoker(type)(id); - static GenericInvoker> giGetToStr = new GenericInvoker>(id => GetToStr(id)); + static readonly GenericInvoker> giGetToStr = new GenericInvoker>(id => GetToStr(id)); public static string GetToStr(PrimaryKey id) where T : Entity { @@ -358,7 +358,7 @@ public static string GetToStr(PrimaryKey id) public static Task GetToStrAsync(Type type, PrimaryKey id, CancellationToken token) => giGetToStrAsync.GetInvoker(type)(id, token); - static GenericInvoker>> giGetToStrAsync = + static readonly GenericInvoker>> giGetToStrAsync = new GenericInvoker>>((id, token) => GetToStrAsync(id, token)); public static async Task GetToStrAsync(PrimaryKey id, CancellationToken token) where T : Entity @@ -416,7 +416,7 @@ public static async Task ExistsAsync(this Lite lite, CancellationTok } public static bool Exists(Type type, PrimaryKey id) => giExist.GetInvoker(type)(id); - static GenericInvoker> giExist = + static readonly GenericInvoker> giExist = new GenericInvoker>(id => Exists(id)); public static bool Exists(PrimaryKey id) where T : Entity @@ -434,7 +434,7 @@ public static bool Exists(PrimaryKey id) } public static Task ExistsAsync(Type type, PrimaryKey id, CancellationToken token) => giExistAsync.GetInvoker(type)(id, token); - static GenericInvoker>> giExistAsync = + static readonly GenericInvoker>> giExistAsync = new GenericInvoker>>((id, token) => ExistsAsync(id, token)); public static async Task ExistsAsync(PrimaryKey id, CancellationToken token) where T : Entity @@ -626,7 +626,7 @@ public static async Task>> RetrieveAllLiteAsync(Type type, Can } - private static GenericInvoker, string?, IList>> giRetrieveList = + private static readonly GenericInvoker, string?, IList>> giRetrieveList = new GenericInvoker, string?, IList>>((ids, message) => RetrieveList(ids, message)); public static List RetrieveList(List ids, string? message = null) where T : Entity @@ -718,7 +718,7 @@ static List RetrieveFromDatabaseOrCache(List ids, string? mess } } - static GenericInvoker, CancellationToken, Task>> giRetrieveListAsync = + static readonly GenericInvoker, CancellationToken, Task>> giRetrieveListAsync = new GenericInvoker, CancellationToken, Task>>((ids, token) => RetrieveListAsyncIList(ids, token)); static Task RetrieveListAsyncIList(List ids, CancellationToken token) where T : Entity => RetrieveListAsync(ids, token).ContinueWith(p => (IList)p.Result); @@ -820,7 +820,7 @@ public static async Task> RetrieveListAsync(Type type, List().ToList(); } - static GenericInvoker, IList>> giRetrieveListLite = + static readonly GenericInvoker, IList>> giRetrieveListLite = new GenericInvoker, IList>>(ids => RetrieveListLite(ids)); public static List> RetrieveListLite(List ids) where T : Entity @@ -847,7 +847,7 @@ public static List> RetrieveListLite(List ids) } } - static GenericInvoker, CancellationToken, Task>> giRetrieveListLiteAsync = + static readonly GenericInvoker, CancellationToken, Task>> giRetrieveListLiteAsync = new GenericInvoker, CancellationToken, Task>>((ids, token) => RetrieveListLiteAsyncIList(ids, token)); static Task RetrieveListLiteAsyncIList(List ids, CancellationToken token) where T : Entity => RetrieveListLiteAsync(ids, token).ContinueWith(t => (IList)t.Result); public static async Task>> RetrieveListLiteAsync(List ids, CancellationToken token) @@ -978,7 +978,7 @@ public static void Delete(this T ident) giDeleteId.GetInvoker(ident.GetType())(ident.Id); } - static GenericInvoker> giDeleteId = new GenericInvoker>(id => Delete(id)); + static readonly GenericInvoker> giDeleteId = new GenericInvoker>(id => Delete(id)); public static void Delete(PrimaryKey id) where T : Entity { @@ -1047,7 +1047,7 @@ public static void DeleteList(Type type, IList ids) giDeleteList.GetInvoker(type)(ids); } - static GenericInvoker>> giDeleteList = new GenericInvoker>>(l => DeleteList(l)); + static readonly GenericInvoker>> giDeleteList = new GenericInvoker>>(l => DeleteList(l)); public static void DeleteList(IList ids) where T : Entity { @@ -1161,7 +1161,7 @@ public static R InDBEntity(this E entity, Expression> selector) return entity.InDB().Select(selector).SingleEx(); } - static GenericInvoker> giInDB = + static readonly GenericInvoker> giInDB = new GenericInvoker>((ie) => InDB((Entity)ie)); static IQueryable InDB(S entity) where S : class, IEntity @@ -1196,7 +1196,7 @@ public static R InDB(this Lite lite, Expression> selector) w return lite.InDB().Select(selector).SingleEx(); } - static GenericInvoker, IQueryable>> giInDBLite = + static readonly GenericInvoker, IQueryable>> giInDBLite = new GenericInvoker, IQueryable>>(l => InDB((Lite)l)); static IQueryable InDB(Lite lite) where S : class, IEntity @@ -1215,8 +1215,8 @@ static IQueryable InDB(Lite lite) public class InDbExpander : IMethodExpander { - static MethodInfo miSelect = ReflectionTools.GetMethodInfo(() => ((IQueryable)null).Select(a => a)).GetGenericMethodDefinition(); - static MethodInfo miSingleEx = ReflectionTools.GetMethodInfo(() => ((IQueryable)null).SingleEx()).GetGenericMethodDefinition(); + static readonly MethodInfo miSelect = ReflectionTools.GetMethodInfo(() => ((IQueryable)null).Select(a => a)).GetGenericMethodDefinition(); + static readonly MethodInfo miSingleEx = ReflectionTools.GetMethodInfo(() => ((IQueryable)null).SingleEx()).GetGenericMethodDefinition(); public Expression Expand(Expression instance, Expression[] arguments, MethodInfo mi) { @@ -1650,9 +1650,9 @@ public interface IUpdateablePart : IUpdateable class UpdateablePart : IUpdateablePart { - IQueryable query; - Expression> partSelector; - ReadOnlyCollection settersExpressions; + readonly IQueryable query; + readonly Expression> partSelector; + readonly ReadOnlyCollection settersExpressions; public UpdateablePart(IQueryable query, Expression> partSelector, IEnumerable? setters) { @@ -1716,8 +1716,8 @@ public interface IUpdateable : IUpdateable class Updateable : IUpdateable { - IQueryable query; - ReadOnlyCollection settersExpressions; + readonly IQueryable query; + readonly ReadOnlyCollection settersExpressions; public Updateable(IQueryable query, IEnumerable? setters) { diff --git a/Signum.Engine/DynamicQuery/AutoDynamicQuery.cs b/Signum.Engine/DynamicQuery/AutoDynamicQuery.cs index 8a0775d90c..84a40fdea5 100644 --- a/Signum.Engine/DynamicQuery/AutoDynamicQuery.cs +++ b/Signum.Engine/DynamicQuery/AutoDynamicQuery.cs @@ -15,7 +15,7 @@ public class AutoDynamicQueryCore : DynamicQueryCore { public IQueryable Query { get; private set; } - Dictionary metas; + readonly Dictionary metas; public AutoDynamicQueryCore(IQueryable query) { @@ -109,7 +109,7 @@ private DQueryable GetDQueryable(QueryRequest request) } } - public override object ExecuteQueryValue(QueryValueRequest request) + public override object? ExecuteQueryValue(QueryValueRequest request) { using (SystemTime.Override(request.SystemTime)) { @@ -127,7 +127,7 @@ public override object ExecuteQueryValue(QueryValueRequest request) } } - public override async Task ExecuteQueryValueAsync(QueryValueRequest request, CancellationToken token) + public override async Task ExecuteQueryValueAsync(QueryValueRequest request, CancellationToken token) { using (SystemTime.Override(request.SystemTime)) { @@ -145,7 +145,7 @@ public override async Task ExecuteQueryValueAsync(QueryValueRequest requ } } - public override Lite ExecuteUniqueEntity(UniqueEntityRequest request) + public override Lite? ExecuteUniqueEntity(UniqueEntityRequest request) { var ex = new _EntityColumn(EntityColumnFactory().BuildColumnDescription(), QueryName); @@ -159,10 +159,10 @@ public override Lite ExecuteUniqueEntity(UniqueEntityRequest request) .SelectOne(ex.Token) .Unique(request.UniqueType); - return (Lite)result; + return (Lite?)result; } - public override async Task> ExecuteUniqueEntityAsync(UniqueEntityRequest request, CancellationToken token) + public override async Task?> ExecuteUniqueEntityAsync(UniqueEntityRequest request, CancellationToken token) { var ex = new _EntityColumn(EntityColumnFactory().BuildColumnDescription(), QueryName); @@ -176,7 +176,7 @@ public override async Task> ExecuteUniqueEntityAsync(UniqueEntityRe .SelectOne(ex.Token) .UniqueAsync(request.UniqueType, token); - return (Lite)result; + return (Lite?)result; } public override IQueryable> GetEntities(QueryEntitiesRequest request) @@ -213,7 +213,7 @@ public override DQueryable GetDQueryable(DQueryableRequest request) return new DQueryable(query.Query, query.Context); } - public override Expression Expression + public override Expression? Expression { get { return Query.Expression; } } diff --git a/Signum.Engine/DynamicQuery/ColumnDescriptionFactory.cs b/Signum.Engine/DynamicQuery/ColumnDescriptionFactory.cs index 39b17e532f..ec202cbc01 100644 --- a/Signum.Engine/DynamicQuery/ColumnDescriptionFactory.cs +++ b/Signum.Engine/DynamicQuery/ColumnDescriptionFactory.cs @@ -11,7 +11,7 @@ namespace Signum.Engine.DynamicQuery { public class ColumnDescriptionFactory { - readonly internal Meta Meta; + readonly internal Meta? Meta; public Func? OverrideDisplayName { get; set; } public Func? OverrideIsAllowed { get; set; } @@ -92,7 +92,7 @@ public PropertyRoute[]? PropertyRoutes throw new InvalidOperationException(); } - public ColumnDescriptionFactory(int index, MemberInfo mi, Meta meta) + public ColumnDescriptionFactory(int index, MemberInfo mi, Meta? meta) { Name = mi.Name; diff --git a/Signum.Engine/DynamicQuery/DynamicQuery.cs b/Signum.Engine/DynamicQuery/DynamicQuery.cs index 2bf39da061..0db3f0f21e 100644 --- a/Signum.Engine/DynamicQuery/DynamicQuery.cs +++ b/Signum.Engine/DynamicQuery/DynamicQuery.cs @@ -64,7 +64,7 @@ public interface IDynamicQueryCore { object QueryName { get; set; } ColumnDescriptionFactory[] StaticColumns { get; } - Expression Expression { get; } //Optional + Expression? Expression { get; } ColumnDescriptionFactory EntityColumnFactory(); QueryDescription GetQueryDescription(); @@ -73,10 +73,10 @@ public interface IDynamicQueryCore Task ExecuteQueryAsync(QueryRequest request, CancellationToken cancellationToken); ResultTable ExecuteQueryGroup(QueryRequest request); Task ExecuteQueryGroupAsync(QueryRequest request, CancellationToken cancellationToken); - object ExecuteQueryValue(QueryValueRequest request); - Task ExecuteQueryValueAsync(QueryValueRequest request, CancellationToken cancellationToken); - Lite ExecuteUniqueEntity(UniqueEntityRequest request); - Task> ExecuteUniqueEntityAsync(UniqueEntityRequest request, CancellationToken cancellationToken); + object? ExecuteQueryValue(QueryValueRequest request); + Task ExecuteQueryValueAsync(QueryValueRequest request, CancellationToken cancellationToken); + Lite? ExecuteUniqueEntity(UniqueEntityRequest request); + Task?> ExecuteUniqueEntityAsync(UniqueEntityRequest request, CancellationToken cancellationToken); IQueryable> GetEntities(QueryEntitiesRequest request); DQueryable GetDQueryable(DQueryableRequest request); @@ -95,7 +95,7 @@ public static ManualDynamicQueryCore Manual(Func(execute); } - internal static IDynamicQueryCore FromSelectorUntyped(Expression> expression) + internal static IDynamicQueryCore FromSelectorUntyped(Expression> expression) where T : Entity { var eType = expression.Parameters.SingleEx().Type; @@ -106,14 +106,14 @@ internal static IDynamicQueryCore FromSelectorUntyped(Expression> giAutoPrivate = - new GenericInvoker>(lambda => FromSelector((Expression>)lambda)); + new GenericInvoker>(lambda => FromSelector((Expression>)lambda)); public static AutoDynamicQueryCore FromSelector(Expression> selector) where E : Entity { return new AutoDynamicQueryCore(Database.Query().Select(selector)); } - public static Dictionary QueryMetadata(IQueryable query) + public static Dictionary QueryMetadata(IQueryable query) { return MetadataVisitor.GatherMetadata(query.Expression); } @@ -122,9 +122,9 @@ public static Dictionary QueryMetadata(IQueryable query) public abstract class DynamicQueryCore : IDynamicQueryCore { - public object QueryName { get; set; } + public object QueryName { get; set; } = null!; - public ColumnDescriptionFactory[] StaticColumns { get; protected set; } + public ColumnDescriptionFactory[] StaticColumns { get; protected set; } = null!; public abstract ResultTable ExecuteQuery(QueryRequest request); public abstract Task ExecuteQueryAsync(QueryRequest request, CancellationToken cancellationToken); @@ -132,11 +132,11 @@ public abstract class DynamicQueryCore : IDynamicQueryCore public abstract ResultTable ExecuteQueryGroup(QueryRequest request); public abstract Task ExecuteQueryGroupAsync(QueryRequest request, CancellationToken cancellationToken); - public abstract object ExecuteQueryValue(QueryValueRequest request); - public abstract Task ExecuteQueryValueAsync(QueryValueRequest request, CancellationToken cancellationToken); + public abstract object? ExecuteQueryValue(QueryValueRequest request); + public abstract Task ExecuteQueryValueAsync(QueryValueRequest request, CancellationToken cancellationToken); - public abstract Lite ExecuteUniqueEntity(UniqueEntityRequest request); - public abstract Task> ExecuteUniqueEntityAsync(UniqueEntityRequest request, CancellationToken cancellationToken); + public abstract Lite? ExecuteUniqueEntity(UniqueEntityRequest request); + public abstract Task?> ExecuteUniqueEntityAsync(UniqueEntityRequest request, CancellationToken cancellationToken); public abstract IQueryable> GetEntities(QueryEntitiesRequest request); public abstract DQueryable GetDQueryable(DQueryableRequest request); @@ -179,7 +179,7 @@ public ColumnDescriptionFactory EntityColumnFactory() return StaticColumns.Where(c => c.IsEntity).SingleEx(() => "Entity column on {0}".FormatWith(QueryUtils.GetKey(QueryName))); } - public virtual Expression Expression + public virtual Expression? Expression { get { return null; } } @@ -187,7 +187,7 @@ public virtual Expression Expression public QueryDescription GetQueryDescription() { var entity = EntityColumnFactory(); - string allowed = entity.IsAllowed(); + string? allowed = entity.IsAllowed(); if (allowed != null) throw new InvalidOperationException( "Not authorized to see Entity column on {0} because {1}".FormatWith(QueryUtils.GetKey(QueryName), allowed)); @@ -209,11 +209,11 @@ public class DQueryable : IDynamicInfo { public DQueryable(IQueryable query, BuildExpressionContext context) { - this.Query= query; + this.Query = query; this.Context = context; } - public IQueryable Query{ get; private set; } + public IQueryable Query { get; private set; } public BuildExpressionContext Context { get; private set; } } @@ -267,9 +267,9 @@ public static DQueryable ToDQueryable(this IQueryable query, QueryDescr var dic = description.Columns.ToDictionary( cd => (QueryToken)new ColumnToken(cd, description.QueryName), - cd => Expression.PropertyOrField(Expression.Convert(pe, typeof(T)), cd.Name).BuildLiteNulifyUnwrapPrimaryKey(cd.PropertyRoutes)); + cd => Expression.PropertyOrField(Expression.Convert(pe, typeof(T)), cd.Name).BuildLiteNulifyUnwrapPrimaryKey(cd.PropertyRoutes!)); - return new DQueryable(query.Select(a => (object)a), new BuildExpressionContext(typeof(T), pe, dic)); + return new DQueryable(query.Select(a => (object)a!), new BuildExpressionContext(typeof(T), pe, dic)); } @@ -287,16 +287,16 @@ public static Task> AllQueryOperationsAsync(this DQueryab #region Select - public static IEnumerable SelectOne(this DEnumerable collection, QueryToken token) + public static IEnumerable SelectOne(this DEnumerable collection, QueryToken token) { - var exp = Expression.Lambda>(Expression.Convert(token.BuildExpression(collection.Context), typeof(object)), collection.Context.Parameter); + var exp = Expression.Lambda>(Expression.Convert(token.BuildExpression(collection.Context), typeof(object)), collection.Context.Parameter); return collection.Collection.Select(exp.Compile()); } - public static IQueryable SelectOne(this DQueryable query, QueryToken token) + public static IQueryable SelectOne(this DQueryable query, QueryToken token) { - var exp = Expression.Lambda>(Expression.Convert(token.BuildExpression(query.Context), typeof(object)), query.Context.Parameter); + var exp = Expression.Lambda>(Expression.Convert(token.BuildExpression(query.Context), typeof(object)), query.Context.Parameter); return query.Query.Select(exp); } @@ -359,7 +359,7 @@ static Expression> TupleConstructor(BuildExpressionContext newContext = new BuildExpressionContext( ctor.Type,pe, - tokens.Select((t, i) => new { Token = t, Expr = TupleReflection.TupleChainProperty(Expression.Convert(pe, ctor.Type), i) }).ToDictionary(t => t.Token, t => t.Expr)); + tokens.Select((t, i) => new { Token = t, Expr = TupleReflection.TupleChainProperty(Expression.Convert(pe, ctor.Type), i) }).ToDictionary(t => t.Token!, t => t.Expr!)); /*CSBUG*/ return Expression.Lambda>( (Expression)Expression.Convert(ctor, typeof(object)), context.Parameter); @@ -394,11 +394,11 @@ public static DQueryable SelectMany(this DQueryable query, List SelectMany(this DQueryable query, CollectionElementToken cet) { - Type elementType = cet.Parent.Type.ElementType(); + Type elementType = cet.Parent!.Type.ElementType()!; var collectionSelector = Expression.Lambda(typeof(Func<,>).MakeGenericType(typeof(object), typeof(IEnumerable<>).MakeGenericType(elementType)), Expression.Call(miDefaultIfEmptyE.MakeGenericMethod(elementType), - cet.Parent.BuildExpression(query.Context)), + cet.Parent!.BuildExpression(query.Context)), query.Context.Parameter); var elementParameter = cet.CreateParameter(); @@ -418,7 +418,7 @@ public static DQueryable SelectMany(this DQueryable query, CollectionEl { Token = a, Expression = TupleReflection.TupleChainProperty(Expression.Convert(parameter, ctor.Type), i) - }).ToDictionary(a => a.Token, a => a.Expression); + }).ToDictionary(a => a.Token!, a => a.Expression!); /*CSBUG*/ return new DQueryable(resultQuery, new BuildExpressionContext(ctor.Type, parameter, newReplacements)); @@ -435,8 +435,7 @@ public static DQueryable Where(this DQueryable query, params Filter[] f public static DQueryable Where(this DQueryable query, List filters) { - Expression> where = GetWhereExpression(query.Context, filters); - + Expression>? where = GetWhereExpression(query.Context, filters); if (where == null) return query; @@ -455,20 +454,19 @@ public static DEnumerable Where(this DEnumerable collection, params Fil public static DEnumerable Where(this DEnumerable collection, List filters) { - Expression> where = GetWhereExpression(collection.Context, filters); - + Expression>? where = GetWhereExpression(collection.Context, filters); if (where == null) return collection; return new DEnumerable(collection.Collection.Where(where.Compile()), collection.Context); } - public static DEnumerable Where(this DEnumerable collection, Func filter) + public static DEnumerable Where(this DEnumerable collection, Func filter) { return new DEnumerable(collection.Collection.Where(filter).ToList(), collection.Context); } - static Expression> GetWhereExpression(BuildExpressionContext context, List filters) + static Expression>? GetWhereExpression(BuildExpressionContext context, List filters) { if (filters == null || filters.Count == 0) return null; @@ -529,20 +527,20 @@ static IOrderedQueryable OrderBy(this IQueryable query, LambdaEx { MethodInfo mi = (orderType == OrderType.Ascending ? miOrderByQ : miOrderByDescendingQ).MakeGenericMethod(lambda.Type.GetGenericArguments()); - return (IOrderedQueryable)query.Provider.CreateQuery(Expression.Call(null, mi, new Expression[] { query.Expression, Expression.Quote(lambda) })); + return (IOrderedQueryable)query.Provider.CreateQuery(Expression.Call(null, mi, new Expression[] { query.Expression, Expression.Quote(lambda) })); } static IOrderedQueryable ThenBy(this IOrderedQueryable query, LambdaExpression lambda, OrderType orderType) { MethodInfo mi = (orderType == OrderType.Ascending ? miThenByQ : miThenByDescendingQ).MakeGenericMethod(lambda.Type.GetGenericArguments()); - return (IOrderedQueryable)query.Provider.CreateQuery(Expression.Call(null, mi, new Expression[] { query.Expression, Expression.Quote(lambda) })); + return (IOrderedQueryable)query.Provider.CreateQuery(Expression.Call(null, mi, new Expression[] { query.Expression, Expression.Quote(lambda) })); } - static GenericInvoker, Delegate, IOrderedEnumerable>> miOrderByE = new GenericInvoker, Delegate, IOrderedEnumerable>>((col, del) => col.OrderBy((Func)del)); - static GenericInvoker, Delegate, IOrderedEnumerable>> miThenByE = new GenericInvoker, Delegate, IOrderedEnumerable>>((col, del) => col.ThenBy((Func)del)); - static GenericInvoker, Delegate, IOrderedEnumerable>> miOrderByDescendingE = new GenericInvoker, Delegate, IOrderedEnumerable>>((col, del) => col.OrderByDescending((Func)del)); - static GenericInvoker, Delegate, IOrderedEnumerable>> miThenByDescendingE = new GenericInvoker, Delegate, IOrderedEnumerable>>((col, del) => col.ThenByDescending((Func)del)); + static readonly GenericInvoker, Delegate, IOrderedEnumerable>> miOrderByE = new GenericInvoker, Delegate, IOrderedEnumerable>>((col, del) => col.OrderBy((Func)del)); + static readonly GenericInvoker, Delegate, IOrderedEnumerable>> miThenByE = new GenericInvoker, Delegate, IOrderedEnumerable>>((col, del) => col.ThenBy((Func)del)); + static readonly GenericInvoker, Delegate, IOrderedEnumerable>> miOrderByDescendingE = new GenericInvoker, Delegate, IOrderedEnumerable>>((col, del) => col.OrderByDescending((Func)del)); + static readonly GenericInvoker, Delegate, IOrderedEnumerable>> miThenByDescendingE = new GenericInvoker, Delegate, IOrderedEnumerable>>((col, del) => col.ThenByDescending((Func)del)); public static DEnumerable OrderBy(this DEnumerable collection, List orders) { @@ -680,7 +678,7 @@ public static async Task> TryPaginateAsync(this DQueryabl return new DEnumerableCount(listTask, query.Context, countTask); } - throw new InvalidOperationException("pagination type {0} not expexted".FormatWith(pagination.GetType().Name)); + throw new InvalidOperationException("pagination type {0} not expexted".FormatWith(pagination!.GetType().Name)); /*CSBUG*/ } public static DEnumerableCount TryPaginate(this DQueryable query, Pagination pagination) @@ -715,7 +713,7 @@ public static DEnumerableCount TryPaginate(this DQueryable query, Pagin return new DEnumerableCount(list, query.Context, count); } - throw new InvalidOperationException("pagination type {0} not expexted".FormatWith(pagination.GetType().Name)); + throw new InvalidOperationException("pagination type {0} not expexted".FormatWith(pagination!.GetType().Name)); /*CSBUG*/ } public static DEnumerableCount TryPaginate(this DEnumerable collection, Pagination pagination) @@ -753,7 +751,7 @@ public static DEnumerableCount TryPaginate(this DEnumerable collection, return new DEnumerableCount(list, collection.Context, totalElements ?? collection.Collection.Count()); } - throw new InvalidOperationException("pagination type {0} not expexted".FormatWith(pagination.GetType().Name)); + throw new InvalidOperationException("pagination type {0} not expexted".FormatWith(pagination!.GetType().Name)); /*CSBUG*/ } public static DEnumerableCount TryPaginate(this DEnumerableCount collection, Pagination pagination) @@ -782,14 +780,14 @@ public static DEnumerableCount TryPaginate(this DEnumerableCount collec return new DEnumerableCount(c, collection.Context, collection.TotalElements); } - throw new InvalidOperationException("pagination type {0} not expexted".FormatWith(pagination.GetType().Name)); + throw new InvalidOperationException("pagination type {0} not expexted".FormatWith(pagination!.GetType().Name));/*CSBUG*/ } #endregion #region GroupBy - static GenericInvoker, Delegate, Delegate, IEnumerable>> giGroupByE = + static readonly GenericInvoker, Delegate, Delegate, IEnumerable>> giGroupByE = new GenericInvoker, Delegate, Delegate, IEnumerable>>( (col, ks, rs) => (IEnumerable)Enumerable.GroupBy((IEnumerable)col, (Func)ks, (Func, double>)rs)); public static DEnumerable GroupBy(this DEnumerable collection, HashSet keyTokens, HashSet aggregateTokens) @@ -810,7 +808,7 @@ public static DQueryable GroupBy(this DQueryable query, HashSet)query.Query.Provider.CreateQuery(Expression.Call(null, miGroupByQ.MakeGenericMethod(typeof(object), keySelector.Body.Type, typeof(object)), + var resultQuery = (IQueryable)query.Query.Provider.CreateQuery(Expression.Call(null, miGroupByQ.MakeGenericMethod(typeof(object), keySelector.Body.Type, typeof(object)), new Expression[] { query.Query.Expression, Expression.Quote(keySelector), Expression.Quote(resultSelector) })); return new DQueryable(resultQuery, newContext); @@ -845,13 +843,12 @@ static LambdaExpression KeySelector(BuildExpressionContext context, HashSet(this DEnumerable collection, AggregateToken simpleAggregate) + public static object? SimpleAggregate(this DEnumerable collection, AggregateToken simpleAggregate) { var expr = BuildAggregateExpressionEnumerable(Expression.Constant(collection.Collection), simpleAggregate, collection.Context); - return Expression.Lambda>(Expression.Convert(expr, typeof(object))).Compile()(); + return Expression.Lambda>(Expression.Convert(expr, typeof(object))).Compile()(); } - public static object SimpleAggregate(this DQueryable query, AggregateToken simpleAggregate) + public static object? SimpleAggregate(this DQueryable query, AggregateToken simpleAggregate) { var expr = BuildAggregateExpressionQueryable(query.Query.Expression, simpleAggregate, query.Context); - return Expression.Lambda>(Expression.Convert(expr, typeof(object))).Compile()(); + return Expression.Lambda>(Expression.Convert(expr, typeof(object))).Compile()(); } - public static Task SimpleAggregateAsync(this DQueryable query, AggregateToken simpleAggregate, CancellationToken token) + public static Task SimpleAggregateAsync(this DQueryable query, AggregateToken simpleAggregate, CancellationToken token) { var expr = BuildAggregateExpressionQueryableAsync(query.Query.Expression, simpleAggregate, query.Context, token); - var func = (Func)Expression.Lambda(expr).Compile(); + var func = (Func)Expression.Lambda(expr).Compile(); var task = func(); return giCastObject.GetInvoker(task.GetType().BaseType.GetGenericArguments())(task); } - static GenericInvoker>> giCastObject = - new GenericInvoker>>(task => CastObject((Task)task)); - static Task CastObject(Task task) + static readonly GenericInvoker>> giCastObject = + new GenericInvoker>>(task => CastObject((Task)task)); + static Task CastObject(Task task) { - return task.ContinueWith(t => (object)t.Result); + return task.ContinueWith(t => (object?)t.Result); } #endregion @@ -1001,7 +998,7 @@ public static ResultTable ToResultTable(object[] result, List<(Column column, La return new ResultTable(columnValues, totalElements, pagination); } - static GenericInvoker> miGetValues = new GenericInvoker>((objs, del) => GetValues(objs, (Func)del)); + static readonly GenericInvoker> miGetValues = new GenericInvoker>((objs, del) => GetValues(objs, (Func)del)); static S[] GetValues(object[] collection, Func getter) { S[] array = new S[collection.Length]; diff --git a/Signum.Engine/DynamicQuery/DynamicQueryContainer.cs b/Signum.Engine/DynamicQuery/DynamicQueryContainer.cs index f8280b055a..7b59b6ff1d 100644 --- a/Signum.Engine/DynamicQuery/DynamicQueryContainer.cs +++ b/Signum.Engine/DynamicQuery/DynamicQueryContainer.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Signum.Utilities; @@ -29,7 +29,7 @@ public void Register(object queryName, DynamicQueryBucket bucket) queries[queryName] = bucket; } - public DynamicQueryBucket TryGetQuery(object queryName) + public DynamicQueryBucket? TryGetQuery(object queryName) { AssertQueryAllowed(queryName, false); return queries.TryGetC(queryName); @@ -58,7 +58,7 @@ static Implementations DefaultImplementations(Type type, object queryName) return Implementations.By(property.PropertyType.CleanType()); } - T Execute(ExecuteType executeType, object queryName, BaseQueryRequest request, Func executor) + T Execute(ExecuteType executeType, object queryName, BaseQueryRequest? request, Func executor) { using (ExecutionMode.UserInterface()) using (HeavyProfiler.Log(executeType.ToString(), () => QueryUtils.GetKey(queryName))) @@ -102,7 +102,7 @@ async Task ExecuteAsync(ExecuteType executeType, object queryName, BaseQue } } - public event Func QueryExecuted; + public event Func QueryExecuted; public enum ExecuteType { @@ -131,22 +131,22 @@ public Task ExecuteQueryAsync(QueryRequest request, CancellationTok return ExecuteAsync(ExecuteType.ExecuteGroupQuery, request.QueryName, request, dqb => dqb.Core.Value.ExecuteQueryGroupAsync(request, token)); } - public object ExecuteQueryValue(QueryValueRequest request) + public object? ExecuteQueryValue(QueryValueRequest request) { return Execute(ExecuteType.ExecuteQueryValue, request.QueryName, request, dqb => dqb.Core.Value.ExecuteQueryValue(request)); } - public Task ExecuteQueryValueAsync(QueryValueRequest request, CancellationToken token) + public Task ExecuteQueryValueAsync(QueryValueRequest request, CancellationToken token) { return ExecuteAsync(ExecuteType.ExecuteQueryValue, request.QueryName, request, dqb => dqb.Core.Value.ExecuteQueryValueAsync(request, token)); } - public Lite ExecuteUniqueEntity(UniqueEntityRequest request) + public Lite? ExecuteUniqueEntity(UniqueEntityRequest request) { return Execute(ExecuteType.ExecuteUniqueEntity, request.QueryName, request, dqb => dqb.Core.Value.ExecuteUniqueEntity(request)); } - public Task> ExecuteUniqueEntityAsync(UniqueEntityRequest request, CancellationToken token) + public Task?> ExecuteUniqueEntityAsync(UniqueEntityRequest request, CancellationToken token) { return ExecuteAsync(ExecuteType.ExecuteUniqueEntity, request.QueryName, request, dqb => dqb.Core.Value.ExecuteUniqueEntityAsync(request, token)); } @@ -212,18 +212,18 @@ public List GetQueryNames() return queries.Keys.ToList(); } - public Task BatchExecute(BaseQueryRequest[] requests, CancellationToken token) + public Task BatchExecute(BaseQueryRequest[] requests, CancellationToken token) { - return Task.WhenAll(requests.Select>(r => + return Task.WhenAll(requests.Select>(r => { if (r is QueryValueRequest) return ExecuteQueryValueAsync((QueryValueRequest)r, token); if (r is QueryRequest) - return ExecuteQueryAsync((QueryRequest)r, token).ContinueWith(a => (object)a.Result); + return ExecuteQueryAsync((QueryRequest)r, token).ContinueWith(a => a.Result); if (r is UniqueEntityRequest) - return ExecuteUniqueEntityAsync((UniqueEntityRequest)r, token).ContinueWith(a => (object)a.Result); + return ExecuteUniqueEntityAsync((UniqueEntityRequest)r, token).ContinueWith(a => (object?)a.Result); throw new InvalidOperationException("Unexpected QueryRequest type"); ; })); diff --git a/Signum.Engine/DynamicQuery/DynamicQueryFluentInclude.cs b/Signum.Engine/DynamicQuery/DynamicQueryFluentInclude.cs index e293b7403f..d0701471cb 100644 --- a/Signum.Engine/DynamicQuery/DynamicQueryFluentInclude.cs +++ b/Signum.Engine/DynamicQuery/DynamicQueryFluentInclude.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using Signum.Utilities; using Signum.Entities; @@ -10,7 +10,7 @@ namespace Signum.Engine.DynamicQuery { public static class DynamicQueryFluentInclude { - public static FluentInclude WithQuery(this FluentInclude fi, Func>> lazyQuerySelector) + public static FluentInclude WithQuery(this FluentInclude fi, Func>> lazyQuerySelector) where T : Entity { QueryLogic.Queries.Register(typeof(T), new DynamicQueryBucket(typeof(T), () => DynamicQueryCore.FromSelectorUntyped(lazyQuerySelector()), Implementations.By(typeof(T)))); diff --git a/Signum.Engine/DynamicQuery/ExpressionContainer.cs b/Signum.Engine/DynamicQuery/ExpressionContainer.cs index 3f87872350..91dd05e6e9 100644 --- a/Signum.Engine/DynamicQuery/ExpressionContainer.cs +++ b/Signum.Engine/DynamicQuery/ExpressionContainer.cs @@ -142,7 +142,7 @@ private Expression>> CombineSelectors(Expres { Expression>> result = e => collectionSelector.Evaluate(embeddedSelector.Evaluate(e)); - return (Expression>>)ExpressionCleaner.Clean(result); + return (Expression>>)ExpressionCleaner.Clean(result)!; } private ResetLazy> GetAllKeysLazy(Expression>> collectionSelector, Expression> keySelector) @@ -183,7 +183,7 @@ public class ExtensionDictionaryInfo : IExtensionDictionaryInfo public Expression> ValueSelector { get; set; } - ConcurrentDictionary metas = new ConcurrentDictionary(); + readonly ConcurrentDictionary metas = new ConcurrentDictionary(); public ExtensionDictionaryInfo( Expression>> collectionSelector, diff --git a/Signum.Engine/DynamicQuery/ManualDynamicQuery.cs b/Signum.Engine/DynamicQuery/ManualDynamicQuery.cs index 43d1f83f19..7f15801a4a 100644 --- a/Signum.Engine/DynamicQuery/ManualDynamicQuery.cs +++ b/Signum.Engine/DynamicQuery/ManualDynamicQuery.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Signum.Entities.DynamicQuery; @@ -66,8 +66,8 @@ public override async Task ExecuteQueryGroupAsync(QueryRequest requ return cols.ToResultTable(request); } - public override object ExecuteQueryValue(QueryValueRequest request) => Task.Run(() => ExecuteQueryValueAsync(request, CancellationToken.None)); - public override async Task ExecuteQueryValueAsync(QueryValueRequest request, CancellationToken cancellationToken) + public override object? ExecuteQueryValue(QueryValueRequest request) => Task.Run(() => ExecuteQueryValueAsync(request, CancellationToken.None)); + public override async Task ExecuteQueryValueAsync(QueryValueRequest request, CancellationToken cancellationToken) { var req = new QueryRequest { @@ -88,7 +88,7 @@ public override async Task ExecuteQueryValueAsync(QueryValueRequest requ else if (request.ValueToken is AggregateToken) { - var parent = request.ValueToken.Parent; + var parent = request.ValueToken.Parent!; req.Columns.Add(new Column(parent, parent.NiceName())); var result = await Execute(req, GetQueryDescription(), cancellationToken); return result.SimpleAggregate((AggregateToken)request.ValueToken); @@ -103,8 +103,8 @@ public override async Task ExecuteQueryValueAsync(QueryValueRequest requ - public override Lite ExecuteUniqueEntity(UniqueEntityRequest request) => Task.Run(() => ExecuteUniqueEntityAsync(request, CancellationToken.None)).Result; - public override async Task> ExecuteUniqueEntityAsync(UniqueEntityRequest request, CancellationToken cancellationToken) + public override Lite? ExecuteUniqueEntity(UniqueEntityRequest request) => Task.Run(() => ExecuteUniqueEntityAsync(request, CancellationToken.None)).Result; + public override async Task?> ExecuteUniqueEntityAsync(UniqueEntityRequest request, CancellationToken cancellationToken) { var req = new QueryRequest { diff --git a/Signum.Engine/Engine/Saver.cs b/Signum.Engine/Engine/Saver.cs index b021504860..f71de66bd7 100644 --- a/Signum.Engine/Engine/Saver.cs +++ b/Signum.Engine/Engine/Saver.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Signum.Utilities; @@ -116,7 +116,7 @@ private static void SaveGraph(Schema schema, DirectedGraph identifiables } } - private static void SaveGroup(Schema schema, IGrouping group, DirectedGraph backEdges) + private static void SaveGroup(Schema schema, IGrouping group, DirectedGraph? backEdges) { Table table = schema.Table(group.Key.Type); diff --git a/Signum.Engine/Engine/SchemaSynchronizer.cs b/Signum.Engine/Engine/SchemaSynchronizer.cs index 1c35e66bcc..6d5cf261ba 100644 --- a/Signum.Engine/Engine/SchemaSynchronizer.cs +++ b/Signum.Engine/Engine/SchemaSynchronizer.cs @@ -22,7 +22,7 @@ public static class SchemaSynchronizer Schema s = Schema.Current; Dictionary modelTables = s.GetDatabaseTables().Where(t => !s.IsExternalDatabase(t.Name.Schema.Database)).ToDictionaryEx(a => a.Name.ToString(), "schema tables"); - var modelTablesHistory = modelTables.Values.Where(a => a.SystemVersioned != null).ToDictionaryEx(a => a.SystemVersioned.TableName.ToString(), "history schema tables"); + var modelTablesHistory = modelTables.Values.Where(a => a.SystemVersioned != null).ToDictionaryEx(a => a.SystemVersioned!.TableName.ToString(), "history schema tables"); HashSet modelSchemas = modelTables.Values.Select(a => a.Name.Schema).Where(a => !SqlBuilder.SystemSchemas.Contains(a.Name)).ToHashSet(); Dictionary databaseTables = DefaultGetDatabaseDescription(s.DatabaseNames()); @@ -296,7 +296,7 @@ from c in t.Columns.Values (SqlPreCommandSimple)SqlBuilder.AlterTableAddPeriod(tab) : null); var addSystemVersioning = (tab.SystemVersioned != null && - (dif.Period == null || !object.Equals(replacements.Apply(Replacements.KeyTables, dif.TemporalTableName.ToString()), tab.SystemVersioned.TableName.ToString())) ? + (dif.Period == null || !object.Equals(replacements.Apply(Replacements.KeyTables, dif.TemporalTableName!.ToString()), tab.SystemVersioned.TableName.ToString())) ? SqlBuilder.AlterTableEnableSystemVersioning(tab).Do(a=>a.GoBefore = true) : null); @@ -325,7 +325,7 @@ from c in t.Columns.Values SqlPreCommand? historyTables = Synchronizer.SynchronizeScript(Spacing.Double, modelTablesHistory, databaseTablesHistory, createNew: null, removeOld: (tn, dif) => SqlBuilder.DropTable(dif.Name), - mergeBoth: (tn, tab, dif) => !object.Equals(dif.Name, tab.SystemVersioned.TableName) ? SqlBuilder.RenameOrChangeSchema(dif.Name, tab.SystemVersioned.TableName) : null); + mergeBoth: (tn, tab, dif) => !object.Equals(dif.Name, tab.SystemVersioned!.TableName) ? SqlBuilder.RenameOrChangeSchema(dif.Name, tab.SystemVersioned!.TableName) : null); SqlPreCommand? syncEnums = SynchronizeEnumsScript(replacements); @@ -399,7 +399,7 @@ from c in t.Columns.Values createNew: (i, mix) => mix is UniqueIndex || mix.Columns.Any(isNew) || SafeConsole.Ask(ref createMissingFreeIndexes, "Create missing non-unique index {0} in {1}?".FormatWith(mix.IndexName, tab.Name)) ? SqlBuilder.CreateIndexBasic(mix, forHistoryTable: true) : null, removeOld: null, mergeBoth: (i, mix, dix) => !dix.IndexEquals(dif, mix) ? SqlBuilder.CreateIndexBasic(mix, forHistoryTable: true) : - mix.IndexName != dix.IndexName ? SqlBuilder.RenameIndex(tab.SystemVersioned.TableName, dix.IndexName, mix.IndexName) : null); + mix.IndexName != dix.IndexName ? SqlBuilder.RenameIndex(tab.SystemVersioned!.TableName, dix.IndexName, mix.IndexName) : null); return SqlPreCommand.Combine(Spacing.Simple, controlledIndexes); }); @@ -438,7 +438,7 @@ private static bool DifferentDatabase(ObjectName name, ObjectName name2) public static Func IgnoreSchema = s => s.Name.Contains("\\"); - private static HashSet DefaultGetSchemas(List list) + private static HashSet DefaultGetSchemas(List list) { HashSet result = new HashSet(); foreach (var db in list) @@ -625,7 +625,7 @@ private static Dictionary ApplyIndexAutoReplacements(DiffTabl public static Func IgnoreTable = null; - public static Dictionary DefaultGetDatabaseDescription(List databases) + public static Dictionary DefaultGetDatabaseDescription(List databases) { List allTables = new List(); @@ -844,7 +844,7 @@ public static SqlDbType ToSqlDbType(string str) } } - private static SqlPreCommand SyncEnums(Schema schema, Table table, Dictionary current, Dictionary should) + private static SqlPreCommand? SyncEnums(Schema schema, Table table, Dictionary current, Dictionary should) { var deletes = Synchronizer.SynchronizeScript(Spacing.Double, should, current, createNew: null, @@ -929,6 +929,7 @@ public static SqlPreCommandSimple DisconnectUsers(string databaseName, string va } } +#pragma warning disable CS8618 // Non-nullable field is uninitialized. public class DiffPeriod { public string StartColumnName; @@ -1152,7 +1153,7 @@ public bool DefaultEquals(IColumn other) return result; } - private string CleanParenthesis(string p) + private string? CleanParenthesis(string? p) { if (p == null) return null; @@ -1401,4 +1402,5 @@ public class DiffForeignKeyColumn public string Parent; public string Referenced; } +#pragma warning restore CS8618 // Non-nullable field is uninitialized. } diff --git a/Signum.Engine/Engine/SqlBuilder.cs b/Signum.Engine/Engine/SqlBuilder.cs index 20dc172dfa..b126814b58 100644 --- a/Signum.Engine/Engine/SqlBuilder.cs +++ b/Signum.Engine/Engine/SqlBuilder.cs @@ -213,7 +213,7 @@ public static string CreateColumn(IColumn c, DefaultConstraint? constraint) var defaultConstraint = constraint != null ? $"CONSTRAINT {constraint.Name} DEFAULT " + constraint.QuotedDefinition : null; c = c!;/*CSBUG*/ - return $" ".CombineIfNotEmpty( + return $" ".Combine( c.Name.SqlEscape(), fullType, c.Identity ? "IDENTITY " : null, diff --git a/Signum.Engine/Engine/Sys.Tables.cs b/Signum.Engine/Engine/Sys.Tables.cs index 8cfaa34128..ac65536c26 100644 --- a/Signum.Engine/Engine/Sys.Tables.cs +++ b/Signum.Engine/Engine/Sys.Tables.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using System.Linq.Expressions; using Signum.Utilities; @@ -7,6 +7,7 @@ namespace Signum.Engine.SchemaInfoTables { #pragma warning disable 649 +#pragma warning disable CS8618 // Non-nullable field is uninitialized. [TableName("sys.objects")] public class SysObjects : IView diff --git a/Signum.Engine/EntityCache.cs b/Signum.Engine/EntityCache.cs index 084c845901..de11500ce6 100644 --- a/Signum.Engine/EntityCache.cs +++ b/Signum.Engine/EntityCache.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Signum.Entities; @@ -22,7 +22,7 @@ public void Add(Entity e) var tuple = (e.GetType(), e.Id); - Entity ident = dic.TryGetC(tuple); + Entity? ident = dic.TryGetC(tuple); if (ident == null) dic.Add(tuple, e); @@ -38,7 +38,7 @@ public bool Contains(Type type, PrimaryKey id) return dic.ContainsKey((type, id)); } - public Entity Get(Type type, PrimaryKey id) + public Entity? Get(Type type, PrimaryKey id) { return dic.TryGetC((type, id)); } @@ -51,7 +51,7 @@ public void AddFullGraph(ModifiableEntity ie) Add(ident); } - IRetriever retriever; + IRetriever? retriever; public RealEntityCache(bool isSealed) { IsSealed = isSealed; @@ -88,16 +88,13 @@ internal bool TryGetValue((Type type, PrimaryKey id) tuple, out Entity result) } public bool IsSealed { get; private set; } - internal Dictionary GetRetrieverUserData() => this.retriever.GetUserData(); + internal Dictionary? GetRetrieverUserData() => this.retriever?.GetUserData(); } - static readonly Variable currentCache = Statics.ThreadVariable("cache"); - - - RealEntityCache oldCache; - - private bool facked = false; + static readonly Variable currentCache = Statics.ThreadVariable("cache"); + readonly RealEntityCache? oldCache; + readonly bool facked = false; public EntityCache(EntityCacheType type = EntityCacheType.Normal) { @@ -124,9 +121,9 @@ static RealEntityCache Current public static bool Created { get { return currentCache.Value != null; } } - internal static bool HasRetriever { get { return currentCache.Value != null && currentCache.Value.HasRetriever; } } + internal static bool HasRetriever { get { return currentCache.Value != null && currentCache.Value!.HasRetriever; } } - public static bool IsSealed { get { return currentCache.Value.IsSealed; } } + public static bool IsSealed { get { return currentCache.Value!.IsSealed; } } public void Dispose() { @@ -169,17 +166,17 @@ public static bool Contains(Type type, PrimaryKey id) return Current.Contains(type, id); } - public static T Get(PrimaryKey id) where T : Entity + public static T? Get(PrimaryKey id) where T : Entity { - return (T)Get(typeof(T), id); + return (T?)Get(typeof(T), id); } - public static Entity Get(Type type, PrimaryKey id) + public static Entity? Get(Type type, PrimaryKey id) { return Current.Get(type, id); } - public static Dictionary RetrieverUserData() + public static Dictionary? RetrieverUserData() { return Current.GetRetrieverUserData(); } diff --git a/Signum.Engine/Exceptions.cs b/Signum.Engine/Exceptions.cs index 314e2d05e7..e44ed23cd6 100644 --- a/Signum.Engine/Exceptions.cs +++ b/Signum.Engine/Exceptions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; @@ -15,14 +15,14 @@ namespace Signum.Engine [Serializable] public class UniqueKeyException : ApplicationException { - public string TableName { get; private set; } - public Table Table { get; private set; } + public string? TableName { get; private set; } + public Table? Table { get; private set; } - public string IndexName { get; private set; } - public UniqueIndex Index { get; private set; } - public List Properties { get; private set; } + public string? IndexName { get; private set; } + public UniqueIndex? Index { get; private set; } + public List? Properties { get; private set; } - public string Values { get; private set; } + public string? Values { get; private set; } protected UniqueKeyException(SerializationInfo info, StreamingContext context) : base(info, context) { } @@ -56,7 +56,7 @@ public UniqueKeyException(Exception inner) : base(null, inner) var properties = (from f in tup.Item1.Fields.Values let cols = f.Field.Columns() - where cols.Any() && cols.All(index.Columns.Contains) + where cols.Any() && cols.All(c => index.Columns.Contains(c)) select Reflector.TryFindPropertyInfo(f.FieldInfo)).NotNull().ToList(); if (properties.IsEmpty()) @@ -90,7 +90,7 @@ public override string Message Table == null ? TableName : Table.Type.NiceName(), Index == null ? IndexName : Properties.IsNullOrEmpty() ? Index.Columns.CommaAnd(c => c.Name) : - Properties.CommaAnd(p=>p.NiceName()), + Properties!.CommaAnd(p => p.NiceName()), Values); } } @@ -100,12 +100,12 @@ public override string Message [Serializable] public class ForeignKeyException : ApplicationException { - public string TableName { get; private set; } - public string Field { get; private set; } - public Type TableType { get; private set; } + public string? TableName { get; private set; } + public string? Field { get; private set; } + public Type? TableType { get; private set; } - public string ReferedTableName { get; private set; } - public Type ReferedTableType { get; private set; } + public string? ReferedTableName { get; private set; } + public Type? ReferedTableType { get; private set; } public bool IsInsert { get; private set; } @@ -173,7 +173,9 @@ public class EntityNotFoundException : Exception public Type Type { get; private set; } public PrimaryKey[] Ids { get; private set; } +#pragma warning disable CS8618 // Non-nullable field is uninitialized. protected EntityNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#pragma warning restore CS8618 // Non-nullable field is uninitialized. public EntityNotFoundException(Type type, params PrimaryKey[] ids) : base(EngineMessage.EntityWithType0AndId1NotFound.NiceToString().FormatWith(type.Name, ids.ToString(", "))) @@ -189,7 +191,9 @@ public class ConcurrencyException: Exception public Type Type { get; private set; } public PrimaryKey[] Ids { get; private set; } +#pragma warning disable CS8618 // Non-nullable field is uninitialized. protected ConcurrencyException(SerializationInfo info, StreamingContext context) : base(info, context) { } +#pragma warning restore CS8618 // Non-nullable field is uninitialized. public ConcurrencyException(Type type, params PrimaryKey[] ids) : base(EngineMessage.ConcurrencyErrorOnDatabaseTable0Id1.NiceToString().FormatWith(type.NiceName(), ids.ToString(", "))) diff --git a/Signum.Engine/ExecutionContext.cs b/Signum.Engine/ExecutionContext.cs index f99536a519..bbd1c5dd34 100644 --- a/Signum.Engine/ExecutionContext.cs +++ b/Signum.Engine/ExecutionContext.cs @@ -1,4 +1,4 @@ -using System; +using System; using Signum.Utilities; namespace Signum.Engine @@ -38,9 +38,10 @@ public static bool IsCacheDisabled } static readonly ThreadVariable cacheTempDisabled = Statics.ThreadVariable("cacheTempDisabled"); - public static IDisposable DisableCache() + public static IDisposable? DisableCache() { - if (cacheTempDisabled.Value) return null; + if (cacheTempDisabled.Value) + return null; cacheTempDisabled.Value = true; return new Disposable(() => cacheTempDisabled.Value = false); } diff --git a/Signum.Engine/Linq/AliasGenerator.cs b/Signum.Engine/Linq/AliasGenerator.cs index f3214207b0..3dd9bff0ad 100644 --- a/Signum.Engine/Linq/AliasGenerator.cs +++ b/Signum.Engine/Linq/AliasGenerator.cs @@ -1,4 +1,4 @@ -using Signum.Engine.Maps; +using Signum.Engine.Maps; using Signum.Utilities; using System; using System.Collections.Generic; @@ -8,7 +8,7 @@ namespace Signum.Engine.Linq { public class AliasGenerator { - HashSet usedAliases = new HashSet(); + readonly HashSet usedAliases = new HashSet(); int selectAliasCount = 0; public Alias NextSelectAlias() @@ -43,11 +43,11 @@ public Alias Raw(string name) public Alias NextTableAlias(string tableName) { - string abv = tableName.Any(char.IsUpper) ? new string(tableName.Where(c => char.IsUpper(c)).ToArray()) : + string? abv = tableName.Any(char.IsUpper) ? new string(tableName.Where(c => char.IsUpper(c)).ToArray()) : tableName.Any(a => a == '_') ? new string(tableName.SplitNoEmpty('_' ).Select(s => s[0]).ToArray()) : null; if (string.IsNullOrEmpty(abv)) - abv = tableName.TryStart(3); + abv = tableName.TryStart(3)!; else abv = abv.ToLower(); @@ -68,8 +68,8 @@ public class Alias: IEquatable { public static readonly Alias Unknown = new Alias("Unknown"); - public readonly string Name; //Mutually exclusive - public readonly ObjectName ObjectName; //Mutually exclusive + public readonly string? Name; //Mutually exclusive + public readonly ObjectName? ObjectName; //Mutually exclusive internal Alias(string name) { @@ -93,12 +93,12 @@ public override bool Equals(object obj) public override int GetHashCode() { - return this.Name == null? this.ObjectName.GetHashCode(): this.Name.GetHashCode(); + return this.Name == null? this.ObjectName!.GetHashCode(): this.Name.GetHashCode(); } public override string ToString() { - return Name?.SqlEscape() ?? ObjectName.ToString(); + return Name?.SqlEscape() ?? ObjectName!.ToString(); } } } diff --git a/Signum.Engine/Linq/DbExpressions.Signum.cs b/Signum.Engine/Linq/DbExpressions.Signum.cs index 8325c6749d..74ba5e50f7 100644 --- a/Signum.Engine/Linq/DbExpressions.Signum.cs +++ b/Signum.Engine/Linq/DbExpressions.Signum.cs @@ -336,10 +336,10 @@ internal class LiteValueExpression : DbExpression { public readonly Expression TypeId; public readonly Expression Id; - public readonly Expression ToStr; //Not readonly + public readonly Expression? ToStr; - public LiteValueExpression(Type type, Expression typeId, Expression id, Expression toStr) : + public LiteValueExpression(Type type, Expression typeId, Expression id, Expression? toStr) : base(DbExpressionType.LiteValue, type) { this.TypeId = typeId ?? throw new ArgumentNullException(nameof(typeId)); @@ -430,9 +430,9 @@ internal class MListExpression : DbExpression { public readonly PrimaryKeyExpression BackID; // not readonly public readonly TableMList TableMList; - public readonly NewExpression ExternalPeriod; + public readonly NewExpression? ExternalPeriod; - public MListExpression(Type type, PrimaryKeyExpression backID, NewExpression externalPeriod, TableMList tr) + public MListExpression(Type type, PrimaryKeyExpression backID, NewExpression? externalPeriod, TableMList tr) : base(DbExpressionType.MList, type) { this.BackID = backID; @@ -483,7 +483,7 @@ internal class MListProjectionExpression : DbExpression public MListProjectionExpression(Type type, ProjectionExpression projection) : base(DbExpressionType.MListProjection, type) { - if (!projection.Type.ElementType().IsInstantiationOf(typeof(MList<>.RowIdElement))) + if (!projection.Type.ElementType()!.IsInstantiationOf(typeof(MList<>.RowIdElement))) throw new ArgumentException("projector should be collation of RowIdValue"); this.Projection = projection; @@ -504,16 +504,16 @@ internal class MListElementExpression : DbExpression { public readonly PrimaryKeyExpression RowId; public readonly EntityExpression Parent; - public readonly Expression Order; + public readonly Expression? Order; public readonly Expression Element; public readonly TableMList Table; public readonly Alias Alias; - public readonly NewExpression TablePeriod; + public readonly NewExpression? TablePeriod; - public MListElementExpression(PrimaryKeyExpression rowId, EntityExpression parent, Expression order, Expression element, NewExpression systemPeriod, TableMList table, Alias alias) + public MListElementExpression(PrimaryKeyExpression rowId, EntityExpression parent, Expression? order, Expression element, NewExpression? systemPeriod, TableMList table, Alias alias) : base(DbExpressionType.MListElement, typeof(MListElement<,>).MakeGenericType(parent.Type, element.Type)) { this.RowId = rowId; @@ -530,7 +530,7 @@ public override string ToString() return "MListElement({0})\r\n{{\r\nParent={1},\r\nOrder={2},\r\nElement={3}}})".FormatWith( RowId.ToString(), Parent.ToString(), - Order == null ? Order.ToString() : null, + Order?.ToString(), Element.ToString()); } diff --git a/Signum.Engine/Linq/DbExpressions.Sql.cs b/Signum.Engine/Linq/DbExpressions.Sql.cs index bddce390db..89d1221e24 100644 --- a/Signum.Engine/Linq/DbExpressions.Sql.cs +++ b/Signum.Engine/Linq/DbExpressions.Sql.cs @@ -1084,7 +1084,7 @@ protected override Expression Accept(DbExpressionVisitor visitor) internal class RowNumberExpression : DbExpression { - public readonly ReadOnlyCollection? OrderBy; + public readonly ReadOnlyCollection OrderBy; public RowNumberExpression(IEnumerable? orderBy) : base(DbExpressionType.RowNumber, typeof(int)) @@ -1127,7 +1127,7 @@ internal ProjectionExpression(SelectExpression select, Expression projector, Uni if (projector == null) throw new ArgumentNullException(nameof(projector)); - var elementType = uniqueFunction == null ? resultType.ElementType() : resultType; + var elementType = uniqueFunction == null ? resultType.ElementType()! : resultType; if (!elementType.IsAssignableFrom(projector.Type)) throw new InvalidOperationException("Projector ({0}) does not fit in the projection ({1})".FormatWith( projector.Type.TypeName(), @@ -1191,9 +1191,9 @@ internal class DeleteExpression : CommandExpression public ObjectName Name { get { return UseHistoryTable ? Table.SystemVersioned!.TableName : Table.Name; } } public readonly SourceWithAliasExpression Source; - public readonly Expression Where; + public readonly Expression? Where; - public DeleteExpression(ITable table, bool useHistoryTable, SourceWithAliasExpression source, Expression where) + public DeleteExpression(ITable table, bool useHistoryTable, SourceWithAliasExpression source, Expression? where) : base(DbExpressionType.Delete) { this.Table = table; diff --git a/Signum.Engine/Linq/DbQueryProvider.cs b/Signum.Engine/Linq/DbQueryProvider.cs index 5352d43af0..1cde442546 100644 --- a/Signum.Engine/Linq/DbQueryProvider.cs +++ b/Signum.Engine/Linq/DbQueryProvider.cs @@ -31,13 +31,13 @@ public SqlPreCommandSimple GetMainSqlCommand(Expression expression) return this.Translate(expression, tr => tr.MainCommand); } - public override object Execute(Expression expression) + public override object Execute(Expression expression) /*CSBUG*/ { using (HeavyProfiler.Log("DBQuery", () => expression.Type.TypeName())) - return this.Translate(expression, tr => tr.Execute()); + return this.Translate(expression, tr => tr.Execute()!); } - public async Task ExecuteAsync(Expression expression, CancellationToken token) + public async Task ExecuteAsync(Expression expression, CancellationToken token) { using (HeavyProfiler.Log("DBQuery", () => expression.Type.TypeName())) return await this.Translate(expression, tr => tr.ExecuteAsync(token)); diff --git a/Signum.Engine/Linq/ExpressionVisitor/AliasProjectionReplacer.cs b/Signum.Engine/Linq/ExpressionVisitor/AliasProjectionReplacer.cs index f76ba0299f..6e52354c4b 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/AliasProjectionReplacer.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/AliasProjectionReplacer.cs @@ -1,19 +1,24 @@ -using System.Linq.Expressions; +using System.Linq.Expressions; namespace Signum.Engine.Linq { internal class AliasProjectionReplacer : DbExpressionVisitor { - ProjectionExpression root; + ProjectionExpression? root; AliasGenerator aliasGenerator; + public AliasProjectionReplacer(ProjectionExpression? root, AliasGenerator aliasGenerator) + { + this.root = root; + this.aliasGenerator = aliasGenerator; + } + public static Expression Replace(Expression proj, AliasGenerator aliasGenerator) { - AliasProjectionReplacer apr = new AliasProjectionReplacer() - { - aliasGenerator = aliasGenerator, - root = proj as ProjectionExpression, - }; + AliasProjectionReplacer apr = new AliasProjectionReplacer( + root: proj as ProjectionExpression, + aliasGenerator : aliasGenerator + ); return apr.Visit(proj); } diff --git a/Signum.Engine/Linq/ExpressionVisitor/AliasReplacer.cs b/Signum.Engine/Linq/ExpressionVisitor/AliasReplacer.cs index 466670b3cf..2c77f47c13 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/AliasReplacer.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/AliasReplacer.cs @@ -8,16 +8,18 @@ namespace Signum.Engine.Linq { internal class AliasReplacer : DbExpressionVisitor { - Dictionary aliasMap; + readonly Dictionary aliasMap; - private AliasReplacer() { } + private AliasReplacer(Dictionary aliasMap) + { + this.aliasMap = aliasMap; + } public static Expression Replace(Expression source, AliasGenerator aliasGenerator) { - AliasReplacer ap = new AliasReplacer() - { - aliasMap = DeclaredAliasGatherer.GatherDeclared(source).Reverse().ToDictionary(a => a, aliasGenerator.CloneAlias) - }; + var aliasMap = DeclaredAliasGatherer.GatherDeclared(source).Reverse().ToDictionary(a => a, aliasGenerator.CloneAlias); + + AliasReplacer ap = new AliasReplacer(aliasMap); return ap.Visit(source); } @@ -39,7 +41,7 @@ protected internal override Expression VisitTable(TableExpression table) protected internal override Expression VisitSelect(SelectExpression select) { Expression top = this.Visit(select.Top); - SourceExpression from = this.VisitSource(select.From); + SourceExpression from = this.VisitSource(select.From!); Expression where = this.Visit(select.Where); ReadOnlyCollection columns = Visit(select.Columns, VisitColumnDeclaration); ReadOnlyCollection orderBy = Visit(select.OrderBy, VisitOrderBy); diff --git a/Signum.Engine/Linq/ExpressionVisitor/ChildProjectionFlattener.cs b/Signum.Engine/Linq/ExpressionVisitor/ChildProjectionFlattener.cs index cb84a3187d..a24344c1a7 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/ChildProjectionFlattener.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/ChildProjectionFlattener.cs @@ -14,36 +14,16 @@ namespace Signum.Engine.Linq internal class ChildProjectionFlattener : DbExpressionVisitor { SelectExpression? currentSource; - AliasGenerator aliasGenerator; - private ChildProjectionFlattener(){} + readonly AliasGenerator aliasGenerator; - public Type? inMList = null; - - protected internal override Expression VisitMListProjection(MListProjectionExpression mlp) - { - var oldInEntity = inMList; - inMList = mlp.Type; - var result = VisitProjection(mlp.Projection); - inMList = oldInEntity; - return result; - } - - private static PropertyInfo GetOrderColumn(Type type) + private ChildProjectionFlattener(AliasGenerator aliasGenerator) { - if (!typeof(ICanBeOrdered).IsAssignableFrom(type)) - throw new InvalidOperationException($"Type '{type.Name}' should implement '{nameof(ICanBeOrdered)}'"); - - var pi = type.GetProperty(nameof(ICanBeOrdered.Order), BindingFlags.Instance | BindingFlags.Public); - - if (pi == null) - throw new InvalidOperationException("Order Property not found"); - - return pi; + this.aliasGenerator = aliasGenerator; } static internal ProjectionExpression Flatten(ProjectionExpression proj, AliasGenerator aliasGenerator) { - var result = (ProjectionExpression)new ChildProjectionFlattener { aliasGenerator = aliasGenerator }.Visit(proj); + var result = (ProjectionExpression)new ChildProjectionFlattener(aliasGenerator).Visit(proj); if (result == proj) return result; @@ -53,6 +33,16 @@ static internal ProjectionExpression Flatten(ProjectionExpression proj, AliasGen return (ProjectionExpression)subqueryCleaned; } + public Type? inMList = null; + protected internal override Expression VisitMListProjection(MListProjectionExpression mlp) + { + var oldInEntity = inMList; + inMList = mlp.Type; + var result = VisitProjection(mlp.Projection); + inMList = oldInEntity; + return result; + } + protected internal override Expression VisitProjection(ProjectionExpression proj) { if (currentSource == null) @@ -119,7 +109,7 @@ protected internal override Expression VisitProjection(ProjectionExpression proj List columnsSMExternal = externalColumns.Select(ce => generatorSM.MapColumn(ce)).ToList(); List columnsSMInternal = proj.Select.Columns.Select(cd => generatorSM.MapColumn(cd.GetReference(proj.Select.Alias))).ToList(); - SelectExpression @internal = ExtractOrders(proj.Select, out List innerOrders); + SelectExpression @internal = ExtractOrders(proj.Select, out List? innerOrders); Alias aliasSM = aliasGenerator.GetUniqueAlias(@internal.Alias.Name + "SM"); SelectExpression selectMany = new SelectExpression(aliasSM, false, null, columnsSMExternal.Concat(columnsSMInternal), @@ -162,7 +152,7 @@ private SelectExpression WithoutOrder(SelectExpression sel) return new SelectExpression(sel.Alias, sel.IsDistinct, sel.Top, sel.Columns, sel.From, sel.Where, null, sel.GroupBy, sel.SelectOptions); } - private SelectExpression ExtractOrders(SelectExpression sel, out List innerOrders) + private SelectExpression ExtractOrders(SelectExpression sel, out List? innerOrders) { if (sel.Top != null || (sel.OrderBy.Count == 0)) { @@ -258,7 +248,7 @@ private static IEnumerable KeysTable(TableExpression table) if (table.Table is Table t && t.IsView) yield return new ColumnExpression(typeof(int), table.Alias, t.Columns.Values.Single(a => a.PrimaryKey).Name); else - yield return new ColumnExpression(typeof(int), table.Alias, table.Table.PrimaryKey.Name); + yield return new ColumnExpression(typeof(int), table.Alias, table!.Table.PrimaryKey.Name); /*CSBUG*/ } private static IEnumerable KeysSelect(SelectExpression select) @@ -266,7 +256,7 @@ private static IEnumerable KeysSelect(SelectExpression select) if (select.GroupBy.Any()) return select.GroupBy.Select(ce => select.Columns.FirstOrDefault(cd => cd.Expression.Equals(ce) /*could be improved*/)?.Let(cd => cd.GetReference(select.Alias))).ToList(); - IEnumerable inner = Keys(select.From); + IEnumerable inner = Keys(select.From!); var result = inner.Select(ce => select.Columns.FirstOrDefault(cd => cd.Expression.Equals(ce))?.Let(cd => cd.GetReference(select.Alias))).ToList(); @@ -287,11 +277,16 @@ private static IEnumerable KeysSelect(SelectExpression select) internal class ColumnReplacer : DbExpressionVisitor { - Dictionary Replacements; + readonly Dictionary Replacements; + + public ColumnReplacer(Dictionary replacements) + { + Replacements = replacements; + } public static Expression Replace(Expression expression, Dictionary replacements) { - return new ColumnReplacer { Replacements = replacements }.Visit(expression); + return new ColumnReplacer(replacements).Visit(expression); } protected internal override Expression VisitColumn(ColumnExpression column) @@ -307,18 +302,17 @@ protected internal override Expression VisitChildProjection(ChildProjectionExpre internal class ExternalColumnGatherer : DbExpressionVisitor { - Alias externalAlias; - - HashSet columns = new HashSet(); - - private ExternalColumnGatherer() { } + readonly Alias externalAlias; + readonly HashSet columns = new HashSet(); + public ExternalColumnGatherer(Alias externalAlias) + { + this.externalAlias = externalAlias; + } + public static HashSet Gatherer(Expression source, Alias externalAlias) { - ExternalColumnGatherer ap = new ExternalColumnGatherer() - { - externalAlias = externalAlias - }; + ExternalColumnGatherer ap = new ExternalColumnGatherer(externalAlias); ap.Visit(source); diff --git a/Signum.Engine/Linq/ExpressionVisitor/ColumnProjector.cs b/Signum.Engine/Linq/ExpressionVisitor/ColumnProjector.cs index bbb34f6bc9..9ee029e943 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/ColumnProjector.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/ColumnProjector.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq.Expressions; @@ -32,9 +32,13 @@ internal class ColumnProjector : DbExpressionVisitor HashSet candidates; Alias newAlias; bool projectTrivialColumns; - - - private ColumnProjector() { } + + public ColumnProjector(HashSet candidates, Alias newAlias, bool projectTrivialColumns) + { + this.candidates = candidates; + this.newAlias = newAlias; + this.projectTrivialColumns = projectTrivialColumns; + } static internal ColumnExpression SingleProjection(ColumnDeclaration declaration, Alias newAlias, Type columnType) { @@ -45,19 +49,13 @@ static internal ProjectedColumns ProjectColumns(Expression projector, Alias newA { var candidates = DbExpressionNominator.Nominate(projector, out Expression newProj, isGroupKey: isGroupKey); - ColumnProjector cp = new ColumnProjector - { - newAlias = newAlias, - candidates = candidates, - projectTrivialColumns = selectTrivialColumns - }; + ColumnProjector cp = new ColumnProjector(candidates, newAlias, selectTrivialColumns); Expression e = cp.Visit(newProj); - return new ProjectedColumns(e, cp.generator.Columns.ToReadOnly()); + return new ProjectedColumns(e, cp.generator.Columns.NotNull().ToReadOnly()); } - - + public override Expression Visit(Expression expression) { if (this.candidates.Contains(expression)) @@ -105,16 +103,16 @@ internal class ColumnUnionProjector : DbExpressionVisitor UnionAllRequest request; Type implementation; - private ColumnUnionProjector() { } - + public ColumnUnionProjector(HashSet candidates, UnionAllRequest request, Type implementation) + { + this.candidates = candidates; + this.request = request; + this.implementation = implementation; + } + static internal Expression Project(Expression projector, HashSet candidates, UnionAllRequest request, Type implementation) { - ColumnUnionProjector cp = new ColumnUnionProjector - { - request = request, - implementation = implementation, - candidates = candidates, - }; + ColumnUnionProjector cp = new ColumnUnionProjector(candidates, request, implementation); return cp.Visit(projector);; } @@ -137,6 +135,7 @@ public override Expression Visit(Expression expression) } else { + expression = expression! /*CSBUG*/; if (expression.Type.UnNullify().IsEnum) { var convert = expression.TryConvert(expression.Type.IsNullable() ? typeof(int?) : typeof(int)); @@ -169,9 +168,9 @@ public ColumnGenerator(IEnumerable columns) this.columns.Add(item.Name ?? "-", item); } - public IEnumerable Columns { get { return columns.Values; } } + public IEnumerable Columns { get { return columns.Values; } } - Dictionary columns = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + Dictionary columns = new Dictionary(StringComparer.InvariantCultureIgnoreCase); int iColumn; public string GetUniqueColumnName(string name) diff --git a/Signum.Engine/Linq/ExpressionVisitor/ConditionsRewriter.cs b/Signum.Engine/Linq/ExpressionVisitor/ConditionsRewriter.cs index 25953eab3b..149dacebf9 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/ConditionsRewriter.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/ConditionsRewriter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq.Expressions; using Signum.Utilities; using System.Collections.ObjectModel; @@ -23,13 +23,13 @@ public IDisposable InSql() return new Disposable(() => inSql = oldInSelect); } - static BinaryExpression TrueCondition = Expression.Equal(new SqlConstantExpression(1), new SqlConstantExpression(1)); - static BinaryExpression FalseCondition = Expression.Equal(new SqlConstantExpression(1), new SqlConstantExpression(0)); + static readonly BinaryExpression TrueCondition = Expression.Equal(new SqlConstantExpression(1), new SqlConstantExpression(1)); + static readonly BinaryExpression FalseCondition = Expression.Equal(new SqlConstantExpression(1), new SqlConstantExpression(0)); Expression MakeSqlCondition(Expression exp) { if (exp == null) - return null; + return null!; if (!inSql || !IsBooleanExpression(exp)) return exp; @@ -53,7 +53,7 @@ Expression MakeSqlCondition(Expression exp) Expression MakeSqlValue(Expression exp) { if (exp == null) - return null; + return null!; if (!inSql || !IsBooleanExpression(exp)) return exp; @@ -114,7 +114,7 @@ static bool IsSqlCondition(Expression expression) } var exp = expression as DbExpression; - switch (exp.DbNodeType) + switch (exp!.DbNodeType) /*CSBUG*/ { case DbExpressionType.Exists: case DbExpressionType.Like: @@ -167,16 +167,16 @@ protected internal override Expression VisitSqlCast(SqlCastExpression castExpr) private bool IsTrue(Expression operand) { - return operand == TrueCondition || (operand is SqlConstantExpression && ((SqlConstantExpression)operand).Value.Equals(1)); + return operand == TrueCondition || (operand is SqlConstantExpression c && object.Equals(c.Value, 1)); } private bool IsFalse(Expression operand) { - return operand == FalseCondition || (operand is SqlConstantExpression && ((SqlConstantExpression)operand).Value.Equals(0)); + return operand == FalseCondition || (operand is SqlConstantExpression c && object.Equals(c.Value, 0)); } - static ConstantExpression False = Expression.Constant(false); - static ConstantExpression True = Expression.Constant(true); + static readonly ConstantExpression False = Expression.Constant(false); + static readonly ConstantExpression True = Expression.Constant(true); Expression SmartAnd(Expression left, Expression right, bool sortCircuit) { @@ -317,7 +317,7 @@ protected internal override Expression VisitAggregate(AggregateExpression aggreg protected internal override Expression VisitSelect(SelectExpression select) { Expression top = this.Visit(select.Top); - SourceExpression from = this.VisitSource(select.From); + SourceExpression from = this.VisitSource(select.From!); Expression where = MakeSqlCondition(this.Visit(select.Where)); ReadOnlyCollection columns = Visit(select.Columns, VisitColumnDeclaration); ReadOnlyCollection orderBy = Visit(select.OrderBy, VisitOrderBy); diff --git a/Signum.Engine/Linq/ExpressionVisitor/DbExpressionComparer.cs b/Signum.Engine/Linq/ExpressionVisitor/DbExpressionComparer.cs index 629d0f0528..4e2d8390d3 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/DbExpressionComparer.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/DbExpressionComparer.cs @@ -34,7 +34,7 @@ public static bool AreEqual(Expression a, Expression b, ScopedDictionary candidates = new HashSet(); + readonly HashSet candidates = new HashSet(); T Add(T expression) where T : Expression? { @@ -89,8 +89,7 @@ public override Expression Visit(Expression? exp) private bool IsExcluded(Expression exp) { - DbExpression? expDb = exp as DbExpression; - if (expDb == null) + if (!(exp is DbExpression expDb)) return false; switch (expDb.DbNodeType) @@ -572,18 +571,7 @@ protected Expression GetFormatToString(MethodCallExpression m, string? defaultFo return Add(result); } - - private Expression DateAdd(SqlEnums part, Expression dateExpression, Expression intExpression) - { - return new SqlFunctionExpression(typeof(DateTime), null, SqlFunction.DATEADD.ToString(), new Expression[] { new SqlEnumExpression(part), dateExpression, intExpression }); - } - - private Expression MinusDatePart(SqlEnums part, Expression dateExpression) - { - return Expression.Negate(new SqlFunctionExpression(typeof(int), null, SqlFunction.DATEPART.ToString(), new Expression[] { new SqlEnumExpression(part), dateExpression })); - } - - + protected override Expression VisitBinary(BinaryExpression b) { if (b.NodeType == ExpressionType.Equal || b.NodeType == ExpressionType.NotEqual) @@ -890,7 +878,7 @@ private Expression ConvertAvoidNominate(BinaryExpression b) throw new InvalidOperationException(); } - static MethodInfo miSimpleConcat = ReflectionTools.GetMethodInfo(() => string.Concat("a", "b")); + static readonly MethodInfo miSimpleConcat = ReflectionTools.GetMethodInfo(() => string.Concat("a", "b")); protected override Expression VisitConditional(ConditionalExpression c) @@ -1284,9 +1272,11 @@ protected override Expression VisitMember(MemberExpression m) { case "string.IndexOf": { - Expression startIndex = m.TryGetArgument("startIndex")?.Let(e => Expression.Add(e, new SqlConstantExpression(1))); + Expression? startIndex = m.TryGetArgument("startIndex")?.Let(e => Expression.Add(e, new SqlConstantExpression(1))); - Expression? charIndex = TrySqlFunction(null, SqlFunction.CHARINDEX, m.Type, m.GetArgument("value"), m.Object, startIndex); + Expression? charIndex = startIndex != null ? + TrySqlFunction(null, SqlFunction.CHARINDEX, m.Type, m.GetArgument("value"), m.Object, startIndex) : + TrySqlFunction(null, SqlFunction.CHARINDEX, m.Type, m.GetArgument("value"), m.Object); if (charIndex == null) return null; Expression result = Expression.Subtract(charIndex, new SqlConstantExpression(1)); @@ -1458,7 +1448,7 @@ protected override Expression VisitMember(MemberExpression m) return Add(acum); } - private Expression? TryEtc(Expression str, Expression max, Expression etcString) + private Expression? TryEtc(Expression str, Expression max, Expression? etcString) { var newStr = Visit(str); if (!Has(newStr)) @@ -1472,8 +1462,8 @@ protected override Expression VisitMember(MemberExpression m) Expression.Call(miEtc3, newStr, max, etcString); } - static MethodInfo miEtc2 = ReflectionTools.GetMethodInfo(() => "".Etc(2)); - static MethodInfo miEtc3 = ReflectionTools.GetMethodInfo(() => "".Etc(2, "...")); + static readonly MethodInfo miEtc2 = ReflectionTools.GetMethodInfo(() => "".Etc(2)); + static readonly MethodInfo miEtc3 = ReflectionTools.GetMethodInfo(() => "".Etc(2, "...")); IDisposable ForceFullNominate() { diff --git a/Signum.Engine/Linq/ExpressionVisitor/DbExpressionVisitor.cs b/Signum.Engine/Linq/ExpressionVisitor/DbExpressionVisitor.cs index 8e92f16d28..d78cfdd03f 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/DbExpressionVisitor.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/DbExpressionVisitor.cs @@ -99,12 +99,10 @@ protected internal virtual Expression VisitTypeEntity(TypeEntityExpression typeF [DebuggerStepThrough] protected static ReadOnlyDictionary Visit(ReadOnlyDictionary dictionary, Func newValue) + where K : object where V : class { - if (dictionary == null) - return null; - - Dictionary alternate = null; + Dictionary? alternate = null; foreach (var k in dictionary.Keys) { V item = dictionary[k]; @@ -310,7 +308,7 @@ protected internal virtual Expression VisitIn(InExpression @in) if (select != null) return new InExpression(expression, select); else - return InExpression.FromValues(expression, @in.Values); + return InExpression.FromValues(expression, @in.Values!); } return @in; } @@ -359,7 +357,7 @@ protected internal virtual Expression VisitAggregateRequest(AggregateRequestsExp protected internal virtual Expression VisitSelect(SelectExpression select) { Expression top = this.Visit(select.Top); - SourceExpression from = this.VisitSource(select.From); + SourceExpression from = this.VisitSource(select.From!); Expression where = this.Visit(select.Where); ReadOnlyCollection columns = Visit(select.Columns, VisitColumnDeclaration); ReadOnlyCollection orderBy = Visit(select.OrderBy, VisitOrderBy); @@ -385,8 +383,8 @@ protected internal virtual Expression VisitJoin(JoinExpression join) protected internal virtual Expression VisitSetOperator(SetOperatorExpression set) { - SourceWithAliasExpression left = (SourceWithAliasExpression)this.VisitSource(set.Left); - SourceWithAliasExpression right = (SourceWithAliasExpression)this.VisitSource(set.Right); + SourceWithAliasExpression left = (SourceWithAliasExpression)this.VisitSource(set.Left)!; + SourceWithAliasExpression right = (SourceWithAliasExpression)this.VisitSource(set.Right)!; if (left != set.Left || right != set.Right) { return new SetOperatorExpression(set.Operator, left, right, set.Alias); diff --git a/Signum.Engine/Linq/ExpressionVisitor/EntityCompleter.cs b/Signum.Engine/Linq/ExpressionVisitor/EntityCompleter.cs index 9b72bb40dc..8819a55069 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/EntityCompleter.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/EntityCompleter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using System.Linq.Expressions; using Signum.Entities; @@ -11,12 +11,17 @@ namespace Signum.Engine.Linq { internal class EntityCompleter : DbExpressionVisitor { - QueryBinder binder; + readonly QueryBinder binder; ImmutableStack previousTypes = ImmutableStack.Empty; + public EntityCompleter(QueryBinder binder) + { + this.binder = binder; + } + public static Expression Complete(Expression source, QueryBinder binder) { - EntityCompleter pc = new EntityCompleter() { binder = binder }; + EntityCompleter pc = new EntityCompleter(binder); var result = pc.Visit(source); @@ -41,7 +46,7 @@ protected internal override Expression VisitLiteReference(LiteReferenceExpressio return new LiteValueExpression(lite.Type, typeId, id, toStr); } - private Expression LiteToString(LiteReferenceExpression lite, Expression typeId) + private Expression? LiteToString(LiteReferenceExpression lite, Expression typeId) { if (lite.CustomToStr != null) return Visit(lite.CustomToStr); @@ -101,7 +106,7 @@ protected internal override Expression VisitEntity(EntityExpression ee) previousTypes = previousTypes.Push(ee.Type); - var bindings = VisitBindings(ee.Bindings); + var bindings = VisitBindings(ee.Bindings!); var mixins = Visit(ee.Mixins, VisitMixinEntity); @@ -179,7 +184,7 @@ protected internal override Expression VisitAdditionalField(AdditionalFieldExpre if (newEx is ProjectionExpression newProj && newProj.Projector.Type.IsInstantiationOf(typeof(MList<>.RowIdElement))) return new MListProjectionExpression(afe.Type, newProj); - return newEx; + return newEx!; /*CSBUG*/ } protected internal override Expression VisitProjection(ProjectionExpression proj) diff --git a/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs b/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs index a0118e2278..2466d16d64 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs @@ -85,7 +85,7 @@ public Expression BindQuery(Expression expression) if (m.Arguments.Count == 2) return this.BindSelectMany(m.Type, m.GetArgument("source"), m.GetArgument("selector").StripQuotes(), null); else - return this.BindSelectMany(m.Type, m.GetArgument("source"), m.GetArgument("collectionSelector").StripQuotes(), m.TryGetArgument("resultSelector").StripQuotes()); + return this.BindSelectMany(m.Type, m.GetArgument("source"), m.GetArgument("collectionSelector").StripQuotes(), m.TryGetArgument("resultSelector")?.StripQuotes()); case "Join": return this.BindJoin( m.Type, m.GetArgument("outer"), m.GetArgument("inner"), @@ -105,14 +105,14 @@ public Expression BindQuery(Expression expression) m.GetArgument("keySelector").StripQuotes(), m.GetArgument("elementSelector").StripQuotes()); case "Any": - return this.BindAnyAll(m.Type, m.GetArgument("source"), m.TryGetArgument("predicate").StripQuotes(), m.Method, m == root); + return this.BindAnyAll(m.Type, m.GetArgument("source"), m.TryGetArgument("predicate")?.StripQuotes(), m.Method, m == root); case "All": return this.BindAnyAll(m.Type, m.GetArgument("source"), m.GetArgument("predicate").StripQuotes(), m.Method, m == root); case "Contains": return this.BindContains(m.Type, m.GetArgument("source"), m.TryGetArgument("item") ?? m.GetArgument("value"), m == root); case "Count": return this.BindAggregate(m.Type, m.Method.Name.ToEnum(), - m.GetArgument("source"), m.TryGetArgument("predicate").StripQuotes(), m == root); + m.GetArgument("source"), m.TryGetArgument("predicate")?.StripQuotes(), m == root); case "Sum": case "Min": case "Max": @@ -120,19 +120,19 @@ public Expression BindQuery(Expression expression) case "StdDev": case "StdDevP": return this.BindAggregate(m.Type, m.Method.Name.ToEnum(), - m.GetArgument("source"), m.TryGetArgument("selector").StripQuotes(), m == root); + m.GetArgument("source"), m.TryGetArgument("selector")?.StripQuotes(), m == root); case "First": case "FirstOrDefault": case "Single": case "SingleOrDefault": return BindUniqueRow(m.Type, m.Method.Name.ToEnum(), - m.GetArgument("source"), m.TryGetArgument("predicate").StripQuotes(), m == root); + m.GetArgument("source"), m.TryGetArgument("predicate")?.StripQuotes(), m == root); case "FirstEx": case "SingleEx": case "SingleOrDefaultEx": return BindUniqueRow(m.Type, m.Method.Name.RemoveEnd(2).ToEnum(), - m.GetArgument("collection"), m.TryGetArgument("predicate").StripQuotes(), m == root); + m.GetArgument("collection"), m.TryGetArgument("predicate")?.StripQuotes(), m == root); case "Distinct": return BindDistinct(m.Type, m.GetArgument("source")); case "Reverse": @@ -473,7 +473,7 @@ private Expression BindTake(Type resultType, Expression source, Expression count //Avoid self referencing SQL problems bool inTableValuedFunction = false; public Dictionary uniqueFunctionReplacements = new Dictionary(DbExpressionComparer.GetComparer(false)); - private Expression BindUniqueRow(Type resultType, UniqueFunction function, Expression source, LambdaExpression predicate, bool isRoot) + private Expression BindUniqueRow(Type resultType, UniqueFunction function, Expression source, LambdaExpression? predicate, bool isRoot) { ProjectionExpression rawProjector = this.VisitCastProjection(source); @@ -745,7 +745,7 @@ bool ExtractDistinct(Expression? source, out Expression? innerSource) } - private Expression? BindAggregate(Type resultType, AggregateSqlFunction aggregateFunction, Expression source, LambdaExpression selectorOrPredicate, bool isRoot) + private Expression? BindAggregate(Type resultType, AggregateSqlFunction aggregateFunction, Expression source, LambdaExpression? selectorOrPredicate, bool isRoot) { var (newSource, selector, distinct) = DisassembleAggregate(aggregateFunction, source, selectorOrPredicate, isRoot); @@ -865,7 +865,7 @@ static Expression RestoreWrappedType(Expression expression, Type wrapType) } - private Expression BindAnyAll(Type resultType, Expression source, LambdaExpression predicate, MethodInfo method, bool isRoot) + private Expression BindAnyAll(Type resultType, Expression source, LambdaExpression? predicate, MethodInfo method, bool isRoot) { bool isAll = method.Name == "All"; @@ -875,7 +875,7 @@ private Expression BindAnyAll(Type resultType, Expression source, LambdaExpressi if (source is ConstantExpression constSource && !typeof(IQueryable).IsAssignableFrom(constSource.Type)) { System.Diagnostics.Debug.Assert(!isRoot); - Type oType = predicate.Parameters[0].Type; + Type oType = predicate!.Parameters[0].Type; Expression[] exp = ((IEnumerable)constSource.Value).Cast().Select(o => Expression.Invoke(predicate, Expression.Constant(o, oType))).ToArray(); Expression where = isAll ? exp.AggregateAnd() : exp.AggregateOr(); @@ -885,7 +885,7 @@ private Expression BindAnyAll(Type resultType, Expression source, LambdaExpressi else { if (isAll) - predicate = Expression.Lambda(Expression.Not(predicate.Body), predicate.Parameters.ToArray()); + predicate = Expression.Lambda(Expression.Not(predicate!.Body), predicate!.Parameters.ToArray()); if (predicate != null) source = Expression.Call(typeof(Enumerable), "Where", method.GetGenericArguments(), source, predicate); @@ -2192,7 +2192,7 @@ internal CommandExpression BindDelete(Expression source) if (pr.Projector is EntityExpression ee) { - Expression id = ee.Table.GetIdExpression(aliasGenerator.Table(ee.Table.GetName(isHistory))); + Expression id = ee.Table.GetIdExpression(aliasGenerator.Table(ee.Table.GetName(isHistory)))!; commands.AddRange(ee.Table.TablesMList().Select(t => { @@ -2212,7 +2212,7 @@ internal CommandExpression BindDelete(Expression source) { var vn = eee.ViewTable!; - Expression id = vn.GetIdExpression(aliasGenerator.Table(vn.Name)); + Expression id = vn.GetIdExpression(aliasGenerator.Table(vn.Name)).ThrowIfNull(() => $"{vn.Name} has no primary name"); commands.Add(new DeleteExpression(vn, false, pr.Select, SmartEqualizer.EqualNullable(id, eee.GetViewId()))); } @@ -2283,7 +2283,7 @@ internal CommandExpression BindUpdate(Expression source, LambdaExpression? partS if (entity is EntityExpression ee) { - Expression id = ee.Table.GetIdExpression(aliasGenerator.Table(ee.Table.GetName(isHistory))); + Expression id = ee.Table.GetIdExpression(aliasGenerator.Table(ee.Table.GetName(isHistory)))!; condition = SmartEqualizer.EqualNullable(id, ee.ExternalId); table = ee.Table; @@ -2297,7 +2297,7 @@ internal CommandExpression BindUpdate(Expression source, LambdaExpression? partS } else if (entity is EmbeddedEntityExpression eee) { - Expression id = eee.ViewTable!.GetIdExpression(aliasGenerator.Table(eee.ViewTable!.GetName(isHistory))); + Expression id = eee.ViewTable!.GetIdExpression(aliasGenerator.Table(eee.ViewTable!.GetName(isHistory))).ThrowIfNull(() => $"{eee.ViewTable} has not primary key"); condition = SmartEqualizer.EqualNullable(id, eee.GetViewId()); table = eee.ViewTable!; @@ -2643,9 +2643,9 @@ public EntityExpression Completed(EntityExpression entity) { var table = entity.Table; var newAlias = NextTableAlias(table.Name); - var id = table.GetIdExpression(newAlias); + var id = table.GetIdExpression(newAlias)!; var period = table.GenerateSystemPeriod(newAlias, this); - var intersect = period.Intesection(entity.ExternalPeriod); + var intersect = period.Intesection(entity.ExternalPeriod); //TODO intersect not used! var bindings = table.GenerateBindings(newAlias, this, id, period); var mixins = table.GenerateMixins(newAlias, this, id, period); diff --git a/Signum.Engine/Linq/ExpressionVisitor/QueryFormatter.cs b/Signum.Engine/Linq/ExpressionVisitor/QueryFormatter.cs index 41b669c6d3..c6c0c5aafb 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/QueryFormatter.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/QueryFormatter.cs @@ -19,9 +19,6 @@ namespace Signum.Engine.Linq /// internal class QueryFormatter : DbExpressionVisitor { - public static readonly ThreadVariable> PostFormatter = Statics.ThreadVariable>("QueryFormatterPostFormatter"); - - StringBuilder sb = new StringBuilder(); int indent = 2; int depth; @@ -33,6 +30,12 @@ class DbParameterPair { internal DbParameter Parameter; internal string Name; + + public DbParameterPair(DbParameter parameter, string name) + { + Parameter = parameter; + Name = name; + } } @@ -45,7 +48,7 @@ public string GetNextParamAlias() return "@p" + (parameter++); } - MethodInfo miCreateParameter = ReflectionTools.GetMethodInfo((ParameterBuilder s) => s.CreateParameter(null, SqlDbType.BigInt, null, false, null)); + MethodInfo miCreateParameter = ReflectionTools.GetMethodInfo((ParameterBuilder s) => s.CreateParameter(null!, SqlDbType.BigInt, null, false, null)); DbParameterPair CreateParameter(ConstantExpression value) { @@ -60,11 +63,9 @@ DbParameterPair CreateParameter(ConstantExpression value) var pb = Connector.Current.ParameterBuilder; - return new DbParameterPair - { - Parameter = pb.CreateParameter(name, typePair.SqlDbType, typePair.UserDefinedTypeName, nullable, value.Value ?? DBNull.Value), - Name = name - }; + var param = pb.CreateParameter(name, typePair.SqlDbType, typePair.UserDefinedTypeName, nullable, value.Value ?? DBNull.Value); + + return new DbParameterPair(param, name); } ObjectNameOptions objectNameOptions; @@ -83,7 +84,7 @@ static internal SqlPreCommandSimple Format(Expression expression) var sqlpc = new SqlPreCommandSimple(qf.sb.ToString(), parameters); - return PostFormatter.Value == null ? sqlpc : PostFormatter.Value.Invoke(sqlpc); + return sqlpc; } protected enum Indentation @@ -673,7 +674,7 @@ protected internal override SourceExpression VisitSource(SourceExpression source else this.VisitJoin((JoinExpression)source); - return source; + return source!; /*CSBUG*/ } protected internal override Expression VisitJoin(JoinExpression join) @@ -1000,25 +1001,4 @@ private InvalidOperationException InvalidSqlExpression(Expression expression) } } - - - - - public class QueryPostFormatter : IDisposable - { - Func prePostFormatter = null; - - public QueryPostFormatter(Func postFormatter) - { - prePostFormatter = QueryFormatter.PostFormatter.Value; - - QueryFormatter.PostFormatter.Value = postFormatter; - } - - public void Dispose() - { - QueryFormatter.PostFormatter.Value = prePostFormatter; - } - } - } diff --git a/Signum.Engine/Linq/ExpressionVisitor/QueryRebinder.cs b/Signum.Engine/Linq/ExpressionVisitor/QueryRebinder.cs index c443829c60..398d6675a0 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/QueryRebinder.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/QueryRebinder.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; @@ -13,15 +13,15 @@ internal class QueryRebinder : DbExpressionVisitor { ImmutableStack> scopes = ImmutableStack>.Empty; - public Dictionary CurrentScope { get { return scopes.Peek(); } } + public Dictionary CurrentScope { get { return scopes.Peek(); } } private QueryRebinder() { } internal class ColumnCollector : DbExpressionVisitor { - internal Alias[] knownAliases; - internal Dictionary currentScope; + internal Alias[] knownAliases = null!; + internal Dictionary currentScope = null!; protected internal override Expression VisitColumn(ColumnExpression column) { @@ -135,7 +135,7 @@ private SourceWithAliasExpression VisitSetOperatorPart(SourceWithAliasExpression { using (NewScope()) { - CurrentScope.AddRange(askedColumns.ToDictionary(c => new ColumnExpression(c.Type, part.Alias, c.Name), c => (ColumnExpression)null)); + CurrentScope.AddRange(askedColumns.ToDictionary(c => new ColumnExpression(c.Type, part.Alias, c.Name), c => (ColumnExpression?)null)); return (SourceWithAliasExpression)Visit(part); } } @@ -185,8 +185,8 @@ protected internal override Expression VisitInsertSelect(InsertSelectExpression protected internal override Expression VisitSelect(SelectExpression select) { - Dictionary askedColumns = CurrentScope.Keys.Where(k => select.KnownAliases.Contains(k.Alias)).ToDictionary(k => k, k => (ColumnExpression)null); - Dictionary externalAnswers = CurrentScope.Where(kvp => !select.KnownAliases.Contains(kvp.Key.Alias) && kvp.Value != null).ToDictionary(); + Dictionary askedColumns = CurrentScope.Keys.Where(k => select.KnownAliases.Contains(k.Alias)).ToDictionary(k => k, k => (ColumnExpression)null); + Dictionary externalAnswers = CurrentScope.Where(kvp => !select.KnownAliases.Contains(kvp.Key.Alias) && kvp.Value != null).ToDictionary(); var disposable = NewScope();//SCOPE START var scope = CurrentScope; @@ -203,7 +203,7 @@ protected internal override Expression VisitSelect(SelectExpression select) foreach (var e in select.GroupBy) col.Visit(e); - SourceExpression from = this.VisitSource(select.From); + SourceExpression from = this.VisitSource(select.From!); Expression top = this.Visit(select.Top); Expression where = this.Visit(select.Where); ReadOnlyCollection orderBy = Visit(select.OrderBy, VisitOrderBy); @@ -244,7 +244,7 @@ private static ReadOnlyCollection RemoveDuplicates(ReadOnlyColl return result.AsReadOnly(); } - private ReadOnlyCollection AnswerAndExpand(ReadOnlyCollection columns, Alias currentAlias, Dictionary askedColumns) + private ReadOnlyCollection AnswerAndExpand(ReadOnlyCollection columns, Alias currentAlias, Dictionary askedColumns) { ColumnGenerator cg = new ColumnGenerator(columns); @@ -258,7 +258,7 @@ private ReadOnlyCollection AnswerAndExpand(ReadOnlyCollection } else { - ColumnExpression colExp = CurrentScope[col]; + ColumnExpression? colExp = CurrentScope[col]; //if (expr is ColumnExpression colExp) //{ ColumnDeclaration cd = cg.Columns.FirstOrDefault(c => c.Expression.Equals(colExp)); @@ -314,4 +314,4 @@ protected internal override Expression VisitScalar(ScalarExpression scalar) } -} \ No newline at end of file +} diff --git a/Signum.Engine/Linq/ExpressionVisitor/Replacer.cs b/Signum.Engine/Linq/ExpressionVisitor/Replacer.cs index 5c69b0fecb..7558ebcb3b 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/Replacer.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/Replacer.cs @@ -1,4 +1,4 @@ -using System.Linq.Expressions; +using System.Linq.Expressions; namespace Signum.Engine.Linq { @@ -10,15 +10,15 @@ internal class Replacer : DbExpressionVisitor Expression searchFor; Expression replaceWith; - private Replacer() { } + private Replacer(Expression searchFor, Expression replaceWith) + { + this.searchFor = searchFor; + this.replaceWith = replaceWith; + } static internal Expression Replace(Expression expression, Expression searchFor, Expression replaceWith) { - return new Replacer - { - searchFor = searchFor, - replaceWith = replaceWith - }.Visit(expression); + return new Replacer(searchFor, replaceWith).Visit(expression); } public override Expression Visit(Expression exp) diff --git a/Signum.Engine/Linq/ExpressionVisitor/ScalarSubqueryRewriter.cs b/Signum.Engine/Linq/ExpressionVisitor/ScalarSubqueryRewriter.cs index 99a3e830b3..f85851b420 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/ScalarSubqueryRewriter.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/ScalarSubqueryRewriter.cs @@ -1,21 +1,17 @@ -using System.Collections.ObjectModel; +using System.Collections.ObjectModel; using System.Linq.Expressions; namespace Signum.Engine.Linq { class ScalarSubqueryRewriter : DbExpressionVisitor { - SourceExpression currentFrom; - Connector connector = Connector.Current; - - bool inAggregate = false; - public static Expression Rewrite(Expression expression) { return new ScalarSubqueryRewriter().Visit(expression); } + bool inAggregate = false; protected internal override Expression VisitAggregate(AggregateExpression aggregate) { var saveInAggregate = this.inAggregate; @@ -29,6 +25,7 @@ protected internal override Expression VisitAggregate(AggregateExpression aggreg return result; } + SourceExpression? currentFrom; protected internal override Expression VisitSelect(SelectExpression select) { var saveFrom = this.currentFrom; @@ -36,7 +33,7 @@ protected internal override Expression VisitSelect(SelectExpression select) this.inAggregate = false; - SourceExpression from = this.VisitSource(select.From); + SourceExpression from = this.VisitSource(select.From!); this.currentFrom = from; Expression top = this.Visit(select.Top); @@ -66,15 +63,15 @@ protected internal override Expression VisitScalar(ScalarExpression scalar) } else { - var select = scalar.Select; + var select = scalar.Select!; if (string.IsNullOrEmpty(select.Columns[0].Name)) { select = new SelectExpression(select.Alias, select.IsDistinct, select.Top, new[] { new ColumnDeclaration("scalar", select.Columns[0].Expression) }, select.From, select.Where, select.OrderBy, select.GroupBy, select.SelectOptions); } - this.currentFrom = new JoinExpression(JoinType.OuterApply, this.currentFrom, select, null); - return new ColumnExpression(scalar.Type, scalar.Select.Alias, select.Columns[0].Name); + this.currentFrom = new JoinExpression(JoinType.OuterApply, this.currentFrom!, select, null); + return new ColumnExpression(scalar.Type, scalar.Select!.Alias, select.Columns[0].Name); } } } diff --git a/Signum.Engine/Linq/ExpressionVisitor/SubqueryRemover.cs b/Signum.Engine/Linq/ExpressionVisitor/SubqueryRemover.cs index 4a842d48a6..1e29164e9d 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/SubqueryRemover.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/SubqueryRemover.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using Signum.Utilities; @@ -9,16 +9,16 @@ internal class SubqueryRemover : DbExpressionVisitor { HashSet selectsToRemove; Dictionary> map; - - private SubqueryRemover() { } + + public SubqueryRemover(IEnumerable selectsToRemove) + { + this.map = selectsToRemove.ToDictionary(d => d.Alias, d => d.Columns.ToDictionary(d2 => d2.Name, d2 => d2.Expression)); + this.selectsToRemove = new HashSet(selectsToRemove); + } public static Expression Remove(Expression expression, IEnumerable selectsToRemove) { - return new SubqueryRemover - { - map = selectsToRemove.ToDictionary(d => d.Alias, d => d.Columns.ToDictionary(d2 => d2.Name, d2 => d2.Expression)), - selectsToRemove = new HashSet(selectsToRemove) - }.Visit(expression); + return new SubqueryRemover(selectsToRemove).Visit(expression); } protected internal override Expression VisitSelect(SelectExpression select) @@ -35,4 +35,4 @@ protected internal override Expression VisitColumn(ColumnExpression column) ?.Let(d => d.GetOrThrow(column.Name, "Reference to undefined column {0}")) ?? column; } } -} \ No newline at end of file +} diff --git a/Signum.Engine/Linq/ExpressionVisitor/TranslatorBuilder.cs b/Signum.Engine/Linq/ExpressionVisitor/TranslatorBuilder.cs index 5e6234951b..1c9d1d6855 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/TranslatorBuilder.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/TranslatorBuilder.cs @@ -18,7 +18,7 @@ internal static class TranslatorBuilder { internal static ITranslateResult Build(ProjectionExpression proj) { - Type type = proj.UniqueFunction == null ? proj.Type.ElementType() : proj.Type; + Type type = proj.UniqueFunction == null ? proj.Type.ElementType()! : proj.Type; return miBuildPrivate.GetInvoker(type)(proj); } @@ -30,27 +30,24 @@ static TranslateResult BuildPrivate(ProjectionExpression proj) var eagerChildProjections = EagerChildProjectionGatherer.Gatherer(proj).Select(cp => BuildChild(cp)).ToList(); var lazyChildProjections = LazyChildProjectionGatherer.Gatherer(proj).Select(cp => BuildChild(cp)).ToList(); - Scope scope = new Scope - { - Alias = proj.Select.Alias, - Positions = proj.Select.Columns.Select((c, i) => new { c.Name, i }).ToDictionary(p => p.Name, p => p.i), - }; + Scope scope = new Scope( + alias :proj.Select.Alias, + positions: proj.Select.Columns.Select((c, i) => new { c.Name, i }).ToDictionary(p => p.Name!, p => p.i) /*CSBUG*/ + ); Expression> lambda = ProjectionBuilder.Build(proj.Projector, scope); var command = QueryFormatter.Format(proj.Select); - var result = new TranslateResult - { - EagerProjections = eagerChildProjections, - LazyChildProjections = lazyChildProjections, - - MainCommand = command, + var result = new TranslateResult( - ProjectorExpression = lambda, + eagerProjections: eagerChildProjections, + lazyChildProjections: lazyChildProjections, - Unique = proj.UniqueFunction, - }; + mainCommand: command, + projectorExpression: lambda, + unique: proj.UniqueFunction + ); return result; } @@ -59,56 +56,46 @@ static IChildProjection BuildChild(ChildProjectionExpression childProj) { var proj = childProj.Projection; - Type type = proj.UniqueFunction == null ? proj.Type.ElementType() : proj.Type; + Type type = proj.UniqueFunction == null ? proj.Type.ElementType()! : proj.Type; if(!type.IsInstantiationOf(typeof(KeyValuePair<,>))) throw new InvalidOperationException("All child projections should create KeyValuePairs"); - Scope scope = new Scope - { - Alias = proj.Select.Alias, - Positions = proj.Select.Columns.Select((c, i) => new { c.Name, i }).ToDictionary(p => p.Name, p => p.i), - }; + Scope scope = new Scope( + alias: proj.Select.Alias, + positions: proj.Select.Columns.Select((c, i) => new { c.Name, i }).ToDictionary(p => p.Name!, p => p.i) /*CSBUG*/ + ); var types = type.GetGenericArguments(); - IChildProjection result; + var command = QueryFormatter.Format(proj.Select); + if (childProj.IsLazyMList) { types[1] = types[1].GetGenericArguments()[0]; - - result = giLazyChild.GetInvoker(types)(proj.Projector, scope); + return giLazyChild.GetInvoker(types)(proj.Projector, scope, childProj.Token, command); } else { - result = giEagerChild.GetInvoker(types)(proj.Projector, scope); + return giEagerChild.GetInvoker(types)(proj.Projector, scope, childProj.Token, command); } - - result.Token = childProj.Token; - result.Command = QueryFormatter.Format(proj.Select); - - return result; } - static GenericInvoker> giLazyChild = - new GenericInvoker>((proj, scope) => LazyChild(proj, scope)); - static IChildProjection LazyChild(Expression projector, Scope scope) + static readonly GenericInvoker> giLazyChild = + new GenericInvoker>((proj, scope, token, sql) => LazyChild(proj, scope, token, sql)); + static IChildProjection LazyChild(Expression projector, Scope scope, LookupToken token, SqlPreCommandSimple command) { - return new LazyChildProjection - { - ProjectorExpression = ProjectionBuilder.Build.RowIdElement>>(projector, scope), - }; + var proj = ProjectionBuilder.Build.RowIdElement>>(projector, scope); + return new LazyChildProjection(token, command, proj); } - static GenericInvoker> giEagerChild = - new GenericInvoker>((proj, scope) => EagerChild(proj, scope)); - static IChildProjection EagerChild(Expression projector, Scope scope) + static readonly GenericInvoker> giEagerChild = + new GenericInvoker>((proj, scope, token, sql) => EagerChild(proj, scope, token, sql)); + static IChildProjection EagerChild(Expression projector, Scope scope, LookupToken token, SqlPreCommandSimple command) { - return new EagerChildProjection - { - ProjectorExpression = ProjectionBuilder.Build>(projector, scope), - }; + var proj = ProjectionBuilder.Build>(projector, scope); + return new EagerChildProjection(token, command, proj); } public static SqlPreCommandSimple BuildCommandResult(CommandExpression command) @@ -172,34 +159,37 @@ protected internal override Expression VisitChildProjection(ChildProjectionExpre /// public class ProjectionBuilder : DbExpressionVisitor { - static ParameterExpression row = Expression.Parameter(typeof(IProjectionRow), "row"); + static readonly ParameterExpression row = Expression.Parameter(typeof(IProjectionRow), "row"); - static PropertyInfo piRetriever = ReflectionTools.GetPropertyInfo((IProjectionRow r) => r.Retriever); - static MemberExpression retriever = Expression.Property(row, piRetriever); + static readonly PropertyInfo piRetriever = ReflectionTools.GetPropertyInfo((IProjectionRow r) => r.Retriever); + static readonly MemberExpression retriever = Expression.Property(row, piRetriever); - static FieldInfo fiId = ReflectionTools.GetFieldInfo((Entity i) => i.id); + static readonly FieldInfo fiId = ReflectionTools.GetFieldInfo((Entity i) => i.id); - static MethodInfo miCached = ReflectionTools.GetMethodInfo((IRetriever r) => r.Complete(null, null)).GetGenericMethodDefinition(); - static MethodInfo miRequest = ReflectionTools.GetMethodInfo((IRetriever r) => r.Request(null)).GetGenericMethodDefinition(); - static MethodInfo miRequestIBA = ReflectionTools.GetMethodInfo((IRetriever r) => r.RequestIBA(null, null)).GetGenericMethodDefinition(); - static MethodInfo miRequestLite = ReflectionTools.GetMethodInfo((IRetriever r) => r.RequestLite(null)).GetGenericMethodDefinition(); - static MethodInfo miModifiablePostRetrieving = ReflectionTools.GetMethodInfo((IRetriever r) => r.ModifiablePostRetrieving(null)).GetGenericMethodDefinition(); + static readonly MethodInfo miCached = ReflectionTools.GetMethodInfo((IRetriever r) => r.Complete(null, null)).GetGenericMethodDefinition(); + static readonly MethodInfo miRequest = ReflectionTools.GetMethodInfo((IRetriever r) => r.Request(null)).GetGenericMethodDefinition(); + static readonly MethodInfo miRequestIBA = ReflectionTools.GetMethodInfo((IRetriever r) => r.RequestIBA(null, null)).GetGenericMethodDefinition(); + static readonly MethodInfo miRequestLite = ReflectionTools.GetMethodInfo((IRetriever r) => r.RequestLite(null)).GetGenericMethodDefinition(); + static readonly MethodInfo miModifiablePostRetrieving = ReflectionTools.GetMethodInfo((IRetriever r) => r.ModifiablePostRetrieving(null)).GetGenericMethodDefinition(); Scope scope; + public ProjectionBuilder(Scope scope) + { + this.scope = scope; + } static internal Expression> Build(Expression expression, Scope scope) { - ProjectionBuilder pb = new ProjectionBuilder() { scope = scope }; + ProjectionBuilder pb = new ProjectionBuilder(scope); Expression body = pb.Visit(expression); return Expression.Lambda>(body, row); } Expression NullifyColumn(Expression exp) { - ColumnExpression ce = exp as ColumnExpression; - if (ce == null) - return exp; + if (!(exp is ColumnExpression ce)) + return exp!; /*CSBUG*/ if (ce.Type.IsNullable() || ce.Type.IsClass) return ce; @@ -433,7 +423,7 @@ protected internal override Expression VisitLiteValue(LiteValueExpression lite) Expression nothing = Expression.Constant(null, lite.Type); - Expression liteConstructor = null; + Expression liteConstructor; if (typeId is TypeEntityExpression) { Type type = ((TypeEntityExpression)typeId).TypeValue; @@ -470,9 +460,9 @@ protected internal override Expression VisitLiteValue(LiteValueExpression lite) return Expression.Call(retriever, miRequestLite.MakeGenericMethod(Lite.Extract(lite.Type)), liteConstructor); } - static MethodInfo miLiteCreateParse = ReflectionTools.GetMethodInfo(() => LiteCreateParse(null, null, null, null)); + static readonly MethodInfo miLiteCreateParse = ReflectionTools.GetMethodInfo(() => LiteCreateParse(null, null, null, null)); - static Lite LiteCreateParse(Schema schema, PrimaryKey? typeId, string id, string toString) + static Lite? LiteCreateParse(Schema schema, PrimaryKey? typeId, string id, string toString) { if (typeId == null) return null; @@ -506,7 +496,7 @@ protected internal override Expression VisitMListElement(MListElementExpression Expression.Constant(null, init.Type)); } - private Type ConstantType(Expression typeId) + private Type? ConstantType(Expression typeId) { if (typeId.NodeType == ExpressionType.Convert) typeId = ((UnaryExpression)typeId).Operand; @@ -541,6 +531,8 @@ protected internal override Expression VisitPrimaryKeyString(PrimaryKeyStringExp static readonly MethodInfo miTryParse = ReflectionTools.GetMethodInfo(() => TryParse(null, null)); + + static PrimaryKey? TryParse(Type type, string id) { if (type == null) @@ -586,8 +578,14 @@ internal class Scope public Alias Alias; public Dictionary Positions; + + public Scope(Alias alias, Dictionary positions) + { + Alias = alias; + Positions = positions; + } - static PropertyInfo miReader = ReflectionTools.GetPropertyInfo((IProjectionRow row) => row.Reader); + static readonly PropertyInfo miReader = ReflectionTools.GetPropertyInfo((IProjectionRow row) => row.Reader); public Expression GetColumnExpression(Expression row, Alias alias, string name, Type type) { @@ -599,15 +597,15 @@ public Expression GetColumnExpression(Expression row, Alias alias, string name, return FieldReader.GetExpression(Expression.Property(row, miReader), position, type); } - static MethodInfo miLookupRequest = ReflectionTools.GetMethodInfo((IProjectionRow row) => row.LookupRequest(null, 0, null)).GetGenericMethodDefinition(); - static MethodInfo miLookup = ReflectionTools.GetMethodInfo((IProjectionRow row) => row.Lookup(null, 0)).GetGenericMethodDefinition(); + static readonly MethodInfo miLookupRequest = ReflectionTools.GetMethodInfo((IProjectionRow row) => row.LookupRequest(null, 0, null)).GetGenericMethodDefinition(); + static readonly MethodInfo miLookup = ReflectionTools.GetMethodInfo((IProjectionRow row) => row.Lookup(null, 0)).GetGenericMethodDefinition(); public Expression LookupEager(Expression row, ChildProjectionExpression cProj) { if (cProj.IsLazyMList) throw new InvalidOperationException("IsLazyMList not expected at this stage"); - Type type = cProj.Projection.UniqueFunction == null ? cProj.Type.ElementType() : cProj.Type; + Type type = cProj.Projection.UniqueFunction == null ? cProj.Type.ElementType()! : cProj.Type; MethodInfo mi = miLookup.MakeGenericMethod(cProj.OuterKey.Type, type); diff --git a/Signum.Engine/Linq/ExpressionVisitor/UpdateDeleteSimplifier.cs b/Signum.Engine/Linq/ExpressionVisitor/UpdateDeleteSimplifier.cs index b6551d1f6e..277e9ade24 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/UpdateDeleteSimplifier.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/UpdateDeleteSimplifier.cs @@ -1,4 +1,4 @@ -using System.Linq.Expressions; +using System.Linq.Expressions; using Signum.Utilities; namespace Signum.Engine.Linq @@ -8,25 +8,30 @@ class CommandSimplifier: DbExpressionVisitor bool removeSelectRowCount; AliasGenerator aliasGenerator; + public CommandSimplifier(bool removeSelectRowCount, AliasGenerator aliasGenerator) + { + this.removeSelectRowCount = removeSelectRowCount; + this.aliasGenerator = aliasGenerator; + } public static CommandExpression Simplify(CommandExpression ce, bool removeSelectRowCount, AliasGenerator aliasGenerator) { - return (CommandExpression)new CommandSimplifier { removeSelectRowCount = removeSelectRowCount, aliasGenerator = aliasGenerator }.Visit(ce); + return (CommandExpression)new CommandSimplifier(removeSelectRowCount, aliasGenerator).Visit(ce); } protected internal override Expression VisitSelectRowCount(SelectRowCountExpression src) { if (removeSelectRowCount) - return null; + return null!; return base.VisitSelectRowCount(src); } protected internal override Expression VisitDelete(DeleteExpression delete) { - var select = delete.Source as SelectExpression; + var select = (SelectExpression)delete.Source; - TableExpression table = select.From as TableExpression; + TableExpression? table = select.From as TableExpression; if (table == null || delete.Table != table.Table) return delete; @@ -84,7 +89,7 @@ private ColumnExpression ResolveColumn(ColumnExpression ce, SelectExpression sel if(result == null) return ce; - TableExpression table = (TableExpression)select.From; + TableExpression table = (TableExpression)select.From!; if (table.Alias == result.Alias) { diff --git a/Signum.Engine/Linq/Meta/MetaEvaluator.cs b/Signum.Engine/Linq/Meta/MetaEvaluator.cs index 1d73b2f779..925bed0d55 100644 --- a/Signum.Engine/Linq/Meta/MetaEvaluator.cs +++ b/Signum.Engine/Linq/Meta/MetaEvaluator.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Signum.Utilities.ExpressionTrees; @@ -13,10 +13,10 @@ namespace Signum.Engine.Linq /// public class MetaEvaluator : ExpressionVisitor { - public static Expression Clean(Expression expression) + public static Expression? Clean(Expression expression) { - Expression expand = ExpressionCleaner.Clean(expression, MetaEvaluator.PartialEval, false); - Expression simplified = OverloadingSimplifier.Simplify(expand); + Expression? expand = ExpressionCleaner.Clean(expression, MetaEvaluator.PartialEval, false); + Expression? simplified = OverloadingSimplifier.Simplify(expand); return simplified; } @@ -35,7 +35,7 @@ public static Expression PartialEval(Expression exp) return new MetaEvaluator { candidates = ExpressionNominator.Nominate(exp) }.Visit(exp); } - public override Expression Visit(Expression exp) + public override Expression? Visit(Expression exp) { if (exp == null) { diff --git a/Signum.Engine/Linq/Meta/MetaExpression.cs b/Signum.Engine/Linq/Meta/MetaExpression.cs index 307cbfdd6d..4f34777f5d 100644 --- a/Signum.Engine/Linq/Meta/MetaExpression.cs +++ b/Signum.Engine/Linq/Meta/MetaExpression.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq.Expressions; using System.Reflection; using Signum.Entities; @@ -69,7 +69,7 @@ public bool IsEntity public readonly Meta Meta; - public MetaExpression(Type type, Meta meta): + public MetaExpression(Type type, Meta? meta): base(MetaExpressionType.MetaExpression, type) { this.Meta = meta; diff --git a/Signum.Engine/Linq/Meta/MetadataVisitor.cs b/Signum.Engine/Linq/Meta/MetadataVisitor.cs index cf8f77585a..400fbfef51 100644 --- a/Signum.Engine/Linq/Meta/MetadataVisitor.cs +++ b/Signum.Engine/Linq/Meta/MetadataVisitor.cs @@ -24,7 +24,7 @@ internal class MetadataVisitor : ExpressionVisitor private MetadataVisitor() { } - static internal Dictionary GatherMetadata(Expression expression) + static internal Dictionary GatherMetadata(Expression expression) { if (expression == null) throw new ArgumentException("expression"); @@ -32,13 +32,10 @@ static internal Dictionary GatherMetadata(Expression expression) if (!typeof(IQueryable).IsAssignableFrom(expression.Type)) throw new InvalidOperationException("Expression type is not IQueryable"); - Expression simplified = MetaEvaluator.Clean(expression); - - MetaProjectorExpression meta = new MetadataVisitor().Visit(simplified) as MetaProjectorExpression; - - if (meta == null) - return null; + Expression? simplified = MetaEvaluator.Clean(expression); + var meta = (MetaProjectorExpression)new MetadataVisitor().Visit(simplified!); + var proj = meta.Projector; if (proj.NodeType != ExpressionType.New && //anonymous types @@ -109,7 +106,7 @@ protected override Expression VisitMethodCall(MethodCallExpression m) if (m.Arguments.Count == 2) return this.BindSelectMany(m.Type, m.GetArgument("source"), m.GetArgument("selector").StripQuotes(), null); else - return this.BindSelectMany(m.Type, m.GetArgument("source"), m.GetArgument("collectionSelector").StripQuotes(), m.TryGetArgument("resultSelector").StripQuotes()); + return this.BindSelectMany(m.Type, m.GetArgument("source"), m.GetArgument("collectionSelector").StripQuotes(), m.TryGetArgument("resultSelector")?.StripQuotes()); case "Join": return this.BindJoin( m.Type, m.GetArgument("outer"), m.GetArgument("inner"), @@ -143,18 +140,18 @@ protected override Expression VisitMethodCall(MethodCallExpression m) case "Max": case "Average": return this.BindAggregate(m.Type, m.Method.Name.ToEnum(), - m.GetArgument("source"), m.TryGetArgument("selector").StripQuotes()); + m.GetArgument("source"), m.TryGetArgument("selector")?.StripQuotes()); case "First": case "FirstOrDefault": case "Single": case "SingleOrDefault": return BindUniqueRow(m.Type, m.Method.Name.ToEnum(), - m.GetArgument("source"), m.TryGetArgument("predicate").StripQuotes()); + m.GetArgument("source"), m.TryGetArgument("predicate")?.StripQuotes()); case "FirstEx": case "SingleEx": case "SingleOrDefaultEx": return BindUniqueRow(m.Type, m.Method.Name.RemoveEnd(2).ToEnum(), - m.GetArgument("collection"), m.TryGetArgument("predicate").StripQuotes()); + m.GetArgument("collection"), m.TryGetArgument("predicate")?.StripQuotes()); case "Distinct": return BindDistinct(m.Type, m.GetArgument("source")); case "Take": @@ -225,7 +222,9 @@ private Expression MapAndVisit(LambdaExpression lambda, params MetaProjectorExpr public static MetaProjectorExpression AsProjection(Expression expression) { if (expression is MetaProjectorExpression mpe) - return (MetaProjectorExpression)mpe; + return mpe; + + expression = expression!; /*CSBUG*/ if (expression.NodeType == ExpressionType.New) { @@ -234,7 +233,7 @@ public static MetaProjectorExpression AsProjection(Expression expression) return (MetaProjectorExpression)nex.Arguments[1]; } - Type elementType = expression.Type.ElementType(); + Type? elementType = expression.Type.ElementType(); if (elementType != null) { if (expression is MetaExpression meta && meta.Meta is CleanMeta) @@ -246,8 +245,7 @@ public static MetaProjectorExpression AsProjection(Expression expression) new CleanMeta(route.TryGetImplementations(), route))); } - return new MetaProjectorExpression(expression.Type, - MakeVoidMeta(elementType)); + return new MetaProjectorExpression(expression!/*CSBUG*/.Type, MakeVoidMeta(elementType)); } throw new InvalidOperationException(); @@ -263,7 +261,7 @@ private Expression BindSkip(Type resultType, Expression source, Expression count return AsProjection(Visit(source)); } - private Expression BindUniqueRow(Type resultType, UniqueFunction function, Expression source, LambdaExpression predicate) + private Expression BindUniqueRow(Type resultType, UniqueFunction function, Expression source, LambdaExpression? predicate) { return AsProjection(Visit(source)).Projector; } @@ -293,7 +291,7 @@ private Expression BindContains(Type resultType, Expression source, Expression i return MakeVoidMeta(resultType); } - private Expression BindAggregate(Type resultType, AggregateSqlFunction aggregateFunction, Expression source, LambdaExpression selector) + private Expression BindAggregate(Type resultType, AggregateSqlFunction aggregateFunction, Expression source, LambdaExpression? selector) { MetaProjectorExpression mp = AsProjection(Visit(source)); if (selector == null) @@ -315,7 +313,7 @@ private Expression BindSelect(Type resultType, Expression source, LambdaExpressi return new MetaProjectorExpression(resultType, projector); } - protected virtual Expression BindSelectMany(Type resultType, Expression source, LambdaExpression collectionSelector, LambdaExpression resultSelector) + protected virtual Expression BindSelectMany(Type resultType, Expression source, LambdaExpression collectionSelector, LambdaExpression? resultSelector) { MetaProjectorExpression mp = AsProjection(Visit(source)); MetaProjectorExpression collectionProjector = AsProjection(MapAndVisit(collectionSelector, mp)); @@ -359,7 +357,7 @@ protected virtual Expression BindThenBy(Expression source, LambdaExpression orde return AsProjection(Visit(source)); } - public Type TableType(object value) + public Type? TableType(object value) { if (value == null) return null; @@ -380,7 +378,7 @@ public override Expression Visit(Expression exp) protected override Expression VisitConstant(ConstantExpression c) { - Type type = TableType(c.Value); + Type? type = TableType(c.Value); if (type != null) { if (typeof(Entity).IsAssignableFrom(type)) @@ -452,6 +450,8 @@ static Expression BindMember(Expression source, MemberInfo member, Type memberTy throw new InvalidOperationException("Property {0} not found on {1}".FormatWith(member.Name, mme.Type.TypeName())); } + source = source! /*CSBUG*/; + if (typeof(ModifiableEntity).IsAssignableFrom(source.Type) || typeof(IEntity).IsAssignableFrom(source.Type)) { var pi = member as PropertyInfo ?? Reflector.TryFindPropertyInfo((FieldInfo)member); diff --git a/Signum.Engine/Linq/TranslateResult.cs b/Signum.Engine/Linq/TranslateResult.cs index b94e5c0744..63d8c465b4 100644 --- a/Signum.Engine/Linq/TranslateResult.cs +++ b/Signum.Engine/Linq/TranslateResult.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -16,20 +16,20 @@ public interface ITranslateResult SqlPreCommandSimple MainCommand { get; set; } - object Execute(); - Task ExecuteAsync(CancellationToken token); + object? Execute(); + Task ExecuteAsync(CancellationToken token); LambdaExpression GetMainProjector(); } interface IChildProjection { - LookupToken Token { get; set; } + LookupToken Token { get; } void Fill(Dictionary lookups, IRetriever retriever); Task FillAsync(Dictionary lookups, IRetriever retriever, CancellationToken token); - SqlPreCommandSimple Command { get; set; } + SqlPreCommandSimple Command { get; } bool IsLazy { get; } } @@ -38,10 +38,16 @@ interface IChildProjection class EagerChildProjection: IChildProjection { public LookupToken Token { get; set; } - public SqlPreCommandSimple Command { get; set; } internal Expression>> ProjectorExpression; + public EagerChildProjection(LookupToken token, SqlPreCommandSimple command, Expression>> projectorExpression) + { + Token = token; + Command = command; + ProjectorExpression = projectorExpression; + } + public void Fill(Dictionary lookups, IRetriever retriever) { using (HeavyProfiler.Log("SQL", () => Command.sp_executesql())) @@ -103,14 +109,21 @@ public bool IsLazy class LazyChildProjection : IChildProjection { - public LookupToken Token { get; set; } + public LookupToken Token { get; } - public SqlPreCommandSimple Command { get; set; } + public SqlPreCommandSimple Command { get; } internal Expression.RowIdElement>>> ProjectorExpression; + public LazyChildProjection(LookupToken token, SqlPreCommandSimple command, Expression.RowIdElement>>> projectorExpression) + { + Token = token; + Command = command; + ProjectorExpression = projectorExpression; + } + public void Fill(Dictionary lookups, IRetriever retriever) { - Dictionary> requests = (Dictionary>)lookups.TryGetC(Token); + Dictionary>? requests = (Dictionary>?)lookups.TryGetC(Token); if (requests == null) return; @@ -148,7 +161,7 @@ public void Fill(Dictionary lookups, IRetriever retrie public async Task FillAsync(Dictionary lookups, IRetriever retriever, CancellationToken token) { - Dictionary> requests = (Dictionary>)lookups.TryGetC(Token); + Dictionary>? requests = (Dictionary>?)lookups.TryGetC(Token); if (requests == null) return; @@ -197,21 +210,33 @@ class TranslateResult : ITranslateResult internal List EagerProjections { get; set; } internal List LazyChildProjections { get; set; } - Dictionary lookups; public SqlPreCommandSimple MainCommand { get; set; } internal Expression> ProjectorExpression; - public object Execute() + public TranslateResult( + List eagerProjections, + List lazyChildProjections, + SqlPreCommandSimple mainCommand, + Expression> projectorExpression, + UniqueFunction? unique) + { + EagerProjections = eagerProjections; + LazyChildProjections = lazyChildProjections; + MainCommand = mainCommand; + ProjectorExpression = projectorExpression; + Unique = unique; + } + + public object? Execute() { using (new EntityCache()) using (Transaction tr = new Transaction()) { - object result; + object? result; using (var retriever = EntityCache.NewRetriever()) { - if (EagerProjections.Any() || LazyChildProjections.Any()) - lookups = new Dictionary(); + var lookups = new Dictionary(); foreach (var child in EagerProjections) child.Fill(lookups, retriever); @@ -250,16 +275,15 @@ public object Execute() } } - public async Task ExecuteAsync(CancellationToken token) + public async Task ExecuteAsync(CancellationToken token) { using (new EntityCache()) using (Transaction tr = new Transaction()) { - object result; + object? result; using (var retriever = EntityCache.NewRetriever()) { - if (EagerProjections.Any() || LazyChildProjections.Any()) - lookups = new Dictionary(); + var lookups = new Dictionary(); foreach (var child in EagerProjections) child.Fill(lookups, retriever); @@ -315,9 +339,9 @@ public string CleanCommandText() { try { - SqlPreCommand eager = EagerProjections?.Select(cp => cp.Command).Combine(Spacing.Double); + SqlPreCommand? eager = EagerProjections?.Select(cp => cp.Command).Combine(Spacing.Double); - SqlPreCommand lazy = LazyChildProjections?.Select(cp => cp.Command).Combine(Spacing.Double); + SqlPreCommand? lazy = LazyChildProjections?.Select(cp => cp.Command).Combine(Spacing.Double); return SqlPreCommandConcat.Combine(Spacing.Double, eager == null ? null : new SqlPreCommandSimple("--------- Eager Client Joins ----------------"), @@ -325,7 +349,7 @@ public string CleanCommandText() eager == null && lazy == null ? null : new SqlPreCommandSimple("--------- MAIN QUERY ------------------------"), MainCommand, lazy == null ? null : new SqlPreCommandSimple("--------- Lazy Client Joins (if needed) -----"), - lazy).PlainSql(); + lazy)!.PlainSql(); } catch diff --git a/Signum.Engine/Operations/Graph.cs b/Signum.Engine/Operations/Graph.cs index b6af7dc82b..cbb50a8fb8 100644 --- a/Signum.Engine/Operations/Graph.cs +++ b/Signum.Engine/Operations/Graph.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Signum.Engine.Basics; @@ -21,14 +21,14 @@ public class Construct : _Construct, IConstructOperation Type IOperation.OverridenType { get { return typeof(T); } } OperationType IOperation.OperationType { get { return OperationType.Constructor; } } bool IOperation.Returns { get { return true; } } - Type IOperation.ReturnType { get { return typeof(T); } } - IEnumerable IOperation.UntypedFromStates { get { return null; } } - IEnumerable IOperation.UntypedToStates { get { return Enumerable.Empty(); } } - Type IOperation.StateType { get { return null; } } + Type? IOperation.ReturnType { get { return typeof(T); } } + IEnumerable? IOperation.UntypedFromStates { get { return null; } } + IEnumerable? IOperation.UntypedToStates { get { return Enumerable.Empty(); } } + Type? IOperation.StateType { get { return null; } } public bool LogAlsoIfNotSaved { get; set; } - //public Func Construct { get; set; } (inherited) + //public Func Construct { get; set; } (inherited) public bool Lite { get { return false; } } public Construct(ConstructSymbol.Simple symbol) @@ -50,18 +50,18 @@ public static Construct Untyped(ConstructSymbol.Simple symbol) return new Construct(symbol.Symbol); } - public void OverrideConstruct(Overrider> overrider) + public void OverrideConstruct(Overrider> overrider) { this.Construct = overrider(this.Construct); } - IEntity IConstructOperation.Construct(params object[] args) + IEntity IConstructOperation.Construct(params object[]? args) { using (HeavyProfiler.Log("Construct", () => operationSymbol.Key)) { OperationLogic.AssertOperationAllowed(operationSymbol, typeof(T), inUserInterface: false); - OperationLogEntity log = new OperationLogEntity + OperationLogEntity? log = new OperationLogEntity { Operation = operationSymbol, Start = TimeZoneManager.Now, @@ -72,7 +72,7 @@ IEntity IConstructOperation.Construct(params object[] args) { using (Transaction tr = new Transaction()) { - T result = null; + T? result = null; using (OperationLogic.AllowSave()) OperationLogic.OnSuroundOperation(this, log, null, args).EndUsing(_ => { @@ -92,7 +92,7 @@ IEntity IConstructOperation.Construct(params object[] args) if (log != null) log.SaveLog(); - return tr.Commit(result); + return tr.Commit(result!); } } catch (Exception ex) @@ -146,15 +146,15 @@ public class ConstructFrom : IConstructorFromOperation OperationSymbol IOperation.OperationSymbol { get { return operationSymbol; } } Type IOperation.OverridenType { get { return typeof(F); } } OperationType IOperation.OperationType { get { return OperationType.ConstructorFrom; } } - IEnumerable IOperation.UntypedFromStates { get { return null; } } - IEnumerable IOperation.UntypedToStates { get { return Enumerable.Empty(); } } - Type IOperation.StateType { get { return null; } } + IEnumerable? IOperation.UntypedFromStates { get { return null; } } + IEnumerable? IOperation.UntypedToStates { get { return Enumerable.Empty(); } } + Type? IOperation.StateType { get { return null; } } public bool CanBeModified { get; set; } public bool LogAlsoIfNotSaved { get; set; } bool IOperation.Returns { get { return true; } } - Type IOperation.ReturnType { get { return typeof(T); } } + Type? IOperation.ReturnType { get { return typeof(T); } } protected readonly Type baseType; Type IEntityOperation.BaseType { get { return baseType; } } @@ -162,17 +162,17 @@ public class ConstructFrom : IConstructorFromOperation public bool CanBeNew { get; set; } - public Func CanConstruct { get; set; } + public Func? CanConstruct { get; set; } - public ConstructFrom OverrideCanConstruct(Overrider> overrider) + public ConstructFrom OverrideCanConstruct(Overrider> overrider) { this.CanConstruct = overrider(this.CanConstruct ?? (f => null)); return this; } - public Func Construct { get; set; } + public Func Construct { get; set; } = null!; - public void OverrideConstruct(Overrider> overrider) + public void OverrideConstruct(Overrider> overrider) { this.Construct = overrider(this.Construct); } @@ -198,12 +198,12 @@ public static ConstructFrom Untyped(ConstructSymbol.From symbol) return new ConstructFrom(symbol.Symbol, symbol.BaseType); } - string IEntityOperation.CanExecute(IEntity entity) + string? IEntityOperation.CanExecute(IEntity entity) { return OnCanConstruct(entity); } - string OnCanConstruct(IEntity entity) + string? OnCanConstruct(IEntity entity) { if (entity.IsNew && !CanBeNew) return EngineMessage.TheEntity0IsNew.NiceToString().FormatWith(entity); @@ -214,17 +214,17 @@ string OnCanConstruct(IEntity entity) return null; } - IEntity IConstructorFromOperation.Construct(IEntity origin, params object[] args) + IEntity IConstructorFromOperation.Construct(IEntity origin, params object[]? args) { using (HeavyProfiler.Log("ConstructFrom", () => operationSymbol.Key)) { OperationLogic.AssertOperationAllowed(operationSymbol, origin.GetType(), inUserInterface: false); - string error = OnCanConstruct(origin); + string? error = OnCanConstruct(origin); if (error != null) throw new ApplicationException(error); - OperationLogEntity log = new OperationLogEntity + OperationLogEntity? log = new OperationLogEntity { Operation = operationSymbol, Start = TimeZoneManager.Now, @@ -236,7 +236,7 @@ IEntity IConstructorFromOperation.Construct(IEntity origin, params object[] args { using (Transaction tr = new Transaction()) { - T result = null; + T? result = null; using (OperationLogic.AllowSave(origin.GetType())) using (OperationLogic.AllowSave()) OperationLogic.OnSuroundOperation(this, log, origin, args).EndUsing(_ => @@ -259,7 +259,7 @@ IEntity IConstructorFromOperation.Construct(IEntity origin, params object[] args if (log != null) log.SaveLog(); - return tr.Commit(result); + return tr.Commit(result!); } } catch (Exception ex) @@ -314,19 +314,19 @@ public class ConstructFromMany : IConstructorFromManyOperation Type IOperation.OverridenType { get { return typeof(F); } } OperationType IOperation.OperationType { get { return OperationType.ConstructorFromMany; } } bool IOperation.Returns { get { return true; } } - Type IOperation.ReturnType { get { return typeof(T); } } + Type? IOperation.ReturnType { get { return typeof(T); } } protected readonly Type baseType; Type IConstructorFromManyOperation.BaseType { get { return baseType; } } - IEnumerable IOperation.UntypedFromStates { get { return null; } } - IEnumerable IOperation.UntypedToStates { get { return Enumerable.Empty(); } } - Type IOperation.StateType { get { return null; } } + IEnumerable? IOperation.UntypedFromStates { get { return null; } } + IEnumerable? IOperation.UntypedToStates { get { return Enumerable.Empty(); } } + Type? IOperation.StateType { get { return null; } } public bool LogAlsoIfNotSaved { get; set; } - public Func>, object[], T> Construct { get; set; } + public Func>, object[]?, T> Construct { get; set; } = null!; - public void OverrideConstruct(Overrider>, object[], T>> overrider) + public void OverrideConstruct(Overrider>, object[]?, T>> overrider) { this.Construct = overrider(this.Construct); } @@ -354,7 +354,7 @@ public static ConstructFromMany Untyped(ConstructSymbol.FromMany sym } - IEntity IConstructorFromManyOperation.Construct(IEnumerable> lites, params object[] args) + IEntity IConstructorFromManyOperation.Construct(IEnumerable> lites, params object[]? args) { using (HeavyProfiler.Log("ConstructFromMany", () => operationSymbol.Key)) { @@ -363,7 +363,7 @@ IEntity IConstructorFromManyOperation.Construct(IEnumerable> lites OperationLogic.AssertOperationAllowed(operationSymbol, type, inUserInterface: false); } - OperationLogEntity log = new OperationLogEntity + OperationLogEntity? log = new OperationLogEntity { Operation = operationSymbol, Start = TimeZoneManager.Now, @@ -374,7 +374,7 @@ IEntity IConstructorFromManyOperation.Construct(IEnumerable> lites { using (Transaction tr = new Transaction()) { - T result = null; + T? result = null; using (OperationLogic.AllowSave()) using (OperationLogic.AllowSave()) @@ -398,7 +398,7 @@ IEntity IConstructorFromManyOperation.Construct(IEnumerable> lites if (log != null) log.SaveLog(); - return tr.Commit(result); + return tr.Commit(result!); } } catch (Exception ex) @@ -427,7 +427,7 @@ IEntity IConstructorFromManyOperation.Construct(IEnumerable> lites } } - protected virtual T OnConstruct(List> lites, object[] args) + protected virtual T OnConstruct(List> lites, object[]? args) { return Construct(lites, args); } @@ -456,26 +456,26 @@ public class Execute : _Execute, IExecuteOperation OperationType IOperation.OperationType { get { return OperationType.Execute; } } public bool CanBeModified { get; set; } bool IOperation.Returns { get { return true; } } - Type IOperation.ReturnType { get { return null; } } - Type IOperation.StateType { get { return null; } } + Type? IOperation.ReturnType { get { return null; } } + Type? IOperation.StateType { get { return null; } } Type IEntityOperation.BaseType { get { return Symbol.BaseType; } } bool IEntityOperation.HasCanExecute { get { return CanExecute != null; } } - IEnumerable IOperation.UntypedFromStates { get { return Enumerable.Empty(); } } - IEnumerable IOperation.UntypedToStates { get { return Enumerable.Empty(); } } + IEnumerable? IOperation.UntypedFromStates { get { return Enumerable.Empty(); } } + IEnumerable? IOperation.UntypedToStates { get { return Enumerable.Empty(); } } public bool CanBeNew { get; set; } - //public Action Execute { get; set; } (inherited) - public Func CanExecute { get; set; } + //public Action Execute { get; set; } (inherited) + public Func? CanExecute { get; set; } - public Execute OverrideCanExecute(Overrider> overrider) + public Execute OverrideCanExecute(Overrider> overrider) { this.CanExecute = overrider(this.CanExecute ?? (t => null)); return this; } - public void OverrideExecute(Overrider> overrider) + public void OverrideExecute(Overrider> overrider) { this.Execute = overrider(this.Execute); } @@ -485,12 +485,12 @@ public Execute(ExecuteSymbol symbol) this.Symbol = symbol ?? throw AutoInitAttribute.ArgumentNullException(typeof(ExecuteSymbol), nameof(symbol)); } - string IEntityOperation.CanExecute(IEntity entity) + string? IEntityOperation.CanExecute(IEntity entity) { return OnCanExecute((T)entity); } - protected virtual string OnCanExecute(T entity) + protected virtual string? OnCanExecute(T entity) { if (entity.IsNew && !CanBeNew) return EngineMessage.TheEntity0IsNew.NiceToString().FormatWith(entity); @@ -501,13 +501,13 @@ protected virtual string OnCanExecute(T entity) return null; } - void IExecuteOperation.Execute(IEntity entity, params object[] args) + void IExecuteOperation.Execute(IEntity entity, params object[]? args) { using (HeavyProfiler.Log("Execute", () => Symbol.Symbol.Key)) { OperationLogic.AssertOperationAllowed(Symbol.Symbol, entity.GetType(), inUserInterface: false); - string error = OnCanExecute((T)entity); + string? error = OnCanExecute((T)entity); if (error != null) throw new ApplicationException(error); @@ -594,26 +594,26 @@ public class Delete : _Delete, IDeleteOperation OperationType IOperation.OperationType { get { return OperationType.Delete; } } public bool CanBeModified { get; set; } bool IOperation.Returns { get { return false; } } - Type IOperation.ReturnType { get { return null; } } - IEnumerable IOperation.UntypedFromStates { get { return Enumerable.Empty(); } } - IEnumerable IOperation.UntypedToStates { get { return null; } } - Type IOperation.StateType { get { return null; } } + Type? IOperation.ReturnType { get { return null; } } + IEnumerable? IOperation.UntypedFromStates { get { return Enumerable.Empty(); } } + IEnumerable? IOperation.UntypedToStates { get { return null; } } + Type? IOperation.StateType { get { return null; } } public bool CanBeNew { get { return false; } } Type IEntityOperation.BaseType { get { return Symbol.BaseType; } } bool IEntityOperation.HasCanExecute { get { return CanDelete != null; } } - //public Action Delete { get; set; } (inherited) - public Func CanDelete { get; set; } + //public Action Delete { get; set; } (inherited) + public Func? CanDelete { get; set; } - public Delete OverrideCanDelete(Overrider> overrider) + public Delete OverrideCanDelete(Overrider> overrider) { this.CanDelete = overrider(this.CanDelete ?? (t => null)); return this; } - public void OverrideDelete(Overrider> overrider) + public void OverrideDelete(Overrider> overrider) { this.Delete = overrider(this.Delete); } @@ -623,12 +623,12 @@ public Delete(DeleteSymbol symbol) this.Symbol = symbol ?? throw AutoInitAttribute.ArgumentNullException(typeof(DeleteSymbol), nameof(symbol)); } - string IEntityOperation.CanExecute(IEntity entity) + string? IEntityOperation.CanExecute(IEntity entity) { return OnCanDelete((T)entity); } - protected virtual string OnCanDelete(T entity) + protected virtual string? OnCanDelete(T entity) { if (entity.IsNew) return EngineMessage.TheEntity0IsNew.NiceToString().FormatWith(entity); @@ -639,13 +639,13 @@ protected virtual string OnCanDelete(T entity) return null; } - void IDeleteOperation.Delete(IEntity entity, params object[] args) + void IDeleteOperation.Delete(IEntity entity, params object[]? args) { using (HeavyProfiler.Log("Delete", () => Symbol.Symbol.Key)) { OperationLogic.AssertOperationAllowed(Symbol.Symbol, entity.GetType(), inUserInterface: false); - string error = OnCanDelete((T)entity); + string? error = OnCanDelete((T)entity); if (error != null) throw new ApplicationException(error); @@ -698,7 +698,7 @@ void IDeleteOperation.Delete(IEntity entity, params object[] args) } } - protected virtual void OnDelete(T entity, object[] args) + protected virtual void OnDelete(T entity, object[]? args) { Delete(entity, args); } diff --git a/Signum.Engine/Operations/GraphState.cs b/Signum.Engine/Operations/GraphState.cs index bb8e37042a..75e1b813cb 100644 --- a/Signum.Engine/Operations/GraphState.cs +++ b/Signum.Engine/Operations/GraphState.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Signum.Utilities; @@ -35,8 +35,8 @@ public interface IGraphFromStatesOperation : IGraphOperation, IGraphHasFromState public class Construct : Graph.Construct, IGraphToStateOperation { public List ToStates { get; private set; } = new List(); - IEnumerable IOperation.UntypedToStates { get { return ToStates.Cast(); } } - Type IOperation.StateType { get { return typeof(S); } } + IEnumerable? IOperation.UntypedToStates { get { return ToStates.Cast(); } } + Type? IOperation.StateType { get { return typeof(S); } } public Construct(ConstructSymbol.Simple symbol) : base(symbol) @@ -90,8 +90,8 @@ public class ConstructFrom : Graph.ConstructFrom, IGraphToStateOperatio where F : class, IEntity { public List ToStates { get; private set; } = new List(); - IEnumerable IOperation.UntypedToStates { get { return ToStates.Cast(); } } - Type IOperation.StateType { get { return typeof(S); } } + IEnumerable? IOperation.UntypedToStates { get { return ToStates.Cast(); } } + Type? IOperation.StateType { get { return typeof(S); } } public ConstructFrom(ConstructSymbol.From symbol) : base(symbol) @@ -135,8 +135,8 @@ public class ConstructFromMany : Graph.ConstructFromMany, IGraphToState where F : class, IEntity { public List ToStates { get; private set; } = new List(); - IEnumerable IOperation.UntypedToStates { get { return ToStates.Cast(); } } - Type IOperation.StateType { get { return typeof(S); } } + IEnumerable? IOperation.UntypedToStates { get { return ToStates.Cast(); } } + Type? IOperation.StateType { get { return typeof(S); } } public ConstructFromMany(ConstructSymbol.FromMany symbol) : base(symbol) @@ -182,9 +182,9 @@ public class Execute : Graph.Execute, IGraphToStateOperation, IGraphFromState { public List FromStates { get; private set; } public List ToStates { get; private set; } - IEnumerable IOperation.UntypedToStates { get { return ToStates.Cast(); } } - IEnumerable IOperation.UntypedFromStates { get { return FromStates.Cast(); } } - Type IOperation.StateType { get { return typeof(S); } } + IEnumerable? IOperation.UntypedToStates { get { return ToStates.Cast(); } } + IEnumerable? IOperation.UntypedFromStates { get { return FromStates.Cast(); } } + Type? IOperation.StateType { get { return typeof(S); } } bool IGraphHasFromStatesOperation.HasFromStates { @@ -200,14 +200,14 @@ public Execute(ExecuteSymbol symbol) bool IEntityOperation.HasCanExecute { get { return true; } } - protected override string OnCanExecute(T entity) + protected override string? OnCanExecute(T entity) { S state = Graph.GetStateFunc(entity); if (!FromStates.Contains(state)) return OperationMessage.StateShouldBe0InsteadOf1.NiceToString().FormatWith( - FromStates.CommaOr(v => ((Enum)(object)v).NiceToString()), - ((Enum)(object)state).NiceToString()); + FromStates.CommaOr(v => ((Enum)(object)v!).NiceToString()), + ((Enum)(object)state!).NiceToString()); return base.OnCanExecute(entity); } @@ -233,8 +233,8 @@ public override void AssertIsValid() public class Delete : Graph.Delete, IGraphOperation, IGraphFromStatesOperation { public List FromStates { get; private set; } - IEnumerable IOperation.UntypedFromStates { get { return FromStates.Cast(); } } - Type IOperation.StateType { get { return typeof(S); } } + IEnumerable? IOperation.UntypedFromStates { get { return FromStates.Cast(); } } + Type? IOperation.StateType { get { return typeof(S); } } bool IGraphHasFromStatesOperation.HasFromStates { @@ -247,19 +247,19 @@ public Delete(DeleteSymbol symbol) FromStates = new List(); } - protected override string OnCanDelete(T entity) + protected override string? OnCanDelete(T entity) { S state = Graph.GetStateFunc(entity); if (!FromStates.Contains(state)) return OperationMessage.StateShouldBe0InsteadOf1.NiceToString().FormatWith( - FromStates.CommaOr(v => ((Enum)(object)v).NiceToString()), - ((Enum)(object)state).NiceToString()); + FromStates.CommaOr(v => ((Enum)(object)v!).NiceToString()), + ((Enum)(object)state!).NiceToString()); return base.OnCanDelete(entity); } - protected override void OnDelete(T entity, object[] args) + protected override void OnDelete(T entity, object[]? args) { AssertGetState(); S oldState = Graph.GetStateFunc(entity); @@ -309,14 +309,14 @@ public static DirectedEdgedGraph ToDirectedGraph() { DirectedEdgedGraph result = new DirectedEdgedGraph(); - Action Add = (from, to, key) => - { - Dictionary dic = result.TryRelatedTo(from); - if (dic == null || !dic.ContainsKey(to)) - result.Add(from, to, key.ToString()); - else - result.Add(from, to, dic[to] + ", " + key.ToString()); - }; + void Add(string from, string to, OperationSymbol key) + { + Dictionary dic = result.TryRelatedTo(from); + if (dic == null || !dic.ContainsKey(to)) + result.Add(from, to, key.ToString()); + else + result.Add(from, to, dic[to] + ", " + key.ToString()); + } foreach (var item in OperationLogic.GraphOperations()) { @@ -328,7 +328,7 @@ public static DirectedEdgedGraph ToDirectedGraph() foreach (var f in gOp.FromStates) foreach (var t in gOp.ToStates) - Add(f.ToString(), t.ToString(), item.OperationSymbol); + Add(f!.ToString(), t!.ToString(), item.OperationSymbol); } break; @@ -336,7 +336,7 @@ public static DirectedEdgedGraph ToDirectedGraph() { Delete dOp = (Delete)item; foreach (var f in dOp.FromStates) - Add(f.ToString(), "[Deleted]", item.OperationSymbol); + Add(f!.ToString(), "[Deleted]", item.OperationSymbol); } break; @@ -350,7 +350,7 @@ public static DirectedEdgedGraph ToDirectedGraph() var dtoState = (IGraphToStateOperation)item; foreach (var t in dtoState.ToStates) - Add(from, t.ToString(), item.OperationSymbol); + Add(from, t!.ToString(), item.OperationSymbol); } break; } diff --git a/Signum.Engine/Operations/Internal.cs b/Signum.Engine/Operations/Internal.cs index 2b33615bf0..43efb2817d 100644 --- a/Signum.Engine/Operations/Internal.cs +++ b/Signum.Engine/Operations/Internal.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Signum.Entities; @@ -6,48 +6,48 @@ namespace Signum.Engine.Operations.Internal { public interface IConstructOperation : IOperation { - IEntity Construct(params object[] parameters); + IEntity Construct(params object[]? parameters); } public interface IConstructorFromOperation : IEntityOperation { - IEntity Construct(IEntity entity, params object[] parameters); + IEntity Construct(IEntity entity, params object[]? parameters); } public interface IConstructorFromManyOperation : IOperation { - IEntity Construct(IEnumerable> lites, params object[] parameters); + IEntity Construct(IEnumerable> lites, params object[]? parameters); Type BaseType { get; } } public interface IExecuteOperation : IEntityOperation { - void Execute(IEntity entity, params object[] parameters); + void Execute(IEntity entity, params object[]? parameters); } public interface IDeleteOperation : IEntityOperation { - void Delete(IEntity entity, params object[] parameters); + void Delete(IEntity entity, params object[]? parameters); } //The only point of this clases is to avoid 'member names cannot be the same as their enclosing type' compilation message public class _Construct where T : class, IEntity { - public Func Construct { get; set; } + public Func Construct { get; set; } = null!; } public class _Execute where T : class, IEntity { - public Action Execute { get; set; } + public Action Execute { get; set; } = null!; } public class _Delete where T : class, IEntity { - public Action Delete { get; set; } + public Action Delete { get; set; } = null!; } -} \ No newline at end of file +} diff --git a/Signum.Engine/Operations/OperationLogic.cs b/Signum.Engine/Operations/OperationLogic.cs index e16a3d9035..2bac7068ac 100644 --- a/Signum.Engine/Operations/OperationLogic.cs +++ b/Signum.Engine/Operations/OperationLogic.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -86,7 +86,7 @@ public static IDisposable AllowSave(Type type) public static void AssertStarted(SchemaBuilder sb) { - sb.AssertDefined(ReflectionTools.GetMethodInfo(() => Start(null))); + sb.AssertDefined(ReflectionTools.GetMethodInfo(() => Start(null!))); } public static void Start(SchemaBuilder sb) @@ -221,12 +221,12 @@ static void EntityEventsGlobal_Saving(Entity ident) public static event SurroundOperationHandler SurroundOperation; public static event AllowOperationHandler AllowOperation; - internal static IDisposable OnSuroundOperation(IOperation operation, OperationLogEntity log, IEntity entity, object[] args) + internal static IDisposable? OnSuroundOperation(IOperation operation, OperationLogEntity log, IEntity? entity, object[]? args) { - return Disposable.Combine(SurroundOperation, f => f(operation, log, (Entity)entity, args)); + return Disposable.Combine(SurroundOperation, f => f(operation, log, (Entity?)entity, args)); } - internal static void SetExceptionData(Exception ex, OperationSymbol operationSymbol, IEntity entity, object[] args) + internal static void SetExceptionData(Exception ex, OperationSymbol operationSymbol, IEntity? entity, object[]? args) { ex.Data["operation"] = operationSymbol; ex.Data["entity"] = entity; @@ -316,12 +316,10 @@ public static IEnumerable AllSymbols() private static OperationInfo ToOperationInfo(IOperation oper) { - return new OperationInfo + return new OperationInfo(oper.OperationSymbol, oper.OperationType) { - OperationSymbol = oper.OperationSymbol, CanBeModified = (oper as IEntityOperation)?.CanBeModified, Returns = oper.Returns, - OperationType = oper.OperationType, ReturnType = oper.ReturnType, HasStates = (oper as IGraphHasFromStatesOperation)?.HasFromStates, HasCanExecute = (oper as IEntityOperation)?.HasCanExecute, @@ -350,7 +348,7 @@ public static Dictionary ServiceCanExecute(Entity entit #region Execute - public static T Execute(this T entity, ExecuteSymbol symbol, params object[] args) + public static T Execute(this T entity, ExecuteSymbol symbol, params object[]? args) where T : class, IEntity { var op = Find(entity.GetType(), symbol.Symbol).AssertEntity((Entity)(IEntity)entity); @@ -358,14 +356,14 @@ public static T Execute(this T entity, ExecuteSymbol symbol, params object return (T)(IEntity)entity; } - public static Entity ServiceExecute(IEntity entity, OperationSymbol operationSymbol, params object[] args) + public static Entity ServiceExecute(IEntity entity, OperationSymbol operationSymbol, params object[]? args) { var op = Find(entity.GetType(), operationSymbol).AssertEntity((Entity)(IEntity)entity); op.Execute(entity, args); return (Entity)(IEntity)entity; } - public static T ExecuteLite(this Lite lite, ExecuteSymbol symbol, params object[] args) + public static T ExecuteLite(this Lite lite, ExecuteSymbol symbol, params object[]? args) where T : class, IEntity { T entity = lite.RetrieveAndForget(); @@ -374,7 +372,7 @@ public static T ExecuteLite(this Lite lite, ExecuteSymbol symbol, param return entity; } - public static Entity ServiceExecuteLite(Lite lite, OperationSymbol operationSymbol, params object[] args) + public static Entity ServiceExecuteLite(Lite lite, OperationSymbol operationSymbol, params object[]? args) { Entity entity = (Entity)lite.RetrieveAndForget(); var op = Find(lite.EntityType, operationSymbol); @@ -383,14 +381,14 @@ public static Entity ServiceExecuteLite(Lite lite, OperationSymbol oper } - public static string CanExecute(this T entity, IEntityOperationSymbolContainer symbol) + public static string? CanExecute(this T entity, IEntityOperationSymbolContainer symbol) where T : class, IEntity { var op = Find(entity.GetType(), symbol.Symbol); return op.CanExecute(entity); } - public static string ServiceCanExecute(Entity entity, OperationSymbol operationSymbol) + public static string? ServiceCanExecute(Entity entity, OperationSymbol operationSymbol) { var op = Find(entity.GetType(), operationSymbol); return op.CanExecute(entity); @@ -399,7 +397,7 @@ public static string ServiceCanExecute(Entity entity, OperationSymbol operationS #region Delete - public static void DeleteLite(this Lite lite, DeleteSymbol symbol, params object[] args) + public static void DeleteLite(this Lite lite, DeleteSymbol symbol, params object[]? args) where T : class, IEntity { IEntity entity = lite.RetrieveAndForget(); @@ -407,21 +405,21 @@ public static void DeleteLite(this Lite lite, DeleteSymbol symbol, para op.Delete(entity, args); } - public static void ServiceDelete(Lite lite, OperationSymbol operationSymbol, params object[] args) + public static void ServiceDelete(Lite lite, OperationSymbol operationSymbol, params object[]? args) { IEntity entity = lite.RetrieveAndForget(); var op = Find(lite.EntityType, operationSymbol); op.Delete(entity, args); } - public static void Delete(this T entity, DeleteSymbol symbol, params object[] args) + public static void Delete(this T entity, DeleteSymbol symbol, params object[]? args) where T : class, IEntity { var op = Find(entity.GetType(), symbol.Symbol).AssertEntity((Entity)(IEntity)entity); op.Delete(entity, args); } - public static void ServiceDelete(Entity entity, OperationSymbol operationSymbol, params object[] args) + public static void ServiceDelete(Entity entity, OperationSymbol operationSymbol, params object[]? args) { var op = Find(entity.GetType(), operationSymbol).AssertEntity((Entity)(IEntity)entity); op.Delete(entity, args); @@ -429,13 +427,13 @@ public static void ServiceDelete(Entity entity, OperationSymbol operationSymbol, #endregion #region Construct - public static Entity ServiceConstruct(Type type, OperationSymbol operationSymbol, params object[] args) + public static Entity ServiceConstruct(Type type, OperationSymbol operationSymbol, params object[]? args) { var op = Find(type, operationSymbol); return (Entity)op.Construct(args); } - public static T Construct(ConstructSymbol.Simple symbol, params object[] args) + public static T Construct(ConstructSymbol.Simple symbol, params object[]? args) where T : class, IEntity { var op = Find(typeof(T), symbol.Symbol); @@ -445,7 +443,7 @@ public static T Construct(ConstructSymbol.Simple symbol, params object[] a #region ConstructFrom - public static T ConstructFrom(this F entity, ConstructSymbol.From symbol, params object[] args) + public static T ConstructFrom(this F entity, ConstructSymbol.From symbol, params object[]? args) where T : class, IEntity where F : class, IEntity { @@ -453,13 +451,13 @@ public static T ConstructFrom(this F entity, ConstructSymbol.From sy return (T)op.Construct(entity, args); } - public static Entity ServiceConstructFrom(IEntity entity, OperationSymbol operationSymbol, params object[] args) + public static Entity ServiceConstructFrom(IEntity entity, OperationSymbol operationSymbol, params object[]? args) { var op = Find(entity.GetType(), operationSymbol).AssertEntity((Entity)(object)entity); return (Entity)op.Construct(entity, args); } - public static T ConstructFromLite(this Lite lite, ConstructSymbol.From symbol, params object[] args) + public static T ConstructFromLite(this Lite lite, ConstructSymbol.From symbol, params object[]? args) where T : class, IEntity where F : class, IEntity { @@ -467,7 +465,7 @@ public static T ConstructFromLite(this Lite lite, ConstructSymbol.Fr return (T)op.Construct(Database.RetrieveAndForget(lite), args); } - public static Entity ServiceConstructFromLite(Lite lite, OperationSymbol operationSymbol, params object[] args) + public static Entity ServiceConstructFromLite(Lite lite, OperationSymbol operationSymbol, params object[]? args) { var op = Find(lite.EntityType, operationSymbol); return (Entity)op.Construct(Database.RetrieveAndForget(lite), args); @@ -475,14 +473,14 @@ public static Entity ServiceConstructFromLite(Lite lite, OperationSymbo #endregion #region ConstructFromMany - public static Entity ServiceConstructFromMany(IEnumerable> lites, Type type, OperationSymbol operationSymbol, params object[] args) + public static Entity ServiceConstructFromMany(IEnumerable> lites, Type type, OperationSymbol operationSymbol, params object[]? args) { var onlyType = lites.Select(a => a.EntityType).Distinct().Only(); return (Entity)Find(onlyType ?? type, operationSymbol).Construct(lites, args); } - public static T ConstructFromMany(List> lites, ConstructSymbol.FromMany symbol, params object[] args) + public static T ConstructFromMany(List> lites, ConstructSymbol.FromMany symbol, params object[]? args) where T : class, IEntity where F : class, IEntity { @@ -510,13 +508,13 @@ public static T Find(Type type, OperationSymbol operationSymbol) public static IOperation FindOperation(Type type, OperationSymbol operationSymbol) { - IOperation result = TryFindOperation(type, operationSymbol); + IOperation? result = TryFindOperation(type, operationSymbol); if (result == null) throw new InvalidOperationException("Operation '{0}' not found for type {1}".FormatWith(operationSymbol, type)); return result; } - public static IOperation TryFindOperation(Type type, OperationSymbol operationSymbol) + public static IOperation? TryFindOperation(Type type, OperationSymbol operationSymbol) { return operations.TryGetValue(type.CleanType())?.TryGetC(operationSymbol); } @@ -603,7 +601,7 @@ select FindOperation(kvp.Value.FirstEx(), kvp.Key) into op return typeOperations.Concat(returnTypeOperations); } - public static string InState(this T state, params T[] fromStates) where T : struct + public static string? InState(this T state, params T[] fromStates) where T : struct { if (!fromStates.Contains(state)) return OperationMessage.StateShouldBe0InsteadOf1.NiceToString().FormatWith( @@ -637,9 +635,9 @@ public static OperationType OperationType(Type type, OperationSymbol operationSy return FindOperation(type, operationSymbol).OperationType; } - public static Dictionary GetContextualCanExecute(IEnumerable> lites, List operationSymbols) + public static Dictionary? GetContextualCanExecute(IEnumerable> lites, List operationSymbols) { - Dictionary result = null; + Dictionary? result = null; using (ExecutionMode.Global()) { foreach (var grLites in lites.GroupBy(a => a.EntityType)) @@ -724,7 +722,7 @@ public static FluentInclude WithDelete(this FluentInclude fi, DeleteSym return fi; } - public static FluentInclude WithConstruct(this FluentInclude fi, ConstructSymbol.Simple construct, Func constructFunction) + public static FluentInclude WithConstruct(this FluentInclude fi, ConstructSymbol.Simple construct, Func constructFunction) where T : Entity { new Graph.Construct(construct) @@ -751,25 +749,25 @@ public interface IOperation Type OverridenType { get; } OperationType OperationType { get; } bool Returns { get; } - Type ReturnType { get; } + Type? ReturnType { get; } void AssertIsValid(); - IEnumerable UntypedFromStates { get; } - IEnumerable UntypedToStates { get; } - Type StateType { get; } + IEnumerable? UntypedFromStates { get; } + IEnumerable? UntypedToStates { get; } + Type? StateType { get; } } public interface IEntityOperation : IOperation { bool CanBeModified { get; } bool CanBeNew { get; } - string CanExecute(IEntity entity); + string? CanExecute(IEntity entity); bool HasCanExecute { get; } Type BaseType { get; } } - public delegate IDisposable SurroundOperationHandler(IOperation operation, OperationLogEntity log, Entity entity, object[] args); + public delegate IDisposable SurroundOperationHandler(IOperation operation, OperationLogEntity log, Entity? entity, object[]? args); public delegate void OperationHandler(IOperation operation, Entity entity); public delegate void ErrorOperationHandler(IOperation operation, Entity entity, Exception ex); public delegate bool AllowOperationHandler(OperationSymbol operationSymbol, Type entityType, bool inUserInterface); diff --git a/Signum.Engine/Patterns/DeletePart.cs b/Signum.Engine/Patterns/DeletePart.cs index 6bc4dce864..2e31ad37ef 100644 --- a/Signum.Engine/Patterns/DeletePart.cs +++ b/Signum.Engine/Patterns/DeletePart.cs @@ -1,4 +1,4 @@ -using Signum.Engine.Maps; +using Signum.Engine.Maps; using Signum.Entities; using Signum.Utilities; using Signum.Utilities.DataStructures; @@ -10,12 +10,12 @@ namespace Signum.Engine { public static class DeletePart { - static readonly Variable> avoidTypes = Statics.ThreadVariable>("avoidDeletePart"); - + static readonly Variable> avoidTypes = Statics.ThreadVariable>("avoidDeletePart"); /*CSBUG*/ + public static bool ShouldAvoidDeletePart(Type partType) { var stack = avoidTypes.Value; - return stack != null && (stack.Contains(partType) || stack.Contains(null)); + return stack != null && (stack.Contains(partType) || stack.Contains(null!)); } /// Use null for every type diff --git a/Signum.Engine/Retriever.cs b/Signum.Engine/Retriever.cs index e02f739424..77873335d0 100644 --- a/Signum.Engine/Retriever.cs +++ b/Signum.Engine/Retriever.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Signum.Entities; @@ -16,12 +16,12 @@ public interface IRetriever : IDisposable { Dictionary GetUserData(); - T Complete(PrimaryKey? id, Action complete) where T : Entity; - T Request(PrimaryKey? id) where T : Entity; - T RequestIBA(PrimaryKey? typeId, string id) where T : class, IEntity; - Lite RequestLite(Lite lite) where T : class, IEntity; - T ModifiablePostRetrieving(T entity) where T : Modifiable; - IRetriever Parent { get; } + T? Complete(PrimaryKey? id, Action complete) where T : Entity; + T? Request(PrimaryKey? id) where T : Entity; + T? RequestIBA(PrimaryKey? typeId, string id) where T : class, IEntity; + Lite? RequestLite(Lite? lite) where T : class, IEntity; + T? ModifiablePostRetrieving(T? entity) where T : Modifiable; + IRetriever? Parent { get; } void CompleteAll(); Task CompleteAllAsync(CancellationToken token); @@ -31,10 +31,10 @@ public interface IRetriever : IDisposable class RealRetriever : IRetriever { - Dictionary userData; + Dictionary? userData; public Dictionary GetUserData() => userData ?? (userData = new Dictionary()); - public IRetriever Parent + public IRetriever? Parent { get { return null; } } @@ -46,8 +46,8 @@ public RealRetriever(EntityCache.RealEntityCache entityCache) EntityCache.RealEntityCache entityCache; Dictionary<(Type type, PrimaryKey id), Entity> retrieved = new Dictionary<(Type type, PrimaryKey id), Entity>(); - Dictionary> requests; - Dictionary<(Type type, PrimaryKey id), List>> liteRequests; + Dictionary>? requests; + Dictionary<(Type type, PrimaryKey id), List>>? liteRequests; List modifiablePostRetrieving = new List(); bool TryGetRequest((Type type, PrimaryKey id) key, out Entity value) @@ -55,11 +55,11 @@ bool TryGetRequest((Type type, PrimaryKey id) key, out Entity value) if (requests != null && requests.TryGetValue(key.type, out Dictionary dic) && dic.TryGetValue(key.id, out value)) return true; - value = null; + value = null!; return false; } - public T Complete(PrimaryKey? id, Action complete) where T : Entity + public T? Complete(PrimaryKey? id, Action complete) where T : Entity { if (id == null) return null; @@ -76,7 +76,7 @@ public T Complete(PrimaryKey? id, Action complete) where T : Entity if (TryGetRequest(tuple, out result)) { entity = (T)result; - requests[typeof(T)].Remove(id.Value); + requests![typeof(T)].Remove(id.Value); } else { @@ -91,20 +91,20 @@ public T Complete(PrimaryKey? id, Action complete) where T : Entity static GenericInvoker> giRequest = new GenericInvoker>((rr, id) => rr.Request(id)); - public T Request(PrimaryKey? id) where T : Entity + public T? Request(PrimaryKey? id) where T : Entity { if (id == null) return null; var tuple = (type: typeof(T), id: id.Value); - if (entityCache.TryGetValue(tuple, out Entity ident)) + if (entityCache.TryGetValue(tuple, out Entity? ident)) return (T)ident; if (retrieved.TryGetValue(tuple, out ident)) return (T)ident; - ICacheController cc = Schema.Current.CacheController(typeof(T)); + ICacheController? cc = Schema.Current.CacheController(typeof(T)); if (cc != null && cc.Enabled) { T entityFromCache = EntityCache.Construct(id.Value); @@ -113,7 +113,7 @@ public T Request(PrimaryKey? id) where T : Entity return entityFromCache; } - ident = (T)requests?.TryGetC(typeof(T))?.TryGetC(id.Value); + ident = (T?)requests?.TryGetC(typeof(T))?.TryGetC(id.Value); if (ident != null) return (T)ident; @@ -126,7 +126,7 @@ public T Request(PrimaryKey? id) where T : Entity return entity; } - public T RequestIBA(PrimaryKey? typeId, string id) where T : class, IEntity + public T? RequestIBA(PrimaryKey? typeId, string id) where T : class, IEntity { if (id == null) return null; @@ -138,12 +138,12 @@ public T RequestIBA(PrimaryKey? typeId, string id) where T : class, IEntity return (T)(IEntity)giRequest.GetInvoker(type)(this, parsedId); } - public Lite RequestLite(Lite lite) where T : class, IEntity + public Lite? RequestLite(Lite? lite) where T : class, IEntity { if (lite == null) return null; - ICacheController cc = Schema.Current.CacheController(lite.EntityType); + ICacheController? cc = Schema.Current.CacheController(lite.EntityType); if (cc != null && cc.Enabled) { lite.SetToString(cc.TryGetToString(lite.Id) ?? ("[" + EngineMessage.EntityWithType0AndId1NotFound.NiceToString().FormatWith(lite.EntityType.NiceName(), lite.Id) + "]")); @@ -157,7 +157,7 @@ public Lite RequestLite(Lite lite) where T : class, IEntity return lite; } - public T ModifiablePostRetrieving(T modifiable) where T : Modifiable + public T? ModifiablePostRetrieving(T? modifiable) where T : Modifiable { if (modifiable != null) modifiablePostRetrieving.Add(modifiable); @@ -190,8 +190,8 @@ public async Task CompleteAllPrivate(CancellationToken? token) var group = requests.WithMax(a => a.Value.Count); var dic = group.Value; - ICacheController cc = Schema.Current.CacheController(group.Key); + ICacheController? cc = Schema.Current.CacheController(group.Key); if (cc != null && cc.Enabled) { cc.Load(); @@ -223,7 +223,7 @@ public async Task CompleteAllPrivate(CancellationToken? token) { { - List<(Type type, PrimaryKey id)> toRemove = null; + List<(Type type, PrimaryKey id)>? toRemove = null; foreach (var item in liteRequests) { var entity = retrieved.TryGetC(item.Key); @@ -303,8 +303,7 @@ public async Task CompleteAllPrivate(CancellationToken? token) new GenericInvoker, CancellationToken?, Task>>>((ids, token) => GetStrings(ids, token)); static async Task> GetStrings(List ids, CancellationToken? token) where T : Entity { - ICacheController cc = Schema.Current.CacheController(typeof(T)); - + ICacheController? cc = Schema.Current.CacheController(typeof(T)); if (cc != null && cc.Enabled) { cc.Load(); @@ -344,39 +343,40 @@ public ModifiedState ModifiedState class ChildRetriever : IRetriever { - public Dictionary GetUserData() => this.Parent.GetUserData(); + public Dictionary GetUserData() => this.parent.GetUserData(); EntityCache.RealEntityCache entityCache; - public IRetriever Parent { get; set; } + public IRetriever parent; + public IRetriever? Parent => parent; public ChildRetriever(IRetriever parent, EntityCache.RealEntityCache entityCache) { - this.Parent = parent; + this.parent= parent; this.entityCache = entityCache; } - public T Complete(PrimaryKey? id, Action complete) where T : Entity + public T? Complete(PrimaryKey? id, Action complete) where T : Entity { - return Parent.Complete(id, complete); + return parent.Complete(id, complete); } - public T Request(PrimaryKey? id) where T : Entity + public T? Request(PrimaryKey? id) where T : Entity { - return Parent.Request(id); + return parent.Request(id); } - public T RequestIBA(PrimaryKey? typeId, string id) where T : class, IEntity + public T? RequestIBA(PrimaryKey? typeId, string id) where T : class, IEntity { - return Parent.RequestIBA(typeId, id); + return parent.RequestIBA(typeId, id); } - public Lite RequestLite(Lite lite) where T : class, IEntity + public Lite? RequestLite(Lite? lite) where T : class, IEntity { - return Parent.RequestLite(lite); + return parent.RequestLite(lite); } - public T ModifiablePostRetrieving(T entity) where T : Modifiable + public T? ModifiablePostRetrieving(T? entity) where T : Modifiable { - return Parent.ModifiablePostRetrieving(entity); + return parent.ModifiablePostRetrieving(entity); } public void CompleteAll() diff --git a/Signum.Engine/Schema/Schema.Expressions.cs b/Signum.Engine/Schema/Schema.Expressions.cs index 6ee7a3fef5..78861c1f8b 100644 --- a/Signum.Engine/Schema/Schema.Expressions.cs +++ b/Signum.Engine/Schema/Schema.Expressions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -18,7 +18,7 @@ public partial class Table { internal Expression GetProjectorExpression(Alias tableAlias, QueryBinder binder) { - Expression id = GetIdExpression(tableAlias); + Expression? id = GetIdExpression(tableAlias); if (IsView) { @@ -33,10 +33,10 @@ internal Expression GetProjectorExpression(Alias tableAlias, QueryBinder binder) Schema.Current.AssertAllowed(Type, inUserInterface: false); var period = GenerateSystemPeriod(tableAlias, binder); - var bindings = GenerateBindings(tableAlias, binder, id, period); - var mixins = GenerateMixins(tableAlias, binder, id, period); + var bindings = GenerateBindings(tableAlias, binder, id!, period); + var mixins = GenerateMixins(tableAlias, binder, id!, period); - var result = new EntityExpression(this.Type, (PrimaryKeyExpression)id, period, tableAlias, bindings, mixins, period, avoidExpandOnRetrieving: false); + var result = new EntityExpression(this.Type, (PrimaryKeyExpression)id!, period, tableAlias, bindings, mixins, period, avoidExpandOnRetrieving: false); return result; } @@ -44,7 +44,7 @@ internal Expression GetProjectorExpression(Alias tableAlias, QueryBinder binder) internal static ConstructorInfo intervalConstructor = typeof(Interval).GetConstructor(new[] { typeof(DateTime), typeof(DateTime) }); - internal NewExpression GenerateSystemPeriod(Alias tableAlias, QueryBinder binder, bool force = false) + internal NewExpression? GenerateSystemPeriod(Alias tableAlias, QueryBinder binder, bool force = false) { return this.SystemVersioned != null && (force || binder.systemTime is SystemTime.Interval) ? Expression.New(intervalConstructor, new ColumnExpression(typeof(DateTime), tableAlias, this.SystemVersioned.StartColumnName), @@ -52,11 +52,12 @@ internal NewExpression GenerateSystemPeriod(Alias tableAlias, QueryBinder binder ) : null; } - internal ReadOnlyCollection GenerateBindings(Alias tableAlias, QueryBinder binder, Expression id, NewExpression period) + internal ReadOnlyCollection GenerateBindings(Alias tableAlias, QueryBinder binder, Expression id, NewExpression? period) { - List result = new List(); - - result.Add(new FieldBinding(Table.fiId, id)); + List result = new List + { + new FieldBinding(Table.fiId, id) + }; foreach (var ef in this.Fields.Values) { @@ -72,7 +73,7 @@ internal ReadOnlyCollection GenerateBindings(Alias tableAlias, Que return result.ToReadOnly(); } - internal ReadOnlyCollection GenerateMixins(Alias tableAlias, QueryBinder binder, Expression id, NewExpression period) + internal ReadOnlyCollection? GenerateMixins(Alias tableAlias, QueryBinder binder, Expression id, NewExpression? period) { if (this.Mixins == null) return null; @@ -81,7 +82,7 @@ internal ReadOnlyCollection GenerateMixins(Alias tableAli } - internal Expression GetIdExpression(Alias alias) + internal Expression? GetIdExpression(Alias alias) { var field = Fields.TryGetC(Table.fiId.Name); @@ -95,10 +96,10 @@ internal Expression GetIdExpression(Alias alias) return new ColumnExpression(Signum.Entities.PrimaryKey.Type(fr.ReferenceTable.Type).Nullify(), alias, fr.Name); } - return field.Field.GetExpression(alias, null, null, null); + return field.Field!.GetExpression(alias, null!, null!, null); } - public EntityField GetViewPrimaryKey() + public EntityField? GetViewPrimaryKey() { return Fields.Values.FirstOrDefault(f => f.Field is IColumn && ((IColumn)f.Field).PrimaryKey); } @@ -108,8 +109,8 @@ ColumnExpression ITablePrivate.GetPrimaryOrder(Alias alias) var res = GetIdExpression(alias); return res is PrimaryKeyExpression ? - (ColumnExpression)((PrimaryKeyExpression)res).Value: - (ColumnExpression)res; + (ColumnExpression)((PrimaryKeyExpression)res!).Value : /*CSBUG*/ + (ColumnExpression)res!; } } @@ -129,10 +130,10 @@ internal PrimaryKeyExpression BackColumnExpression(Alias tableAlias) internal ColumnExpression OrderExpression(Alias tableAlias) { - return new ColumnExpression(typeof(int), tableAlias, ((IColumn)this.Order).Name); + return new ColumnExpression(typeof(int), tableAlias, ((IColumn)this.Order!).Name); } - internal Expression FieldExpression(Alias tableAlias, QueryBinder binder, NewExpression externalPeriod, bool withRowId) + internal Expression FieldExpression(Alias tableAlias, QueryBinder binder, NewExpression? externalPeriod, bool withRowId) { var rowId = RowIdExpression(tableAlias); @@ -157,11 +158,11 @@ internal Expression GetProjectorExpression(Alias tableAlias, QueryBinder binder) Type elementType = typeof(MListElement<,>).MakeGenericType(BackReference.FieldType, Field.FieldType); var rowId = RowIdExpression(tableAlias); - NewExpression period = GenerateSystemPeriod(tableAlias, binder); + NewExpression? period = GenerateSystemPeriod(tableAlias, binder); return new MListElementExpression( rowId, - (EntityExpression)this.BackReference.GetExpression(tableAlias, binder, null, period), + (EntityExpression)this.BackReference.GetExpression(tableAlias, binder, null!, period), this.Order == null ? null : OrderExpression(tableAlias), this.Field.GetExpression(tableAlias, binder, rowId, period), period, @@ -169,9 +170,9 @@ internal Expression GetProjectorExpression(Alias tableAlias, QueryBinder binder) tableAlias); } - internal NewExpression GenerateSystemPeriod(Alias tableAlias, QueryBinder binder, bool force = false) + internal NewExpression? GenerateSystemPeriod(Alias tableAlias, QueryBinder binder, bool force = false) { - return this.SystemVersioned != null || (force || binder.systemTime is SystemTime.Interval) ? Expression.New(Table.intervalConstructor, + return this.SystemVersioned != null && (force || binder.systemTime is SystemTime.Interval) ? Expression.New(Table.intervalConstructor, new ColumnExpression(typeof(DateTime), tableAlias, this.SystemVersioned.StartColumnName), new ColumnExpression(typeof(DateTime), tableAlias, this.SystemVersioned.EndColumnName) ) : null; @@ -185,12 +186,12 @@ ColumnExpression ITablePrivate.GetPrimaryOrder(Alias alias) public abstract partial class Field { - internal abstract Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression period); + internal abstract Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression? period); } public partial class FieldPrimaryKey { - internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression period) + internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression? period) { return new PrimaryKeyExpression(new ColumnExpression(this.Type.Nullify(), tableAlias, this.Name).Nullify()); } @@ -198,7 +199,7 @@ internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, public partial class FieldValue { - internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression period) + internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression? period) { var column = new ColumnExpression(this.Type, tableAlias, this.Name); @@ -213,7 +214,7 @@ public partial class FieldTicks { public static readonly PropertyInfo piDateTimeTicks = ReflectionTools.GetPropertyInfo((DateTime d) => d.Ticks); - internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression period) + internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression? period) { if (this.Type == this.FieldType) return new ColumnExpression(this.Type, tableAlias, this.Name); @@ -227,9 +228,9 @@ internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, public partial class FieldReference { - internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression period) + internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression? period) { - Type cleanType = IsLite ? Lite.Extract(FieldType) : FieldType; + Type cleanType = IsLite ? Lite.Extract(FieldType)! : FieldType; var result = new EntityExpression(cleanType, new PrimaryKeyExpression(new ColumnExpression(this.Type.Nullify(), tableAlias, Name)), period, null, null, null, null, AvoidExpandOnRetrieving); @@ -242,7 +243,7 @@ internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, public partial class FieldEnum { - internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression period) + internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression? period) { return Expression.Convert(new ColumnExpression(this.Type, tableAlias, Name), FieldType); } @@ -250,7 +251,7 @@ internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, public partial class FieldMList { - internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression period) + internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression? period) { return new MListExpression(FieldType, (PrimaryKeyExpression)id, period, TableMList); // keep back id empty for some seconds } @@ -258,7 +259,7 @@ internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, public partial class FieldEmbedded { - internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression period) + internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression? period) { var bindings = (from kvp in EmbeddedFields let fi = kvp.Value.FieldInfo @@ -276,7 +277,7 @@ internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, public partial class FieldMixin { - internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression period) + internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression? period) { var bindings = (from kvp in Fields let fi = kvp.Value.FieldInfo @@ -290,12 +291,12 @@ internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, public partial class FieldImplementedBy { - internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression period) + internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression? period) { var implementations = ImplementationColumns.SelectDictionary(t => t, (t, ic) => new EntityExpression(t, new PrimaryKeyExpression(new ColumnExpression(ic.Type.Nullify(), tableAlias, ic.Name)), period, null, null, null, null, AvoidExpandOnRetrieving)); - var result = new ImplementedByExpression(IsLite ? Lite.Extract(FieldType) : FieldType, SplitStrategy, implementations); + var result = new ImplementedByExpression(IsLite ? Lite.Extract(FieldType)! : FieldType, SplitStrategy, implementations); if (this.IsLite) return binder.MakeLite(result, null); @@ -306,10 +307,10 @@ internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, public partial class FieldImplementedByAll { - internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression period) + internal override Expression GetExpression(Alias tableAlias, QueryBinder binder, Expression id, NewExpression? period) { Expression result = new ImplementedByAllExpression( - IsLite ? Lite.Extract(FieldType) : FieldType, + IsLite ? Lite.Extract(FieldType)! : FieldType, new ColumnExpression(Column.Type, tableAlias, Column.Name), new TypeImplementedByAllExpression(new PrimaryKeyExpression(new ColumnExpression(ColumnType.Type.Nullify(), tableAlias, ColumnType.Name))), period); diff --git a/Signum.Engine/Schema/Schema.Save.cs b/Signum.Engine/Schema/Schema.Save.cs index 97d3be8376..18ca99ba6b 100644 --- a/Signum.Engine/Schema/Schema.Save.cs +++ b/Signum.Engine/Schema/Schema.Save.cs @@ -24,7 +24,7 @@ public Forbidden(HashSet? set) this.set = set; } - public Forbidden(DirectedGraph graph, Entity entity) + public Forbidden(DirectedGraph? graph, Entity entity) { this.set = graph?.TryRelatedTo(entity); } @@ -53,7 +53,7 @@ public EntityForbidden(Entity entity, Forbidden forbidden) this.Forbidden = forbidden; } - public EntityForbidden(Entity entity, DirectedGraph graph) + public EntityForbidden(Entity entity, DirectedGraph? graph) { this.Entity = (Entity)entity; this.Forbidden = new Forbidden(graph, entity); @@ -65,7 +65,7 @@ public partial class Table ResetLazy inserterIdentity; ResetLazy inserterDisableIdentity; - internal void InsertMany(List list, DirectedGraph backEdges) + internal void InsertMany(List list, DirectedGraph? backEdges) { using (HeavyProfiler.LogNoStackTrace("InsertMany", () => this.Type.TypeName())) { @@ -98,8 +98,8 @@ class InsertCacheDisableIdentity public Func SqlInsertPattern; public Func> InsertParameters; - ConcurrentDictionary, DirectedGraph>> insertDisableIdentityCache = - new ConcurrentDictionary, DirectedGraph>>(); + ConcurrentDictionary, DirectedGraph?>> insertDisableIdentityCache = + new ConcurrentDictionary, DirectedGraph?>>(); public InsertCacheDisableIdentity(Table table, Func sqlInsertPattern, Func> insertParameters) { @@ -108,13 +108,13 @@ public InsertCacheDisableIdentity(Table table, Func sqlInsertPat InsertParameters = insertParameters; } - internal Action, DirectedGraph> GetInserter(int numElements) + internal Action, DirectedGraph?> GetInserter(int numElements) { return insertDisableIdentityCache.GetOrAdd(numElements, (int num) => num == 1 ? GetInsertDisableIdentity() : GetInsertMultiDisableIdentity(num)); } - Action, DirectedGraph> GetInsertDisableIdentity() + Action, DirectedGraph?> GetInsertDisableIdentity() { string sqlSingle = SqlInsertPattern(""); @@ -140,7 +140,7 @@ Action, DirectedGraph> GetInsertDisableIdentity() - Action, DirectedGraph> GetInsertMultiDisableIdentity(int num) + Action, DirectedGraph?> GetInsertMultiDisableIdentity(int num) { string sqlMulti = Enumerable.Range(0, num).ToString(i => SqlInsertPattern(i.ToString()), ";\r\n"); @@ -214,8 +214,8 @@ class InsertCacheIdentity public Func SqlInsertPattern; public Func> InsertParameters; - ConcurrentDictionary, DirectedGraph>> insertIdentityCache = - new ConcurrentDictionary, DirectedGraph>>(); + ConcurrentDictionary, DirectedGraph?>> insertIdentityCache = + new ConcurrentDictionary, DirectedGraph?>>(); public InsertCacheIdentity(Table table, Func sqlInsertPattern, Func> insertParameters) { @@ -224,12 +224,12 @@ public InsertCacheIdentity(Table table, Func sqlInsertPatt InsertParameters = insertParameters; } - internal Action, DirectedGraph> GetInserter(int numElements) + internal Action, DirectedGraph?> GetInserter(int numElements) { return insertIdentityCache.GetOrAdd(numElements, (int num) => GetInsertMultiIdentity(num)); } - Action, DirectedGraph> GetInsertMultiIdentity(int num) + Action, DirectedGraph?> GetInsertMultiIdentity(int num) { string sqlMulti = new StringBuilder() .AppendLine("DECLARE @MyTable TABLE (Id " + this.table.PrimaryKey.SqlDbType.ToString().ToUpperInvariant() + ");") @@ -637,7 +637,7 @@ public SqlPreCommand InsertSqlSync(Entity ident, bool includeCollections = true, return SqlPreCommand.Combine(Spacing.Simple, declareParent, insert, setParent, collections)!; } - public SqlPreCommand? UpdateSqlSync(T entity, Expression> where, bool includeCollections = true, string? comment = null, string suffix = "") + public SqlPreCommand? UpdateSqlSync(T entity, Expression>? where, bool includeCollections = true, string? comment = null, string suffix = "") where T : Entity { if (typeof(T) != Type && where != null) diff --git a/Signum.Engine/Schema/Schema.cs b/Signum.Engine/Schema/Schema.cs index ffe4af0a39..aa05fa5380 100644 --- a/Signum.Engine/Schema/Schema.cs +++ b/Signum.Engine/Schema/Schema.cs @@ -241,7 +241,7 @@ internal void OnPreBulkInsert(Type type, bool inMListTable) return ee.CacheController; } - internal IEnumerable GetAdditionalQueryBindings(PropertyRoute parent, PrimaryKeyExpression id, NewExpression period) + internal IEnumerable GetAdditionalQueryBindings(PropertyRoute parent, PrimaryKeyExpression id, NewExpression? period) { //AssertAllowed(parent.RootType, inUserInterface: false); diff --git a/Signum.Engine/Schema/SchemaBuilder/NameSequence.cs b/Signum.Engine/Schema/SchemaBuilder/NameSequence.cs index 91bbca1fbe..cad72bc0d2 100644 --- a/Signum.Engine/Schema/SchemaBuilder/NameSequence.cs +++ b/Signum.Engine/Schema/SchemaBuilder/NameSequence.cs @@ -1,11 +1,9 @@ -using Signum.Utilities; +using Signum.Utilities; namespace Signum.Engine.Maps { public class NameSequence { - private NameSequence() { } - public static readonly NameSequence Void = new VoidNameSequence(); class VoidNameSequence : NameSequence @@ -19,6 +17,7 @@ public override string ToString() readonly string Value; readonly NameSequence PreSequence; + private NameSequence() : this(null!, null!) { } private NameSequence(string value, NameSequence preSequence) { this.Value = value; diff --git a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs index 31097591f2..d3f6ad1cf6 100644 --- a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs +++ b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs @@ -496,7 +496,7 @@ public enum KindOfField if (route.FieldInfo != null && ReflectionTools.FieldEquals(route.FieldInfo, fiTicks)) return KindOfField.Ticks; - if (Settings.GetSqlDbType(Settings.FieldAttribute(route), route.Type) != null) + if (Settings.TryGetSqlDbType(Settings.FieldAttribute(route), route.Type) != null) return KindOfField.Value; if (route.Type.UnNullify().IsEnum) @@ -679,7 +679,7 @@ protected virtual FieldImplementedByAll GenerateFieldImplementedByAll(PropertyRo protected virtual FieldMList GenerateFieldMList(Table table, PropertyRoute route, NameSequence name) { - Type elementType = route.Type.ElementType(); + Type elementType = route.Type.ElementType()!; if (table.Ticks == null) throw new InvalidOperationException("Type '{0}' has field '{1}' but does not Ticks. MList requires concurrency control.".FormatWith(route.Parent!.Type.TypeName(), route.FieldInfo!.FieldName())); diff --git a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs index 3fe6d3da44..f75d1fc17c 100644 --- a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs +++ b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs @@ -25,12 +25,12 @@ public SchemaSettings() public PrimaryKeyAttribute DefaultPrimaryKeyAttribute = new PrimaryKeyAttribute(typeof(int), "ID"); public int DefaultImplementedBySize = 40; - public Action AssertNotIncluded = null; + public Action AssertNotIncluded = null!; public int MaxNumberOfParameters = 2000; public int MaxNumberOfStatementsInSaveQueries = 16; - public ConcurrentDictionary FieldAttributesCache = new ConcurrentDictionary(); + public ConcurrentDictionary FieldAttributesCache = new ConcurrentDictionary(); public ConcurrentDictionary TypeAttributesCache = new ConcurrentDictionary(); public Dictionary UdtSqlName = new Dictionary() @@ -62,7 +62,7 @@ public SchemaSettings() {typeof(Guid), SqlDbType.UniqueIdentifier}, }; - internal Dictionary desambiguatedNames; + internal Dictionary? desambiguatedNames; Dictionary defaultSize = new Dictionary() { @@ -83,10 +83,10 @@ public SchemaSettings() public AttributeCollection FieldAttributes(Expression> propertyRoute) where T : IRootEntity { - return FieldAttributes(PropertyRoute.Construct(propertyRoute)); + return FieldAttributes(PropertyRoute.Construct(propertyRoute))!; } - public AttributeCollection FieldAttributes(PropertyRoute propertyRoute) + public AttributeCollection? FieldAttributes(PropertyRoute propertyRoute) { using (HeavyProfiler.LogNoStackTrace("FieldAttributes")) { @@ -99,9 +99,9 @@ public AttributeCollection FieldAttributes(PropertyRoute propertyRoute) return null; return CreateFieldAttributeCollection(propertyRoute); case PropertyRouteType.MListItems: - if (propertyRoute.Parent.FieldInfo == null) + if (propertyRoute.Parent!.FieldInfo == null) return null; - return CreateFieldAttributeCollection(propertyRoute.Parent); + return CreateFieldAttributeCollection(propertyRoute.Parent!); default: throw new InvalidOperationException("Route of type {0} not supported for this method".FormatWith(propertyRoute.PropertyRouteType)); } @@ -111,7 +111,7 @@ public AttributeCollection FieldAttributes(PropertyRoute propertyRoute) AttributeCollection CreateFieldAttributeCollection(PropertyRoute route) { - var fieldAttributes = route.FieldInfo.GetCustomAttributes(false).Cast(); + var fieldAttributes = route.FieldInfo!.GetCustomAttributes(false).Cast(); var fieldAttributesInProperty = route.PropertyInfo == null ? Enumerable.Empty() : route.PropertyInfo.GetCustomAttributes(false).Cast().Where(a => AttributeCollection.IsCompatibleWith(a, AttributeTargets.Field)); return new AttributeCollection(AttributeTargets.Field, fieldAttributes.Concat(fieldAttributesInProperty).ToList(), () => AssertNotIncluded(route.RootType)); @@ -164,7 +164,7 @@ public AttributeCollection TypeAttributes(Type entityType) throw new InvalidOperationException($"In order to {errorContext} you need to override the attributes for {pr} {solution}"); } - public A FieldAttribute(PropertyRoute propertyRoute) where A : Attribute + public A? FieldAttribute(PropertyRoute propertyRoute) where A : Attribute { using (HeavyProfiler.LogNoStackTrace("FieldAttribute")) { @@ -175,13 +175,13 @@ public A FieldAttribute(PropertyRoute propertyRoute) where A : Attribute } } - public V ValidatorAttribute(PropertyRoute propertyRoute) where V: ValidatorAttribute + public V? ValidatorAttribute(PropertyRoute propertyRoute) where V: ValidatorAttribute { if (!typeof(ModifiableEntity).IsAssignableFrom(propertyRoute.RootType)) return null; if (propertyRoute.PropertyRouteType == PropertyRouteType.MListItems) - propertyRoute = propertyRoute.Parent; + propertyRoute = propertyRoute.Parent!; if (propertyRoute.PropertyInfo == null) return null; @@ -223,13 +223,13 @@ private IsNullable GetIsNullablePrivate(PropertyRoute propertyRoute) if (ValidatorAttribute(propertyRoute) != null) return IsNullable.No; - if (propertyRoute.Type == typeof(string)) - { - var slv = ValidatorAttribute(propertyRoute); + //if (propertyRoute.Type == typeof(string)) + //{ + // var slv = ValidatorAttribute(propertyRoute); - if (slv != null) - return slv.AllowNulls ? IsNullable.Yes : IsNullable.No; - } + // if (slv != null) + // return slv.AllowNulls ? IsNullable.Yes : IsNullable.No; + //} return !propertyRoute.Type.IsValueType || propertyRoute.Type.IsNullable() ? IsNullable.Yes : IsNullable.No; } @@ -268,7 +268,7 @@ public Implementations GetImplementations(PropertyRoute propertyRoute) FieldAttribute(propertyRoute)); } - internal SqlDbTypePair GetSqlDbType(SqlDbTypeAttribute att, Type type) + internal SqlDbTypePair GetSqlDbType(SqlDbTypeAttribute? att, Type type) { if (att != null && att.HasSqlDbType) return new SqlDbTypePair(att.SqlDbType, att.UserDefinedTypeName); @@ -276,7 +276,15 @@ internal SqlDbTypePair GetSqlDbType(SqlDbTypeAttribute att, Type type) return GetSqlDbTypePair(type.UnNullify()); } - internal int? GetSqlSize(SqlDbTypeAttribute att, PropertyRoute? route, SqlDbType sqlDbType) + internal SqlDbTypePair? TryGetSqlDbType(SqlDbTypeAttribute? att, Type type) + { + if (att != null && att.HasSqlDbType) + return new SqlDbTypePair(att.SqlDbType, att.UserDefinedTypeName); + + return TryGetSqlDbTypePair(type.UnNullify()); + } + + internal int? GetSqlSize(SqlDbTypeAttribute? att, PropertyRoute? route, SqlDbType sqlDbType) { if (att != null && att.HasSize) return att.Size; @@ -291,7 +299,7 @@ internal SqlDbTypePair GetSqlDbType(SqlDbTypeAttribute att, Type type) return defaultSize.TryGetS(sqlDbType); } - internal int? GetSqlScale(SqlDbTypeAttribute att, SqlDbType sqlDbType) + internal int? GetSqlScale(SqlDbTypeAttribute? att, SqlDbType sqlDbType) { if (att != null && att.HasScale) { @@ -304,7 +312,7 @@ internal SqlDbTypePair GetSqlDbType(SqlDbTypeAttribute att, Type type) return defaultScale.TryGetS(sqlDbType); } - internal string GetCollate(SqlDbTypeAttribute att) + internal string? GetCollate(SqlDbTypeAttribute att) { if (att != null && att.Collation != null) return att.Collation; @@ -319,25 +327,34 @@ internal SqlDbType DefaultSqlType(Type type) public void Desambiguate(Type type, string cleanName) { - if (desambiguatedNames != null) + if (desambiguatedNames == null) desambiguatedNames = new Dictionary(); desambiguatedNames[type] = cleanName; } public SqlDbTypePair GetSqlDbTypePair(Type type) + { + var result = TryGetSqlDbTypePair(type); + if (result == null) + throw new ArgumentException($"Type {type.Name} has no DB representation"); + + return result; + } + + public SqlDbTypePair? TryGetSqlDbTypePair(Type type) { if (TypeValues.TryGetValue(type, out SqlDbType result)) return new SqlDbTypePair(result, null); - string udtTypeName = GetUdtName(type); + string? udtTypeName = GetUdtName(type); if (udtTypeName != null) return new SqlDbTypePair(SqlDbType.Udt, udtTypeName); return null; } - public string GetUdtName(Type udtType) + public string? GetUdtName(Type udtType) { var att = udtType.GetCustomAttribute(); @@ -357,11 +374,9 @@ public bool IsDbType(Type type) public class SqlDbTypePair { public SqlDbType SqlDbType { get; private set; } - public string UserDefinedTypeName { get; private set; } - - public SqlDbTypePair() { } - - public SqlDbTypePair(SqlDbType type, string udtTypeName) + public string? UserDefinedTypeName { get; private set; } + + public SqlDbTypePair(SqlDbType type, string? udtTypeName) { this.SqlDbType = type; this.UserDefinedTypeName = udtTypeName; diff --git a/Signum.Engine/Schema/UniqueIndex.cs b/Signum.Engine/Schema/UniqueIndex.cs index 5df6ea7de2..a877324259 100644 --- a/Signum.Engine/Schema/UniqueIndex.cs +++ b/Signum.Engine/Schema/UniqueIndex.cs @@ -169,7 +169,7 @@ static Type RemoveCasting(ref Expression body) if (body.NodeType == ExpressionType.Convert && body.Type == typeof(object)) body = ((UnaryExpression)body).Operand; - Type type = null; + Type? type = null; if ((body.NodeType == ExpressionType.Convert || body.NodeType == ExpressionType.TypeAs) && body.Type != typeof(object)) { diff --git a/Signum.Entities/DynamicQuery/Filter.cs b/Signum.Entities/DynamicQuery/Filter.cs index f1f8ea7871..7624f28872 100644 --- a/Signum.Entities/DynamicQuery/Filter.cs +++ b/Signum.Entities/DynamicQuery/Filter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -47,8 +47,7 @@ public override IEnumerable GetFilterConditions() public override Expression GetExpression(BuildExpressionContext ctx) { - var anyAll = Token as CollectionAnyAllToken; - if(anyAll == null) + if (!(Token is CollectionAnyAllToken anyAll)) { return this.GroupOperation == FilterGroupOperation.And ? Filters.Select(f => f.GetExpression(ctx)).AggregateAnd() : @@ -56,8 +55,8 @@ public override Expression GetExpression(BuildExpressionContext ctx) } else { - Expression collection = anyAll.Parent.BuildExpression(ctx); - Type elementType = collection.Type.ElementType(); + Expression collection = anyAll.Parent!.BuildExpression(ctx); + Type elementType = collection.Type.ElementType()!; var p = Expression.Parameter(elementType, elementType.Name.Substring(0, 1).ToLower()); ctx.Replacemens.Add(anyAll, p); @@ -90,7 +89,7 @@ public class FilterCondition : Filter { public QueryToken Token { get; } public FilterOperation Operation { get; } - public object Value { get; } + public object? Value { get; } public FilterCondition(QueryToken token, FilterOperation operation, object value) { @@ -116,11 +115,11 @@ public override Expression GetExpression(BuildExpressionContext ctx) if (anyAll == null) return GetConditionExpressionBasic(ctx); - Expression collection = anyAll.Parent.BuildExpression(ctx); - Type elementType = collection.Type.ElementType(); + Expression collection = anyAll.Parent!.BuildExpression(ctx); + Type elementType = collection.Type.ElementType()!; var p = Expression.Parameter(elementType, elementType.Name.Substring(0, 1).ToLower()); - ctx.Replacemens.Add(anyAll, p.BuildLiteNulifyUnwrapPrimaryKey(new[] { anyAll.GetPropertyRoute() })); + ctx.Replacemens.Add(anyAll, p.BuildLiteNulifyUnwrapPrimaryKey(new[] { anyAll.GetPropertyRoute()! })); var body = GetExpression(ctx); ctx.Replacemens.Remove(anyAll); diff --git a/Signum.Entities/DynamicQuery/QueryUtils.cs b/Signum.Entities/DynamicQuery/QueryUtils.cs index 735426ccdc..90c7d115ba 100644 --- a/Signum.Entities/DynamicQuery/QueryUtils.cs +++ b/Signum.Entities/DynamicQuery/QueryUtils.cs @@ -98,7 +98,7 @@ public static List GetFilterOperations(FilterType filtertype) return FilterOperations[filtertype]; } - static Dictionary> FilterOperations = new Dictionary> + static readonly Dictionary> FilterOperations = new Dictionary> { { FilterType.String, new List @@ -419,7 +419,7 @@ public static LambdaExpression CreateOrderLambda(QueryToken token, BuildExpressi } - static MethodInfo miToLite = ReflectionTools.GetMethodInfo((Entity ident) => ident.ToLite()).GetGenericMethodDefinition(); + static readonly MethodInfo miToLite = ReflectionTools.GetMethodInfo((Entity ident) => ident.ToLite()).GetGenericMethodDefinition(); internal static Expression ExtractEntity(this Expression expression, bool idAndToStr) { if (expression.Type.IsLite()) @@ -430,7 +430,7 @@ internal static Expression ExtractEntity(this Expression expression, bool idAndT if (!idAndToStr) return Expression.Property(expression, "Entity"); } - return expression; + return expression!; /*CSBUG*/ } internal static Expression BuildLiteNulifyUnwrapPrimaryKey(this Expression expression, PropertyRoute[] routes) @@ -496,12 +496,12 @@ internal static Type BuildLite(this Type type) } - static MethodInfo miContains = ReflectionTools.GetMethodInfo((string s) => s.Contains(s)); - static MethodInfo miStartsWith = ReflectionTools.GetMethodInfo((string s) => s.StartsWith(s)); - static MethodInfo miEndsWith = ReflectionTools.GetMethodInfo((string s) => s.EndsWith(s)); - static MethodInfo miLike = ReflectionTools.GetMethodInfo((string s) => s.Like(s)); - static MethodInfo miDistinctNullable = ReflectionTools.GetMethodInfo((string s) => LinqHints.DistinctNull(null, null)).GetGenericMethodDefinition(); - static MethodInfo miDistinct = ReflectionTools.GetMethodInfo((string s) => LinqHints.DistinctNull(null, null)).GetGenericMethodDefinition(); + static readonly MethodInfo miContains = ReflectionTools.GetMethodInfo((string s) => s.Contains(s)); + static readonly MethodInfo miStartsWith = ReflectionTools.GetMethodInfo((string s) => s.StartsWith(s)); + static readonly MethodInfo miEndsWith = ReflectionTools.GetMethodInfo((string s) => s.EndsWith(s)); + static readonly MethodInfo miLike = ReflectionTools.GetMethodInfo((string s) => s.Like(s)); + static readonly MethodInfo miDistinctNullable = ReflectionTools.GetMethodInfo((string s) => LinqHints.DistinctNull(null, null)).GetGenericMethodDefinition(); + static readonly MethodInfo miDistinct = ReflectionTools.GetMethodInfo((string s) => LinqHints.DistinctNull(null, null)).GetGenericMethodDefinition(); public static Expression GetCompareExpression(FilterOperation operation, Expression left, Expression right, bool inMemory = false) { diff --git a/Signum.Entities/DynamicQuery/ResultTable.cs b/Signum.Entities/DynamicQuery/ResultTable.cs index 890d29c83e..762f2d85f7 100644 --- a/Signum.Entities/DynamicQuery/ResultTable.cs +++ b/Signum.Entities/DynamicQuery/ResultTable.cs @@ -36,7 +36,7 @@ public ResultColumn(Column column, IList values) } -#pragma warning disable CS8618 // Non-nullable field is uninitialized. +#pragma warning disable CS8618, IDE0051 // Non-nullable field is uninitialized. ResultColumn(SerializationInfo info, StreamingContext context) { foreach (SerializationEntry entry in info) @@ -49,7 +49,7 @@ public ResultColumn(Column column, IList values) } } } -#pragma warning restore CS8618 // Non-nullable field is uninitialized. +#pragma warning restore CS8618, IDE0051 // Non-nullable field is uninitialized. GenericInvoker> listBuilder = new GenericInvoker>(num => new List(num)); @@ -207,7 +207,7 @@ static object DeserializeLite(string str, Type defaultEntityType) string toStr = tmp.After(';'); - Type type = string.IsNullOrEmpty(typeStr) ? defaultEntityType : TypeEntity.TryGetType(typeStr); + Type type = string.IsNullOrEmpty(typeStr) ? defaultEntityType : TypeEntity.TryGetType(typeStr)!; return Lite.Create(type, PrimaryKey.Parse(idStr, type), toStr); } diff --git a/Signum.Entities/DynamicQuery/Tokens/AggregateToken.cs b/Signum.Entities/DynamicQuery/Tokens/AggregateToken.cs index b182de936d..34527979cc 100644 --- a/Signum.Entities/DynamicQuery/Tokens/AggregateToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/AggregateToken.cs @@ -62,7 +62,7 @@ public override string ToString() { string? suffix = GetNiceOperation(); - return " ".CombineIfNotEmpty(AggregateFunction.NiceToString(), this.GeNiceDistinct(), this.GetNiceOperation(), this.GetNiceValue()); + return " ".Combine(AggregateFunction.NiceToString(), this.GeNiceDistinct(), this.GetNiceOperation(), this.GetNiceValue()); } public override string NiceName() @@ -70,7 +70,7 @@ public override string NiceName() if (AggregateFunction == AggregateFunction.Count && Parent == null) return AggregateFunction.NiceToString(); - return " ".CombineIfNotEmpty(AggregateFunction.NiceToString(), this.GeNiceDistinct(), this.GetNiceOperation(), this.GetNiceValue(), "of", Parent); + return " ".Combine(AggregateFunction.NiceToString(), this.GeNiceDistinct(), this.GetNiceOperation(), this.GetNiceValue(), "of", Parent); } string? GetNiceOperation() diff --git a/Signum.Entities/DynamicQuery/Tokens/AsTypeToken.cs b/Signum.Entities/DynamicQuery/Tokens/AsTypeToken.cs index 40ab75ba78..f9adb3f91d 100644 --- a/Signum.Entities/DynamicQuery/Tokens/AsTypeToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/AsTypeToken.cs @@ -73,7 +73,7 @@ public override string? Unit var routeAllowed = GetPropertyRoute()!.IsAllowed(); if (parentAllowed.HasText() && routeAllowed.HasText()) - QueryTokenMessage.And.NiceToString().CombineIfNotEmpty(parentAllowed, routeAllowed); + QueryTokenMessage.And.NiceToString().Combine(parentAllowed, routeAllowed); return parentAllowed ?? routeAllowed; } diff --git a/Signum.Entities/DynamicQuery/Tokens/CollectionAnyAllToken.cs b/Signum.Entities/DynamicQuery/Tokens/CollectionAnyAllToken.cs index 53eff2cfcc..7c9e69ac8a 100644 --- a/Signum.Entities/DynamicQuery/Tokens/CollectionAnyAllToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/CollectionAnyAllToken.cs @@ -14,13 +14,13 @@ public class CollectionAnyAllToken : QueryToken { public CollectionAnyAllType CollectionAnyAllType { get; private set; } - QueryToken parent; + readonly QueryToken parent; public override QueryToken? Parent => parent; - - Type elementType; + + readonly Type elementType; internal CollectionAnyAllToken(QueryToken parent, CollectionAnyAllType type) { - elementType = parent.Type.ElementType(); + elementType = parent.Type.ElementType()!; if (elementType == null) throw new InvalidOperationException("not a collection"); @@ -125,10 +125,10 @@ public override string TypeColor get { return "#0000FF"; } } - static MethodInfo miAnyE = ReflectionTools.GetMethodInfo((IEnumerable col) => col.Any(null)).GetGenericMethodDefinition(); - static MethodInfo miAllE = ReflectionTools.GetMethodInfo((IEnumerable col) => col.All(null)).GetGenericMethodDefinition(); - static MethodInfo miAnyQ = ReflectionTools.GetMethodInfo((IQueryable col) => col.Any(null)).GetGenericMethodDefinition(); - static MethodInfo miAllQ = ReflectionTools.GetMethodInfo((IQueryable col) => col.All(null)).GetGenericMethodDefinition(); + static readonly MethodInfo miAnyE = ReflectionTools.GetMethodInfo((IEnumerable col) => col.Any(null)).GetGenericMethodDefinition(); + static readonly MethodInfo miAllE = ReflectionTools.GetMethodInfo((IEnumerable col) => col.All(null)).GetGenericMethodDefinition(); + static readonly MethodInfo miAnyQ = ReflectionTools.GetMethodInfo((IQueryable col) => col.Any(null)).GetGenericMethodDefinition(); + static readonly MethodInfo miAllQ = ReflectionTools.GetMethodInfo((IQueryable col) => col.All(null)).GetGenericMethodDefinition(); public Expression BuildAnyAll(Expression collection, ParameterExpression param, Expression body) { diff --git a/Signum.Entities/DynamicQuery/Tokens/CollectionElementToken.cs b/Signum.Entities/DynamicQuery/Tokens/CollectionElementToken.cs index 3056feef7b..98de049ebe 100644 --- a/Signum.Entities/DynamicQuery/Tokens/CollectionElementToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/CollectionElementToken.cs @@ -17,11 +17,10 @@ public class CollectionElementToken : QueryToken QueryToken parent; public override QueryToken? Parent => parent; - - Type elementType; + readonly Type elementType; internal CollectionElementToken(QueryToken parent, CollectionElementType type) { - elementType = parent.Type.ElementType(); + elementType = parent.Type.ElementType()!; if (elementType == null) throw new InvalidOperationException("not a collection"); @@ -104,7 +103,7 @@ public override bool HasElement() if (parent is ExtensionToken et && et.IsProjection) return et.GetElementPropertyRoute(); - PropertyRoute? pr = this.parent.GetPropertyRoute(); + PropertyRoute? pr = this.parent!.GetPropertyRoute(); if (pr != null && pr.Type.ElementType() != null) return pr.Add("Item"); diff --git a/Signum.Entities/DynamicQuery/Tokens/DecimalSpecialTokens.cs b/Signum.Entities/DynamicQuery/Tokens/DecimalSpecialTokens.cs index 931f74c097..cbe48cb8ee 100644 --- a/Signum.Entities/DynamicQuery/Tokens/DecimalSpecialTokens.cs +++ b/Signum.Entities/DynamicQuery/Tokens/DecimalSpecialTokens.cs @@ -148,7 +148,7 @@ public override string Key protected override Expression BuildExpressionInternal(BuildExpressionContext context) { - var exp = parent.Parent.BuildExpression(context); + var exp = parent.Parent!.BuildExpression(context); return RoundingExpressionGenerator.RoundExpression(exp, this.StepSize(), RoundingType.Ceil); } diff --git a/Signum.Entities/DynamicQuery/Tokens/EntityToStringToken.cs b/Signum.Entities/DynamicQuery/Tokens/EntityToStringToken.cs index b61ec97a34..a95b01b446 100644 --- a/Signum.Entities/DynamicQuery/Tokens/EntityToStringToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/EntityToStringToken.cs @@ -10,7 +10,7 @@ namespace Signum.Entities.DynamicQuery [Serializable] public class EntityToStringToken : QueryToken { - QueryToken parent; + readonly QueryToken parent; public override QueryToken? Parent => parent; internal EntityToStringToken(QueryToken parent) @@ -71,19 +71,9 @@ public override string? Unit public override PropertyRoute? GetPropertyRoute() { - PropertyRoute? pr = parent.GetPropertyRoute(); - if (pr == null) - { - Type? type = Lite.Extract(pr.Type); //Because Parent.Type is always a lite - if (type != null) - return PropertyRoute.Root(type).Add(miToStringProperty); - } - else - { - Type? type = Lite.Extract(pr.Type); //Because Add doesn't work with lites - if (type != null) - return PropertyRoute.Root(type).Add(miToStringProperty); - } + Type? type = Lite.Extract(parent.GetPropertyRoute()?.Type ?? parent.Type); + if (type != null) + return PropertyRoute.Root(type).Add(miToStringProperty); return null; } diff --git a/Signum.Entities/DynamicQuery/Tokens/ExtensionToken.cs b/Signum.Entities/DynamicQuery/Tokens/ExtensionToken.cs index 8b1f462646..b5ea070108 100644 --- a/Signum.Entities/DynamicQuery/Tokens/ExtensionToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/ExtensionToken.cs @@ -19,7 +19,7 @@ public ExtensionToken(QueryToken parent, string key, Type type, bool isProjectio { this.parent = parent ?? throw new ArgumentNullException(nameof(parent)); - var shouldHaveImplementations = typeof(IEntity).IsAssignableFrom((isProjection ? type.ElementType() : type).CleanType()); + var shouldHaveImplementations = typeof(IEntity).IsAssignableFrom((isProjection ? type.ElementType()! : type).CleanType()); if (shouldHaveImplementations && implementations == null) throw new ArgumentException(@"Impossible to determine automatically the implementations for extension token '{0}' (of type {1}) registered on type {2}. diff --git a/Signum.Entities/DynamicQuery/Tokens/QueryToken.cs b/Signum.Entities/DynamicQuery/Tokens/QueryToken.cs index d56fb20635..c478173303 100644 --- a/Signum.Entities/DynamicQuery/Tokens/QueryToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/QueryToken.cs @@ -362,7 +362,7 @@ public string NiceTypeName if (IsCollection(type)) { - return QueryTokenMessage.ListOf0.NiceToString().FormatWith(GetNiceTypeName(Type.ElementType(), GetElementImplementations())); + return QueryTokenMessage.ListOf0.NiceToString().FormatWith(GetNiceTypeName(Type.ElementType()!, GetElementImplementations())); } return GetNiceTypeName(Type, GetImplementations()); diff --git a/Signum.Entities/FieldAttributes.cs b/Signum.Entities/FieldAttributes.cs index 887b436b7a..b076e3d841 100644 --- a/Signum.Entities/FieldAttributes.cs +++ b/Signum.Entities/FieldAttributes.cs @@ -55,7 +55,7 @@ private IEnumerable Enumerate() throw new InvalidOperationException("IsByAll"); } - public static Implementations? TryFromAttributes(Type t, PropertyRoute route, ImplementedByAttribute ib, ImplementedByAllAttribute iba) + public static Implementations? TryFromAttributes(Type t, PropertyRoute route, ImplementedByAttribute? ib, ImplementedByAllAttribute? iba) { if (ib != null && iba != null) throw new NotSupportedException("Route {0} contains both {1} and {2}".FormatWith(route, ib.GetType().Name, iba.GetType().Name)); @@ -70,7 +70,7 @@ private IEnumerable Enumerate() } - public static Implementations FromAttributes(Type t, PropertyRoute route, ImplementedByAttribute ib, ImplementedByAllAttribute iba) + public static Implementations FromAttributes(Type t, PropertyRoute route, ImplementedByAttribute? ib, ImplementedByAllAttribute? iba) { Implementations? imp = TryFromAttributes(t, route, ib, iba); diff --git a/Signum.Entities/FieldNotificationAttributes.cs b/Signum.Entities/FieldNotificationAttributes.cs index 777d981ff6..a649ff2957 100644 --- a/Signum.Entities/FieldNotificationAttributes.cs +++ b/Signum.Entities/FieldNotificationAttributes.cs @@ -40,7 +40,7 @@ internal static class AttributeManager return null; return new TypeAttributePack( - fields: list.Select(fi => ReflectionTools.CreateGetterUntyped(type, fi)).ToArray(), + fields: list.Select(fi => ReflectionTools.CreateGetterUntyped(type, fi)!).ToArray(), propertyNames: list.Select(fi => Reflector.FindPropertyInfo(fi).Name).ToArray() ); }); @@ -59,7 +59,7 @@ public static bool FieldContainsAttribute(Type type, PropertyInfo pi) readonly static object[] EmptyArray = new object[0]; - public static object[] FieldsWithAttribute(ModifiableEntity entity) + public static object?[] FieldsWithAttribute(ModifiableEntity entity) { TypeAttributePack? pack = GetFieldsAndProperties(entity.GetType()); @@ -87,10 +87,10 @@ public static object[] FieldsWithAttribute(ModifiableEntity entity) internal class TypeAttributePack { - public Func[] Fields; + public Func[] Fields; public string[] PropertyNames; - public TypeAttributePack(Func[] fields, string[] propertyNames) + public TypeAttributePack(Func[] fields, string[] propertyNames) { Fields = fields; PropertyNames = propertyNames; diff --git a/Signum.Entities/Lite.cs b/Signum.Entities/Lite.cs index d81f0dc2a4..277c83f517 100644 --- a/Signum.Entities/Lite.cs +++ b/Signum.Entities/Lite.cs @@ -320,7 +320,7 @@ public static Lite Parse(string liteKey) where T : class, IEntity if (!match.Success) return ValidationMessage.InvalidFormat.NiceToString(); - Type type = TypeEntity.TryGetType(match.Groups["type"].Value); + Type? type = TypeEntity.TryGetType(match.Groups["type"].Value); if (type == null) return LiteMessage.Type0NotFound.NiceToString().FormatWith(match.Groups["type"].Value); @@ -378,7 +378,7 @@ public static Lite ToLiteFat(this T entity) } [DebuggerStepThrough] - public static Lite ToLiteFat(this T entity, string toStr) + public static Lite ToLiteFat(this T entity, string? toStr) where T : class, IEntity { return (Lite)giNewLiteFat.GetInvoker(entity.GetType())((Entity)(IEntity)entity, toStr ?? entity.ToString()); diff --git a/Signum.Entities/MList.cs b/Signum.Entities/MList.cs index db3590bf3b..69de1a90fe 100644 --- a/Signum.Entities/MList.cs +++ b/Signum.Entities/MList.cs @@ -86,7 +86,9 @@ public override string ToString() return "({0}) {1}".FormatWith(pre, Element); } +#pragma warning disable IDE0051 // Remove unused private members private RowIdElement(SerializationInfo info, StreamingContext ctxt) +#pragma warning restore IDE0051 // Remove unused private members { this.RowId = null; this.Element = default(T)!; @@ -121,7 +123,7 @@ void ISerializable.GetObjectData(SerializationInfo info, StreamingContext contex [NonSerialized] NotifyCollectionChangedEventHandler? collectionChanged; - event NotifyCollectionChangedEventHandler INotifyCollectionChanged.CollectionChanged + public event NotifyCollectionChangedEventHandler CollectionChanged { add { collectionChanged += value; } remove { collectionChanged -= value; } @@ -639,7 +641,7 @@ List IMListPrivate.InnerList get { return this.innerList; } } - void IMListPrivate.InnerListModified(IList newItems, IList oldItems) + void IMListPrivate.InnerListModified(IList? newItems, IList? oldItems) { this.SetSelfModified(); @@ -807,7 +809,7 @@ public interface IMListPrivate void SetRowId(int index, PrimaryKey rowId); void ForceRowId(int index, PrimaryKey rowId); - void InnerListModified(IList newItems, IList oldItems); + void InnerListModified(IList? newItems, IList? oldItems); void AssignAndPostRetrieving(IMListPrivate newList); } @@ -822,7 +824,7 @@ public interface IMListPrivate : IMListPrivate internal sealed class MListDebugging { - private ICollection collection; + private readonly ICollection collection; public MListDebugging(ICollection collection) { diff --git a/Signum.Entities/MixinEntity.cs b/Signum.Entities/MixinEntity.cs index ff9a304f89..cdaaacd15a 100644 --- a/Signum.Entities/MixinEntity.cs +++ b/Signum.Entities/MixinEntity.cs @@ -167,7 +167,7 @@ static class MixinSetterCache where T : MixinEntity internal static Action Setter(PropertyInfo pi) { - return (Action)cache.GetOrAdd(pi.Name, s => ReflectionTools.CreateSetter(Reflector.FindFieldInfo(typeof(T), pi))); + return (Action)cache.GetOrAdd(pi.Name, s => ReflectionTools.CreateSetter(Reflector.FindFieldInfo(typeof(T), pi))!); } } @@ -181,7 +181,7 @@ on nm.GetType() equals om.GetType() foreach (var pair in list) { - pair.nm.CopyFrom(pair.om, args); + pair.nm!.CopyFrom(pair.om!, args); /*CSBUG*/ } return newEntity; diff --git a/Signum.Entities/ModifiableEntity.cs b/Signum.Entities/ModifiableEntity.cs index a8eb69c778..d56bd7b135 100644 --- a/Signum.Entities/ModifiableEntity.cs +++ b/Signum.Entities/ModifiableEntity.cs @@ -114,7 +114,7 @@ public PropertyKey(Type type, string propertyName) public override int GetHashCode() => Type.GetHashCode() ^ PropertyName.GetHashCode(); } - static ConcurrentDictionary PropertyCache = new ConcurrentDictionary(); + static readonly ConcurrentDictionary PropertyCache = new ConcurrentDictionary(); protected PropertyInfo GetPropertyInfo(string propertyName) { @@ -143,7 +143,7 @@ protected internal override void PostRetrieving() protected virtual void RebindEvents() { - foreach (INotifyCollectionChanged notify in AttributeManager.FieldsWithAttribute(this)) + foreach (INotifyCollectionChanged? notify in AttributeManager.FieldsWithAttribute(this)) { if (notify == null) continue; @@ -432,7 +432,7 @@ public IntegrityCheck(ModifiableEntity me, Dictionary errors) public override string ToString() { - return $"{Errors.Count} errors in {" ".CombineIfNotEmpty(Type.Name, Id)}\r\n" + return $"{Errors.Count} errors in {" ".Combine(Type.Name, Id)}\r\n" + Errors.ToString(kvp => " {0}: {1}".FormatWith(kvp.Key, kvp.Value), "\r\n"); } } @@ -451,7 +451,7 @@ public IntegrityCheckWithEntity(IntegrityCheck integrityCheck, ModifiableEntity public override string ToString() { var validators = Validator.GetPropertyValidators(Entity.GetType()); - return $"{IntegrityCheck.Errors.Count} errors in {" ".CombineIfNotEmpty(IntegrityCheck.Type.Name, IntegrityCheck.Id)}\r\n" + return $"{IntegrityCheck.Errors.Count} errors in {" ".Combine(IntegrityCheck.Type.Name, IntegrityCheck.Id)}\r\n" + IntegrityCheck.Errors.ToString(kvp => " {0} ({1}): {2}".FormatWith( kvp.Key, validators.GetOrThrow(kvp.Key).GetValueUntyped(Entity), diff --git a/Signum.Entities/Patterns/CorruptEntity.cs b/Signum.Entities/Patterns/CorruptEntity.cs index 2fba0adc08..02f3e819d5 100644 --- a/Signum.Entities/Patterns/CorruptEntity.cs +++ b/Signum.Entities/Patterns/CorruptEntity.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Signum.Utilities; @@ -36,16 +36,18 @@ public static class Corruption public static bool Strict { get { return !allowed.Value; } } - public static IDisposable AllowScope() + public static IDisposable? AllowScope() { - if (allowed.Value) return null; + if (allowed.Value) + return null; allowed.Value = true; return new Disposable(() => allowed.Value = false); } - public static IDisposable DenyScope() + public static IDisposable? DenyScope() { - if (!allowed.Value) return null; + if (!allowed.Value) + return null; allowed.Value = false; return new Disposable(() => allowed.Value = true); } diff --git a/Signum.Entities/Patterns/LockeableEntity.cs b/Signum.Entities/Patterns/LockeableEntity.cs index f14d833a61..d85daef7ef 100644 --- a/Signum.Entities/Patterns/LockeableEntity.cs +++ b/Signum.Entities/Patterns/LockeableEntity.cs @@ -43,7 +43,7 @@ protected override bool Set(ref T field, T value, [CallerMemberNameAttribute] protected override void ChildCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs args) { if (this.locked) - throw new ApplicationException(EntityMessage.AttemptToAddRemove0InLockedEntity1.NiceToString(sender.GetType().ElementType().NicePluralName(), this.ToString())); + throw new ApplicationException(EntityMessage.AttemptToAddRemove0InLockedEntity1.NiceToString(sender.GetType().ElementType()!.NicePluralName(), this.ToString())); base.ChildCollectionChanged(sender, args); } diff --git a/Signum.Entities/PropertyAttributes.cs b/Signum.Entities/PropertyAttributes.cs index 6c649a52f8..36ca411d7b 100644 --- a/Signum.Entities/PropertyAttributes.cs +++ b/Signum.Entities/PropertyAttributes.cs @@ -29,7 +29,7 @@ public class UnitAttribute : Attribute { public static Dictionary> UnitTranslations = new Dictionary>(); - public static string GetTranslation(string unitName) + public static string? GetTranslation(string unitName) { if (string.IsNullOrEmpty(unitName)) return null; diff --git a/Signum.Entities/PropertyRoute.cs b/Signum.Entities/PropertyRoute.cs index 67aedee18b..701e63c050 100644 --- a/Signum.Entities/PropertyRoute.cs +++ b/Signum.Entities/PropertyRoute.cs @@ -382,7 +382,7 @@ public static void SetIsAllowedCallback(Func isAllowed) return null; } - static PropertyInfo piId = ReflectionTools.GetPropertyInfo((Entity a) => a.Id); + static readonly PropertyInfo piId = ReflectionTools.GetPropertyInfo((Entity a) => a.Id); public static List GenerateRoutes(Type type, bool includeIgnored = true) @@ -403,7 +403,7 @@ public static List GenerateRoutes(Type type, bool includeIgnored if (Reflector.IsMList(pi.PropertyType)) { - Type colType = pi.PropertyType.ElementType(); + Type colType = pi.PropertyType.ElementType()!; if (Reflector.IsEmbeddedEntity(colType)) result.AddRange(GenerateEmbeddedProperties(route.Add("Item"), includeIgnored)); } @@ -432,7 +432,7 @@ static List GenerateEmbeddedProperties(PropertyRoute embeddedProp if (Reflector.IsMList(pi.PropertyType)) { - Type colType = pi.PropertyType.ElementType(); + Type colType = pi.PropertyType.ElementType()!; if (Reflector.IsEmbeddedEntity(colType)) result.AddRange(GenerateEmbeddedProperties(route.Add("Item"), includeIgnored)); } @@ -508,7 +508,9 @@ public PropertyRoute SimplifyToPropertyOrRoot() } } - private PropertyRoute(SerializationInfo info, StreamingContext ctxt) +#pragma warning disable IDE0051 // Remove unused private members + PropertyRoute(SerializationInfo info, StreamingContext ctxt) +#pragma warning restore IDE0051 // Remove unused private members { string rootName = info.GetString("rootType"); diff --git a/Signum.Entities/Reflection/GraphExplorer.cs b/Signum.Entities/Reflection/GraphExplorer.cs index bca73c788f..032867f0db 100644 --- a/Signum.Entities/Reflection/GraphExplorer.cs +++ b/Signum.Entities/Reflection/GraphExplorer.cs @@ -110,7 +110,7 @@ public static DirectedGraph FromRootsEntity(IEnumerable roots) DirectedGraph identGraph = DirectedGraph.Generate(graph.Where(a => a is Entity), graph.RelatedTo); - var identErrors = identGraph.OfType().Select(ident => ident.EntityIntegrityCheck()).Where(errors => errors != null).SelectMany(errors => errors.Values); + var identErrors = identGraph.OfType().Select(ident => ident.EntityIntegrityCheck()).NotNull().SelectMany(errors => errors.Values); var modErros = graph.Except(identGraph).OfType() .Select(a => a.IntegrityCheck()) @@ -324,7 +324,7 @@ private static XAttribute[] GetAttributes(IList list) new XAttribute("Label", (list.ToString() ?? "[null]") + Modified((Modifiable)list)), new XAttribute("TypeName", list.GetType().TypeName()), new XAttribute("NodeRadius", 2), - new XAttribute("Background", ColorExtensions.ToHtmlColor(list.GetType().ElementType().FullName.GetHashCode())), + new XAttribute("Background", ColorExtensions.ToHtmlColor(list.GetType().ElementType()!.FullName.GetHashCode())), }; } diff --git a/Signum.Entities/Reflection/ModifyInspector.cs b/Signum.Entities/Reflection/ModifyInspector.cs index 301009fe5e..cc80c8c010 100644 --- a/Signum.Entities/Reflection/ModifyInspector.cs +++ b/Signum.Entities/Reflection/ModifyInspector.cs @@ -10,29 +10,27 @@ namespace Signum.Entities.Reflection { public class ModifyInspector { - static Dictionary[]> getterCache = new Dictionary[]>(); - - static Func[] ModifiableFieldGetters(Type type) + static readonly Dictionary[]> getterCache = new Dictionary[]>(); + static Func[] ModifiableFieldGetters(Type type) { lock (getterCache) return getterCache.GetOrCreate(type, () => { FieldInfo[] aux = Reflector.InstanceFieldsInOrder(type); return aux.Where(fi => Reflector.IsModifiableIdentifiableOrLite(fi.FieldType) && !IsIgnored(fi)) - .Select(fi => ReflectionTools.CreateGetterUntyped(type, fi)).ToArray(); + .Select(fi => ReflectionTools.CreateGetterUntyped(type, fi)!).ToArray(); }); } - static Dictionary[]> getterVirtualCache = new Dictionary[]>(); - - static Func[] ModifiableFieldGettersVirtual(Type type) + static readonly Dictionary[]> getterVirtualCache = new Dictionary[]>(); + static Func[] ModifiableFieldGettersVirtual(Type type) { lock (getterVirtualCache) return getterVirtualCache.GetOrCreate(type, () => { FieldInfo[] aux = Reflector.InstanceFieldsInOrder(type); return aux.Where(fi => Reflector.IsModifiableIdentifiableOrLite(fi.FieldType) && (!IsIgnored(fi) || IsQueryableProperty(fi))) - .Select(fi => ReflectionTools.CreateGetterUntyped(type, fi)).ToArray(); + .Select(fi => ReflectionTools.CreateGetterUntyped(type, fi)!).ToArray(); }); } @@ -55,7 +53,7 @@ public static IEnumerable FullExplore(Modifiable obj) if (Reflector.IsMList(obj.GetType())) { - Type t = obj.GetType().ElementType(); + Type t = obj.GetType().ElementType()!; if (Reflector.IsModifiableIdentifiableOrLite(t)) { IEnumerable col = (IEnumerable)obj; @@ -93,7 +91,7 @@ public static IEnumerable FullExploreVirtual(Modifiable obj) if (Reflector.IsMList(obj.GetType())) { - Type t = obj.GetType().ElementType(); + Type t = obj.GetType().ElementType()!; if (Reflector.IsModifiableIdentifiableOrLite(t)) { IEnumerable col = (IEnumerable)obj; @@ -131,7 +129,7 @@ public static IEnumerable EntityExplore(Modifiable obj) if (Reflector.IsMList(obj.GetType())) { - Type t = obj.GetType().ElementType(); + Type t = obj.GetType().ElementType()!; if (t.IsModifiable() && !t.IsEntity()) { diff --git a/Signum.Entities/Services/Security.cs b/Signum.Entities/Services/Security.cs index 80b81944a0..31d0f27328 100644 --- a/Signum.Entities/Services/Security.cs +++ b/Signum.Entities/Services/Security.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text; using System.Security.Cryptography; @@ -19,9 +19,8 @@ public static string GetSHA1(string str) { SHA1 sha1 = SHA1Managed.Create(); ASCIIEncoding encoding = new ASCIIEncoding(); - byte[] stream = null; StringBuilder sb = new StringBuilder(); - stream = sha1.ComputeHash(encoding.GetBytes(str)); + byte[] stream = sha1.ComputeHash(encoding.GetBytes(str)); for (int i = 0; i < stream.Length; i++) sb.AppendFormat("{0:x2}", stream[i]); return sb.ToString(); @@ -103,4 +102,4 @@ public static string CalculateMD5Hash(byte[] inputBytes) } } -} \ No newline at end of file +} diff --git a/Signum.Entities/SystemTime.cs b/Signum.Entities/SystemTime.cs index ef33aaa475..6d6fc991b2 100644 --- a/Signum.Entities/SystemTime.cs +++ b/Signum.Entities/SystemTime.cs @@ -133,7 +133,7 @@ public static Interval SystemPeriod(this MListElement mlis static ConstructorInfo ciInterval = ReflectionTools.GetConstuctorInfo(() => new Interval(new DateTime(), new DateTime())); - internal static Expression Intesection(this NewExpression? interval1, NewExpression? interval2) + internal static Expression? Intesection(this NewExpression? interval1, NewExpression? interval2) { if (interval1 == null) return interval2; diff --git a/Signum.React/Scripts/Signum.Entities.Basics.ts b/Signum.React/Scripts/Signum.Entities.Basics.ts index ed27536bb5..98310ed3fa 100644 --- a/Signum.React/Scripts/Signum.Entities.Basics.ts +++ b/Signum.React/Scripts/Signum.Entities.Basics.ts @@ -67,8 +67,8 @@ export interface OperationLogEntity extends Entities.Entity { Type: "OperationLog"; target: Entities.Lite | null; origin: Entities.Lite | null; - operation: Entities.OperationSymbol; - user: Entities.Lite; + operation: Entities.OperationSymbol | null; + user: Entities.Lite | null; start: string; end: string | null; exception: Entities.Lite | null; @@ -77,14 +77,14 @@ export interface OperationLogEntity extends Entities.Entity { export const PropertyRouteEntity = new Type("PropertyRoute"); export interface PropertyRouteEntity extends Entities.Entity { Type: "PropertyRoute"; - path: string; + path: string | null; rootType: TypeEntity; } export const QueryEntity = new Type("Query"); export interface QueryEntity extends Entities.Entity { Type: "Query"; - key: string; + key: string | null; } export interface SemiSymbol extends Entities.Entity { @@ -95,10 +95,10 @@ export interface SemiSymbol extends Entities.Entity { export const TypeEntity = new Type("Type"); export interface TypeEntity extends Entities.Entity { Type: "Type"; - tableName: string; - cleanName: string; - namespace: string; - className: string; + tableName: string | null; + cleanName: string | null; + namespace: string | null; + className: string | null; } diff --git a/Signum.React/Scripts/Signum.Entities.ts b/Signum.React/Scripts/Signum.Entities.ts index 7e12265029..5cd7dbee18 100644 --- a/Signum.React/Scripts/Signum.Entities.ts +++ b/Signum.React/Scripts/Signum.Entities.ts @@ -471,7 +471,7 @@ export module SelectorMessage { } export interface Symbol extends Entity { - key: string; + key: string | null; } export module SynchronizerMessage { @@ -549,6 +549,7 @@ export module ValidationMessage { export const _0Have1ElementsButAllowedOnly2 = new MessageKey("ValidationMessage", "_0Have1ElementsButAllowedOnly2"); export const _0IsEmpty = new MessageKey("ValidationMessage", "_0IsEmpty"); export const _AtLeastOneValueIsNeeded = new MessageKey("ValidationMessage", "_AtLeastOneValueIsNeeded"); + export const BeAString = new MessageKey("ValidationMessage", "BeAString"); } export module VoidEnumMessage { diff --git a/Signum.Utilities/DataStructures/DirectedEdgedGraph.cs b/Signum.Utilities/DataStructures/DirectedEdgedGraph.cs index 2502f1956b..f28ebccc7d 100644 --- a/Signum.Utilities/DataStructures/DirectedEdgedGraph.cs +++ b/Signum.Utilities/DataStructures/DirectedEdgedGraph.cs @@ -7,6 +7,7 @@ namespace Signum.Utilities.DataStructures { public class DirectedEdgedGraph : IEnumerable + where T: object { Dictionary> adjacency; public IEqualityComparer Comparer { get; private set; } @@ -149,7 +150,7 @@ public static void RemoveFullNodeSymetric(DirectedEdgedGraph original, Dir inverse.RemoveFullNode(node, to); } - Dictionary TryGet(T node) + Dictionary? TryGet(T node) { return adjacency.TryGetC(node); } @@ -360,15 +361,15 @@ public override string ToString() public string ToGraphviz() { - return ToGraphviz(typeof(E).Name, a => a.ToString(), e => e.ToString()); + return ToGraphviz(typeof(E).Name, a => a.ToString(), e => e?.ToString()); } public string ToGraphviz(string name) { - return ToGraphviz(name, a => a.ToString(), e => e.ToString()); + return ToGraphviz(name, a => a.ToString(), e => e?.ToString()); } - public string ToGraphviz(string name, Func getNodeLabel, Func getEdgeLabel) + public string ToGraphviz(string name, Func getNodeLabel, Func getEdgeLabel) { int num = 0; Dictionary nodeDic = Nodes.ToDictionary(n => n, n => num++, Comparer); @@ -385,7 +386,7 @@ public XDocument ToDGML() return ToDGML( a => a.ToString() ?? "[null]", a => ColorExtensions.ToHtmlColor(a.GetType().FullName.GetHashCode()), - e => e.ToString() ?? "[null]"); + e => e?.ToString() ?? "[null]"); } public XDocument ToDGML(Func getNodeLabel, Func getColor, Func? getEdgeLabel = null) @@ -545,7 +546,7 @@ public DirectedEdgedGraph WhereEdges(Func, bool> condition, boo } } - public List ShortestPath(T from, T to, Func getWeight) + public List? ShortestPath(T from, T to, Func getWeight) { //http://en.wikipedia.org/wiki/Dijkstra's_algorithm diff --git a/Signum.Utilities/DataStructures/DirectedGraph.cs b/Signum.Utilities/DataStructures/DirectedGraph.cs index bc811f22c6..25b2bea5a5 100644 --- a/Signum.Utilities/DataStructures/DirectedGraph.cs +++ b/Signum.Utilities/DataStructures/DirectedGraph.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Collections; @@ -7,8 +7,9 @@ namespace Signum.Utilities.DataStructures { public class DirectedGraph : IEnumerable + where T : object { - Dictionary> adjacency; + readonly Dictionary> adjacency; public IEqualityComparer Comparer { get; private set; } public DirectedGraph() @@ -142,7 +143,7 @@ public static void RemoveFullNodeSymetric(DirectedGraph original, DirectedGra inverse.RemoveFullNode(node, to); } - HashSet TryGet(T node) + HashSet? TryGet(T node) { return adjacency.TryGetC(node); } @@ -464,7 +465,7 @@ public DirectedGraph FeedbackEdgeSet() continue; } - Func fanInOut = n => clone.RelatedTo(n).Count() - inv.RelatedTo(n).Count(); + int fanInOut(T n) => clone.RelatedTo(n).Count() - inv.RelatedTo(n).Count(); MinMax mm = clone.WithMinMaxPair(fanInOut); @@ -502,7 +503,7 @@ public DirectedGraph WhereEdges(Func, bool> condition) return result; } - public List ShortestPath(T from, T to) + public List? ShortestPath(T from, T to) { //http://en.wikipedia.org/wiki/Dijkstra's_algorithm diff --git a/Signum.Utilities/DataStructures/IntervalDictionaries/CubeDictionary.cs b/Signum.Utilities/DataStructures/IntervalDictionaries/CubeDictionary.cs index 96864f7f9b..77a3105a11 100644 --- a/Signum.Utilities/DataStructures/IntervalDictionaries/CubeDictionary.cs +++ b/Signum.Utilities/DataStructures/IntervalDictionaries/CubeDictionary.cs @@ -70,7 +70,7 @@ public bool TryGetValue(K1 x, K2 y, K3 z, out V value) !yDimension.TryGetValue(y, out int iy) || !zDimension.TryGetValue(z, out int iz) || !used[ix, iy, iz]) { - value = default(V); + value = default(V)!; return false; } diff --git a/Signum.Utilities/DataStructures/IntervalDictionaries/Interval.cs b/Signum.Utilities/DataStructures/IntervalDictionaries/Interval.cs index e108dfa86a..a9c13554c5 100644 --- a/Signum.Utilities/DataStructures/IntervalDictionaries/Interval.cs +++ b/Signum.Utilities/DataStructures/IntervalDictionaries/Interval.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.Linq.Expressions; @@ -308,7 +308,7 @@ public override int GetHashCode() return min.GetHashCode(); } - public string ToString(string format, IFormatProvider formatProvider) + public string ToString(string? format, IFormatProvider formatProvider) { if (string.IsNullOrEmpty(format)) return BuildString(formatProvider, "{0} - {1}", "< {0}", "{0} ≤", "All"); diff --git a/Signum.Utilities/DataStructures/IntervalDictionaries/IntervalDictionary.cs b/Signum.Utilities/DataStructures/IntervalDictionaries/IntervalDictionary.cs index efb122ff22..4b800f5daf 100644 --- a/Signum.Utilities/DataStructures/IntervalDictionaries/IntervalDictionary.cs +++ b/Signum.Utilities/DataStructures/IntervalDictionaries/IntervalDictionary.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Collections; using System.Linq; @@ -153,7 +153,7 @@ public V TryGet(K key, V defaultValue) public bool TryGetValue(K key, out V value) { - value = default(V); + value = default(V)!; int index = PossibleIndex(key); if (index == -1) @@ -287,7 +287,7 @@ public static class IntervalDictionaryExtensions public static IntervalDictionary Mix(this IntervalDictionary me, IntervalDictionary other, Func, IntervalValue, IntervalValue, IntervalValue> mixer) where K : struct, IComparable, IEquatable { - Interval[] keys = me.Intervals.Concat(other.Intervals).SelectMany(a => a.Elements()).Distinct().OrderBy().BiSelect((min, max) => new Interval(min, max)).ToArray(); + Interval[] keys = me.Intervals.Concat(other.Intervals).SelectMany(a => a.Elements()).Distinct().OrderBy().BiSelectS((min, max) => new Interval(min.Value, max.Value)).ToArray(); return new IntervalDictionary(keys .Select(k => new { Intervalo = k, Valor = mixer(k, me.TryGetValue(k.Min), other.TryGetValue(k.Min)) }) .Where(a => a.Valor.HasInterval).Select(a => KVP.Create(a.Intervalo, a.Valor.Value))); @@ -296,14 +296,14 @@ public static IntervalDictionary Mix(this IntervalDictiona public static IntervalDictionary Collapse(this IEnumerable> collection, Func, IEnumerable, VR> mixer) where K : struct, IComparable, IEquatable { - Interval[] keys = collection.SelectMany(a => a).SelectMany(a => a.Key.Elements()).Distinct().OrderBy().BiSelect((min, max) => new Interval(min, max)).ToArray(); + Interval[] keys = collection.SelectMany(a => a).SelectMany(a => a.Key.Elements()).Distinct().OrderBy().BiSelectS((min, max) => new Interval(min.Value, max.Value)).ToArray(); return new IntervalDictionary(keys.Select(k => KVP.Create(k, mixer(k, collection.Select(intDic => intDic.TryGetValue(k.Min)).Where(vi => vi.HasInterval).Select(vi => vi.Value))))); } public static IntervalDictionary AggregateIntervalDictionary(this IEnumerable<(Interval interval, V value)> collection, Func, IEnumerable, VR> mixer) where K : struct, IComparable, IEquatable { - Interval[] keys = collection.SelectMany(a => a.interval.Elements()).Distinct().OrderBy().BiSelect((min, max) => new Interval(min, max)).ToArray(); + Interval[] keys = collection.SelectMany(a => a.interval.Elements()).Distinct().OrderBy().BiSelectS((min, max) => new Interval(min.Value, max.Value)).ToArray(); return new IntervalDictionary(keys.Select(k => KVP.Create(k, mixer(k, collection.Where(a => a.interval.Subset(k)).Select(a => a.value))))); } diff --git a/Signum.Utilities/DataStructures/IntervalDictionaries/SquareDictionary.cs b/Signum.Utilities/DataStructures/IntervalDictionaries/SquareDictionary.cs index 5d14a0317f..077a2c5d01 100644 --- a/Signum.Utilities/DataStructures/IntervalDictionaries/SquareDictionary.cs +++ b/Signum.Utilities/DataStructures/IntervalDictionaries/SquareDictionary.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; @@ -62,7 +62,7 @@ public bool TryGetValue(K1 x, K2 y, out V value) if (!xDimension.TryGetValue(x, out int ix) || !yDimension.TryGetValue(y, out int iy) || !used[ix,iy]) { - value = default(V); + value = default(V)!; return false; } diff --git a/Signum.Utilities/DataStructures/RecentsDictionary.cs b/Signum.Utilities/DataStructures/RecentsDictionary.cs index cce52ae359..8fe5d0c11c 100644 --- a/Signum.Utilities/DataStructures/RecentsDictionary.cs +++ b/Signum.Utilities/DataStructures/RecentsDictionary.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Text; using System.Collections; @@ -28,7 +28,7 @@ public RecentDictionary(int capacity): this(capacity, null) { } - public RecentDictionary(int capacity, IEqualityComparer comparer) + public RecentDictionary(int capacity, IEqualityComparer? comparer) { this.capacity = capacity; keyToLink = new Dictionary>(comparer); @@ -83,7 +83,7 @@ public bool Contains(K key) public bool Remove(K key) { - LinkedListNode link = keyToLink.TryGetC(key); + LinkedListNode? link = keyToLink.TryGetC(key); if (link == null) return false; @@ -137,7 +137,7 @@ public bool TryGetValue(K key, out V value) return true; } - value = default(V); + value = default(V)!; return false; } @@ -181,7 +181,7 @@ public override string ToString() if (buff.Length > 1) buff.Append(", "); - buff.Append(item.ToString()); + buff.Append(item?.ToString()); } buff.Append("]"); diff --git a/Signum.Utilities/DescriptionManager.cs b/Signum.Utilities/DescriptionManager.cs index 18db70bc06..d77b6310e1 100644 --- a/Signum.Utilities/DescriptionManager.cs +++ b/Signum.Utilities/DescriptionManager.cs @@ -123,7 +123,7 @@ public static class DescriptionManager public static event Func DefaultDescriptionOptions = t => t.IsEnum && t.Name.EndsWith("Message") ? DescriptionOptions.Members : (DescriptionOptions?)null; public static event Func ShouldLocalizeMemeber = m => true; - public static event Action NotLocalizedMemeber ; + public static event Action NotLocalizedMember; public static Dictionary> ExternalEnums = new Dictionary> { @@ -131,14 +131,14 @@ public static class DescriptionManager }; - static string Fallback(Type type, Func typeValue, Action notLocalized) + static string Fallback(Type type, Func typeValue, Action notLocalized) { var cc = CultureInfo.CurrentUICulture; { var loc = GetLocalizedType(type, cc); if (loc != null) { - string result = typeValue(loc); + string? result = typeValue(loc); if (result != null) return result; } @@ -149,17 +149,13 @@ static string Fallback(Type type, Func typeValue, Action< var loc = GetLocalizedType(type, cc.Parent); if (loc != null) { - string result = typeValue(loc); + string? result = typeValue(loc); if (result != null) return result; } - } - - var defaultCulture = LocalizedAssembly.GetDefaultAssemblyCulture(type.Assembly); - //if (defaultCulture != null) { var loc = GetLocalizedType(type, CultureInfo.GetCultureInfo(defaultCulture)); if (loc == null) @@ -168,10 +164,8 @@ static string Fallback(Type type, Func typeValue, Action< if (notLocalized != null) notLocalized.Invoke(loc); - return typeValue(loc); + return typeValue(loc)!; } - - //return null; } @@ -184,7 +178,7 @@ public static string NiceName(this Type type) return type.GetCustomAttribute()?.Description ?? type.Name.NiceName(); } - var result = Fallback(type, lt => lt.Description, lt => OnNotLocalizedMemeber(type, null)); + var result = Fallback(type, lt => lt.Description, lt => OnNotLocalizedMember(type)); if (result != null) return result; @@ -197,7 +191,7 @@ public static string NicePluralName(this Type type) { type = CleanType(type); - var result = Fallback(type, lt => lt.PluralDescription, lt => OnNotLocalizedMemeber(type,null)); + var result = Fallback(type, lt => lt.PluralDescription, lt => OnNotLocalizedMember(type)); if (result != null) return result; @@ -213,9 +207,6 @@ public static string NiceToString(this Enum a, params object[] args) public static string NiceToString(this Enum a) { - if (a == null) - return null; - var fi = EnumFieldCache.Get(a.GetType()).TryGetC(a); if (fi != null) return GetMemberNiceName(fi) ?? DefaultMemberDescription(fi); @@ -263,23 +254,17 @@ static string GetMemberNiceName(MemberInfo memberInfo) return memberInfo.GetCustomAttribute()?.Description ?? memberInfo.Name.NiceName(); } - - var result = Fallback(type, lt => lt.Members.TryGetC(memberInfo.Name), lt => OnNotLocalizedMemeber(null,memberInfo)); + + var result = Fallback(type, lt => lt.Members!.TryGetC(memberInfo.Name), lt => OnNotLocalizedMember(memberInfo)); if (result != null) return result; - - return result; } - private static void OnNotLocalizedMemeber(Type type, MemberInfo memberInfo) + private static void OnNotLocalizedMember(MemberInfo memberInfo) { - if (NotLocalizedMemeber != null) - { - var cc = CultureInfo.CurrentUICulture; - NotLocalizedMemeber.Invoke(cc, type, memberInfo); - } + NotLocalizedMember?.Invoke(CultureInfo.CurrentUICulture, memberInfo); } public static char? GetGender(this Type type) @@ -307,10 +292,10 @@ private static void OnNotLocalizedMemeber(Type type, MemberInfo memberInfo) return null; } - static ConcurrentDictionary> localizations = - new ConcurrentDictionary>(); + static ConcurrentDictionary> localizations = + new ConcurrentDictionary>(); - public static LocalizedType GetLocalizedType(Type type, CultureInfo cultureInfo) + public static LocalizedType? GetLocalizedType(Type type, CultureInfo cultureInfo) { var la = GetLocalizedAssembly(type.Assembly, cultureInfo); @@ -328,11 +313,11 @@ public static LocalizedType GetLocalizedType(Type type, CultureInfo cultureInfo) return null; } - public static LocalizedAssembly GetLocalizedAssembly(Assembly assembly, CultureInfo cultureInfo) + public static LocalizedAssembly? GetLocalizedAssembly(Assembly assembly, CultureInfo cultureInfo) { return localizations - .GetOrAdd(cultureInfo, ci => new ConcurrentDictionary()) - .GetOrAdd(assembly, (Assembly a) => LocalizedAssembly.ImportXml(assembly, cultureInfo, forceCreate : false)); + .GetOrAdd(cultureInfo, ci => new ConcurrentDictionary()) + .GetOrAdd(assembly, (Assembly a) => LocalizedAssembly.ImportXml(assembly, cultureInfo, forceCreate: false)); } internal static DescriptionOptions? OnDefaultDescriptionOptions(Type type) @@ -458,7 +443,7 @@ select lt.ExportXml() return doc; } - public static LocalizedAssembly ImportXml(Assembly assembly, CultureInfo cultureInfo, bool forceCreate) + public static LocalizedAssembly? ImportXml(Assembly assembly, CultureInfo cultureInfo, bool forceCreate) { var defaultCulture = GetDefaultAssemblyCulture(assembly); @@ -469,7 +454,7 @@ public static LocalizedAssembly ImportXml(Assembly assembly, CultureInfo culture string fileName = TranslationFileName(assembly, cultureInfo); - XDocument doc = !File.Exists(fileName) ? null : XDocument.Load(fileName); + XDocument? doc = !File.Exists(fileName) ? null : XDocument.Load(fileName); if (!isDefault && !forceCreate && doc == null) return null; @@ -477,9 +462,9 @@ public static LocalizedAssembly ImportXml(Assembly assembly, CultureInfo culture return FromXml(assembly, cultureInfo, doc, null); } - public static LocalizedAssembly FromXml(Assembly assembly, CultureInfo cultureInfo, XDocument doc, Dictionary replacements /*new -> old*/) + public static LocalizedAssembly FromXml(Assembly assembly, CultureInfo cultureInfo, XDocument? doc, Dictionary? replacements /*new -> old*/) { - Dictionary file = doc?.Element("Translations").Elements("Type") + Dictionary? file = doc?.Element("Translations").Elements("Type") .Select(x => KVP.Create(x.Attribute("Name").Value, x)) .Distinct(x => x.Key) .ToDictionary(); @@ -513,11 +498,11 @@ public class LocalizedType public LocalizedAssembly Assembly { get; private set; } public DescriptionOptions Options { get; private set; } - public string Description { get; set; } - public string PluralDescription { get; set; } + public string? Description { get; set; } + public string? PluralDescription { get; set; } public char? Gender { get; set; } - public Dictionary Members = new Dictionary(); + public Dictionary? Members { get; set; } LocalizedType() { } @@ -533,19 +518,19 @@ public XElement ExportXml() !Options.IsSetAssert(DescriptionOptions.PluralDescription, Type) || PluralDescription == null || - (PluralDescription == NaturalLanguageTools.Pluralize(Description, Assembly.Culture)) ? null : + (PluralDescription == NaturalLanguageTools.Pluralize(Description!, Assembly.Culture)) ? null : new XAttribute("PluralDescription", PluralDescription), !Options.IsSetAssert(DescriptionOptions.Gender, Type) || Gender == null || - (Gender == NaturalLanguageTools.GetGender(Description, Assembly.Culture)) ? null : + (Gender == NaturalLanguageTools.GetGender(Description!, Assembly.Culture)) ? null : new XAttribute("Gender", Gender.ToString()), !Options.IsSetAssert(DescriptionOptions.Members, Type) ? null : (from m in GetMembers(Type) where DescriptionManager.OnShouldLocalizeMember(m) orderby m.Name - let value = Members.TryGetC(m.Name) + let value = Members!.TryGetC(m.Name) where value != null && !(Assembly.IsDefault && (DescriptionManager.DefaultMemberDescription(m) == value)) select new XElement("Member", new XAttribute("Name", m.Name), new XAttribute("Description", value))) ); @@ -566,7 +551,7 @@ public static IEnumerable GetMembers(Type type) internal static LocalizedType ImportXml(Type type, DescriptionOptions opts, LocalizedAssembly assembly, XElement x) { - string description = !opts.IsSetAssert(DescriptionOptions.Description, type) ? null : + string? description = !opts.IsSetAssert(DescriptionOptions.Description, type) ? null : (x == null || x.Attribute("Name").Value != type.Name ? null : x.Attribute("Description")?.Value) ?? (!assembly.IsDefault ? null : DescriptionManager.DefaultTypeDescription(type)); @@ -618,8 +603,8 @@ public bool Contains(string text) public bool ContainsDescription(string text) { return this.Type.Name.Contains(text, StringComparison.InvariantCultureIgnoreCase) || - this.Description != null && this.Description.Contains(text, StringComparison.InvariantCultureIgnoreCase) || - this.PluralDescription != null && this.Description.Contains(text, StringComparison.InvariantCultureIgnoreCase); + this.Description?.Contains(text, StringComparison.InvariantCultureIgnoreCase) == true || + this.PluralDescription?.Contains(text, StringComparison.InvariantCultureIgnoreCase) == true; } } diff --git a/Signum.Utilities/Disposable.cs b/Signum.Utilities/Disposable.cs index cddf772f89..9819eeed35 100644 --- a/Signum.Utilities/Disposable.cs +++ b/Signum.Utilities/Disposable.cs @@ -28,7 +28,7 @@ public void Dispose() var secondEx = second as IDisposableException; if (firstEx == null && secondEx == null) - return new Disposable(() => { try { first.Dispose(); } finally { second.Dispose(); } }); + return new Disposable(() => { try { first!.Dispose(); } finally { second!.Dispose(); } }); return new DisposableException( ex => @@ -36,15 +36,15 @@ public void Dispose() try { if (firstEx != null) firstEx.OnException(ex); } finally { if (secondEx != null) secondEx.OnException(ex); } }, - () => { try { first.Dispose(); } finally { second.Dispose(); } }); + () => { try { first!.Dispose(); } finally { second!.Dispose(); } }); } - public static IDisposable Combine(Del delegated, Func invoke) where Del : class, ICloneable, ISerializable + public static IDisposable? Combine(Del delegated, Func invoke) where Del : class, ICloneable, ISerializable { if (delegated == null) return null; - IDisposable result = null; + IDisposable? result = null; foreach (var func in delegated.GetInvocationListTyped()) { try diff --git a/Signum.Utilities/ExpressionExpanderSamples.cs b/Signum.Utilities/ExpressionExpanderSamples.cs index f778cf5f41..dcd0f7be03 100644 --- a/Signum.Utilities/ExpressionExpanderSamples.cs +++ b/Signum.Utilities/ExpressionExpanderSamples.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -89,11 +89,11 @@ public static bool None(this IEnumerable source, Func "".Contains("")); + static readonly MethodInfo miContains = ReflectionTools.GetMethodInfo(() => "".Contains("")); public Expression Expand(Expression instance, Expression[] parameters, MethodInfo mi) { - var parts = (string[])ExpressionEvaluator.Eval(parameters[1]); + var parts = (string[])ExpressionEvaluator.Eval(parameters[1])!; return parts.Select(p => (Expression)Expression.Call(parameters[0], miContains, Expression.Constant(p))).AggregateOr(); } @@ -101,11 +101,11 @@ public Expression Expand(Expression instance, Expression[] parameters, MethodInf class ExpandContainsAll : IMethodExpander { - static MethodInfo miContains = ReflectionTools.GetMethodInfo(() => "".Contains("")); + static readonly MethodInfo miContains = ReflectionTools.GetMethodInfo(() => "".Contains("")); public Expression Expand(Expression instance, Expression[] parameters, MethodInfo mi) { - var parts = (string[])ExpressionEvaluator.Eval(parameters[1]); + var parts = (string[])ExpressionEvaluator.Eval(parameters[1])!; return parts.Select(p => (Expression)Expression.Call(parameters[0], miContains, Expression.Constant(p))).AggregateAnd(); } @@ -114,30 +114,27 @@ public Expression Expand(Expression instance, Expression[] parameters, MethodInf class ExpandNone : IMethodExpander { - static MethodInfo miAnyEnumerable = ReflectionTools.GetMethodInfo(() => Enumerable.Any((IEnumerable)null)).GetGenericMethodDefinition(); - static MethodInfo miAnyQueryable = ReflectionTools.GetMethodInfo(() =>Queryable.Any((IQueryable)null)).GetGenericMethodDefinition(); - static MethodInfo miAnyEnumerableWithPredicate = ReflectionTools.GetMethodInfo(() =>Enumerable.Any((IEnumerable)null, null)).GetGenericMethodDefinition(); - static MethodInfo miAnyQueryableWithPredicate = ReflectionTools.GetMethodInfo(() => Queryable.Any((IQueryable)null, null)).GetGenericMethodDefinition(); + static readonly MethodInfo miAnyEnumerable = ReflectionTools.GetMethodInfo(() => Enumerable.Any((IEnumerable)null)).GetGenericMethodDefinition(); + static readonly MethodInfo miAnyQueryable = ReflectionTools.GetMethodInfo(() =>Queryable.Any((IQueryable)null)).GetGenericMethodDefinition(); + static readonly MethodInfo miAnyEnumerableWithPredicate = ReflectionTools.GetMethodInfo(() =>Enumerable.Any((IEnumerable)null, null)).GetGenericMethodDefinition(); + static readonly MethodInfo miAnyQueryableWithPredicate = ReflectionTools.GetMethodInfo(() => Queryable.Any((IQueryable)null, null)).GetGenericMethodDefinition(); public Expression Expand(Expression instance, Expression[] arguments, MethodInfo mi) { Type foo = mi.DeclaringType; Type bar = typeof(Queryable); - MethodInfo any = getAny(mi).MakeGenericMethod(mi.GetGenericArguments()); + MethodInfo any = GetAny(mi).MakeGenericMethod(mi.GetGenericArguments()); return Expression.Not(Expression.Call(any, arguments)); } - private MethodInfo getAny(MethodInfo mi) + private MethodInfo GetAny(MethodInfo mi) { - var parameters = mi.GetParameters(); bool query = parameters[0].ParameterType.IsInstantiationOf(typeof(IQueryable<>)); if (parameters.Length == 1) return query ? miAnyQueryable : miAnyEnumerable; else return query ? miAnyQueryableWithPredicate : miAnyEnumerableWithPredicate; - - } } diff --git a/Signum.Utilities/ExpressionTrees/CSharpRenderer.cs b/Signum.Utilities/ExpressionTrees/CSharpRenderer.cs index 2ff3a8c31c..02603e942e 100644 --- a/Signum.Utilities/ExpressionTrees/CSharpRenderer.cs +++ b/Signum.Utilities/ExpressionTrees/CSharpRenderer.cs @@ -102,7 +102,7 @@ static string TypeNameSimple(Type type, List globalGenericArguments) if (type.IsEnum) return type.Name; - string result = BasicTypeNames.TryGetC(Type.GetTypeCode(type)); + string? result = BasicTypeNames.TryGetC(Type.GetTypeCode(type)); if (result != null) return result; @@ -142,8 +142,9 @@ public static string Value(object obj) if (obj is string s) return ToSrtringLiteral(s); - - if (obj.GetType().IsEnum) + + obj = obj!/*CSBUG*/; + if (obj.GetType().IsEnum) return $"{obj.GetType().FullName}.{obj.ToString()}"; return obj.ToString(); diff --git a/Signum.Utilities/ExpressionTrees/ExpandableQueryProvider.cs b/Signum.Utilities/ExpressionTrees/ExpandableQueryProvider.cs index 63675c30b9..221f66c975 100644 --- a/Signum.Utilities/ExpressionTrees/ExpandableQueryProvider.cs +++ b/Signum.Utilities/ExpressionTrees/ExpandableQueryProvider.cs @@ -29,7 +29,7 @@ public object Execute(Expression expression) public IQueryable CreateQuery(Expression expression) { - Expression res = ExpressionCleaner.Clean(expression); + Expression res = ExpressionCleaner.Clean(expression)!; return new ExpandableQueryProvider(_item.Provider.CreateQuery(res)); } @@ -38,12 +38,12 @@ public S Execute(Expression expression) return _item.Provider.Execute(expression); } - IEnumerator IEnumerable.GetEnumerator() - { - return _item.GetEnumerator(); - } + public IEnumerator GetEnumerator() + { + return _item.GetEnumerator(); + } - public Type ElementType + public Type ElementType { get { return _item.ElementType; } } diff --git a/Signum.Utilities/ExpressionTrees/ExpressionCleaner.cs b/Signum.Utilities/ExpressionTrees/ExpressionCleaner.cs index d5c645c6fe..72346ef88e 100644 --- a/Signum.Utilities/ExpressionTrees/ExpressionCleaner.cs +++ b/Signum.Utilities/ExpressionTrees/ExpressionCleaner.cs @@ -25,7 +25,7 @@ public class ExpressionCleaner : ExpressionVisitor return Clean(expr, ExpressionEvaluator.PartialEval, true); } - public static Expression Clean(Expression expr, Func partialEval, bool shortCircuit) + public static Expression? Clean(Expression? expr, Func partialEval, bool shortCircuit) { ExpressionCleaner ee = new ExpressionCleaner() { @@ -59,7 +59,7 @@ protected override Expression VisitMethodCall(MethodCallExpression m) { if (m.Method.DeclaringType == typeof(ExpressionExtensions) && m.Method.Name == "Evaluate") { - LambdaExpression lambda = (LambdaExpression)(ExpressionEvaluator.Eval(m.Arguments[0])); + LambdaExpression lambda = (LambdaExpression)ExpressionEvaluator.Eval(m.Arguments[0])!; return Expression.Invoke(lambda, m.Arguments.Skip(1).ToArray()); } @@ -191,15 +191,13 @@ static bool IsStatic(MemberInfo mi) if (obj == null) throw new InvalidOperationException("Expression field '{0}' is null".FormatWith(efa.Name)); - var result = obj as LambdaExpression; - - if (result == null) + if (!(obj is LambdaExpression result)) throw new InvalidOperationException("Expression field '{0}' does not contain a lambda expression".FormatWith(efa.Name, type.TypeName())); return result; } - static BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; + static readonly BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; static MemberInfo? GetMember(Type decType, MemberInfo mi) { @@ -235,10 +233,9 @@ static bool IsStatic(MemberInfo mi) static MemberInfo? BaseMember(MemberInfo mi) { - MemberInfo result; + MemberInfo? result; if (mi is MethodInfo mti) result = mti.GetBaseDefinition(); - else if (mi is PropertyInfo pi) result = pi.GetBaseDefinition(); else diff --git a/Signum.Utilities/ExpressionTrees/ExpressionComparer.cs b/Signum.Utilities/ExpressionTrees/ExpressionComparer.cs index 88f261fd2a..c77f53b666 100644 --- a/Signum.Utilities/ExpressionTrees/ExpressionComparer.cs +++ b/Signum.Utilities/ExpressionTrees/ExpressionComparer.cs @@ -26,12 +26,12 @@ protected ExpressionComparer(ScopedDictionary? parameterScope = null, bool checkParameterNames = false) + public static bool AreEqual(Expression? a, Expression? b, ScopedDictionary? parameterScope = null, bool checkParameterNames = false) { return new ExpressionComparer(parameterScope, checkParameterNames).Compare(a, b); } - protected virtual bool Compare(Expression a, Expression b) + protected virtual bool Compare(Expression? a, Expression? b) { if (a == b) return true; @@ -264,7 +264,7 @@ protected virtual bool CompareListInit(ListInitExpression a, ListInitExpression && CompareList(a.Initializers, b.Initializers, CompareElementInit); } - protected static bool CompareList(ReadOnlyCollection a, ReadOnlyCollection b, Func comparer) + protected static bool CompareList(ReadOnlyCollection? a, ReadOnlyCollection? b, Func comparer) { if (a == b) return true; diff --git a/Signum.Utilities/ExpressionTrees/ExpressionEvaluator.cs b/Signum.Utilities/ExpressionTrees/ExpressionEvaluator.cs index 345731919a..85b2ea34ab 100644 --- a/Signum.Utilities/ExpressionTrees/ExpressionEvaluator.cs +++ b/Signum.Utilities/ExpressionTrees/ExpressionEvaluator.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Reflection; @@ -12,9 +12,12 @@ namespace Signum.Utilities.ExpressionTrees /// public class ExpressionEvaluator : ExpressionVisitor { - HashSet candidates; - - private ExpressionEvaluator() { } + readonly HashSet candidates; + + public ExpressionEvaluator(HashSet candidates) + { + this.candidates = candidates; + } /// /// Performs evaluation & replacement of independent sub-trees @@ -29,10 +32,10 @@ public static Expression PartialEval(Expression exp) HashSet candidates = ExpressionNominator.Nominate(exp); - return new ExpressionEvaluator { candidates = candidates }.Visit(exp); + return new ExpressionEvaluator(candidates).Visit(exp)!; } - public static object Eval(Expression expression) + public static object? Eval(Expression expression) { switch (expression.NodeType) { @@ -113,8 +116,8 @@ public static object Eval(Expression expression) public struct MethodKey : IEquatable { - MethodInfo mi; - Type[] arguments; + readonly MethodInfo mi; + readonly Type[]? arguments; public MethodKey(MethodInfo mi) { @@ -156,7 +159,8 @@ public override int GetHashCode() var result = mi.MetadataToken ^ mi.DeclaringType.GetHashCode(); if (!mi.IsGenericMethod) return result; - Type[] types = arguments; + + Type[] types = arguments!; for (int i = 0; i < types.Length; i++) result ^= i ^ types[i].GetHashCode(); @@ -164,61 +168,60 @@ public override int GetHashCode() } } - static ConcurrentDictionary> cachedStaticMethods = new ConcurrentDictionary>(); - private static Func GetStaticMethodCaller(MethodInfo mi) + static readonly ConcurrentDictionary> cachedStaticMethods = new ConcurrentDictionary>(); + private static Func GetStaticMethodCaller(MethodInfo mi) { return cachedStaticMethods.GetOrAdd(new MethodKey(mi), (MethodKey _) => { - return Expression.Lambda>(Expression.Convert(Expression.Call(mi), typeof(object))).Compile(); + return Expression.Lambda>(Expression.Convert(Expression.Call(mi), typeof(object))).Compile(); }); } - static ConcurrentDictionary> cachedExtensionMethods = new ConcurrentDictionary>(); - private static Func GetExtensionMethodCaller(MethodInfo mi) + static readonly ConcurrentDictionary> cachedExtensionMethods = new ConcurrentDictionary>(); + private static Func GetExtensionMethodCaller(MethodInfo mi) { return cachedExtensionMethods.GetOrAdd(new MethodKey(mi), (MethodKey _) => { ParameterExpression p = Expression.Parameter(typeof(object), "p"); - return Expression.Lambda>(Expression.Convert(Expression.Call(mi, Expression.Convert(p, mi.GetParameters()[0].ParameterType)), typeof(object)), p).Compile(); + return Expression.Lambda>(Expression.Convert(Expression.Call(mi, Expression.Convert(p, mi.GetParameters()[0].ParameterType)), typeof(object)), p).Compile(); }); } - static ConcurrentDictionary> cachedInstanceMethods = new ConcurrentDictionary>(); - private static Func GetInstanceMethodCaller(MethodInfo mi) + static readonly ConcurrentDictionary> cachedInstanceMethods = new ConcurrentDictionary>(); + private static Func GetInstanceMethodCaller(MethodInfo mi) { return cachedInstanceMethods.GetOrAdd(new MethodKey(mi), (MethodKey _) => { ParameterExpression p = Expression.Parameter(typeof(object), "p"); - return Expression.Lambda>(Expression.Convert(Expression.Call(Expression.Convert(p, mi.DeclaringType), mi), typeof(object)), p).Compile(); + return Expression.Lambda>(Expression.Convert(Expression.Call(Expression.Convert(p, mi.DeclaringType), mi), typeof(object)), p).Compile(); }); } - static ConcurrentDictionary<(Type type, string name), Func> cachedStaticGetters = new ConcurrentDictionary<(Type type, string name), Func>(); - private static Func GetStaticGetter(MemberInfo mi) + static readonly ConcurrentDictionary<(Type type, string name), Func> cachedStaticGetters = new ConcurrentDictionary<(Type type, string name), Func>(); + private static Func GetStaticGetter(MemberInfo mi) { return cachedStaticGetters.GetOrAdd((type: mi.DeclaringType, name: mi.Name), _ => { - return Expression.Lambda>(Expression.Convert(Expression.MakeMemberAccess(null, mi), typeof(object))).Compile(); + return Expression.Lambda>(Expression.Convert(Expression.MakeMemberAccess(null, mi), typeof(object?))).Compile(); }); } - static ConcurrentDictionary<(Type type, string name), Func> cachedInstanceGetters = new ConcurrentDictionary<(Type type, string name), Func>(); - private static Func GetInstanceGetter(MemberInfo mi) + static readonly ConcurrentDictionary<(Type type, string name), Func> cachedInstanceGetters = new ConcurrentDictionary<(Type type, string name), Func>(); + private static Func GetInstanceGetter(MemberInfo mi) { return cachedInstanceGetters.GetOrAdd((type: mi.DeclaringType, name: mi.Name), _ => { ParameterExpression p = Expression.Parameter(typeof(object), "p"); - return Expression.Lambda>(Expression.Convert(Expression.MakeMemberAccess(Expression.Convert(p, mi.DeclaringType), mi), typeof(object)), p).Compile(); + return Expression.Lambda>(Expression.Convert(Expression.MakeMemberAccess(Expression.Convert(p, mi.DeclaringType), mi), typeof(object)), p).Compile(); }); } - public override Expression Visit(Expression exp) + public override Expression? Visit(Expression? exp) { if (exp == null) - { return null; - } + if (this.candidates.Contains(exp)) { if (exp.NodeType == ExpressionType.Constant) @@ -236,4 +239,4 @@ public override Expression Visit(Expression exp) return base.Visit(exp); } } -} \ No newline at end of file +} diff --git a/Signum.Utilities/ExpressionTrees/ExpressionHelper.cs b/Signum.Utilities/ExpressionTrees/ExpressionHelper.cs index abb57f59e9..781b9fef5d 100644 --- a/Signum.Utilities/ExpressionTrees/ExpressionHelper.cs +++ b/Signum.Utilities/ExpressionTrees/ExpressionHelper.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Diagnostics; @@ -22,9 +22,8 @@ public static Expression TryConvert(this Expression expression, Type type) } [DebuggerStepThrough] - public static Expression TryRemoveConvert(this Expression expression, Func isAllowed) + public static Expression? TryRemoveConvert(this Expression expression, Func isAllowed) { - if (expression.NodeType == ExpressionType.Convert && isAllowed(expression.Type)) return ((UnaryExpression)expression).Operand; @@ -112,7 +111,7 @@ public static Expression GetArgument(this MethodCallExpression mce, string param } [DebuggerStepThrough] - public static Expression TryGetArgument(this MethodCallExpression mce, string parameterName) + public static Expression? TryGetArgument(this MethodCallExpression mce, string parameterName) { int index = FindParameter(mce.Method.GetParameters(), parameterName); @@ -135,9 +134,6 @@ private static int FindParameter(ParameterInfo[] parameters, string parameterNam [DebuggerStepThrough] public static LambdaExpression StripQuotes(this Expression e) { - if (e == null) - return null; - if (e is ConstantExpression) return (LambdaExpression)((ConstantExpression)e).Value; @@ -151,7 +147,7 @@ public static LambdaExpression StripQuotes(this Expression e) [DebuggerStepThrough] public static bool IsBase(this IQueryable query) { - ConstantExpression ce = query.Expression as ConstantExpression; + ConstantExpression? ce = query.Expression as ConstantExpression; return ce != null && ce.Value == query; } diff --git a/Signum.Utilities/ExpressionTrees/ExpressionReplacer.cs b/Signum.Utilities/ExpressionTrees/ExpressionReplacer.cs index e4853c683d..1d1c54fa14 100644 --- a/Signum.Utilities/ExpressionTrees/ExpressionReplacer.cs +++ b/Signum.Utilities/ExpressionTrees/ExpressionReplacer.cs @@ -1,29 +1,28 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq.Expressions; namespace Signum.Utilities.ExpressionTrees { public class ExpressionReplacer: ExpressionVisitor { - Dictionary replacements = new Dictionary(); + Dictionary replacements; + + public ExpressionReplacer(Dictionary replacements) + { + this.replacements = replacements; + } public static Expression Replace(InvocationExpression invocation) { - LambdaExpression lambda = invocation.Expression as LambdaExpression; - var replacer = new ExpressionReplacer() - { - replacements = 0.To(lambda.Parameters.Count).ToDictionaryEx(i => lambda.Parameters[i], i => invocation.Arguments[i]) - }; + LambdaExpression lambda = (LambdaExpression)invocation.Expression; + var replacer = new ExpressionReplacer(0.To(lambda.Parameters.Count).ToDictionaryEx(i => lambda.Parameters[i], i => invocation.Arguments[i])); return replacer.Visit(lambda.Body); } public static Expression Replace(Expression expression, Dictionary replacements) { - var replacer = new ExpressionReplacer() - { - replacements = replacements - }; + var replacer = new ExpressionReplacer(replacements); return replacer.Visit(expression); } diff --git a/Signum.Utilities/ExpressionTrees/Query.cs b/Signum.Utilities/ExpressionTrees/Query.cs index d7ad966698..a77a961945 100644 --- a/Signum.Utilities/ExpressionTrees/Query.cs +++ b/Signum.Utilities/ExpressionTrees/Query.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Collections; @@ -66,7 +66,7 @@ public override string ToString() if (expression is ConstantExpression ce && ce.Value == this) return this.GetType().TypeName().CleanIdentifiers(); else - return expression.ToString(); + return expression!/*CSBUG*/.ToString(); } public string QueryText diff --git a/Signum.Utilities/ExpressionTrees/QueryProvider.cs b/Signum.Utilities/ExpressionTrees/QueryProvider.cs index 7285ea5b80..aa5c60823d 100644 --- a/Signum.Utilities/ExpressionTrees/QueryProvider.cs +++ b/Signum.Utilities/ExpressionTrees/QueryProvider.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using System.Linq.Expressions; using System.Reflection; @@ -40,7 +40,7 @@ S IQueryProvider.Execute(Expression expression) return (S)this.Execute(expression); } - object IQueryProvider.Execute(Expression expression) + object? IQueryProvider.Execute(Expression expression) { return this.Execute(expression); } diff --git a/Signum.Utilities/ExpressionTrees/QueryableAsyncExtensions.cs b/Signum.Utilities/ExpressionTrees/QueryableAsyncExtensions.cs index d9f6069580..d36b708f33 100644 --- a/Signum.Utilities/ExpressionTrees/QueryableAsyncExtensions.cs +++ b/Signum.Utilities/ExpressionTrees/QueryableAsyncExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -11,7 +11,7 @@ namespace Signum.Utilities.ExpressionTrees public interface IQueryProviderAsync : IQueryProvider { - Task ExecuteAsync(Expression expression, CancellationToken token); + Task ExecuteAsync(Expression expression, CancellationToken token); } public static class QueryableAsyncExtensions @@ -23,7 +23,7 @@ public static async Task> ToListAsync(this IQueryable)value; + return (List)value!; } public static Task ToArrayAsync(this IQueryable source) => source.ToArrayAsync(CancellationToken.None); @@ -33,16 +33,16 @@ public static async Task ToArrayAsync(this IQueryable)value).ToArray(); + return ((List)value!).ToArray(); } static async Task Bind(CancellationToken cancellationToken, Expression> bind) { var mce = (MethodCallExpression)bind.Body; - IQueryable query = (IQueryable)ExpressionEvaluator.Eval(mce.Arguments.FirstEx()); + IQueryable query = (IQueryable)ExpressionEvaluator.Eval(mce.Arguments.FirstEx())!; - List otherExpressions = mce.Arguments.Skip(1).Select(a => (Expression)ExpressionEvaluator.Eval(a)).ToList(); + List otherExpressions = mce.Arguments.Skip(1).Select(a => (Expression)ExpressionEvaluator.Eval(a)!).ToList(); var mc2 = Expression.Call(mce.Method, otherExpressions.PreAnd(query.Expression)); diff --git a/Signum.Utilities/Extensions/ArgsExtensions.cs b/Signum.Utilities/Extensions/ArgsExtensions.cs index d72badf7b2..135dc7dbf4 100644 --- a/Signum.Utilities/Extensions/ArgsExtensions.cs +++ b/Signum.Utilities/Extensions/ArgsExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -9,18 +9,18 @@ namespace Signum.Utilities { public static class ArgsExtensions { - public static T GetArg(this IEnumerable args) + public static T GetArg(this IEnumerable? args) { return args.SmartConvertTo().SingleEx(() => "{0} in the argument list".FormatWith(typeof(T))); ; } - public static T TryGetArgC(this IEnumerable args) where T : class + public static T TryGetArgC(this IEnumerable? args) where T : class { return args.SmartConvertTo().SingleOrDefaultEx( () => "There are more than one {0} in the argument list".FormatWith(typeof(T))); } - public static T? TryGetArgS(this IEnumerable args) where T : struct + public static T? TryGetArgS(this IEnumerable? args) where T : struct { var casted = args.SmartConvertTo(); @@ -30,7 +30,7 @@ public static T TryGetArgC(this IEnumerable args) where T : class return casted.SingleEx(() => "{0} in the argument list".FormatWith(typeof(T))); } - static IEnumerable SmartConvertTo(this IEnumerable args) + static IEnumerable SmartConvertTo(this IEnumerable? args) { if (args == null) yield break; @@ -50,7 +50,7 @@ static IEnumerable SmartConvertTo(this IEnumerable args) yield return ReflectionTools.ChangeType(obj); } else if (obj is List list) - yield return (T)giConvertListTo.GetInvoker(typeof(T).ElementType())(list); + yield return (T)giConvertListTo.GetInvoker(typeof(T).ElementType()!)(list); } } diff --git a/Signum.Utilities/Extensions/ColorExtensions.cs b/Signum.Utilities/Extensions/ColorExtensions.cs index 1e0b473fd1..3c943daa1a 100644 --- a/Signum.Utilities/Extensions/ColorExtensions.cs +++ b/Signum.Utilities/Extensions/ColorExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Drawing; using System.Globalization; @@ -22,7 +22,7 @@ public static string ToHtml(this Color color) return ToHtmlColor(color.ToArgb()); } - public static string TryToHtml(this Color? color) + public static string? TryToHtml(this Color? color) { if (color == null) return null; @@ -145,8 +145,8 @@ public static Color FromHex(string hex) public static void FromHex(string hex, out byte a, out byte r, out byte g, out byte b) { - hex = ToRgbaHex(hex); - if (hex == null || !uint.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var packedValue)) + var nhex = ToRgbaHex(hex); + if (nhex == null || !uint.TryParse(nhex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var packedValue)) { throw new ArgumentException("Hexadecimal string is not in the correct format.", nameof(hex)); } @@ -157,7 +157,7 @@ public static void FromHex(string hex, out byte a, out byte r, out byte g, out b b = (byte)(packedValue >> 8); } - private static string ToRgbaHex(string hex) + private static string? ToRgbaHex(string hex) { hex = hex.StartsWith("#") ? hex.Substring(1) : hex; diff --git a/Signum.Utilities/Extensions/DateTimeExtensions.cs b/Signum.Utilities/Extensions/DateTimeExtensions.cs index d92f5856e3..4360bf2a25 100644 --- a/Signum.Utilities/Extensions/DateTimeExtensions.cs +++ b/Signum.Utilities/Extensions/DateTimeExtensions.cs @@ -524,7 +524,7 @@ public DateSpan Invert() public override string ToString() { - string result = ", ".CombineIfNotEmpty( + string result = ", ".Combine( Years == 0 ? null : Years == 1 ? DateTimeMessage._0Year.NiceToString().FormatWith(Years) : DateTimeMessage._0Years.NiceToString().FormatWith(Years), diff --git a/Signum.Utilities/Extensions/EnumExtensions.cs b/Signum.Utilities/Extensions/EnumExtensions.cs index aad1cb602d..c12622e9fe 100644 --- a/Signum.Utilities/Extensions/EnumExtensions.cs +++ b/Signum.Utilities/Extensions/EnumExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -90,7 +90,7 @@ public static bool TryParse(string value, Type enumType, bool ignoreCase, out En { if (!Enum.IsDefined(enumType, value) && !int.TryParse(value, out int rubish)) { - result = null; + result = null!; return false; } result = (Enum)Enum.Parse(enumType, value); diff --git a/Signum.Utilities/Extensions/EnumerableExtensions.cs b/Signum.Utilities/Extensions/EnumerableExtensions.cs index e54f876e11..312f2d95f1 100644 --- a/Signum.Utilities/Extensions/EnumerableExtensions.cs +++ b/Signum.Utilities/Extensions/EnumerableExtensions.cs @@ -11,6 +11,7 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; +using System.Runtime.CompilerServices; using System.Text; namespace Signum.Utilities @@ -399,12 +400,12 @@ public Expression Expand(Expression instance, Expression[] arguments, MethodInfo } } - public static bool IsNullOrEmpty(this IEnumerable? collection) + public static bool IsNullOrEmpty([NotNullWhenFalse]this IEnumerable? collection) { return collection == null || collection.IsEmpty(); } - public static bool HasItems(this IEnumerable? collection) + public static bool HasItems([NotNullWhenTrue]this IEnumerable? collection) { return collection != null && collection.Any(); } @@ -904,8 +905,7 @@ public static IEnumerable BiSelectC(this IEnumerable collection, Fun { if (!enumerator.MoveNext()) yield break; - - + T firstItem = enumerator.Current; if (options == BiSelectOptions.Initial || options == BiSelectOptions.InitialAndFinal) yield return func(null, firstItem); diff --git a/Signum.Utilities/Extensions/Extensions.cs b/Signum.Utilities/Extensions/Extensions.cs index df9b9c7ba4..d307374667 100644 --- a/Signum.Utilities/Extensions/Extensions.cs +++ b/Signum.Utilities/Extensions/Extensions.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Globalization; using System.Linq; +using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Web; @@ -261,7 +262,7 @@ public static int NotFound(this int value, int defaultValue) return value == -1 ? defaultValue : value; } - public static T ThrowIfNull(this T? t, string message) + public static T ThrowIfNull([EnsuresNotNull]this T? t, string message) where T : struct { if (t == null) @@ -269,7 +270,7 @@ public static T ThrowIfNull(this T? t, string message) return t.Value; } - public static T ThrowIfNull(this T t, string message) + public static T ThrowIfNull([EnsuresNotNull]this T t, string message) where T : class { if (t == null) @@ -278,7 +279,7 @@ public static T ThrowIfNull(this T t, string message) } - public static T ThrowIfNull(this T? t, Func message) + public static T ThrowIfNull([EnsuresNotNull]this T? t, Func message) where T : struct { if (t == null) @@ -286,7 +287,7 @@ public static T ThrowIfNull(this T? t, Func message) return t.Value; } - public static T ThrowIfNull(this T t, Func message) + public static T ThrowIfNull([EnsuresNotNull]this T? t, Func message) where T : class { if (t == null) diff --git a/Signum.Utilities/Extensions/GroupExtensions.cs b/Signum.Utilities/Extensions/GroupExtensions.cs index 17886d1046..3436374174 100644 --- a/Signum.Utilities/Extensions/GroupExtensions.cs +++ b/Signum.Utilities/Extensions/GroupExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Signum.Utilities.DataStructures; @@ -21,7 +21,7 @@ public static Dictionary GroupDistinctToDictionary(this IEnumerab .ToDictionaryEx(g => g.Key, g => g.Distinct().AssertSingle(g.Key)); } - public static T AssertSingle(this IEnumerable collection, object key) + public static T AssertSingle(this IEnumerable collection, object? key) { int c = collection.Count(); if (c == 0) throw new InvalidOperationException("No element exists with key '{0}'".FormatWith(key)); @@ -184,7 +184,7 @@ public static IEnumerable> IntervalsOf(this IEnumerable public static List> GroupWhen(this IEnumerable collection, Func isGroupKey, bool includeKeyInGroup = false, bool initialGroup = false) { List> result = new List>(); - Grouping group = null; + Grouping? group = null; foreach (var item in collection) { if (isGroupKey(item)) @@ -201,7 +201,7 @@ public static List> GroupWhen(this IEnumerable collection, if(!initialGroup) throw new InvalidOperationException("Parameter initialGroup is false"); - group = new Grouping(default(T)); + group = new Grouping(default(T)!); result.Add(group); } @@ -214,7 +214,7 @@ public static List> GroupWhen(this IEnumerable collection, public static IEnumerable> GroupWhenChange(this IEnumerable collection, Func getGroupKey) { - Grouping current = null; + Grouping? current = null; foreach (var item in collection) { @@ -225,7 +225,7 @@ public static IEnumerable> GroupWhenChange(this IEnumerabl item }; } - else if (current.Key.Equals(getGroupKey(item))) + else if (object.Equals(current.Key, getGroupKey(item))) { current.Add(item); } diff --git a/Signum.Utilities/Extensions/ReflectionExtensions.cs b/Signum.Utilities/Extensions/ReflectionExtensions.cs index a001965b7c..bc00e7d943 100644 --- a/Signum.Utilities/Extensions/ReflectionExtensions.cs +++ b/Signum.Utilities/Extensions/ReflectionExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -38,11 +38,12 @@ public static bool IsAnonymous(this Type type) public static Type ReturningType(this MemberInfo m) { - return (m is PropertyInfo) ? ((PropertyInfo)m).PropertyType : - (m is FieldInfo) ? ((FieldInfo)m).FieldType : - (m is MethodInfo) ? ((MethodInfo)m).ReturnType : - (m is ConstructorInfo) ? ((ConstructorInfo)m).DeclaringType : - (m is EventInfo) ? ((EventInfo)m).EventHandlerType : null; + return (m is PropertyInfo pi) ? pi.PropertyType : + (m is FieldInfo fi) ? fi.FieldType : + (m is MethodInfo mi) ? mi.ReturnType : + (m is ConstructorInfo ci) ? ci.DeclaringType : + (m is EventInfo ei) ? ei.EventHandlerType : + throw new UnexpectedValueException(m! /*CSBUG*/); } public static bool HasAttribute(this ICustomAttributeProvider mi) where T : Attribute @@ -93,7 +94,7 @@ public static bool IsReadOnly(this PropertyInfo pi) return mi == null || !mi.IsPublic; } - public static Type ElementType(this Type ft) + public static Type? ElementType(this Type ft) { if (!typeof(IEnumerable).IsAssignableFrom(ft)) return null; @@ -108,7 +109,7 @@ public static bool IsExtensionMethod(this MethodInfo m) return m.IsStatic && m.HasAttribute(); } - public static PropertyInfo GetBaseDefinition(this PropertyInfo propertyInfo) + public static PropertyInfo? GetBaseDefinition(this PropertyInfo propertyInfo) { var method = propertyInfo.GetAccessors(true)[0]; if (method == null) @@ -142,7 +143,7 @@ public static DateTime CompilationDate(this Assembly assembly) const int c_PeHeaderOffset = 60; const int c_LinkerTimestampOffset = 8; byte[] b = new byte[2048]; - System.IO.Stream s = null; + System.IO.Stream? s = null; try { diff --git a/Signum.Utilities/Extensions/RegexExtensions.cs b/Signum.Utilities/Extensions/RegexExtensions.cs index 5b80f409fb..b36766a9b0 100644 --- a/Signum.Utilities/Extensions/RegexExtensions.cs +++ b/Signum.Utilities/Extensions/RegexExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; @@ -41,7 +41,11 @@ public static T MostSimilar(this IEnumerable collection, Func s } public static IEnumerable JoinSimilar(this List outer, List inner, - Func outerKeySelector, Func innerKeySelector, Func resultSelector) + Func outerKeySelector, + Func innerKeySelector, + Func resultSelector) + where T : object + where S : object { StringDistance sd = new StringDistance(); Dictionary, int> distances = (from o in outer @@ -61,7 +65,7 @@ select KVP.Create(Tuple.Create(o, i), } } - public static IEnumerable<(Match match, string after)> SplitAfter(this Regex regex, string input) + public static IEnumerable<(Match? match, string after)> SplitAfter(this Regex regex, string input) { var matches = regex.Matches(input).Cast().ToList(); diff --git a/Signum.Utilities/Extensions/StringExtensions.cs b/Signum.Utilities/Extensions/StringExtensions.cs index eb1a42c015..638c65c019 100644 --- a/Signum.Utilities/Extensions/StringExtensions.cs +++ b/Signum.Utilities/Extensions/StringExtensions.cs @@ -11,14 +11,18 @@ namespace Signum.Utilities { public static class StringExtensions { +#pragma warning disable IDE0052 // Remove unread private members static readonly Expression> HasTextExpression = str => (str ?? "").Length > 0; +#pragma warning restore IDE0052 // Remove unread private members [ExpressionField("HasTextExpression")] public static bool HasText(this string? str) { return !string.IsNullOrEmpty(str); } +#pragma warning disable IDE0052 // Remove unread private members static readonly Expression> DefaultTextExpression = (a, b) => ((a ?? "").Length > 0) ? a : b; +#pragma warning restore IDE0052 // Remove unread private members [ExpressionField("DefaultTextExpression")] public static string DefaultText(this string? str, string defaultText) { @@ -41,17 +45,17 @@ public static bool Contains(this string source, string toCheck, StringComparison return source.IndexOf(toCheck, comp) >= 0; } - public static string? Add(this string? str, string separator, string? part) + public static string Add(this string? str, string separator, string? part) { if (str.HasText()) { if (part.HasText()) return str + separator + part; else - return str; + return str ?? ""; } else - return part; + return part ?? ""; } public static string? AddLine(this string? str, string part) @@ -710,7 +714,7 @@ public static bool Wildcards(this string fileName, IEnumerable wildcards return wildcards.Any(wc => fileName.Wildcards(wc)); } - static Dictionary wildcardsPatterns = new Dictionary(); + static readonly Dictionary wildcardsPatterns = new Dictionary(); public static bool Wildcards(this string fileName, string wildcard) { var pattern = wildcardsPatterns.GetOrCreate(wildcard, wildcard.Replace(".", "[.]").Replace("*", ".*").Replace("?", ".")); @@ -749,8 +753,8 @@ public static string ToComputerSize(this long value) return ToComputerSize(value, false); } - static string[] abbreviations = new[] { "Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" }; - static string[] magnitudes = new[] { "Bytes", "KBytes", "MBytes", "GBytes", "TBytes", "PBytes", "EBytes", "ZBytes", "YBytes" }; + static readonly string[] abbreviations = new[] { "Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" }; + static readonly string[] magnitudes = new[] { "Bytes", "KBytes", "MBytes", "GBytes", "TBytes", "PBytes", "EBytes", "ZBytes", "YBytes" }; public static string ToComputerSize(this long value, bool useAbbreviations) { double valor = value; @@ -760,27 +764,8 @@ public static string ToComputerSize(this long value, bool useAbbreviations) return "{0:#,###.00} {1}".FormatWith(valor, (useAbbreviations ? abbreviations : magnitudes)[i]); } - - public static string Combine(this string separator, params object[] elements) - { - StringBuilder? sb = null; - foreach (var item in elements) - { - if (item != null) - { - if (sb == null) - sb = new StringBuilder(); - else - sb.Append(separator); - - sb.Append(item.ToString()); - } - } - - return sb == null ? "" : sb.ToString(); // Remove at the end is faster - } - - public static string CombineIfNotEmpty(this string separator, params object?[] elements) + + public static string Combine(this string separator, params object?[] elements) { StringBuilder? sb = null; foreach (var item in elements) diff --git a/Signum.Utilities/Extensions/StringExtensions.md b/Signum.Utilities/Extensions/StringExtensions.md index be63bfebe6..9ed5493ffe 100644 --- a/Signum.Utilities/Extensions/StringExtensions.md +++ b/Signum.Utilities/Extensions/StringExtensions.md @@ -463,20 +463,20 @@ It's useful for code generation, like C# or SQL statements: // Address //FROM Customers ``` -### Combine / CombineIfNotEmpty +### Combine / Combine Given a separator `this`, combines a sequence of string `params` writing the separator in between. ```C# public static string Combine(this string separator, params object[] elements) -public static string CombineIfNotEmpty(this string separator, params object[] elements) +public static string Combine(this string separator, params object[] elements) ``` -CombineIfNotEmpty ignores null or empty elements. +Combine ignores null or empty elements. ```C# ",".Combine(0, null, "", "hola"); //returns 0,,,hola -",".CombineIfNotEmpty(0, null, "", "hola"); //returns 0,hola +",".Combine(0, null, "", "hola"); //returns 0,hola ``` ### ToComputerSize diff --git a/Signum.Utilities/Extensions/TimeSpanExtensions.cs b/Signum.Utilities/Extensions/TimeSpanExtensions.cs index df885fd0f4..3aac177b5e 100644 --- a/Signum.Utilities/Extensions/TimeSpanExtensions.cs +++ b/Signum.Utilities/Extensions/TimeSpanExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text; namespace Signum.Utilities diff --git a/Signum.Utilities/Extensions/TreeHelper.cs b/Signum.Utilities/Extensions/TreeHelper.cs index 6d7d94ef65..6e09b5e3b8 100644 --- a/Signum.Utilities/Extensions/TreeHelper.cs +++ b/Signum.Utilities/Extensions/TreeHelper.cs @@ -15,16 +15,16 @@ public static ObservableCollection> ToTreeC(IEnumerable collection Dictionary> dic = new Dictionary>(); - Func> createNode = null; + Func> createNode = null!; createNode = item => dic.GetOrCreate(item, () => - { - Node itemNode = new Node(item); - T parent = getParent(item); - Node parentNode = parent != null ? createNode(parent) : top; - parentNode.Children.Add(itemNode); - return itemNode; - }); + { + Node itemNode = new Node(item); + T parent = getParent(item); + Node parentNode = parent != null ? createNode(parent) : top; + parentNode.Children.Add(itemNode); + return itemNode; + }); foreach (var item in collection) { @@ -41,7 +41,7 @@ public static ObservableCollection> ToTreeS(IEnumerable collection Dictionary> dic = new Dictionary>(); - Func> createNode = null; + Func> createNode = null!; createNode = item => dic.GetOrCreate(item, () => { @@ -84,7 +84,7 @@ public static IEnumerable DepthFirst(T root, Func> child } } - public static ObservableCollection> SelectTree(ObservableCollection> nodes, Func selector) + public static ObservableCollection>? SelectTree(ObservableCollection> nodes, Func selector) { return nodes.Select(n => new Node(selector(n.Value), SelectTree(n.Children, selector))).ToObservableCollection(); } @@ -123,7 +123,7 @@ public static ObservableCollection> SelectSimplifyTreeS(Observable return result; } - public static ObservableCollection> Apply(ObservableCollection> collection, Func>, ObservableCollection>> action) + public static ObservableCollection>? Apply(ObservableCollection> collection, Func>, ObservableCollection>> action) { return action(collection).Select(a => new Node(a.Value, Apply(a.Children, action))).ToObservableCollection(); } @@ -134,7 +134,7 @@ public class Node : INotifyPropertyChanged public T Value { get; set; } public ObservableCollection> Children { get; set; } - public Node(T value, ObservableCollection> children) + public Node(T value, ObservableCollection>? children) { Value = value; Children = children ?? new ObservableCollection>(); diff --git a/Signum.Utilities/NaturalLanguage/German.cs b/Signum.Utilities/NaturalLanguage/German.cs index a1d4918fde..395689da41 100644 --- a/Signum.Utilities/NaturalLanguage/German.cs +++ b/Signum.Utilities/NaturalLanguage/German.cs @@ -7,7 +7,7 @@ namespace Signum.Utilities.NaturalLanguage public class GermanPluralizer : IPluralizer { //http://www.alemansencillo.com/el-plural-en-aleman#TOC-Reglas-generales-aplicables-a-todos - Dictionary terminationsFemenine = new Dictionary + readonly Dictionary terminationsFemenine = new Dictionary { {"itis", "itiden"}, {"sis", "sen"}, @@ -18,8 +18,7 @@ public class GermanPluralizer : IPluralizer {"a", "en"}, {"", "en"}, }; - - Dictionary terminationsMasculine = new Dictionary + readonly Dictionary terminationsMasculine = new Dictionary { {"ant", "anten"}, {"ent", "enten"}, @@ -29,8 +28,7 @@ public class GermanPluralizer : IPluralizer {"e", "en"}, {"", "e"}, }; - - Dictionary terminationsNeutro = new Dictionary + readonly Dictionary terminationsNeutro = new Dictionary { {"nis", "nisse"}, {"um", "a"}, @@ -44,7 +42,7 @@ public string MakePlural(string singularName) if (string.IsNullOrEmpty(singularName)) return singularName; - string last = singularName.TryAfterLast(' '); + string? last = singularName.TryAfterLast(' '); if (last != null) return singularName.BeforeLast(' ') + " " + MakePlural(last); @@ -67,7 +65,7 @@ public string MakePlural(string singularName) public class GermanGenderDetector : IGenderDetector { - Dictionary terminations = new Dictionary + readonly Dictionary terminations = new Dictionary { //http://www.alemansencillo.com/genero-de-los-sustantivos-masculinos {"ich", 'm' }, @@ -136,18 +134,13 @@ public class GermanGenderDetector : IGenderDetector return null; } - - ReadOnlyCollection pronoms = new ReadOnlyCollection(new[] + + public ReadOnlyCollection Pronoms { get; } = new ReadOnlyCollection(new[] { new PronomInfo('m', "der", "die"), new PronomInfo('f', "die", "die"), new PronomInfo('n', "das", "die"), }); - - public ReadOnlyCollection Pronoms - { - get { return pronoms; } - } } diff --git a/Signum.Utilities/NaturalLanguage/Spanish.cs b/Signum.Utilities/NaturalLanguage/Spanish.cs index 9fa3e77728..fa0824c215 100644 --- a/Signum.Utilities/NaturalLanguage/Spanish.cs +++ b/Signum.Utilities/NaturalLanguage/Spanish.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; @@ -129,9 +129,9 @@ public string ToNumber(decimal number, NumberWriterSettings settings) settings.UnitGender == 'f' ? (bool?)true : settings.UnitGender == 'm' ? (bool?)false : null; - string signo = null; - string integerPart = null; - string decimalPart = null; + string? signo = null; + string? integerPart = null; + string? decimalPart = null; if (number < 0) { @@ -161,7 +161,7 @@ public string ToNumber(decimal number, NumberWriterSettings settings) } private static string ConvertNumber(long num, bool? femenine, string singular, string plural) { - string result = null; + string? result = null; long numAux = num; for (int i = 0; numAux > 0; i++, numAux /= 1000) result = " ".Combine(ConvertTrio((int)(numAux % 1000), i, femenine), " ", result); @@ -173,7 +173,7 @@ private static string ConvertNumber(long num, bool? femenine, string singular, s return separator.Combine(result ?? "cero", numMod1M == 1 ? singular : plural); } - static string ConvertTrio(int val, int group, bool? femenine) + static string? ConvertTrio(int val, int group, bool? femenine) { string trio = val.ToString("000"); @@ -184,14 +184,14 @@ static string ConvertTrio(int val, int group, bool? femenine) if (cent == 0 && dec == 0 && unit == 0 && group % 2 == 1) return null; - string groupName = UnitsGroup(group, unit != 1 || dec > 0 || cent > 0); + string? groupName = UnitsGroup(group, unit != 1 || dec > 0 || cent > 0); string num = CentsDecsUnits(cent, dec, unit, group >= 2 ? null : femenine); return " ".Combine(val == 1 && groupName == "mil" ? null : num, groupName); } - static string UnitsGroup(int numGroup, bool plural) + static string? UnitsGroup(int numGroup, bool plural) { //en función de la cantidad de elementos que haya en enteros tendremos los //billones, millones, unidades... @@ -252,7 +252,7 @@ static string DecsUnits(int decena, int unit, bool? femenine) } } - static string Units(int num, bool? femenine) + static string? Units(int num, bool? femenine) { switch (num) { @@ -272,7 +272,7 @@ static string Units(int num, bool? femenine) } } - static string Decs(int num) + static string? Decs(int num) { switch (num) { @@ -290,7 +290,7 @@ static string Decs(int num) } } - static string Cents(int num, bool femenine) + static string? Cents(int num, bool femenine) { switch (num) { diff --git a/Signum.Utilities/NotNullAttributes.cs b/Signum.Utilities/NotNullAttributes.cs new file mode 100644 index 0000000000..038a2f56d4 --- /dev/null +++ b/Signum.Utilities/NotNullAttributes.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Text; + + +namespace System.Runtime.CompilerServices +{ + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] + public class AssertsTrueAttribute : Attribute + { + public AssertsTrueAttribute() { } + } + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] + public class AssertsFalseAttribute : Attribute + { + public AssertsFalseAttribute() { } + } + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] + public class EnsuresNotNullAttribute : Attribute + { + public EnsuresNotNullAttribute() { } + } + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] + public class NotNullWhenFalseAttribute : Attribute + { + public NotNullWhenFalseAttribute() { } + } + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] + public class NotNullWhenTrueAttribute : Attribute + { + public NotNullWhenTrueAttribute() { } + } +} diff --git a/Signum.Utilities/ProgressProxy.cs b/Signum.Utilities/ProgressProxy.cs index 57ebe9809b..ed7cc94d47 100644 --- a/Signum.Utilities/ProgressProxy.cs +++ b/Signum.Utilities/ProgressProxy.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Signum.Utilities { @@ -6,7 +6,7 @@ public class ProgressProxy { const int numUpdates = 10000; - private string currentTask; + private string? currentTask; private int min; private int max; @@ -42,7 +42,7 @@ public int Position } } - public string CurrentTask + public string? CurrentTask { get { return currentTask; } } diff --git a/Signum.Utilities/Reflection/ReflectionTools.cs b/Signum.Utilities/Reflection/ReflectionTools.cs index 41fa4da332..89921a4441 100644 --- a/Signum.Utilities/Reflection/ReflectionTools.cs +++ b/Signum.Utilities/Reflection/ReflectionTools.cs @@ -103,8 +103,7 @@ public static ConstructorInfo BaseConstuctorInfo(LambdaExpression constuctor) if (body.NodeType == ExpressionType.Convert) body = ((UnaryExpression)body).Operand; - NewExpression? ex = body as NewExpression; - if (ex == null) + if (!(body is NewExpression ex)) throw new ArgumentException("The lambda 'constuctor' should be an expression constructing an object"); return ex.Constructor; @@ -288,9 +287,7 @@ public static Type GetReceiverType(Expression> lambda) return (Action)exp.Compile(); } } - - static Module module = ((Expression>)(() => 2)).Compile().Method.Module; - + public static Action? CreateSetterUntyped(Type type, MemberInfo m) { using (HeavyProfiler.LogNoStackTrace("CreateSetterUntyped")) @@ -463,13 +460,13 @@ public static T Parse(string value, CultureInfo culture) return (T)Convert.ChangeType(value, utype, culture); } - public static object Parse(string value, Type type, CultureInfo culture) + public static object? Parse(string value, Type type, CultureInfo culture) { if (type == typeof(string)) - return (object)value; + return value; if (value == null || value == "") - return (object?)null; + return null; Type utype = type.UnNullify(); if (utype.IsEnum) @@ -489,7 +486,7 @@ public static bool TryParse(string value, out T result) } else { - result = default(T); + result = default(T)!; return false; } } @@ -503,7 +500,7 @@ public static bool TryParse(string value, CultureInfo ci, out T result) } else { - result = default(T); + result = default(T)!; return false; } } diff --git a/Signum.Utilities/Reflection/TupleExtensions.cs b/Signum.Utilities/Reflection/TupleExtensions.cs index 0458cc7bd6..4696ec5cef 100644 --- a/Signum.Utilities/Reflection/TupleExtensions.cs +++ b/Signum.Utilities/Reflection/TupleExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -31,7 +31,7 @@ public static Type TupleOf(int numParameters) case 6: return typeof(Tuple<,,,,,>); case 7: return typeof(Tuple<,,,,,,>); case 8: return typeof(Tuple<,,,,,,,>); - default: return null; + default: throw new UnexpectedValueException(numParameters); } } diff --git a/Signum.Utilities/Statics.cs b/Signum.Utilities/Statics.cs index 10d2eb62bf..0eb566994d 100644 --- a/Signum.Utilities/Statics.cs +++ b/Signum.Utilities/Statics.cs @@ -158,7 +158,7 @@ public override void Clean() public abstract class SessionVariable: Variable { - public abstract Func? ValueFactory { get; set; } + public Func ValueFactory { get; set; } protected internal SessionVariable(string name) : base(name) @@ -191,7 +191,7 @@ public SessionVariable CreateVariable(string name) class VoidVariable : SessionVariable { - public override Func? ValueFactory { get; set; } + //public override Func ValueFactory { get; set; } public VoidVariable(string name) : base(name) @@ -227,7 +227,7 @@ public SessionVariable CreateVariable(string name) class SingletonVariable : SessionVariable { - public override Func? ValueFactory { get; set; } + //public override Func ValueFactory { get; set; } public SingletonVariable(string name) : base(name) @@ -297,11 +297,12 @@ public OverrideableVariable(SessionVariable variable) this.variable = variable; } - public override Func? ValueFactory - { - get { return variable.ValueFactory; } - set { variable.ValueFactory = value; } - } + /*CSBUG*/ + //public override Func ValueFactory + //{ + // get { return variable.ValueFactory; } + // set { variable.ValueFactory = value; } + //} public override T Value { diff --git a/Signum.Utilities/Synchronization/ThreadSafeEnumerator.cs b/Signum.Utilities/Synchronization/ThreadSafeEnumerator.cs index eb9bbcc9be..d3587812ce 100644 --- a/Signum.Utilities/Synchronization/ThreadSafeEnumerator.cs +++ b/Signum.Utilities/Synchronization/ThreadSafeEnumerator.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Collections; using System.Threading; @@ -34,7 +34,7 @@ public T Current get { return current.Value; } } - object IEnumerator.Current + object? IEnumerator.Current { get { return current.Value; } } @@ -46,7 +46,7 @@ public bool MoveNext() if (moveNext && (moveNext = enumerator.MoveNext())) current.Value = enumerator.Current; else - current.Value = default(T); + current.Value = default(T)!; return moveNext; } diff --git a/Signum.Utilities/Tsv.cs b/Signum.Utilities/Tsv.cs index c41f1fabcd..eb2751b323 100644 --- a/Signum.Utilities/Tsv.cs +++ b/Signum.Utilities/Tsv.cs @@ -102,7 +102,7 @@ public static void ToTsv(this IEnumerable collection, Stream stream, Encod { for (int i = 0; i < members.Count; i++) { - var obj = members[i].Getter(item); + var obj = members[i].Getter!(item); var str = toString[i](obj); @@ -197,7 +197,7 @@ static string HandleSpaces(string p) { e.Data["row"] = line; - if (defOptions.SkipError == null || !options.SkipError(e, tsvLine)) + if (defOptions.SkipError?.Invoke(e, tsvLine) != true) throw new ParseCsvException(e); } @@ -247,7 +247,7 @@ public static T ReadLine(string tsvLine, TsvReadOptions? options = null) { str = vals[i]; object? val = parsers[i](str); - members[i].Setter(t, val); + members[i].Setter!(t, val); } catch (Exception e) { From 06ef8e83be801baef9d5135a966233cfff8acf3f Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Thu, 24 Jan 2019 22:59:44 +0100 Subject: [PATCH 10/25] more on nullables --- .../CodeGeneration/LogicCodeGenerator.cs | 2 +- Signum.Engine/Connection/FieldReader.cs | 17 +++++----- Signum.Engine/GlobalLazy.cs | 6 ++-- .../ExpressionVisitor/GroupEntityCleaner.cs | 6 ++-- .../Linq/ExpressionVisitor/OrderByRewriter.cs | 33 +++++++++---------- Signum.Engine/Linq/Meta/MetaEvaluator.cs | 16 +++++---- Signum.Engine/Linq/Meta/MetadataVisitor.cs | 21 +++++------- 7 files changed, 49 insertions(+), 52 deletions(-) diff --git a/Signum.Engine/CodeGeneration/LogicCodeGenerator.cs b/Signum.Engine/CodeGeneration/LogicCodeGenerator.cs index b58f51cc8c..ccdfaa62e1 100644 --- a/Signum.Engine/CodeGeneration/LogicCodeGenerator.cs +++ b/Signum.Engine/CodeGeneration/LogicCodeGenerator.cs @@ -424,7 +424,7 @@ protected virtual string GetWithVirtualMList(Type type, PropertyInfo p, Property if (!pi.HasAttribute()) return null; - var t = pi.PropertyType.ElementType(); + var t = pi.PropertyType.ElementType()!; var backProperty = Reflector.PublicInstancePropertiesInOrder(t).SingleOrDefaultEx(bp => IsVirtualMListBackReference(bp, pi.DeclaringType)); diff --git a/Signum.Engine/Connection/FieldReader.cs b/Signum.Engine/Connection/FieldReader.cs index 92b1aeb482..16e10a199f 100644 --- a/Signum.Engine/Connection/FieldReader.cs +++ b/Signum.Engine/Connection/FieldReader.cs @@ -566,12 +566,11 @@ public static Expression GetIsNull(Expression reader, int ordinal) internal FieldReaderException CreateFieldReaderException(Exception ex) { - return new FieldReaderException(ex) - { - Ordinal = LastOrdinal, - ColumnName = reader.GetName(LastOrdinal), - ColumnType = reader.GetFieldType(LastOrdinal), - }; + return new FieldReaderException(ex, + ordinal: LastOrdinal, + columnName: reader.GetName(LastOrdinal), + columnType: reader.GetFieldType(LastOrdinal) + ); } } @@ -583,8 +582,10 @@ public FieldReaderException(Exception inner, int ordinal, string columnName, Typ this.Ordinal = ordinal; this.ColumnName = columnName; this.ColumnType = columnType; - } - protected FieldReaderException( + } +#pragma warning disable CS8618 // Non-nullable field is uninitialized. + protected FieldReaderException( +#pragma warning restore CS8618 // Non-nullable field is uninitialized. System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { } diff --git a/Signum.Engine/GlobalLazy.cs b/Signum.Engine/GlobalLazy.cs index 1833ea90fd..51bae85fdb 100644 --- a/Signum.Engine/GlobalLazy.cs +++ b/Signum.Engine/GlobalLazy.cs @@ -1,4 +1,4 @@ -using Signum.Utilities; +using Signum.Utilities; using Signum.Utilities.ExpressionTrees; using System; using System.Collections.Generic; @@ -38,7 +38,7 @@ public InvalidateWith(params Type[] types) public static class GlobalLazy { - static HashSet registeredLazyList = new HashSet(); + static readonly HashSet registeredLazyList = new HashSet(); public static List Statistics() { return registeredLazyList.Select(a => a.Stats()).OrderByDescending(x=>x.SumLoadTime).ToList(); @@ -51,7 +51,7 @@ public static ResetLazy WithoutInvalidations(Func func, LazyThreadSafet { using (ExecutionMode.Global()) using (HeavyProfiler.Log("ResetLazy", () => typeof(T).TypeName())) - using (Transaction tr = Transaction.InTestTransaction ? null : Transaction.ForceNew()) + using (Transaction? tr = Transaction.InTestTransaction ? null : Transaction.ForceNew()) using (new EntityCache(EntityCacheType.ForceNewSealed)) { var value = func(); diff --git a/Signum.Engine/Linq/ExpressionVisitor/GroupEntityCleaner.cs b/Signum.Engine/Linq/ExpressionVisitor/GroupEntityCleaner.cs index 76327dffbe..395318e8b6 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/GroupEntityCleaner.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/GroupEntityCleaner.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq.Expressions; namespace Signum.Engine.Linq @@ -14,7 +14,7 @@ public static Expression Clean(Expression source) public override Expression Visit(Expression exp) { if (exp == null) - return null; + return null!; if (exp.Type == typeof(Type)) return VisitType(exp); @@ -59,7 +59,7 @@ protected internal override Expression VisitLiteReference(LiteReferenceExpressio public override Expression Visit(Expression exp) { if (exp == null) - return null; + return null!; if (exp.Type == typeof(Type)) return VisitType(exp); diff --git a/Signum.Engine/Linq/ExpressionVisitor/OrderByRewriter.cs b/Signum.Engine/Linq/ExpressionVisitor/OrderByRewriter.cs index 0cfeb55646..b8cf9ac3fd 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/OrderByRewriter.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/OrderByRewriter.cs @@ -1,4 +1,4 @@ -using Signum.Entities.DynamicQuery; +using Signum.Entities.DynamicQuery; using Signum.Utilities; using System; using System.Collections.Generic; @@ -10,9 +10,9 @@ namespace Signum.Engine.Linq { internal class OrderByRewriter : DbExpressionVisitor { - List gatheredKeys; - ReadOnlyCollection gatheredOrderings; - SelectExpression outerMostSelect; + List? gatheredKeys; + ReadOnlyCollection? gatheredOrderings; + SelectExpression? outerMostSelect; bool hasProjectionInProjector; private OrderByRewriter() { } @@ -73,7 +73,7 @@ protected internal override Expression VisitSelect(SelectExpression select) gatheredKeys = new List(); } - List savedKeys = null; + List? savedKeys = null; if (gatheredKeys != null && (select.IsDistinct || select.GroupBy.HasItems() || select.IsAllAggregates)) savedKeys = gatheredKeys.ToList(); @@ -82,7 +82,7 @@ protected internal override Expression VisitSelect(SelectExpression select) if (savedKeys != null) gatheredKeys = savedKeys; - List newColumns = null; + List? newColumns = null; if (select.GroupBy.HasItems()) { @@ -96,7 +96,7 @@ protected internal override Expression VisitSelect(SelectExpression select) foreach (var ge in select.GroupBy) { - var cd = cg.Columns.FirstOrDefault(a => DbExpressionComparer.AreEqual(a.Expression, ge)); + var cd = cg.Columns.NotNull().FirstOrDefault(a => DbExpressionComparer.AreEqual(a.Expression, ge)); if (cd != null) newKeys.Add(cd); @@ -105,7 +105,7 @@ protected internal override Expression VisitSelect(SelectExpression select) } if (cg.Columns.Count() != select.Columns.Count) - newColumns = cg.Columns.ToList(); + newColumns = cg.Columns.NotNull().ToList(); gatheredKeys.AddRange(newKeys.Select(cd => new ColumnExpression(cd.Expression.Type, select.Alias, cd.Name))); } @@ -137,7 +137,7 @@ protected internal override Expression VisitSelect(SelectExpression select) if (select.OrderBy.Count > 0) this.PrependOrderings(select.OrderBy); - ReadOnlyCollection orderings = null; + ReadOnlyCollection? orderings = null; if (isOuterMost && !IsCountSumOrAvg(select) || select.Top != null) { @@ -150,7 +150,7 @@ protected internal override Expression VisitSelect(SelectExpression select) if (AreEqual(select.OrderBy, orderings) && !select.IsReverse && newColumns == null) return select; - return new SelectExpression(select.Alias, select.IsDistinct, select.Top, (IEnumerable)newColumns ?? select.Columns, + return new SelectExpression(select.Alias, select.IsDistinct, select.Top, (IEnumerable?)newColumns ?? select.Columns, select.From, select.Where, orderings, select.GroupBy, select.SelectOptions & ~SelectOptions.Reverse); } @@ -164,7 +164,7 @@ protected internal override Expression VisitRowNumber(RowNumberExpression rowNum protected internal override Expression VisitScalar(ScalarExpression scalar) { - if (!scalar.Select.IsForXmlPathEmpty) + if (!scalar.Select!.IsForXmlPathEmpty) { using (Scope()) return base.VisitScalar(scalar); @@ -174,7 +174,7 @@ protected internal override Expression VisitScalar(ScalarExpression scalar) using (Scope()) { var oldOuterMostSelect = outerMostSelect; - outerMostSelect = scalar.Select; + outerMostSelect = scalar.Select!; var result = base.VisitScalar(scalar); outerMostSelect = oldOuterMostSelect; @@ -199,7 +199,7 @@ protected internal override Expression VisitIn(InExpression @in) return base.VisitIn(@in); } - static bool AreEqual(IEnumerable col1, IEnumerable col2) + static bool AreEqual(IEnumerable? col1, IEnumerable? col2) { bool col1Empty = col1 == null || col1.IsEmpty(); bool col2Empty = col2 == null || col2.IsEmpty(); @@ -231,8 +231,7 @@ private bool IsCountSumOrAvg(SelectExpression select) exp = ((BinaryExpression)exp).Left; } - AggregateExpression aggExp = exp as AggregateExpression; - if (aggExp == null) + if (!(exp is AggregateExpression aggExp)) return false; return aggExp.AggregateFunction == AggregateSqlFunction.Count || @@ -246,7 +245,7 @@ protected internal override Expression VisitJoin(JoinExpression join) { SourceExpression left = this.VisitSource(join.Left); - ReadOnlyCollection leftOrders = this.gatheredOrderings; + ReadOnlyCollection? leftOrders = this.gatheredOrderings; this.gatheredOrderings = null; SourceExpression right = join.Right is TableExpression ? join.Right : this.VisitSource(join.Right); @@ -302,7 +301,7 @@ static Expression CleanCast(Expression exp) return exp; } - protected void PrependOrderings(ReadOnlyCollection newOrderings) + protected void PrependOrderings(ReadOnlyCollection? newOrderings) { if (!newOrderings.IsNullOrEmpty()) { diff --git a/Signum.Engine/Linq/Meta/MetaEvaluator.cs b/Signum.Engine/Linq/Meta/MetaEvaluator.cs index 925bed0d55..8985f6af0a 100644 --- a/Signum.Engine/Linq/Meta/MetaEvaluator.cs +++ b/Signum.Engine/Linq/Meta/MetaEvaluator.cs @@ -21,8 +21,11 @@ public class MetaEvaluator : ExpressionVisitor } HashSet candidates; - - private MetaEvaluator() { } + + public MetaEvaluator(HashSet candidates) + { + this.candidates = candidates; + } /// /// Performs evaluation & replacement of independent sub-trees @@ -32,15 +35,14 @@ private MetaEvaluator() { } /// A new tree with sub-trees evaluated and replaced. public static Expression PartialEval(Expression exp) { - return new MetaEvaluator { candidates = ExpressionNominator.Nominate(exp) }.Visit(exp); + return new MetaEvaluator(candidates: ExpressionNominator.Nominate(exp)).Visit(exp); } - public override Expression? Visit(Expression exp) + public override Expression Visit(Expression exp) { if (exp == null) - { - return null; - } + return null!; + if (this.candidates.Contains(exp) && exp.NodeType != ExpressionType.Constant) { if (exp.Type.IsInstantiationOf(typeof(IQueryable<>))) diff --git a/Signum.Engine/Linq/Meta/MetadataVisitor.cs b/Signum.Engine/Linq/Meta/MetadataVisitor.cs index 400fbfef51..392ab931ee 100644 --- a/Signum.Engine/Linq/Meta/MetadataVisitor.cs +++ b/Signum.Engine/Linq/Meta/MetadataVisitor.cs @@ -24,7 +24,7 @@ internal class MetadataVisitor : ExpressionVisitor private MetadataVisitor() { } - static internal Dictionary GatherMetadata(Expression expression) + static internal Dictionary? GatherMetadata(Expression expression) { if (expression == null) throw new ArgumentException("expression"); @@ -572,19 +572,16 @@ protected override Expression VisitBinary(BinaryExpression b) { var right = Visit(b.Right); var left = Visit(b.Left); - - var mRight = right as MetaExpression; - var mLeft = left as MetaExpression; - + Implementations? imps = - mRight != null && mRight.Meta.Implementations != null && - mLeft != null && mLeft.Meta.Implementations != null ? + right is MetaExpression mRight && mRight.Meta.Implementations != null && + left is MetaExpression mLeft && mLeft.Meta.Implementations != null ? AggregateImplementations(new[] { mRight.Meta.Implementations.Value, mLeft.Meta.Implementations.Value }) : (Implementations?)null; - return MakeDirtyMeta(b.Type, imps, left, right); + return MakeDirtyMeta(b.Type, imps, left!, right!); /*CSBUG*/ } protected override Expression VisitConditional(ConditionalExpression c) @@ -592,18 +589,16 @@ protected override Expression VisitConditional(ConditionalExpression c) var ifTrue = Visit(c.IfTrue); var ifFalse = Visit(c.IfFalse); - var mIfTrue = ifTrue as MetaExpression; - var mIfFalse = ifFalse as MetaExpression; Implementations? imps = - mIfTrue != null && mIfTrue.Meta.Implementations != null && - mIfFalse != null && mIfFalse.Meta.Implementations != null ? + ifTrue is MetaExpression mIfTrue && mIfTrue.Meta.Implementations != null && + ifFalse is MetaExpression mIfFalse && mIfFalse.Meta.Implementations != null ? AggregateImplementations(new[] { mIfTrue.Meta.Implementations.Value, mIfFalse.Meta.Implementations.Value }) : (Implementations?)null; - return MakeDirtyMeta(c.Type, imps, Visit(c.Test), ifTrue, ifFalse); + return MakeDirtyMeta(c.Type, imps, Visit(c.Test), ifTrue!, ifFalse!); /*CSBUG*/ } } } From c8a0be6defa949025eb479efb545e3a86215ef8b Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Sat, 26 Jan 2019 10:50:04 +0100 Subject: [PATCH 11/25] Signum.Engine not nullable --- Signum.Engine/Basics/PropertyRouteLogic.cs | 8 +-- Signum.Engine/Basics/QueryLogic.cs | 8 +-- Signum.Engine/Basics/SemiSymbolLogic.cs | 16 ++--- Signum.Engine/Basics/SymbolLogic.cs | 10 ++-- Signum.Engine/CodeGeneration/CodeGenerator.cs | 2 +- .../CodeGeneration/ReactCodeGenerator.cs | 31 +++++----- Signum.Engine/Connection/SqlConnector.cs | 8 +-- Signum.Engine/Database.cs | 16 ++--- .../DynamicQuery/ExpressionContainer.cs | 4 +- Signum.Engine/Engine/Saver.cs | 2 +- Signum.Engine/Engine/SchemaGenerator.cs | 34 +++++------ Signum.Engine/Engine/SchemaSynchronizer.cs | 4 +- Signum.Engine/Engine/SqlBuilder.cs | 6 +- Signum.Engine/Engine/SqlUtils.cs | 8 +-- Signum.Engine/Linq/DbExpressions.Signum.cs | 4 +- .../DbExpressionNominator.cs | 2 +- .../OverloadingSimplifier.cs | 6 +- .../Linq/ExpressionVisitor/QueryFilterer.cs | 10 ++-- .../Linq/ExpressionVisitor/QueryFormatter.cs | 4 +- .../Linq/ExpressionVisitor/QueryRebinder.cs | 18 +++--- .../RedundantSubqueryRemover.cs | 38 ++++++------ .../Linq/ExpressionVisitor/SmartEqualizer.cs | 58 +++++++++---------- .../ExpressionVisitor/UnusedColumnRemover.cs | 12 ++-- Signum.Engine/Linq/Meta/MetaExpression.cs | 4 +- Signum.Engine/Linq/Meta/MetadataVisitor.cs | 10 ++-- Signum.Engine/Linq/ProjectionReader.cs | 15 ++--- Signum.Engine/Patterns/VirtualMList.cs | 8 +-- Signum.Engine/Schema/Schema.Basics.cs | 4 +- Signum.Engine/Schema/Schema.Delete.cs | 6 +- Signum.Engine/Schema/Schema.Save.cs | 14 ++--- Signum.Engine/Schema/Schema.cs | 4 +- Signum.Engine/Schema/SchemaAssets.cs | 55 +++++++++--------- .../Schema/SchemaBuilder/SchemaBuilder.cs | 8 +-- .../SchemaBuilder/SchemaBuilderSettings.cs | 2 +- Signum.Engine/Schema/UniqueIndex.cs | 20 ++++--- Signum.Engine/Signum.Engine.csproj | 6 +- Signum.Entities/Basics/OperationLog.cs | 2 + Signum.Entities/DynamicQuery/QueryUtils.cs | 2 +- .../DynamicQuery/Tokens/NetPropertyToken.cs | 4 +- Signum.Entities/MList.cs | 2 +- Signum.Entities/ModifiableEntity.cs | 2 + Signum.Entities/ObjectDumper.cs | 6 +- .../EntityStructuralEqualityComparer.cs | 4 +- Signum.Entities/Reflection/GraphExplorer.cs | 4 +- Signum.Entities/Reflection/Reflector.cs | 2 +- Signum.Entities/Signum.Entities.csproj | 6 +- Signum.Utilities/ConsoleSwitch.cs | 8 ++- .../DataStructures/ImmutableStack.cs | 3 - .../IntervalDictionaries/Interval.cs | 2 + .../IntervalDictionary.cs | 11 +++- .../ExpressionTrees/CSharpRenderer.cs | 5 +- Signum.Utilities/ExpressionTrees/Query.cs | 2 +- .../QueryableAsyncExtensions.cs | 2 +- Signum.Utilities/Extensions/Extensions.cs | 2 +- .../Extensions/ReflectionExtensions.cs | 2 +- .../Extensions/StringExtensions.cs | 13 ++--- Signum.Utilities/Polymorphic.cs | 10 ++++ Signum.Utilities/Profiler/HeavyProfiler.cs | 2 +- .../Reflection/ReflectionTools.cs | 10 ++-- Signum.Utilities/Signum.Utilities.csproj | 2 +- Signum.Utilities/Statics.cs | 33 +++++------ .../Synchronization/CultureInfoUtils.cs | 2 +- Signum.Utilities/Synchronization/ResetLazy.cs | 2 +- 63 files changed, 310 insertions(+), 300 deletions(-) diff --git a/Signum.Engine/Basics/PropertyRouteLogic.cs b/Signum.Engine/Basics/PropertyRouteLogic.cs index 59e54621d9..40acbd3fb7 100644 --- a/Signum.Engine/Basics/PropertyRouteLogic.cs +++ b/Signum.Engine/Basics/PropertyRouteLogic.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Signum.Entities.Basics; @@ -40,7 +40,7 @@ public static void Start(SchemaBuilder sb) } } - private static SqlPreCommand PropertyRouteLogic_PreDeleteSqlSync(Entity arg) + private static SqlPreCommand? PropertyRouteLogic_PreDeleteSqlSync(Entity arg) { Table table = Schema.Current.Table(); @@ -51,13 +51,13 @@ private static SqlPreCommand PropertyRouteLogic_PreDeleteSqlSync(Entity arg) return prs.Select(pr => table.DeleteSqlSync(pr, p => p.RootType.CleanName == pr.RootType.CleanName && p.Path == pr.Path)).Combine(Spacing.Simple); } - public static PropertyRouteEntity TryGetPropertyRouteEntity(TypeEntity entity, string path) + public static PropertyRouteEntity? TryGetPropertyRouteEntity(TypeEntity entity, string path) { return Properties.Value.TryGetC(entity)?.TryGetC(path); } public const string PropertiesFor = "Properties For:{0}"; - static SqlPreCommand SynchronizeProperties(Replacements rep) + static SqlPreCommand? SynchronizeProperties(Replacements rep) { var current = Administrator.TryRetrieveAll(rep).AgGroupToDictionary(a => a.RootType.CleanName, g => g.ToDictionaryEx(f => f.Path, "PropertyEntity in the database with path")); diff --git a/Signum.Engine/Basics/QueryLogic.cs b/Signum.Engine/Basics/QueryLogic.cs index 098bd87b52..4968ad0d97 100644 --- a/Signum.Engine/Basics/QueryLogic.cs +++ b/Signum.Engine/Basics/QueryLogic.cs @@ -104,7 +104,7 @@ public static object ToQueryName(string queryKey) return QueryNames.GetOrThrow(queryKey, "QueryName with unique name {0} not found"); } - public static object TryToQueryName(string queryKey) + public static object? TryToQueryName(string queryKey) { return QueryNames.TryGetC(queryKey); } @@ -133,17 +133,17 @@ public static List GetTypeQueries(TypeEntity typeEntity) public const string QueriesKey = "Queries"; - static SqlPreCommand Schema_Generating() + static SqlPreCommand? Schema_Generating() { Table table = Schema.Current.Table(); var should = GenerateQueries(); - return should.Select((q, i) => table.InsertSqlSync(q, suffix: i.ToString())).Combine(Spacing.Simple).PlainSqlCommand(); + return should.Select((q, i) => table.InsertSqlSync(q, suffix: i.ToString())).Combine(Spacing.Simple)?.PlainSqlCommand(); } - static SqlPreCommand SynchronizeQueries(Replacements replacements) + static SqlPreCommand? SynchronizeQueries(Replacements replacements) { var should = GenerateQueries(); diff --git a/Signum.Engine/Basics/SemiSymbolLogic.cs b/Signum.Engine/Basics/SemiSymbolLogic.cs index 94bc4cede0..63c5a73c71 100644 --- a/Signum.Engine/Basics/SemiSymbolLogic.cs +++ b/Signum.Engine/Basics/SemiSymbolLogic.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Signum.Engine.Maps; @@ -49,8 +49,8 @@ public static void Start(SchemaBuilder sb, Func> getSemiSymbols) (c, s) => { s.SetIdAndProps(c); return s; }, "caching " + typeof(T).Name); - SemiSymbol.SetFromDatabase(current.ToDictionary(a => a.Key)); - return result.ToDictionary(a => a.Key); + SemiSymbol.SetFromDatabase(current.ToDictionary(a => a.Key!)); + return result.ToDictionary(a => a.Key!); } }, new InvalidateWith(typeof(T)), @@ -74,7 +74,7 @@ static void SymbolLogic_Retrieved(T ident) } } - static SqlPreCommand Schema_Generating() + static SqlPreCommand? Schema_Generating() { Table table = Schema.Current.Table(); @@ -89,12 +89,12 @@ private static IEnumerable CreateSemiSymbols() using (CultureInfoUtils.ChangeCulture(Schema.Current.ForceCultureInfo)) foreach (var item in should) - item.Name = item.NiceToString(); + item.Name = item.NiceToString()!; return should; } - static SqlPreCommand Schema_Synchronizing(Replacements replacements) + static SqlPreCommand? Schema_Synchronizing(Replacements replacements) { Table table = Schema.Current.Table(); @@ -103,8 +103,8 @@ static SqlPreCommand Schema_Synchronizing(Replacements replacements) using (replacements.WithReplacedDatabaseName()) return Synchronizer.SynchronizeScriptReplacing(replacements, typeof(T).Name, Spacing.Double, - should.ToDictionary(s => s.Key), - current.Where(c => c.Key.HasText()).ToDictionary(c => c.Key), + should.ToDictionary(s => s.Key!), + current.Where(c => c.Key.HasText()).ToDictionary(c => c.Key!), createNew: (k, s) => table.InsertSqlSync(s), removeOld: (k, c) => table.DeleteSqlSync(c, s => s.Key == c.Key), mergeBoth: (k, s, c) => diff --git a/Signum.Engine/Basics/SymbolLogic.cs b/Signum.Engine/Basics/SymbolLogic.cs index 29d3528939..ee27736c57 100644 --- a/Signum.Engine/Basics/SymbolLogic.cs +++ b/Signum.Engine/Basics/SymbolLogic.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Signum.Engine.Maps; @@ -93,16 +93,16 @@ static void SymbolLogic_Retrieved(T ident) } } - static SqlPreCommand Schema_Generating() + static SqlPreCommand? Schema_Generating() { Table table = Schema.Current.Table(); IEnumerable should = getSymbols(); - return should.Select((a, i) => table.InsertSqlSync(a, suffix: i.ToString())).Combine(Spacing.Simple).PlainSqlCommand(); + return should.Select((a, i) => table.InsertSqlSync(a, suffix: i.ToString())).Combine(Spacing.Simple)?.PlainSqlCommand(); } - static SqlPreCommand Schema_Synchronizing(Replacements replacements) + static SqlPreCommand? Schema_Synchronizing(Replacements replacements) { Table table = Schema.Current.Table(); @@ -136,7 +136,7 @@ public static ICollection Symbols get { return AssertStarted().Values; } } - public static T TryToSymbol(string key) + public static T? TryToSymbol(string key) { return AssertStarted().TryGetC(key); } diff --git a/Signum.Engine/CodeGeneration/CodeGenerator.cs b/Signum.Engine/CodeGeneration/CodeGenerator.cs index c97c2e15cf..5f9535fb4e 100644 --- a/Signum.Engine/CodeGeneration/CodeGenerator.cs +++ b/Signum.Engine/CodeGeneration/CodeGenerator.cs @@ -63,7 +63,7 @@ public static IEnumerable GetModules(Dictionary types, strin if (selected.IsNullOrEmpty()) yield break; - string? moduleName = GetDefaultModuleName(selected, solutionName); + string moduleName = GetDefaultModuleName(selected, solutionName)!; SafeConsole.WriteColor(ConsoleColor.Gray, $"Module name? ([Enter] for '{moduleName}'):"); moduleName = Console.ReadLine().DefaultText(moduleName!); diff --git a/Signum.Engine/CodeGeneration/ReactCodeGenerator.cs b/Signum.Engine/CodeGeneration/ReactCodeGenerator.cs index 0417aa19d6..69e1b04433 100644 --- a/Signum.Engine/CodeGeneration/ReactCodeGenerator.cs +++ b/Signum.Engine/CodeGeneration/ReactCodeGenerator.cs @@ -15,10 +15,10 @@ namespace Signum.Engine.CodeGeneration { public class ReactCodeGenerator { - public string SolutionName; - public string SolutionFolder; + public string SolutionName = null!; + public string SolutionFolder = null!; - public Schema CurrentSchema; + public Schema CurrentSchema = null!; public virtual void GenerateReactFromEntities() { @@ -73,7 +73,7 @@ public virtual void GenerateReactFromEntities() } } - protected virtual void WriteFile(Func getContent, Func getFileName, ref bool? overwriteFiles) + protected virtual void WriteFile(Func getContent, Func getFileName, ref bool? overwriteFiles) { var content = getContent(); if (content == null) @@ -82,7 +82,6 @@ protected virtual void WriteFile(Func getContent, Func getFileNa var fileName = getFileName(); - FileTools.CreateParentDirectory(fileName); if (!File.Exists(fileName) || SafeConsole.Ask(ref overwriteFiles, "Overwrite {0}?".FormatWith(fileName))) File.WriteAllText(fileName, content, Encoding.UTF8); @@ -150,7 +149,7 @@ public IEnumerable ReactGetModules(Dictionary types, string var directories = Directory.GetDirectories(GetProjectFolder(), "App\\").Select(a => Path.GetFileName(a)); - string moduleName; + string? moduleName; if (directories.IsEmpty()) { moduleName = AskModuleName(solutionName, selectedTypes); @@ -168,11 +167,7 @@ public IEnumerable ReactGetModules(Dictionary types, string if (!moduleName.HasText()) yield break; - yield return new Module - { - ModuleName = moduleName, - Types = selectedTypes.ToList() - }; + yield return new Module(moduleName, selectedTypes.ToList()); types.SetRange(selectedTypes, a => a, a => true); } @@ -181,10 +176,10 @@ public IEnumerable ReactGetModules(Dictionary types, string private static string AskModuleName(string solutionName, Type[] selected) { - string moduleName = CodeGenerator.GetDefaultModuleName(selected, solutionName); + string? moduleName = CodeGenerator.GetDefaultModuleName(selected, solutionName); SafeConsole.WriteColor(ConsoleColor.Gray, $"Module name? ([Enter] for '{moduleName}'):"); - moduleName = Console.ReadLine().DefaultText(moduleName); + moduleName = Console.ReadLine().DefaultText(moduleName!); return moduleName; } @@ -195,7 +190,7 @@ protected virtual List CandidateTypes() return assembly.GetTypes().Where(t => t.IsModifiableEntity() && !t.IsAbstract && !typeof(MixinEntity).IsAssignableFrom(t)).ToList(); } - protected virtual string WriteServerFile(Module mod) + protected virtual string? WriteServerFile(Module mod) { if (!ShouldWriteServerFile(mod)) return null; @@ -248,7 +243,7 @@ protected virtual string WriteServerStartMethod(Module mod) } - protected virtual string WriteControllerFile(Module mod) + protected virtual string? WriteControllerFile(Module mod) { if (!ShouldWriteControllerFile(mod)) return null; @@ -434,7 +429,7 @@ protected virtual string WriteEntityComponentFile(Type type) foreach (var pi in GetProperties(type)) { - string prop = WriteProperty(pi, v); + string? prop = WriteProperty(pi, v); if (prop != null) sb.AppendLine(prop.Indent(8)); } @@ -447,7 +442,7 @@ protected virtual string WriteEntityComponentFile(Type type) return sb.ToString(); } - protected virtual string WriteProperty(PropertyInfo pi, string v) + protected virtual string? WriteProperty(PropertyInfo pi, string v) { if (pi.PropertyType.IsLite() || pi.PropertyType.IsIEntity()) return WriteEntityProperty(pi, v); @@ -466,7 +461,7 @@ protected virtual string WriteProperty(PropertyInfo pi, string v) protected virtual string WriteMListProperty(PropertyInfo pi, string v) { - var elementType = pi.PropertyType.ElementType().CleanType(); + var elementType = pi.PropertyType.ElementType()!.CleanType(); if (!(elementType.IsLite() || elementType.IsModifiableEntity())) return $"{{ /* {pi.PropertyType.TypeName()} not supported */ }}"; diff --git a/Signum.Engine/Connection/SqlConnector.cs b/Signum.Engine/Connection/SqlConnector.cs index e8293c8003..cb7dbfaf8e 100644 --- a/Signum.Engine/Connection/SqlConnector.cs +++ b/Signum.Engine/Connection/SqlConnector.cs @@ -134,8 +134,8 @@ SqlCommand NewCommand(SqlPreCommandSimple preCommand, SqlConnection? overridenCo cmd.Connection = overridenConnection; else { - cmd.Connection = (SqlConnection)Transaction.CurrentConnection; - cmd.Transaction = (SqlTransaction)Transaction.CurrentTransaccion; + cmd.Connection = (SqlConnection)Transaction.CurrentConnection!; + cmd.Transaction = (SqlTransaction)Transaction.CurrentTransaccion!; } cmd.CommandText = preCommand.Sql; @@ -394,9 +394,9 @@ protected internal override void BulkCopy(DataTable dt, ObjectName destinationTa { using (SqlConnection? con = EnsureConnection()) using (SqlBulkCopy bulkCopy = new SqlBulkCopy( - options.HasFlag(SqlBulkCopyOptions.UseInternalTransaction) ? con : (SqlConnection)Transaction.CurrentConnection, + options.HasFlag(SqlBulkCopyOptions.UseInternalTransaction) ? con : (SqlConnection)Transaction.CurrentConnection!, options, - options.HasFlag(SqlBulkCopyOptions.UseInternalTransaction) ? null : (SqlTransaction)Transaction.CurrentTransaccion)) + options.HasFlag(SqlBulkCopyOptions.UseInternalTransaction) ? null : (SqlTransaction)Transaction.CurrentTransaccion!)) using (HeavyProfiler.Log("SQL", () => destinationTable.ToString() + " Rows:" + dt.Rows.Count)) { bulkCopy.BulkCopyTimeout = timeout ?? Connector.ScopeTimeout ?? this.CommandTimeout ?? bulkCopy.BulkCopyTimeout; diff --git a/Signum.Engine/Database.cs b/Signum.Engine/Database.cs index 46b0419365..3f2e460981 100644 --- a/Signum.Engine/Database.cs +++ b/Signum.Engine/Database.cs @@ -123,7 +123,7 @@ public static T Retrieve(PrimaryKey id) where T : Entity { if (EntityCache.Created) { - T cached = EntityCache.Get(id); + T? cached = EntityCache.Get(id); if (cached != null) return cached; @@ -143,7 +143,7 @@ public static T Retrieve(PrimaryKey id) where T : Entity using (new EntityCache()) using (var r = EntityCache.NewRetriever()) { - result = r.Request(id); + result = r.Request(id)!; r.CompleteAll(); } @@ -171,7 +171,7 @@ public static async Task RetrieveAsync(PrimaryKey id, CancellationToken to { if (EntityCache.Created) { - T cached = EntityCache.Get(id); + T? cached = EntityCache.Get(id); if (cached != null) return cached; @@ -191,7 +191,7 @@ public static async Task RetrieveAsync(PrimaryKey id, CancellationToken to using (new EntityCache()) using (var r = EntityCache.NewRetriever()) { - result = r.Request(id); + result = r.Request(id)!; await r.CompleteAllAsync(token); } @@ -471,7 +471,7 @@ public static List RetrieveAll() using (new EntityCache()) using (var r = EntityCache.NewRetriever()) { - result = cc.GetAllIds().Select(id => r.Request(id)).ToList(); + result = cc.GetAllIds().Select(id => r.Request(id)!).ToList(); r.CompleteAll(); } @@ -510,7 +510,7 @@ public static async Task> RetrieveAllAsync(CancellationToken token) using (new EntityCache()) using (var r = EntityCache.NewRetriever()) { - result = cc.GetAllIds().Select(id => r.Request(id)).ToList(); + result = cc.GetAllIds().Select(id => r.Request(id)!).ToList(); await r.CompleteAllAsync(token); } @@ -687,7 +687,7 @@ static List RetrieveFromDatabaseOrCache(List ids, string? mess using (new EntityCache()) using (var rr = EntityCache.NewRetriever()) { - result = ids.Select(id => rr.Request(id)).ToList(); + result = ids.Select(id => rr.Request(id)!).ToList(); rr.CompleteAll(); } @@ -781,7 +781,7 @@ static async Task> RetrieveFromDatabaseOrCache(List ids, using (new EntityCache()) using (var rr = EntityCache.NewRetriever()) { - result = ids.Select(id => rr.Request(id)).ToList(); + result = ids.Select(id => rr.Request(id)!).ToList(); await rr.CompleteAllAsync(token); } diff --git a/Signum.Engine/DynamicQuery/ExpressionContainer.cs b/Signum.Engine/DynamicQuery/ExpressionContainer.cs index 91dd05e6e9..b1b14776bf 100644 --- a/Signum.Engine/DynamicQuery/ExpressionContainer.cs +++ b/Signum.Engine/DynamicQuery/ExpressionContainer.cs @@ -212,7 +212,7 @@ public IEnumerable GetAllTokens(QueryToken parent) var cleanType = me!.Type.CleanType(); result.PropertyRoute = cm.PropertyRoutes.Only(); - result.Implementations = me!.Meta.Implementations; + result.Implementations = me.Meta.Implementations; result.Format = ColumnDescriptionFactory.GetFormat(cm.PropertyRoutes); result.Unit = ColumnDescriptionFactory.GetUnit(cm.PropertyRoutes); } @@ -301,7 +301,7 @@ protected internal virtual ExtensionToken CreateToken(QueryToken parent) result.Unit = dirtyMeta.CleanMetas.Select(cm => ColumnDescriptionFactory.GetUnit(cm.PropertyRoutes)).Distinct().Only(); } - result.IsAllowed = () => (me == null || me.Meta == null) ? null : me.Meta.IsAllowed(); + result.IsAllowed = () => me?.Meta.IsAllowed(); if (ForcePropertyRoute != null) result.PropertyRoute = ForcePropertyRoute!; diff --git a/Signum.Engine/Engine/Saver.cs b/Signum.Engine/Engine/Saver.cs index f71de66bd7..0581eeb4a6 100644 --- a/Signum.Engine/Engine/Saver.cs +++ b/Signum.Engine/Engine/Saver.cs @@ -83,7 +83,7 @@ public static void Save(Entity[] entities) private static void SaveGraph(Schema schema, DirectedGraph identifiables) { //takes apart the 'forbidden' connections from the good ones - DirectedGraph backEdges = identifiables.FeedbackEdgeSet(); + DirectedGraph? backEdges = identifiables.FeedbackEdgeSet(); if (backEdges.IsEmpty()) backEdges = null; diff --git a/Signum.Engine/Engine/SchemaGenerator.cs b/Signum.Engine/Engine/SchemaGenerator.cs index 14c2774e32..ee89dc8b45 100644 --- a/Signum.Engine/Engine/SchemaGenerator.cs +++ b/Signum.Engine/Engine/SchemaGenerator.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using Signum.Engine.Maps; using Signum.Utilities; @@ -9,7 +9,7 @@ namespace Signum.Engine { public static class SchemaGenerator { - public static SqlPreCommand CreateSchemasScript() + public static SqlPreCommand? CreateSchemasScript() { Schema s = Schema.Current; @@ -21,16 +21,16 @@ public static SqlPreCommand CreateSchemasScript() .Combine(Spacing.Simple); } - public static SqlPreCommand CreateTablesScript() + public static SqlPreCommand? CreateTablesScript() { Schema s = Schema.Current; List tables = s.GetDatabaseTables().Where(t => !s.IsExternalDatabase(t.Name.Schema.Database)).ToList(); - SqlPreCommand createTables = tables.Select(SqlBuilder.CreateTableSql).Combine(Spacing.Double).PlainSqlCommand(); + SqlPreCommand? createTables = tables.Select(SqlBuilder.CreateTableSql).Combine(Spacing.Double)?.PlainSqlCommand(); - SqlPreCommand foreignKeys = tables.Select(SqlBuilder.AlterTableForeignKeys).Combine(Spacing.Double).PlainSqlCommand(); + SqlPreCommand? foreignKeys = tables.Select(SqlBuilder.AlterTableForeignKeys).Combine(Spacing.Double)?.PlainSqlCommand(); - SqlPreCommand indices = tables.Select(t => + SqlPreCommand? indices = tables.Select(t => { var allIndexes = t.GeneratAllIndexes().Where(a => !(a is PrimaryClusteredIndex)); ; @@ -41,23 +41,23 @@ public static SqlPreCommand CreateTablesScript() return SqlPreCommand.Combine(Spacing.Double, mainIndices, historyIndices); - }).NotNull().Combine(Spacing.Double).PlainSqlCommand(); + }).NotNull().Combine(Spacing.Double)?.PlainSqlCommand(); return SqlPreCommand.Combine(Spacing.Triple, createTables, foreignKeys, indices); } - public static SqlPreCommand InsertEnumValuesScript() + public static SqlPreCommand? InsertEnumValuesScript() { return (from t in Schema.Current.Tables.Values let enumType = EnumEntity.Extract(t.Type) where enumType != null select EnumEntity.GetEntities(enumType).Select((e, i) => t.InsertSqlSync(e, suffix: t.Name.Name + i)).Combine(Spacing.Simple) - ).Combine(Spacing.Double).PlainSqlCommand(); + ).Combine(Spacing.Double)?.PlainSqlCommand(); } - public static SqlPreCommand SnapshotIsolation() + public static SqlPreCommand? SnapshotIsolation() { if (!Connector.Current.AllowsSetSnapshotIsolation) return null; @@ -71,13 +71,13 @@ public static SqlPreCommand SnapshotIsolation() list.Add(Connector.Current.DatabaseName()); } - var cmd = list + var cmd = list.NotNull() .Where(db => !SnapshotIsolationEnabled(db)) - .Select(a => SqlPreCommand.Combine(Spacing.Simple, - SqlBuilder.SetSingleUser(a), - SqlBuilder.SetSnapshotIsolation(a, true), - SqlBuilder.MakeSnapshotIsolationDefault(a, true), - SqlBuilder.SetMultiUser(a)) + .Select(db => SqlPreCommand.Combine(Spacing.Simple, + SqlBuilder.SetSingleUser(db), + SqlBuilder.SetSnapshotIsolation(db, true), + SqlBuilder.MakeSnapshotIsolationDefault(db, true), + SqlBuilder.SetMultiUser(db)) ).Combine(Spacing.Double); return cmd; @@ -90,4 +90,4 @@ private static bool SnapshotIsolationEnabled(string dbName) return result; } } -} \ No newline at end of file +} diff --git a/Signum.Engine/Engine/SchemaSynchronizer.cs b/Signum.Engine/Engine/SchemaSynchronizer.cs index 6d5cf261ba..d132c09c00 100644 --- a/Signum.Engine/Engine/SchemaSynchronizer.cs +++ b/Signum.Engine/Engine/SchemaSynchronizer.cs @@ -1055,7 +1055,7 @@ bool ColumnsChanged(DiffTable dif, Index mix) return true; } - private static bool IdenticalColumns(DiffTable dif, IColumn[] modColumns, List diffColumns) + private static bool IdenticalColumns(DiffTable dif, IColumn[]? modColumns, List diffColumns) { if ((modColumns?.Length ?? 0) != diffColumns.Count) return false; @@ -1065,7 +1065,7 @@ private static bool IdenticalColumns(DiffTable dif, IColumn[] modColumns, List dif.Columns.Values.SingleOrDefault(dc => dc.Name == cn.ColumnName)).ToList(); //Ny old name - var perfect = difColumns.ZipOrDefault(modColumns, (dc, mc) => dc != null && mc != null && dc.ColumnEquals(mc, ignorePrimaryKey: true, ignoreIdentity: true, ignoreGenerateAlways: true)).All(a => a); + var perfect = difColumns.ZipOrDefault(modColumns!, (dc, mc) => dc != null && mc != null && dc.ColumnEquals(mc, ignorePrimaryKey: true, ignoreIdentity: true, ignoreGenerateAlways: true)).All(a => a); return perfect; } diff --git a/Signum.Engine/Engine/SqlBuilder.cs b/Signum.Engine/Engine/SqlBuilder.cs index b126814b58..c132db966b 100644 --- a/Signum.Engine/Engine/SqlBuilder.cs +++ b/Signum.Engine/Engine/SqlBuilder.cs @@ -80,7 +80,7 @@ static SqlPreCommand DropViewIndex(ObjectName viewName, string index) public static SqlPreCommand AlterTableAddPeriod(ITable table) { - return new SqlPreCommandSimple($"ALTER TABLE {table.Name} ADD {Period(table.SystemVersioned)}"); + return new SqlPreCommandSimple($"ALTER TABLE {table.Name} ADD {Period(table.SystemVersioned!)}"); } static string Period(SystemVersionedInfo sv) { @@ -98,7 +98,7 @@ public static SqlPreCommand AlterTableDropPeriod(ITable table) public static SqlPreCommand AlterTableEnableSystemVersioning(ITable table) { - return new SqlPreCommandSimple($"ALTER TABLE {table.Name} SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = {table.SystemVersioned.TableName}))"); + return new SqlPreCommandSimple($"ALTER TABLE {table.Name} SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = {table.SystemVersioned!.TableName}))"); } public static SqlPreCommand AlterTableDisableSystemVersioning(ObjectName tableName) @@ -401,7 +401,7 @@ public static SqlPreCommand CreateIndexBasic(Index index, bool forHistoryTable) var include = index.IncludeColumns.HasItems() ? $" INCLUDE ({index.IncludeColumns.ToString(c => c.Name.SqlEscape(), ", ")})" : null; var where = index.Where.HasText() ? $" WHERE {index.Where}" : ""; - var tableName = forHistoryTable ? index.Table.SystemVersioned.TableName : index.Table.Name; + var tableName = forHistoryTable ? index.Table.SystemVersioned!.TableName : index.Table.Name; return new SqlPreCommandSimple($"CREATE {indexType} {index.IndexName} ON {tableName}({columns}){include}{where}"); } diff --git a/Signum.Engine/Engine/SqlUtils.cs b/Signum.Engine/Engine/SqlUtils.cs index e36fc5e2bb..337e8d1781 100644 --- a/Signum.Engine/Engine/SqlUtils.cs +++ b/Signum.Engine/Engine/SqlUtils.cs @@ -218,7 +218,7 @@ public static string SqlEscape(this string ident) return ident; } - public static SqlPreCommand RemoveDuplicatedIndices() + public static SqlPreCommand? RemoveDuplicatedIndices() { var plainData = (from s in Database.View() from t in s.Tables() @@ -238,7 +238,7 @@ from c in t.Columns() }).ToList(); var tables = plainData.AgGroupToDictionary(a => a.table, - gr => gr.AgGroupToDictionary(a => new { a.index, a.is_unique }, + gr => gr.AgGroupToDictionary(a => new { a.index, a.is_unique }, gr2 => gr2.OrderBy(a => a.index_column_id) .Select(a => a.column + (a.is_included_column ? "(K)" : "(I)") + (a.is_descending_key ? "(D)" : "(A)")) .ToString("|"))); @@ -248,10 +248,10 @@ from c in t.Columns() .Where(gr => gr.Count() > 1) .Select(gr => { - var best = gr.OrderByDescending(a => a.is_unique).ThenByDescending(a => a.index.StartsWith("IX")).ThenByDescending(a => a.index).First(); + var best = gr.OrderByDescending(a => a.is_unique).ThenByDescending(a => a.index!/*CSBUG*/.StartsWith("IX")).ThenByDescending(a => a.index).First(); return gr.Where(g => g != best) - .Select(g => SqlBuilder.DropIndex(t.Key, g.index)) + .Select(g => SqlBuilder.DropIndex(t.Key!, g.index!)) .PreAnd(new SqlPreCommandSimple("-- DUPLICATIONS OF {0}".FormatWith(best.index))).Combine(Spacing.Simple); }) ).Combine(Spacing.Double); diff --git a/Signum.Engine/Linq/DbExpressions.Signum.cs b/Signum.Engine/Linq/DbExpressions.Signum.cs index 74ba5e50f7..ff5155f762 100644 --- a/Signum.Engine/Linq/DbExpressions.Signum.cs +++ b/Signum.Engine/Linq/DbExpressions.Signum.cs @@ -454,10 +454,10 @@ protected override Expression Accept(DbExpressionVisitor visitor) internal class AdditionalFieldExpression : DbExpression { public readonly PrimaryKeyExpression BackID; // not readonly - public readonly NewExpression ExternalPeriod; + public readonly NewExpression? ExternalPeriod; public readonly PropertyRoute Route; - public AdditionalFieldExpression(Type type, PrimaryKeyExpression backID, NewExpression externalPeriod, PropertyRoute route) + public AdditionalFieldExpression(Type type, PrimaryKeyExpression backID, NewExpression? externalPeriod, PropertyRoute route) : base(DbExpressionType.AdditionalField, type) { this.BackID = backID; diff --git a/Signum.Engine/Linq/ExpressionVisitor/DbExpressionNominator.cs b/Signum.Engine/Linq/ExpressionVisitor/DbExpressionNominator.cs index 062692a671..e168f98f94 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/DbExpressionNominator.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/DbExpressionNominator.cs @@ -41,7 +41,7 @@ internal class DbExpressionNominator : DbExpressionVisitor T Add(T expression) where T : Expression? { if (expression == null) - return null; + return null!; this.candidates.Add(expression); return expression; diff --git a/Signum.Engine/Linq/ExpressionVisitor/OverloadingSimplifier.cs b/Signum.Engine/Linq/ExpressionVisitor/OverloadingSimplifier.cs index e9aee96131..e1eb73d666 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/OverloadingSimplifier.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/OverloadingSimplifier.cs @@ -248,7 +248,7 @@ protected override Expression VisitMethodCall(MethodCallExpression m) { var source = Visit(m.GetArgument("source")); - Type elemType = source.Type.ElementType(); + Type elemType = source.Type.ElementType()!; ParameterExpression pe = Expression.Parameter(elemType); @@ -261,7 +261,7 @@ protected override Expression VisitMethodCall(MethodCallExpression m) { var source = Visit(m.GetArgument("source")); - Type elemType = source.Type.ElementType(); + Type elemType = source.Type.ElementType()!; ParameterExpression pe = Expression.Parameter(elemType); @@ -279,7 +279,7 @@ protected override Expression VisitMethodCall(MethodCallExpression m) if (mi.Name.Contains("Last")) { var source = Visit(m.GetArgument("source")); - var predicate = (LambdaExpression)Visit(m.TryGetArgument("predicate").StripQuotes()); + var predicate = (LambdaExpression)Visit(m.TryGetArgument("predicate")?.StripQuotes()); Expression reverse = Expression.Call((query ? miReverseQ : miReverseE).MakeGenericMethod(paramTypes[0]), source); diff --git a/Signum.Engine/Linq/ExpressionVisitor/QueryFilterer.cs b/Signum.Engine/Linq/ExpressionVisitor/QueryFilterer.cs index 5d61ea352d..dce2404f94 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/QueryFilterer.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/QueryFilterer.cs @@ -39,8 +39,8 @@ protected override Expression VisitConstant(ConstantExpression c) if (rawFilter != null) { - Expression clean = ExpressionCleaner.Clean(rawFilter); - var cleanFilter = (LambdaExpression)OverloadingSimplifier.Simplify(clean); + Expression clean = ExpressionCleaner.Clean(rawFilter)!; + var cleanFilter = (LambdaExpression)OverloadingSimplifier.Simplify(clean)!; return Expression.Call(miWhere.MakeGenericMethod(queryType), query.Expression, cleanFilter); } @@ -56,8 +56,8 @@ protected override Expression VisitConstant(ConstantExpression c) var param = Expression.Parameter(queryType, "mle"); var lambda = Expression.Lambda(Expression.Invoke(rawFilter, Expression.Property(param, "Parent")), param); - Expression clean = ExpressionCleaner.Clean(lambda); - var cleanFilter = (LambdaExpression)OverloadingSimplifier.Simplify(clean); + Expression clean = ExpressionCleaner.Clean(lambda)!; + var cleanFilter = (LambdaExpression)OverloadingSimplifier.Simplify(clean)!; return Expression.Call(miWhere.MakeGenericMethod(queryType), query.Expression, cleanFilter); } @@ -71,7 +71,7 @@ protected override Expression VisitConstant(ConstantExpression c) /// /// Replaces every expression like ConstantExpression{ Type = IQueryable, Value = complexExpr } by complexExpr /// - return DbQueryProvider.Clean(query.Expression, filter, null); + return DbQueryProvider.Clean(query.Expression, filter, null)!; } } diff --git a/Signum.Engine/Linq/ExpressionVisitor/QueryFormatter.cs b/Signum.Engine/Linq/ExpressionVisitor/QueryFormatter.cs index c6c0c5aafb..51a76f2db7 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/QueryFormatter.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/QueryFormatter.cs @@ -316,7 +316,7 @@ protected internal override Expression VisitIn(InExpression inExpression) if (inExpression.Select == null) { bool any = false; - foreach (var obj in inExpression.Values) + foreach (var obj in inExpression.Values!) { VisitConstant(Expression.Constant(obj)); sb.Append(","); @@ -572,7 +572,7 @@ protected internal override Expression VisitSqlTableValuedFunction(SqlTableValue private void AppendColumn(ColumnDeclaration column) { - ColumnExpression c = column.Expression as ColumnExpression; + ColumnExpression? c = column.Expression as ColumnExpression; if (column.Name.HasText() && (c == null || c.Name != column.Name)) { diff --git a/Signum.Engine/Linq/ExpressionVisitor/QueryRebinder.cs b/Signum.Engine/Linq/ExpressionVisitor/QueryRebinder.cs index 398d6675a0..15909da986 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/QueryRebinder.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/QueryRebinder.cs @@ -11,7 +11,7 @@ namespace Signum.Engine.Linq { internal class QueryRebinder : DbExpressionVisitor { - ImmutableStack> scopes = ImmutableStack>.Empty; + ImmutableStack> scopes = ImmutableStack>.Empty; public Dictionary CurrentScope { get { return scopes.Peek(); } } @@ -185,7 +185,7 @@ protected internal override Expression VisitInsertSelect(InsertSelectExpression protected internal override Expression VisitSelect(SelectExpression select) { - Dictionary askedColumns = CurrentScope.Keys.Where(k => select.KnownAliases.Contains(k.Alias)).ToDictionary(k => k, k => (ColumnExpression)null); + Dictionary askedColumns = CurrentScope.Keys.Where(k => select.KnownAliases.Contains(k.Alias)).ToDictionary(k => k, k => (ColumnExpression?)null); Dictionary externalAnswers = CurrentScope.Where(kvp => !select.KnownAliases.Contains(kvp.Key.Alias) && kvp.Value != null).ToDictionary(); var disposable = NewScope();//SCOPE START @@ -261,11 +261,9 @@ private ReadOnlyCollection AnswerAndExpand(ReadOnlyCollection ColumnExpression? colExp = CurrentScope[col]; //if (expr is ColumnExpression colExp) //{ - ColumnDeclaration cd = cg.Columns.FirstOrDefault(c => c.Expression.Equals(colExp)); + ColumnDeclaration? cd = cg.Columns.FirstOrDefault(c => c!.Expression.Equals(colExp)); if (cd == null) - { - cd = cg.MapColumn(colExp); - } + cd = cg.MapColumn(colExp!); askedColumns[col] = new ColumnExpression(col.Type, currentAlias, cd.Name); //} @@ -278,20 +276,20 @@ private ReadOnlyCollection AnswerAndExpand(ReadOnlyCollection if (columns.Count != cg.Columns.Count()) - return cg.Columns.ToReadOnly(); + return cg.Columns.NotNull().ToReadOnly(); return columns; } public IDisposable NewScope() { - scopes = scopes.Push(new Dictionary()); + scopes = scopes.Push(new Dictionary()); return new Disposable(() => scopes = scopes.Pop()); } protected internal override Expression VisitColumn(ColumnExpression column) { - if (CurrentScope.TryGetValue(column, out ColumnExpression result)) + if (CurrentScope.TryGetValue(column, out ColumnExpression? result)) return result ?? column; else { @@ -302,7 +300,7 @@ protected internal override Expression VisitColumn(ColumnExpression column) protected internal override Expression VisitScalar(ScalarExpression scalar) { - var column = scalar.Select.Columns.SingleEx(); + var column = scalar.Select!.Columns.SingleEx(); VisitColumn(new ColumnExpression(scalar.Type, scalar.Select.Alias, column.Name ?? "-")); diff --git a/Signum.Engine/Linq/ExpressionVisitor/RedundantSubqueryRemover.cs b/Signum.Engine/Linq/ExpressionVisitor/RedundantSubqueryRemover.cs index 083f577f4d..53173dbd49 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/RedundantSubqueryRemover.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/RedundantSubqueryRemover.cs @@ -1,7 +1,8 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq.Expressions; using System.Collections.ObjectModel; using Signum.Utilities.ExpressionTrees; +using Signum.Utilities; namespace Signum.Engine.Linq { @@ -23,7 +24,7 @@ protected internal override Expression VisitSelect(SelectExpression select) select = (SelectExpression)base.VisitSelect(select); // first remove all purely redundant subqueries - List redundant = RedundantSubqueryGatherer.Gather(select.From); + List? redundant = RedundantSubqueryGatherer.Gather(select.From!); if (redundant != null) { select = (SelectExpression)SubqueryRemover.Remove(select, redundant); @@ -37,7 +38,7 @@ protected internal override Expression VisitProjection(ProjectionExpression proj proj = (ProjectionExpression)base.VisitProjection(proj); if (proj.Select.From is SelectExpression) { - List redundant = RedundantSubqueryGatherer.Gather(proj.Select); + List? redundant = RedundantSubqueryGatherer.Gather(proj.Select); if (redundant != null) { proj = (ProjectionExpression)SubqueryRemover.Remove(proj, redundant); @@ -50,7 +51,7 @@ internal static bool IsSimpleProjection(SelectExpression select) { foreach (ColumnDeclaration decl in select.Columns) { - ColumnExpression col = decl.Expression as ColumnExpression; + ColumnExpression? col = decl.Expression as ColumnExpression; if (col == null || decl.Name != col.Name) { return false; @@ -62,7 +63,7 @@ internal static bool IsSimpleProjection(SelectExpression select) internal static bool IsNameMapProjection(SelectExpression select) { if (select.From is TableExpression) return false; - SelectExpression fromSelect = select.From as SelectExpression; + SelectExpression? fromSelect = select.From as SelectExpression; if (fromSelect == null || select.Columns.Count != fromSelect.Columns.Count) return false; ReadOnlyCollection fromColumns = fromSelect.Columns; @@ -70,7 +71,7 @@ internal static bool IsNameMapProjection(SelectExpression select) // in from. for (int i = 0, n = select.Columns.Count; i < n; i++) { - ColumnExpression col = select.Columns[i].Expression as ColumnExpression; + ColumnExpression? col = select.Columns[i].Expression as ColumnExpression; if (col == null || !(col.Name == fromColumns[i].Name)) return false; } @@ -84,13 +85,9 @@ internal static bool IsInitialProjection(SelectExpression select) class RedundantSubqueryGatherer : DbExpressionVisitor { - List redundant; - - private RedundantSubqueryGatherer() - { - } - - internal static List Gather(Expression source) + List? redundant; + + internal static List? Gather(Expression source) { RedundantSubqueryGatherer gatherer = new RedundantSubqueryGatherer(); gatherer.Visit(source); @@ -163,13 +160,13 @@ protected internal override Expression VisitSelect(SelectExpression select) // logic except for the existence of a where clause while (CanMergeWithFrom(select, wasTopLevel)) { - SelectExpression fromSelect = GetLeftMostSelect(select.From); + SelectExpression? fromSelect = GetLeftMostSelect(select.From!); // remove the redundant subquery select = (SelectExpression)SubqueryRemover.Remove(select, new[] { fromSelect }); // merge where expressions - Expression where = select.Where; + Expression? where = select.Where; if (fromSelect.Where != null) { if (where != null) @@ -184,7 +181,7 @@ protected internal override Expression VisitSelect(SelectExpression select) var orderBy = select.OrderBy.Count > 0 ? select.OrderBy : fromSelect.OrderBy; var groupBy = select.GroupBy.Count > 0 ? select.GroupBy : fromSelect.GroupBy; //Expression skip = select.Skip != null ? select.Skip : fromSelect.Skip; - Expression top = select.Top != null ? select.Top : fromSelect.Top; + Expression? top = select.Top ?? fromSelect.Top; bool isDistinct = select.IsDistinct | fromSelect.IsDistinct; if (where != select.Where @@ -215,11 +212,13 @@ static bool IsColumnProjection(SelectExpression select) static bool CanMergeWithFrom(SelectExpression select, bool isTopLevel) { - SelectExpression fromSelect = GetLeftMostSelect(select.From); + SelectExpression? fromSelect = GetLeftMostSelect(select.From!); if (fromSelect == null) return false; + if (!IsColumnProjection(fromSelect)) return false; + bool selHasOrderBy = select.OrderBy.Count > 0; bool selHasGroupBy = select.GroupBy.Count > 0; @@ -243,7 +242,7 @@ static bool CanMergeWithFrom(SelectExpression select, bool isTopLevel) return false; // cannot move forward a take if outer has take or skip or distinct - if (fromSelect.Top != null && (select.Top != null || /*select.Skip != null ||*/ select.IsDistinct || selHasGroupBy || HasApplyJoin(select.From) || select.Where != null)) + if (fromSelect.Top != null && (select.Top != null || /*select.Skip != null ||*/ select.IsDistinct || selHasGroupBy || HasApplyJoin(select.From!) || select.Where != null)) return false; // cannot move forward a skip if outer has skip or distinct //if (fromSelect.Skip != null && (select.Skip != null || select.Distinct || selHasAggregates || selHasGroupBy)) @@ -261,7 +260,8 @@ static SelectExpression GetLeftMostSelect(Expression source) if (source is JoinExpression join) return GetLeftMostSelect(join.Left); - return null; + + throw new UnexpectedValueException(source); } static bool HasApplyJoin(SourceExpression source) diff --git a/Signum.Engine/Linq/ExpressionVisitor/SmartEqualizer.cs b/Signum.Engine/Linq/ExpressionVisitor/SmartEqualizer.cs index 70e2155067..3804d4d2df 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/SmartEqualizer.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/SmartEqualizer.cs @@ -56,11 +56,11 @@ public static Expression PolymorphicEqual(Expression exp1, Expression exp2) exp1 = ConstanToNewExpression(exp1) ?? exp1; exp2 = ConstanToNewExpression(exp2) ?? exp2; - return (exp1 as NewExpression).Arguments.ZipStrict( - (exp2 as NewExpression).Arguments, (o, i) => SmartEqualizer.PolymorphicEqual(o, i)).AggregateAnd(); + return ((NewExpression)exp1).Arguments.ZipStrict( + ((NewExpression)exp2).Arguments, (o, i) => SmartEqualizer.PolymorphicEqual(o, i)).AggregateAnd(); } - Expression result; + Expression? result; result = PrimaryKeyEquals(exp1, exp2); if (result != null) return result; @@ -101,7 +101,7 @@ public static Expression PolymorphicEqual(Expression exp1, Expression exp2) return EqualNullable(exp1, exp2); } - private static Expression EnumEquals(Expression exp1, Expression exp2) + private static Expression? EnumEquals(Expression exp1, Expression exp2) { var exp1Clean = RemoveConvertChain(exp1); var exp2Clean = RemoveConvertChain(exp2); @@ -124,7 +124,7 @@ private static Expression EnumEquals(Expression exp1, Expression exp2) return null; } - private static Expression ConstantToDayOfWeek(Expression exp) + private static Expression? ConstantToDayOfWeek(Expression exp) { if (exp is ConstantExpression c) { @@ -150,10 +150,8 @@ private static Expression RemoveConvertChain(Expression exp) } } - - - - private static Expression ConstanToNewExpression(Expression exp) + + private static Expression? ConstanToNewExpression(Expression exp) { var ce = exp as ConstantExpression; @@ -172,7 +170,7 @@ private static Expression ConstanToNewExpression(Expression exp) return Expression.New(ci, ci.GetParameters().Select(p => Expression.Constant(values.GetOrThrow(p.Name), p.ParameterType))); } - public static Expression PrimaryKeyEquals(Expression exp1, Expression exp2) + public static Expression? PrimaryKeyEquals(Expression exp1, Expression exp2) { if (exp1.Type.UnNullify() == typeof(PrimaryKey) || exp2.Type.UnNullify() == typeof(PrimaryKey)) { @@ -185,7 +183,7 @@ public static Expression PrimaryKeyEquals(Expression exp1, Expression exp2) return null; } - public static Expression ObjectEquals(Expression expr1, Expression expr2) + public static Expression? ObjectEquals(Expression expr1, Expression expr2) { if (expr1.Type == typeof(object) && expr2.Type == typeof(object)) { @@ -195,8 +193,8 @@ public static Expression ObjectEquals(Expression expr1, Expression expr2) if (left == null && right == null) return null; - left = left ?? ChangeConstant(expr1, right.Type); - right = right ?? ChangeConstant(expr2, left.Type); + left = left ?? ChangeConstant(expr1, right!.Type); + right = right ?? ChangeConstant(expr2, left!.Type); if (left == null || right == null) return null; @@ -207,7 +205,7 @@ public static Expression ObjectEquals(Expression expr1, Expression expr2) return null; } - private static Expression ChangeConstant(Expression exp, Type type) + private static Expression? ChangeConstant(Expression exp, Type type) { if (exp is ConstantExpression ce) { @@ -230,7 +228,7 @@ private static Expression ChangeConstant(Expression exp, Type type) return null; } - private static Expression UncastObject(Expression expr) + private static Expression? UncastObject(Expression expr) { if (expr.NodeType == ExpressionType.Convert) return ((UnaryExpression)expr).Operand; @@ -281,7 +279,7 @@ static bool LessThanOrEqual(Guid a, Guid b) return a.CompareTo(b) <= 0; } - public static MethodInfo GetMethod(ExpressionType type) + public static MethodInfo? GetMethod(ExpressionType type) { switch (type) { @@ -318,7 +316,7 @@ public static Expression UnwrapPrimaryKey(Expression unary) return unary; } - private static Expression ConditionalEquals(Expression exp1, Expression exp2) + private static Expression? ConditionalEquals(Expression exp1, Expression exp2) { if (Schema.Current.Settings.IsDbType(exp1.Type)|| Schema.Current.Settings.IsDbType(exp2.Type)) @@ -341,7 +339,7 @@ private static Expression DispachConditional(ConditionalExpression ce, Expressio return SmartOr(SmartAnd(ce.Test, ifTrue), SmartAnd(SmartNot(ce.Test), ifFalse)); } - private static Expression CoalesceEquals(Expression exp1, Expression exp2) + private static Expression? CoalesceEquals(Expression exp1, Expression exp2) { if (Schema.Current.Settings.IsDbType(exp1.Type)|| Schema.Current.Settings.IsDbType(exp2.Type)) @@ -405,7 +403,7 @@ private static Expression SmartOr(Expression e1, Expression e2) return Expression.Or(e1, e2); } - private static Expression TypeEquals(Expression exp1, Expression exp2) + private static Expression? TypeEquals(Expression exp1, Expression exp2) { if (exp1.Type != typeof(Type) || exp2.Type != typeof(Type)) return null; @@ -455,7 +453,7 @@ private static Expression TypeConstantEntityEquals(ConstantExpression ce, TypeEn return False; } - private static Expression TypeConstantIbEquals(ConstantExpression ce, TypeImplementedByExpression typeIb) + private static Expression? TypeConstantIbEquals(ConstantExpression ce, TypeImplementedByExpression typeIb) { if (ce.IsNull()) { @@ -466,7 +464,7 @@ private static Expression TypeConstantIbEquals(ConstantExpression ce, TypeImplem var externalId = typeIb.TypeImplementations.TryGetC(type); - return NotEqualToNull(externalId); + return externalId == null ? False : NotEqualToNull(externalId); } private static Expression TypeConstantIbaEquals(ConstantExpression ce, TypeImplementedByAllExpression typeIba) @@ -575,7 +573,7 @@ internal static Expression TypeIn(Expression typeExpr, IEnumerable collect public static Expression In(Expression element, object[] values) { - var nominate = DbExpressionNominator.FullNominate(element); + var nominate = DbExpressionNominator.FullNominate(element)!; if (nominate is ToDayOfWeekExpression dowe) { @@ -599,7 +597,7 @@ public static Expression InPrimaryKey(Expression element, PrimaryKey[] values) if (cleanElement == NewId) return False; - return InExpression.FromValues(DbExpressionNominator.FullNominate(cleanElement), cleanValues); + return InExpression.FromValues(DbExpressionNominator.FullNominate(cleanElement)!, cleanValues); } private static Expression DispachConditionalTypesIn(ConditionalExpression ce, IEnumerable collection) @@ -650,7 +648,7 @@ static Expression EntityIn(Expression newItem, Dictionary en - public static Expression LiteEquals(Expression e1, Expression e2) + public static Expression? LiteEquals(Expression e1, Expression e2) { if ( e1.Type.IsLite() || e2.Type.IsLite()) { @@ -663,7 +661,7 @@ public static Expression LiteEquals(Expression e1, Expression e2) return null; } - public static Expression MListElementEquals(Expression e1, Expression e2) + public static Expression? MListElementEquals(Expression e1, Expression e2) { if (e1 is MListElementExpression || e2 is MListElementExpression) { @@ -695,7 +693,7 @@ private static Expression GetEntity(Expression liteExp) return liteReference.Reference; } - public static Expression EntityEquals(Expression e1, Expression e2) + public static Expression? EntityEquals(Expression e1, Expression e2) { e1 = ConstantToEntity(e1) ?? e1; e2 = ConstantToEntity(e2) ?? e2; @@ -804,9 +802,9 @@ static Expression NotEqualToNull(PrimaryKeyExpression exp) return NotEqualNullable(exp.Value, new SqlConstantExpression(null, exp.ValueType)); } - public static Expression ConstantToEntity(Expression expression) + public static Expression? ConstantToEntity(Expression expression) { - ConstantExpression c = expression as ConstantExpression; + ConstantExpression? c = expression as ConstantExpression; if (c == null) return null; @@ -828,9 +826,9 @@ public static Expression ConstantToEntity(Expression expression) - public static Expression ConstantToLite(Expression expression) + public static Expression? ConstantToLite(Expression expression) { - ConstantExpression c = expression as ConstantExpression; + ConstantExpression? c = expression as ConstantExpression; if (c == null) return null; diff --git a/Signum.Engine/Linq/ExpressionVisitor/UnusedColumnRemover.cs b/Signum.Engine/Linq/ExpressionVisitor/UnusedColumnRemover.cs index da35a0d10e..570aa6d42c 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/UnusedColumnRemover.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/UnusedColumnRemover.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; @@ -48,7 +48,7 @@ protected internal override Expression VisitSelect(SelectExpression select) Expression where = this.Visit(select.Where); ReadOnlyCollection groupBy = select.GroupBy.Select(e => IsConstant(e) ? null : Visit(e)).NotNull().ToReadOnly(); - SourceExpression from = this.VisitSource(select.From); + SourceExpression? from = this.VisitSource(select.From!); if (columns != select.Columns || orderbys != select.OrderBy || where != select.Where || from != select.From || groupBy != select.GroupBy) return new SelectExpression(select.Alias, select.IsDistinct, select.Top, columns, from, where, orderbys, groupBy, select.SelectOptions); @@ -74,7 +74,7 @@ protected internal override Expression VisitScalar(ScalarExpression scalar) private void AddSingleColumn(SubqueryExpression subQuery) { - if (subQuery.Select.Columns.Count != 1) + if (subQuery.Select!.Columns.Count != 1) throw new InvalidOperationException("Subquery has {0} columns: {1}".FormatWith(subQuery.Select.Columns.Count, subQuery.ToString())); allColumnsUsed.GetOrCreate(subQuery.Select.Alias).Add(subQuery.Select.Columns[0].Name); } @@ -105,7 +105,7 @@ protected internal override Expression VisitJoin(JoinExpression join) { if (join.JoinType == JoinType.SingleRowLeftOuterJoin) { - var source = join.Right as SourceWithAliasExpression; + var source = (SourceWithAliasExpression)join.Right; var hs = allColumnsUsed.TryGetC(source.Alias); @@ -165,7 +165,7 @@ protected internal override Expression VisitInsertSelect(InsertSelectExpression protected internal override Expression VisitRowNumber(RowNumberExpression rowNumber) { - var orderBys = Visit(rowNumber.OrderBy, o => IsConstant(o.Expression) ? null : Visit(o.Expression).Let(e => e == o.Expression ? o : new OrderExpression(o.OrderType, e))); ; + var orderBys = Visit(rowNumber.OrderBy, o => IsConstant(o.Expression) ? null! : Visit(o.Expression).Let(e => e == o.Expression ? o : new OrderExpression(o.OrderType, e))); ; if (orderBys != rowNumber.OrderBy) return new RowNumberExpression(orderBys); return rowNumber; @@ -183,4 +183,4 @@ protected internal override Expression VisitChildProjection(ChildProjectionExpre return child; } } -} \ No newline at end of file +} diff --git a/Signum.Engine/Linq/Meta/MetaExpression.cs b/Signum.Engine/Linq/Meta/MetaExpression.cs index 4f34777f5d..1d0c4484d4 100644 --- a/Signum.Engine/Linq/Meta/MetaExpression.cs +++ b/Signum.Engine/Linq/Meta/MetaExpression.cs @@ -67,9 +67,9 @@ public bool IsEntity get { return typeof(ModifiableEntity).IsAssignableFrom(Type); } } - public readonly Meta Meta; + public Meta Meta { get; private set; } - public MetaExpression(Type type, Meta? meta): + public MetaExpression(Type type, Meta meta): base(MetaExpressionType.MetaExpression, type) { this.Meta = meta; diff --git a/Signum.Engine/Linq/Meta/MetadataVisitor.cs b/Signum.Engine/Linq/Meta/MetadataVisitor.cs index 392ab931ee..ba3d5be742 100644 --- a/Signum.Engine/Linq/Meta/MetadataVisitor.cs +++ b/Signum.Engine/Linq/Meta/MetadataVisitor.cs @@ -24,7 +24,7 @@ internal class MetadataVisitor : ExpressionVisitor private MetadataVisitor() { } - static internal Dictionary? GatherMetadata(Expression expression) + static internal Dictionary GatherMetadata(Expression expression) { if (expression == null) throw new ArgumentException("expression"); @@ -41,7 +41,7 @@ private MetadataVisitor() { } if (proj.NodeType != ExpressionType.New && //anonymous types proj.NodeType != ExpressionType.MemberInit && // not-anonymous type !(proj is MetaExpression && ((MetaExpression)proj).IsEntity)) // raw-entity! - return null; + throw new UnexpectedValueException(proj); PropertyInfo[] props = proj.Type.GetProperties(BindingFlags.Public | BindingFlags.Instance); @@ -457,13 +457,13 @@ static Expression BindMember(Expression source, MemberInfo member, Type memberTy var pi = member as PropertyInfo ?? Reflector.TryFindPropertyInfo((FieldInfo)member); if (pi == null) - return new MetaExpression(memberType, null); + return new MetaExpression(memberType, new DirtyMeta(null, new Meta[0])); MetaExpression meta = (MetaExpression)source; if (meta.Meta.Implementations != null) { - var routes = meta.Meta.Implementations.Value.Types.Select(t=> PropertyRoute.Root(t).Add(pi)).ToArray(); + var routes = meta.Meta.Implementations.Value.Types.Select(t => PropertyRoute.Root(t).Add(pi)).ToArray(); return new MetaExpression(memberType, new CleanMeta(GetImplementations(routes, memberType), routes)); } @@ -542,7 +542,7 @@ protected override Expression VisitUnary(UnaryExpression u) if (u.NodeType == ExpressionType.Convert || u.NodeType == ExpressionType.TypeAs) { - var imps = exp.Meta.Implementations?.Let(s => CastImplementations(s, u.Type.CleanType())); + var imps = exp.Meta?.Implementations?.Let(s => CastImplementations(s, u.Type.CleanType())); return new MetaExpression(u.Type, exp.Meta is DirtyMeta ? (Meta)new DirtyMeta(imps, ((DirtyMeta)exp.Meta).CleanMetas.Cast().ToArray()) : diff --git a/Signum.Engine/Linq/ProjectionReader.cs b/Signum.Engine/Linq/ProjectionReader.cs index 0b6d2d011c..0b8f2e4f0b 100644 --- a/Signum.Engine/Linq/ProjectionReader.cs +++ b/Signum.Engine/Linq/ProjectionReader.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -32,14 +32,12 @@ internal class ProjectionRowEnumerator : IProjectionRow, IEnumerator { public FieldReader Reader { get; private set;} public IRetriever Retriever { get; private set; } - - public IProjectionRow Parent { get; private set; } - + public CancellationToken Token { get; private set; } DbDataReader dataReader; - T current; + T current = default(T)!; Func projector; Expression> projectorExpression; @@ -63,7 +61,7 @@ public T Current get { return this.current; } } - object IEnumerator.Current + object? IEnumerator.Current { get { return this.current; } } @@ -110,7 +108,7 @@ public MList LookupRequest(LookupToken token, K key, MList field) internal class ProjectionRowEnumerable : IEnumerable, IEnumerable { - ProjectionRowEnumerator enumerator; + ProjectionRowEnumerator? enumerator; internal ProjectionRowEnumerable(ProjectionRowEnumerator enumerator) { @@ -119,8 +117,7 @@ internal ProjectionRowEnumerable(ProjectionRowEnumerator enumerator) public IEnumerator GetEnumerator() { - return Interlocked.Exchange(ref enumerator, null) - .ThrowIfNull("Cannot enumerate more than once"); + return Interlocked.Exchange(ref enumerator, null).ThrowIfNull("Cannot enumerate more than once"); } IEnumerator IEnumerable.GetEnumerator() diff --git a/Signum.Engine/Patterns/VirtualMList.cs b/Signum.Engine/Patterns/VirtualMList.cs index c35f6548f7..e07411f61f 100644 --- a/Signum.Engine/Patterns/VirtualMList.cs +++ b/Signum.Engine/Patterns/VirtualMList.cs @@ -132,8 +132,8 @@ public static FluentInclude WithVirtualMList(this FluentInclude fi, sb.Schema.EntityEvents().RegisterBinding>(mListField, shouldSet: () => !lazyRetrieve.Value && !VirtualMList.ShouldAvoidMListType(typeof(L)), valueExpression: e => Database.Query().Where(line => backReference.Evaluate(line) == e.ToLite()).ExpandLite(line => backReference.Evaluate(line), ExpandLite.ToStringLazy).ToVirtualMListWithOrder(), - valueFunction: (e, retriever) => Schema.Current.CacheController().Enabled ? - Schema.Current.CacheController().RequestByBackReference(retriever, backReference, e.ToLite()).ToVirtualMListWithOrder(): + valueFunction: (e, retriever) => Schema.Current.CacheController()!.Enabled ? + Schema.Current.CacheController()!.RequestByBackReference(retriever, backReference, e.ToLite()).ToVirtualMListWithOrder(): Database.Query().Where(line => backReference.Evaluate(line) == e.ToLite()).ExpandLite(line => backReference.Evaluate(line), ExpandLite.ToStringLazy).ToVirtualMListWithOrder() ); @@ -143,8 +143,8 @@ public static FluentInclude WithVirtualMList(this FluentInclude fi, sb.Schema.EntityEvents().RegisterBinding(mListField, shouldSet: () => !lazyRetrieve.Value && !VirtualMList.ShouldAvoidMListType(typeof(L)), valueExpression: e => Database.Query().Where(line => backReference.Evaluate(line) == e.ToLite()).ExpandLite(line => backReference.Evaluate(line), ExpandLite.ToStringLazy).ToVirtualMList(), - valueFunction: (e, retriever) => Schema.Current.CacheController().Enabled ? - Schema.Current.CacheController().RequestByBackReference(retriever, backReference, e.ToLite()).ToVirtualMList() : + valueFunction: (e, retriever) => Schema.Current.CacheController()!.Enabled ? + Schema.Current.CacheController()!.RequestByBackReference(retriever, backReference, e.ToLite()).ToVirtualMList() : Database.Query().Where(line => backReference.Evaluate(line) == e.ToLite()).ExpandLite(line => backReference.Evaluate(line), ExpandLite.ToStringLazy).ToVirtualMList() ); } diff --git a/Signum.Engine/Schema/Schema.Basics.cs b/Signum.Engine/Schema/Schema.Basics.cs index f1355d08d9..6926fe18fe 100644 --- a/Signum.Engine/Schema/Schema.Basics.cs +++ b/Signum.Engine/Schema/Schema.Basics.cs @@ -147,7 +147,7 @@ public void GenerateColumns() inserterDisableIdentity = new ResetLazy(() => InsertCacheDisableIdentity.InitializeInsertDisableIdentity(this)); inserterIdentity = new ResetLazy(() => InsertCacheIdentity.InitializeInsertIdentity(this)); updater = new ResetLazy(() => UpdateCache.InitializeUpdate(this)); - saveCollections = new ResetLazy(() => CollectionsCache.InitializeCollections(this)); + saveCollections = new ResetLazy(() => CollectionsCache.InitializeCollections(this)); } public Field GetField(MemberInfo member) @@ -325,7 +325,7 @@ public virtual IEnumerable GenerateIndexes(ITable table) return new[] { UniqueIndex }; } - public virtual UniqueIndex? GenerateUniqueIndex(ITable table, UniqueIndexAttribute attribute) + public virtual UniqueIndex? GenerateUniqueIndex(ITable table, UniqueIndexAttribute? attribute) { if (attribute == null) return null; diff --git a/Signum.Engine/Schema/Schema.Delete.cs b/Signum.Engine/Schema/Schema.Delete.cs index 8858582858..41561cf92e 100644 --- a/Signum.Engine/Schema/Schema.Delete.cs +++ b/Signum.Engine/Schema/Schema.Delete.cs @@ -27,7 +27,7 @@ public SqlPreCommand DeleteSqlSync(T entity, Expression>? where var main = new SqlPreCommandSimple("DELETE {0} WHERE {1} = {2} --{3}" .FormatWith(Name, this.PrimaryKey.Name.SqlEscape(), variableOrId, comment ?? entity.ToString())); - return SqlPreCommand.Combine(Spacing.Simple, declaration, pre, collections, main); + return SqlPreCommand.Combine(Spacing.Simple, declaration, pre, collections, main)!; } int parameterIndex; @@ -45,9 +45,9 @@ private SqlPreCommand DeclarePrimaryKeyVariable(T entity, Expression PreDeleteSqlSync; + public event Func PreDeleteSqlSync; - SqlPreCommand OnPreDeleteSqlSync(Entity entity) + SqlPreCommand? OnPreDeleteSqlSync(Entity entity) { if (PreDeleteSqlSync == null) return null; diff --git a/Signum.Engine/Schema/Schema.Save.cs b/Signum.Engine/Schema/Schema.Save.cs index 18ca99ba6b..b2f37c0c97 100644 --- a/Signum.Engine/Schema/Schema.Save.cs +++ b/Signum.Engine/Schema/Schema.Save.cs @@ -353,7 +353,7 @@ internal bool SetToStrField(Entity entity) internal static FieldInfo fiId = ReflectionTools.GetFieldInfo((Entity i) => i.id); - internal void UpdateMany(List list, DirectedGraph backEdges) + internal void UpdateMany(List list, DirectedGraph? backEdges) { using (HeavyProfiler.LogNoStackTrace("UpdateMany", () => this.Type.TypeName())) { @@ -369,8 +369,8 @@ class UpdateCache public Func SqlUpdatePattern; public Func> UpdateParameters; - ConcurrentDictionary, DirectedGraph>> updateCache = - new ConcurrentDictionary, DirectedGraph>>(); + ConcurrentDictionary, DirectedGraph?>> updateCache = + new ConcurrentDictionary, DirectedGraph?>>(); public UpdateCache(Table table, Func sqlUpdatePattern, Func> updateParameters) { @@ -379,12 +379,12 @@ public UpdateCache(Table table, Func sqlUpdatePattern, Fun UpdateParameters = updateParameters; } - public Action, DirectedGraph> GetUpdater(int numElements) + public Action, DirectedGraph?> GetUpdater(int numElements) { return updateCache.GetOrAdd(numElements, num => num == 1 ? GenerateUpdate() : GetUpdateMultiple(num)); } - Action, DirectedGraph> GenerateUpdate() + Action, DirectedGraph?> GenerateUpdate() { string sqlUpdate = SqlUpdatePattern("", false); @@ -427,7 +427,7 @@ Action, DirectedGraph> GenerateUpdate() } } - Action, DirectedGraph> GetUpdateMultiple(int num) + Action, DirectedGraph?> GetUpdateMultiple(int num) { string sqlMulti = new StringBuilder() .AppendLine("DECLARE @NotFound TABLE (Id " + this.table.PrimaryKey.SqlDbType.ToString().ToUpperInvariant() + ");") @@ -602,7 +602,7 @@ public CollectionsCache(Func insertCollecti } } - ResetLazy saveCollections; + ResetLazy saveCollections; public SqlPreCommand InsertSqlSync(Entity ident, bool includeCollections = true, string? comment = null, string suffix = "") diff --git a/Signum.Engine/Schema/Schema.cs b/Signum.Engine/Schema/Schema.cs index aa05fa5380..e093da820b 100644 --- a/Signum.Engine/Schema/Schema.cs +++ b/Signum.Engine/Schema/Schema.cs @@ -697,10 +697,8 @@ public Implementations FindImplementations(PropertyRoute route) Expression e = MetadataVisitor.JustVisit(lambda, new MetaExpression(route.Parent!.Type, new CleanMeta(route.Parent!.TryGetImplementations(), new[] { route.Parent! }))); MetaExpression? me = e as MetaExpression; - if (me == null) - return null; - return me.Meta.Implementations; + return me?.Meta.Implementations; } /// diff --git a/Signum.Engine/Schema/SchemaAssets.cs b/Signum.Engine/Schema/SchemaAssets.cs index 1dfdc69e6f..f408261bf2 100644 --- a/Signum.Engine/Schema/SchemaAssets.cs +++ b/Signum.Engine/Schema/SchemaAssets.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using Signum.Utilities; using Signum.Engine.SchemaInfoTables; @@ -7,18 +7,18 @@ namespace Signum.Engine.Maps { public class SchemaAssets { - internal SqlPreCommand Schema_Generating() + internal SqlPreCommand? Schema_Generating() { - SqlPreCommand views = GenerateViews(); - SqlPreCommand procedures = GenerateProcedures(); + SqlPreCommand? views = GenerateViews(); + SqlPreCommand? procedures = GenerateProcedures(); return SqlPreCommand.Combine(Spacing.Triple, views, procedures); } - internal SqlPreCommand Schema_Synchronizing(Replacements replacements) + internal SqlPreCommand? Schema_Synchronizing(Replacements replacements) { - SqlPreCommand views = SyncViews(replacements); - SqlPreCommand procedures = SyncProcedures(replacements); + SqlPreCommand? views = SyncViews(replacements); + SqlPreCommand? procedures = SyncProcedures(replacements); return SqlPreCommand.Combine(Spacing.Triple, views, procedures); } @@ -34,6 +34,12 @@ public class View public ObjectName Name; public string Definition; + public View(ObjectName name, string definition) + { + Name = name; + Definition = definition; + } + public SqlPreCommandSimple CreateView() { return new SqlPreCommandSimple("CREATE VIEW {0} ".FormatWith(Name) + Definition) { GoBefore = true, GoAfter = true }; @@ -53,19 +59,15 @@ public View IncludeView(string viewName, string viewDefinition) public Dictionary Views = new Dictionary(); public View IncludeView(ObjectName viewName, string viewDefinition) { - return Views[viewName] = new View - { - Name = viewName, - Definition = viewDefinition - }; + return Views[viewName] = new View(viewName, viewDefinition); } - SqlPreCommand GenerateViews() + SqlPreCommand? GenerateViews() { return Views.Values.Select(v => v.CreateView()).Combine(Spacing.Double); } - SqlPreCommand SyncViews(Replacements replacements) + SqlPreCommand? SyncViews(Replacements replacements) { var oldView = Schema.Current.DatabaseNames().SelectMany(db => { @@ -98,12 +100,7 @@ public Procedure IncludeStoreProcedure(string procedureName, string procedureCod public Procedure IncludeStoreProcedure(ObjectName procedureName, string procedureCodeAndArguments) { - return StoreProcedures[procedureName] = new Procedure - { - ProcedureName = procedureName, - ProcedureCodeAndArguments = procedureCodeAndArguments, - ProcedureType = "PROCEDURE" - }; + return StoreProcedures[procedureName] = new Procedure("PROCEDURE", procedureName, procedureCodeAndArguments); } public Procedure IncludeUserDefinedFunction(string functionName, string functionCodeAndArguments) @@ -113,20 +110,15 @@ public Procedure IncludeUserDefinedFunction(string functionName, string function public Procedure IncludeUserDefinedFunction(ObjectName functionName, string functionCodeAndArguments) { - return StoreProcedures[functionName] = new Procedure - { - ProcedureName = functionName, - ProcedureCodeAndArguments = functionCodeAndArguments, - ProcedureType = "FUNCTION" - }; + return StoreProcedures[functionName] = new Procedure("FUNCTION", functionName, functionCodeAndArguments); } - SqlPreCommand GenerateProcedures() + SqlPreCommand? GenerateProcedures() { return StoreProcedures.Select(p => p.Value.CreateSql()).Combine(Spacing.Double); } - SqlPreCommand SyncProcedures(Replacements replacements) + SqlPreCommand? SyncProcedures(Replacements replacements) { var oldProcedures = Schema.Current.DatabaseNames().SelectMany(db => { @@ -156,6 +148,13 @@ public class Procedure public ObjectName ProcedureName; public string ProcedureCodeAndArguments; + public Procedure(string procedureType, ObjectName procedureName, string procedureCodeAndArguments) + { + ProcedureType = procedureType; + ProcedureName = procedureName; + ProcedureCodeAndArguments = procedureCodeAndArguments; + } + public SqlPreCommandSimple CreateSql() { return new SqlPreCommandSimple("CREATE {0} {1} ".FormatWith(ProcedureType, ProcedureName) + ProcedureCodeAndArguments) { GoBefore = true, GoAfter = true }; diff --git a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs index d3f6ad1cf6..80a0a30c36 100644 --- a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs +++ b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs @@ -292,7 +292,7 @@ void Complete(Table table) } } - public SystemVersionedInfo? ToSystemVersionedInfo(SystemVersionedAttribute att, ObjectName tableName) + public SystemVersionedInfo? ToSystemVersionedInfo(SystemVersionedAttribute? att, ObjectName tableName) { if (att == null) return null; @@ -437,7 +437,7 @@ protected virtual Field GenerateField(ITable table, PropertyRoute route, NameSeq //field name generation NameSequence name; - ColumnNameAttribute vc = Settings.FieldAttribute(route); + ColumnNameAttribute? vc = Settings.FieldAttribute(route); if (vc != null && vc.Name.HasText()) name = NameSequence.Void.Add(vc.Name); else if (route.PropertyRouteType != PropertyRouteType.MListItems) @@ -801,7 +801,7 @@ private SchemaName GetSchemaName(TableNameAttribute tn) return schema; } - public virtual ObjectName GenerateTableNameCollection(Table table, NameSequence name, TableNameAttribute tn) + public virtual ObjectName GenerateTableNameCollection(Table table, NameSequence name, TableNameAttribute? tn) { SchemaName sn = tn != null ? GetSchemaName(tn) : SchemaName.Default; @@ -846,7 +846,7 @@ public virtual string GenerateFieldName(PropertyRoute route, KindOfField kindOfF } } - public virtual string GenerateBackReferenceName(Type type, BackReferenceColumnNameAttribute attribute) + public virtual string GenerateBackReferenceName(Type type, BackReferenceColumnNameAttribute? attribute) { return attribute?.Name ?? "ParentID"; } diff --git a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs index f75d1fc17c..4f1349e974 100644 --- a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs +++ b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs @@ -312,7 +312,7 @@ internal SqlDbTypePair GetSqlDbType(SqlDbTypeAttribute? att, Type type) return defaultScale.TryGetS(sqlDbType); } - internal string? GetCollate(SqlDbTypeAttribute att) + internal string? GetCollate(SqlDbTypeAttribute? att) { if (att != null && att.Collation != null) return att.Collation; diff --git a/Signum.Engine/Schema/UniqueIndex.cs b/Signum.Engine/Schema/UniqueIndex.cs index a877324259..d895e9fae8 100644 --- a/Signum.Engine/Schema/UniqueIndex.cs +++ b/Signum.Engine/Schema/UniqueIndex.cs @@ -16,9 +16,9 @@ public class Index { public ITable Table { get; private set; } public IColumn[] Columns { get; private set; } - public IColumn[] IncludeColumns { get; set; } + public IColumn[]? IncludeColumns { get; set; } - public string Where { get; set; } + public string? Where { get; set; } public static IColumn[] GetColumnsFromFields(params Field[] fields) { @@ -95,7 +95,7 @@ public override string IndexName get { return "UIX_{0}".FormatWith(ColumnSignature()).TryStart(Connector.Current.MaxNameLength); } } - public string ViewName + public string? ViewName { get { @@ -140,7 +140,7 @@ static IColumn[] GetColumns(IFieldFinder finder, LambdaExpression field) { var body = field.Body; - Type type = RemoveCasting(ref body); + Type? type = RemoveCasting(ref body); body = IndexWhereExpressionVisitor.RemoveLiteEntity(body); @@ -164,7 +164,7 @@ where type.IsAssignableFrom(ic.Key) return Index.GetColumnsFromFields(f); } - static Type RemoveCasting(ref Expression body) + static Type? RemoveCasting(ref Expression body) { if (body.NodeType == ExpressionType.Convert && body.Type == typeof(object)) body = ((UnaryExpression)body).Operand; @@ -187,12 +187,14 @@ public class IndexWhereExpressionVisitor : ExpressionVisitor IFieldFinder RootFinder; + public IndexWhereExpressionVisitor(IFieldFinder rootFinder) + { + RootFinder = rootFinder; + } + public static string GetIndexWhere(LambdaExpression lambda, IFieldFinder rootFiender) { - IndexWhereExpressionVisitor visitor = new IndexWhereExpressionVisitor - { - RootFinder = rootFiender - }; + IndexWhereExpressionVisitor visitor = new IndexWhereExpressionVisitor(rootFiender); var newLambda = (LambdaExpression)ExpressionEvaluator.PartialEval(lambda); diff --git a/Signum.Engine/Signum.Engine.csproj b/Signum.Engine/Signum.Engine.csproj index b309f217c9..961a8f4250 100644 --- a/Signum.Engine/Signum.Engine.csproj +++ b/Signum.Engine/Signum.Engine.csproj @@ -4,11 +4,15 @@ netcoreapp2.2 8.0 true - true + enable true x64 + + + 1701;1702;8629 + diff --git a/Signum.Entities/Basics/OperationLog.cs b/Signum.Entities/Basics/OperationLog.cs index 61b91df511..76733b745f 100644 --- a/Signum.Entities/Basics/OperationLog.cs +++ b/Signum.Entities/Basics/OperationLog.cs @@ -24,7 +24,9 @@ public class OperationLogEntity : Entity static Expression> DurationExpression = log => (double?)(log.End - log.Start).Value.TotalMilliseconds; +#pragma warning disable SF0002 // Use ExpressionFieldAttribute in non-trivial method or property CSBUG [ExpressionField("DurationExpression"), Unit("ms")] +#pragma warning restore SF0002 // Use ExpressionFieldAttribute in non-trivial method or property public double? Duration { get { return End == null ? null : DurationExpression.Evaluate(this); } diff --git a/Signum.Entities/DynamicQuery/QueryUtils.cs b/Signum.Entities/DynamicQuery/QueryUtils.cs index 90c7d115ba..5bd960d680 100644 --- a/Signum.Entities/DynamicQuery/QueryUtils.cs +++ b/Signum.Entities/DynamicQuery/QueryUtils.cs @@ -430,7 +430,7 @@ internal static Expression ExtractEntity(this Expression expression, bool idAndT if (!idAndToStr) return Expression.Property(expression, "Entity"); } - return expression!; /*CSBUG*/ + return expression; } internal static Expression BuildLiteNulifyUnwrapPrimaryKey(this Expression expression, PropertyRoute[] routes) diff --git a/Signum.Entities/DynamicQuery/Tokens/NetPropertyToken.cs b/Signum.Entities/DynamicQuery/Tokens/NetPropertyToken.cs index fcbb872729..d32fc32c73 100644 --- a/Signum.Entities/DynamicQuery/Tokens/NetPropertyToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/NetPropertyToken.cs @@ -39,7 +39,7 @@ public override Type Type return MemberInfo is PropertyInfo pi ? pi.PropertyType.Nullify() : MemberInfo is MethodInfo mi ? mi.ReturnType.Nullify() : - throw new UnexpectedValueException(MemberInfo! /*CSBUG*/); + throw new UnexpectedValueException(MemberInfo); } } @@ -62,7 +62,7 @@ protected override Expression BuildExpressionInternal(BuildExpressionContext con var prop = MemberInfo is PropertyInfo pi ? (Expression)Expression.Property(result.UnNullify(), pi) : MemberInfo is MethodInfo mi ? (mi.IsStatic ? Expression.Call(null, mi, result.UnNullify()) : Expression.Call(result.UnNullify(), mi)) : - throw new UnexpectedValueException(MemberInfo! /*CSBUG*/); + throw new UnexpectedValueException(MemberInfo); return Expression.Call(miInSql.MakeGenericMethod(prop.Type), prop).Nullify(); } diff --git a/Signum.Entities/MList.cs b/Signum.Entities/MList.cs index 69de1a90fe..73edeae855 100644 --- a/Signum.Entities/MList.cs +++ b/Signum.Entities/MList.cs @@ -616,7 +616,7 @@ void IList.Remove(object value) object? IList.this[int index] { get { return this[index]; } - set { this[index] = (T)value; } + set { this[index] = (T)value!; } } void ICollection.CopyTo(Array array, int index) diff --git a/Signum.Entities/ModifiableEntity.cs b/Signum.Entities/ModifiableEntity.cs index d56bd7b135..dfa7614a3e 100644 --- a/Signum.Entities/ModifiableEntity.cs +++ b/Signum.Entities/ModifiableEntity.cs @@ -124,7 +124,9 @@ protected PropertyInfo GetPropertyInfo(string propertyName) } static Expression> ToStringPropertyExpression = m => m.ToString(); +#pragma warning disable SF0002 // Use ExpressionFieldAttribute in non-trivial method or property CSBUG [HiddenProperty, ExpressionField("ToStringPropertyExpression")] +#pragma warning restore SF0002 // Use ExpressionFieldAttribute in non-trivial method or property public string ToStringProperty { get diff --git a/Signum.Entities/ObjectDumper.cs b/Signum.Entities/ObjectDumper.cs index 078a89f4cb..db8276e176 100644 --- a/Signum.Entities/ObjectDumper.cs +++ b/Signum.Entities/ObjectDumper.cs @@ -44,8 +44,8 @@ class DumpVisitor HashSet objects = new HashSet(ReferenceEqualityComparer.Default); public StringBuilder Sb = new StringBuilder(); int level = 0; - ShowIgnoredFields showIgnoredFields; - bool showByteArrays; + readonly ShowIgnoredFields showIgnoredFields; + readonly bool showByteArrays; public DumpVisitor(ShowIgnoredFields showIgnoredFields, bool showByteArrays) { @@ -69,7 +69,7 @@ public void DumpObject(object o) return; } - Type t = o!.GetType(); /*CSBUG*/ + Type t = o.GetType(); if (IsDelegate(t)) { diff --git a/Signum.Entities/Reflection/EntityStructuralEqualityComparer.cs b/Signum.Entities/Reflection/EntityStructuralEqualityComparer.cs index 9d9a5dd53c..3203649ba0 100644 --- a/Signum.Entities/Reflection/EntityStructuralEqualityComparer.cs +++ b/Signum.Entities/Reflection/EntityStructuralEqualityComparer.cs @@ -267,7 +267,7 @@ public override int GetHashCode(IList obj) public abstract class EqualityComparerResolverWithCache : IEqualityComparerResolver { - Dictionary<(Type, PropertyInfo?), IEqualityComparer> cache = new Dictionary<(Type, PropertyInfo?), IEqualityComparer>(); + readonly Dictionary<(Type, PropertyInfo?), IEqualityComparer> cache = new Dictionary<(Type, PropertyInfo?), IEqualityComparer>(); public virtual IEqualityComparer GetEqualityComparer(Type type, PropertyInfo? pi) { if (cache.TryGetValue((type, pi), out var comparer)) @@ -280,7 +280,7 @@ public virtual IEqualityComparer GetEqualityComparer(Type type, PropertyInfo? pi if (comp is ICompletableComparer cc) cc.Complete(this, pi); - return comp! /*CSBUG*/; + return comp; } } diff --git a/Signum.Entities/Reflection/GraphExplorer.cs b/Signum.Entities/Reflection/GraphExplorer.cs index 032867f0db..eda8003de8 100644 --- a/Signum.Entities/Reflection/GraphExplorer.cs +++ b/Signum.Entities/Reflection/GraphExplorer.cs @@ -157,7 +157,7 @@ public static DirectedGraph PreSaving(Func if (m is ModifiableEntity me) me.SetTemporalErrors(null); - m!.PreSaving(ctx); /*CSBUG*/ + m.PreSaving(ctx); }); } @@ -194,7 +194,7 @@ public static DirectedGraph PreSaving(Func } - static string[] colors = + static readonly string[] colors = { "aquamarine1", "aquamarine4", "blue", "blueviolet", "brown4", "burlywood", "cadetblue1", "cadetblue", diff --git a/Signum.Entities/Reflection/Reflector.cs b/Signum.Entities/Reflection/Reflector.cs index 495d6658ce..4500e1bf8e 100644 --- a/Signum.Entities/Reflection/Reflector.cs +++ b/Signum.Entities/Reflection/Reflector.cs @@ -209,7 +209,7 @@ public static MemberInfo[] GetMemberListUntyped(LambdaExpression lambdaToField) if (e is UnaryExpression ue && ue.NodeType == ExpressionType.Convert && ue.Type == typeof(object)) e = ue.Operand; - MemberInfo[] result = GetMemberListBase(e! /*CSBUG*/); + MemberInfo[] result = GetMemberListBase(e); return result; } diff --git a/Signum.Entities/Signum.Entities.csproj b/Signum.Entities/Signum.Entities.csproj index 715a252080..8d977101ff 100644 --- a/Signum.Entities/Signum.Entities.csproj +++ b/Signum.Entities/Signum.Entities.csproj @@ -4,11 +4,15 @@ netcoreapp2.2 8.0 true - true + enable true x64 + + 1701;1702;8629 + + diff --git a/Signum.Utilities/ConsoleSwitch.cs b/Signum.Utilities/ConsoleSwitch.cs index 6d7d7c58eb..3655611882 100644 --- a/Signum.Utilities/ConsoleSwitch.cs +++ b/Signum.Utilities/ConsoleSwitch.cs @@ -9,9 +9,9 @@ public class ConsoleSwitch : IEnumerable> dictionary = new Dictionary>(StringComparer.InvariantCultureIgnoreCase); - Dictionary separators = new Dictionary(); - string welcomeMessage; + readonly Dictionary> dictionary = new Dictionary>(StringComparer.InvariantCultureIgnoreCase); + readonly Dictionary separators = new Dictionary(); + readonly string welcomeMessage; public ConsoleSwitch() : this(ConsoleMessage.SelectOneOfTheFollowingOptions.NiceToString()) @@ -176,7 +176,9 @@ IEnumerable> GetValuesRange(string line) if (from.HasValue && to == null) return dictionary.Keys.Skip(from.Value).Select(s => dictionary.GetOrThrow(s)); +#pragma warning disable CS8629 // Nullable value type may be null. CSBUG return dictionary.Keys.Skip(from.Value).Take((to.Value + 1) - from.Value).Select(s => dictionary.GetOrThrow(s)); +#pragma warning restore CS8629 // Nullable value type may be null. } else { diff --git a/Signum.Utilities/DataStructures/ImmutableStack.cs b/Signum.Utilities/DataStructures/ImmutableStack.cs index 077b696ea7..579561525b 100644 --- a/Signum.Utilities/DataStructures/ImmutableStack.cs +++ b/Signum.Utilities/DataStructures/ImmutableStack.cs @@ -5,10 +5,7 @@ namespace Signum.Utilities.DataStructures { - - public class ImmutableStack : IEnumerable - where T : object /*CSBUG*/ { class ImmutableFullStack : ImmutableStack { diff --git a/Signum.Utilities/DataStructures/IntervalDictionaries/Interval.cs b/Signum.Utilities/DataStructures/IntervalDictionaries/Interval.cs index a9c13554c5..6b66003dfa 100644 --- a/Signum.Utilities/DataStructures/IntervalDictionaries/Interval.cs +++ b/Signum.Utilities/DataStructures/IntervalDictionaries/Interval.cs @@ -277,7 +277,9 @@ public int CompareTo(NullableInterval other) if (temp != 0) return temp; +#pragma warning disable CS8629 // Nullable value type may be null. CSBUG return min.Value.CompareTo(other.min.Value); +#pragma warning restore CS8629 // Nullable value type may be null. } public int CompareTo(object obj) diff --git a/Signum.Utilities/DataStructures/IntervalDictionaries/IntervalDictionary.cs b/Signum.Utilities/DataStructures/IntervalDictionaries/IntervalDictionary.cs index 4b800f5daf..24506faaec 100644 --- a/Signum.Utilities/DataStructures/IntervalDictionaries/IntervalDictionary.cs +++ b/Signum.Utilities/DataStructures/IntervalDictionaries/IntervalDictionary.cs @@ -11,7 +11,7 @@ namespace Signum.Utilities.DataStructures public class IntervalDictionary: IEnumerable, V>> where K: struct, IComparable, IEquatable { - SortedList, V> dic = new SortedList, V>(); + readonly SortedList, V> dic = new SortedList, V>(); public IntervalDictionary() { @@ -147,7 +147,8 @@ public V this[K key] public V TryGet(K key, V defaultValue) { - this.TryGetValue(key, out defaultValue); + if (this.TryGetValue(key, out var value)) + return value; return defaultValue; } @@ -287,7 +288,9 @@ public static class IntervalDictionaryExtensions public static IntervalDictionary Mix(this IntervalDictionary me, IntervalDictionary other, Func, IntervalValue, IntervalValue, IntervalValue> mixer) where K : struct, IComparable, IEquatable { +#pragma warning disable CS8629 // Nullable value type may be null. CSBUG Interval[] keys = me.Intervals.Concat(other.Intervals).SelectMany(a => a.Elements()).Distinct().OrderBy().BiSelectS((min, max) => new Interval(min.Value, max.Value)).ToArray(); +#pragma warning restore CS8629 // Nullable value type may be null. return new IntervalDictionary(keys .Select(k => new { Intervalo = k, Valor = mixer(k, me.TryGetValue(k.Min), other.TryGetValue(k.Min)) }) .Where(a => a.Valor.HasInterval).Select(a => KVP.Create(a.Intervalo, a.Valor.Value))); @@ -296,14 +299,18 @@ public static IntervalDictionary Mix(this IntervalDictiona public static IntervalDictionary Collapse(this IEnumerable> collection, Func, IEnumerable, VR> mixer) where K : struct, IComparable, IEquatable { +#pragma warning disable CS8629 // Nullable value type may be null. Interval[] keys = collection.SelectMany(a => a).SelectMany(a => a.Key.Elements()).Distinct().OrderBy().BiSelectS((min, max) => new Interval(min.Value, max.Value)).ToArray(); +#pragma warning restore CS8629 // Nullable value type may be null. return new IntervalDictionary(keys.Select(k => KVP.Create(k, mixer(k, collection.Select(intDic => intDic.TryGetValue(k.Min)).Where(vi => vi.HasInterval).Select(vi => vi.Value))))); } public static IntervalDictionary AggregateIntervalDictionary(this IEnumerable<(Interval interval, V value)> collection, Func, IEnumerable, VR> mixer) where K : struct, IComparable, IEquatable { +#pragma warning disable CS8629 // Nullable value type may be null. Interval[] keys = collection.SelectMany(a => a.interval.Elements()).Distinct().OrderBy().BiSelectS((min, max) => new Interval(min.Value, max.Value)).ToArray(); +#pragma warning restore CS8629 // Nullable value type may be null. return new IntervalDictionary(keys.Select(k => KVP.Create(k, mixer(k, collection.Where(a => a.interval.Subset(k)).Select(a => a.value))))); } diff --git a/Signum.Utilities/ExpressionTrees/CSharpRenderer.cs b/Signum.Utilities/ExpressionTrees/CSharpRenderer.cs index 02603e942e..86c9aa2d62 100644 --- a/Signum.Utilities/ExpressionTrees/CSharpRenderer.cs +++ b/Signum.Utilities/ExpressionTrees/CSharpRenderer.cs @@ -132,7 +132,7 @@ public static string CleanIdentifiers(this string str) .Replace("<>h__TransparentIdentifier", "τ"); } - public static string Value(object obj) + public static string Value(object? obj) { if (obj == null) return "null"; @@ -142,8 +142,7 @@ public static string Value(object obj) if (obj is string s) return ToSrtringLiteral(s); - - obj = obj!/*CSBUG*/; + if (obj.GetType().IsEnum) return $"{obj.GetType().FullName}.{obj.ToString()}"; diff --git a/Signum.Utilities/ExpressionTrees/Query.cs b/Signum.Utilities/ExpressionTrees/Query.cs index a77a961945..f5d77cbdbd 100644 --- a/Signum.Utilities/ExpressionTrees/Query.cs +++ b/Signum.Utilities/ExpressionTrees/Query.cs @@ -66,7 +66,7 @@ public override string ToString() if (expression is ConstantExpression ce && ce.Value == this) return this.GetType().TypeName().CleanIdentifiers(); else - return expression!/*CSBUG*/.ToString(); + return expression.ToString(); } public string QueryText diff --git a/Signum.Utilities/ExpressionTrees/QueryableAsyncExtensions.cs b/Signum.Utilities/ExpressionTrees/QueryableAsyncExtensions.cs index d36b708f33..51149897d0 100644 --- a/Signum.Utilities/ExpressionTrees/QueryableAsyncExtensions.cs +++ b/Signum.Utilities/ExpressionTrees/QueryableAsyncExtensions.cs @@ -50,7 +50,7 @@ static async Task Bind(CancellationToken cancellationToken, Expression BindAsyncWithoutCancellationToken___(Expression> bind) diff --git a/Signum.Utilities/Extensions/Extensions.cs b/Signum.Utilities/Extensions/Extensions.cs index d307374667..17f0972b4b 100644 --- a/Signum.Utilities/Extensions/Extensions.cs +++ b/Signum.Utilities/Extensions/Extensions.cs @@ -270,7 +270,7 @@ public static T ThrowIfNull([EnsuresNotNull]this T? t, string message) return t.Value; } - public static T ThrowIfNull([EnsuresNotNull]this T t, string message) + public static T ThrowIfNull([EnsuresNotNull]this T? t, string message) where T : class { if (t == null) diff --git a/Signum.Utilities/Extensions/ReflectionExtensions.cs b/Signum.Utilities/Extensions/ReflectionExtensions.cs index bc00e7d943..7c02699bea 100644 --- a/Signum.Utilities/Extensions/ReflectionExtensions.cs +++ b/Signum.Utilities/Extensions/ReflectionExtensions.cs @@ -43,7 +43,7 @@ public static Type ReturningType(this MemberInfo m) (m is MethodInfo mi) ? mi.ReturnType : (m is ConstructorInfo ci) ? ci.DeclaringType : (m is EventInfo ei) ? ei.EventHandlerType : - throw new UnexpectedValueException(m! /*CSBUG*/); + throw new UnexpectedValueException(m); } public static bool HasAttribute(this ICustomAttributeProvider mi) where T : Attribute diff --git a/Signum.Utilities/Extensions/StringExtensions.cs b/Signum.Utilities/Extensions/StringExtensions.cs index 638c65c019..2f6cd282d7 100644 --- a/Signum.Utilities/Extensions/StringExtensions.cs +++ b/Signum.Utilities/Extensions/StringExtensions.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Linq.Expressions; +using System.Runtime.CompilerServices; using System.Text; using System.Text.RegularExpressions; @@ -15,7 +16,7 @@ public static class StringExtensions static readonly Expression> HasTextExpression = str => (str ?? "").Length > 0; #pragma warning restore IDE0052 // Remove unread private members [ExpressionField("HasTextExpression")] - public static bool HasText(this string? str) + public static bool HasText([NotNullWhenTrue]this string? str) { return !string.IsNullOrEmpty(str); } @@ -439,11 +440,8 @@ public static string Start(this string str, int numChars) return str.Substring(0, numChars); } - public static string? TryStart(this string? str, int numChars) + public static string TryStart(this string str, int numChars) { - if (str == null) - return null; - if (numChars > str.Length) return str; @@ -458,11 +456,8 @@ public static string End(this string str, int numChars) return str.Substring(str.Length - numChars, numChars); } - public static string? TryEnd(this string? str, int numChars) + public static string TryEnd(this string str, int numChars) { - if (str == null) - return null; - if (numChars > str.Length) return str; diff --git a/Signum.Utilities/Polymorphic.cs b/Signum.Utilities/Polymorphic.cs index 68315a3424..e9d4720525 100644 --- a/Signum.Utilities/Polymorphic.cs +++ b/Signum.Utilities/Polymorphic.cs @@ -226,52 +226,62 @@ public static class PolymorphicExtensions public static void Register(this Polymorphic> polymorphic, Action action) where S : T + where T : class { polymorphic.SetDefinition(typeof(S), t => action((S)t)); } public static void Register(this Polymorphic> polymorphic, Action action) where S : T + where T : class { polymorphic.SetDefinition(typeof(S), (t, p0) => action((S)t, p0)); } public static void Register(this Polymorphic> polymorphic, Action action) where S : T + where T : class { polymorphic.SetDefinition(typeof(S), (t, p0, p1) => action((S)t, p0, p1)); } public static void Register(this Polymorphic> polymorphic, Action action) where S : T + where T : class { polymorphic.SetDefinition(typeof(S), (t, p0, p1, p2) => action((S)t, p0, p1, p2)); } public static void Register(this Polymorphic> polymorphic, Action action) where S : T + where T : class { polymorphic.SetDefinition(typeof(S), (t, p0, p1, p2, p3) => action((S)t, p0, p1, p2, p3)); } public static void Register(this Polymorphic> polymorphic, Func func) where S : T + where T : class { polymorphic.SetDefinition(typeof(S), t => func((S)t)); } public static void Register(this Polymorphic> polymorphic, Func func) where S : T + where T : class { polymorphic.SetDefinition(typeof(S), (t, p0) => func((S)t, p0)); } public static void Register(this Polymorphic> polymorphic, Func func) where S : T + where T : class { polymorphic.SetDefinition(typeof(S), (t, p0, p1) => func((S)t, p0, p1)); } public static void Register(this Polymorphic> polymorphic, Func func) where S : T + where T : class { polymorphic.SetDefinition(typeof(S), (t, p0, p1, p2) => func((S)t, p0, p1, p2)); } public static void Register(this Polymorphic> polymorphic, Func func) where S : T + where T : class { polymorphic.SetDefinition(typeof(S), (t, p0, p1, p2, p3) => func((S)t, p0, p1, p2, p3)); } diff --git a/Signum.Utilities/Profiler/HeavyProfiler.cs b/Signum.Utilities/Profiler/HeavyProfiler.cs index 556f5e2d16..458e4d609c 100644 --- a/Signum.Utilities/Profiler/HeavyProfiler.cs +++ b/Signum.Utilities/Profiler/HeavyProfiler.cs @@ -113,7 +113,7 @@ public static T LogValueNoStackTrace(string role, Func valueFactory) { long beforeStart = PerfCounter.Ticks; - if (enabled == false || TimeLimit.Value < beforeStart) + if (enabled == false || TimeLimit! < beforeStart) { enabled = false; Clean(); diff --git a/Signum.Utilities/Reflection/ReflectionTools.cs b/Signum.Utilities/Reflection/ReflectionTools.cs index 89921a4441..0bcec9612f 100644 --- a/Signum.Utilities/Reflection/ReflectionTools.cs +++ b/Signum.Utilities/Reflection/ReflectionTools.cs @@ -403,7 +403,7 @@ public static T Parse(string value) return (T)(object)value; if (value == null || value == "") - return (T)(object?)null; + return (T)(object?)null!; Type utype = typeof(T).UnNullify(); if (utype.IsEnum) @@ -449,7 +449,7 @@ public static T Parse(string value, CultureInfo culture) return (T)(object)value; if (value == null || value == "") - return (T)(object?)null; + return (T)(object?)null!; Type utype = typeof(T).UnNullify(); if (utype.IsEnum) @@ -481,7 +481,7 @@ public static bool TryParse(string value, out T result) { if (TryParse(value, typeof(T), CultureInfo.CurrentCulture, out object? objResult)) { - result = (T)objResult; + result = (T)objResult!; return true; } else @@ -495,7 +495,7 @@ public static bool TryParse(string value, CultureInfo ci, out T result) { if (TryParse(value, typeof(T), ci, out object? objResult)) { - result = (T)objResult; + result = (T)objResult!; return true; } else @@ -701,7 +701,7 @@ public static bool TryParse(string value, Type type, CultureInfo ci, out object? public static T ChangeType(object value) { if (value == null) - return (T)(object?)null; + return (T)(object?)null!; if (value.GetType() == typeof(T)) return (T)value; diff --git a/Signum.Utilities/Signum.Utilities.csproj b/Signum.Utilities/Signum.Utilities.csproj index eadfd1b5af..0b16398a45 100644 --- a/Signum.Utilities/Signum.Utilities.csproj +++ b/Signum.Utilities/Signum.Utilities.csproj @@ -4,7 +4,7 @@ netcoreapp2.2 8.0 true - true + enable true x64 diff --git a/Signum.Utilities/Statics.cs b/Signum.Utilities/Statics.cs index 0eb566994d..01dc2aa263 100644 --- a/Signum.Utilities/Statics.cs +++ b/Signum.Utilities/Statics.cs @@ -8,7 +8,7 @@ namespace Signum.Utilities { public static class Statics { - static Dictionary threadVariables = new Dictionary(); + static readonly Dictionary threadVariables = new Dictionary(); public static ThreadVariable ThreadVariable(string name, bool avoidExportImport = false) { @@ -56,7 +56,7 @@ public static void CleanThreadContextAndAssert() throw new InvalidOperationException("The thread variable \r\n" + errors); } - static Dictionary sessionVariables = new Dictionary(); + static readonly Dictionary sessionVariables = new Dictionary(); public static SessionVariable SessionVariable(string name) { @@ -101,7 +101,7 @@ public Variable(string name) public object? UntypedValue { get { return Value; } - set { Value = (T)value; } + set { Value = (T)value!; } } public bool IsClean @@ -138,7 +138,7 @@ public interface IThreadVariable: IUntypedVariable public class ThreadVariable : Variable, IThreadVariable { - AsyncLocal store = new AsyncLocal(); + readonly AsyncLocal store = new AsyncLocal(); internal ThreadVariable(string name) : base(name) { } @@ -158,7 +158,7 @@ public override void Clean() public abstract class SessionVariable: Variable { - public Func ValueFactory { get; set; } + public abstract Func ValueFactory { get; set; } protected internal SessionVariable(string name) : base(name) @@ -191,7 +191,7 @@ public SessionVariable CreateVariable(string name) class VoidVariable : SessionVariable { - //public override Func ValueFactory { get; set; } + public override Func ValueFactory { get; set; } public VoidVariable(string name) : base(name) @@ -227,7 +227,7 @@ public SessionVariable CreateVariable(string name) class SingletonVariable : SessionVariable { - //public override Func ValueFactory { get; set; } + public override Func ValueFactory { get; set; } public SingletonVariable(string name) : base(name) @@ -238,7 +238,7 @@ public override T Value get { if (singletonSession.TryGetValue(Name, out object? result)) - return (T)result; + return (T)result!; return GetDefaulValue(); } @@ -289,20 +289,19 @@ public SessionVariable CreateVariable(string name) class OverrideableVariable : SessionVariable { - SessionVariable variable; + readonly SessionVariable variable; public OverrideableVariable(SessionVariable variable) : base(variable.Name) { this.variable = variable; } - - /*CSBUG*/ - //public override Func ValueFactory - //{ - // get { return variable.ValueFactory; } - // set { variable.ValueFactory = value; } - //} + + public override Func ValueFactory + { + get { return variable.ValueFactory; } + set { variable.ValueFactory = value; } + } public override T Value { @@ -313,7 +312,7 @@ public override T Value if (dic != null) { if (dic.TryGetValue(Name, out object? result)) - return (T)result; + return (T)result!; return GetDefaulValue(); } diff --git a/Signum.Utilities/Synchronization/CultureInfoUtils.cs b/Signum.Utilities/Synchronization/CultureInfoUtils.cs index f860657b1a..0f2290cee6 100644 --- a/Signum.Utilities/Synchronization/CultureInfoUtils.cs +++ b/Signum.Utilities/Synchronization/CultureInfoUtils.cs @@ -39,7 +39,7 @@ public static class CultureInfoUtils return ChangeCulture(CultureInfo.GetCultureInfo(cultureName)); } - public static IDisposable? ChangeCulture(CultureInfo ci) + public static IDisposable? ChangeCulture(CultureInfo? ci) { if (ci == null) return null; diff --git a/Signum.Utilities/Synchronization/ResetLazy.cs b/Signum.Utilities/Synchronization/ResetLazy.cs index ab5de3b2a6..7e3420c266 100644 --- a/Signum.Utilities/Synchronization/ResetLazy.cs +++ b/Signum.Utilities/Synchronization/ResetLazy.cs @@ -29,7 +29,7 @@ public ResetLazyStats(Type type) [ComVisible(false)] - public class ResetLazy: IResetLazy where T : class + public class ResetLazy: IResetLazy { class Box { From 7664706e817ebf07ead2a2fd818f90d6b3a39927 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Mon, 28 Jan 2019 08:01:49 +0100 Subject: [PATCH 12/25] bring Try back to live --- Signum.Utilities/Extensions/Extensions.cs | 51 +++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/Signum.Utilities/Extensions/Extensions.cs b/Signum.Utilities/Extensions/Extensions.cs index 17f0972b4b..ced4c0fa34 100644 --- a/Signum.Utilities/Extensions/Extensions.cs +++ b/Signum.Utilities/Extensions/Extensions.cs @@ -300,6 +300,57 @@ public static R Let(this T t, Func func) return func(t); } + public delegate R? TryCC(T val) where T : class where R : class; + public static R? Try(this T? t, TryCC func) where T : class where R : class + { + if (t == null) + return null; + return func(t); + } + + public delegate R TryCS(T val) where T : class where R : struct; + public static R? Try(this T? t, TryCS func) where T : class where R : struct + { + if (t == null) + return null; + return func(t); + } + + public delegate R? TryCN(T val) where T : class where R : struct; + public static R? Try(this T? t, TryCN func) where T : class where R : struct + { + if (t == null) + return null; + return func(t); + } + + public delegate R? TrySC(T val) where T : struct where R : class; + public static R? Try(this T? t, TrySC func) where T : struct where R : class + { + if (t == null) + return null; + return func(t.Value); + } + + public delegate R TrySS(T val) where T : struct where R : struct; + public static R? Try(this T? t, TrySS func) where T : struct where R : struct + { + if (t == null) + return null; + + return func(t.Value); + } + + public delegate R? TrySN(T val) where T : struct where R : struct; + public static R? Try(this T? t, TrySN func) where T : struct where R : struct + { + if (t == null) + return null; + + return func(t.Value); + } + + public static T Do(this T t, Action action) { action(t); From ec253447d53dc8935a5eff38f500310d5ce15920 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Mon, 28 Jan 2019 08:02:01 +0100 Subject: [PATCH 13/25] update tests --- Signum.Entities/Lite.cs | 4 +- Signum.Test/Environment/Entities.cs | 50 +++++++++---------- Signum.Test/Environment/MusicLoader.cs | 6 +-- Signum.Test/Environment/MusicLogic.cs | 4 +- Signum.Test/Environment/MusicStarter.cs | 2 +- Signum.Test/ExtensionsTest.cs | 2 +- Signum.Test/LinqProvider/GroupByTest.cs | 8 +-- Signum.Test/LinqProvider/OrderByTest.cs | 4 +- .../LinqProvider/SelectImplementations.cs | 10 ++-- Signum.Test/LinqProvider/SelectNestedTest.cs | 4 +- Signum.Test/LinqProvider/SelectTest.cs | 20 ++++---- Signum.Test/LinqProvider/UnsafeUpdateTest.cs | 30 +++++------ Signum.Test/LinqProvider/WhereTest.cs | 8 +-- Signum.Test/MetaTest.cs | 12 ++--- Signum.Test/ObjectNameTest.cs | 10 ++-- Signum.Test/Signum.Test.csproj | 8 ++- 16 files changed, 94 insertions(+), 88 deletions(-) diff --git a/Signum.Entities/Lite.cs b/Signum.Entities/Lite.cs index 277c83f517..480a095c86 100644 --- a/Signum.Entities/Lite.cs +++ b/Signum.Entities/Lite.cs @@ -412,7 +412,7 @@ public Expression Expand(Expression instance, Expression[] arguments, MethodInfo [MethodExpander(typeof(IsExpander))] - public static bool Is(this T entity1, T entity2) + public static bool Is(this T? entity1, T? entity2) where T : class, IEntity { if (entity1 == null && entity2 == null) @@ -431,7 +431,7 @@ public static bool Is(this T entity1, T entity2) } [MethodExpander(typeof(IsExpander))] - public static bool Is(this Lite lite1, Lite lite2) + public static bool Is(this Lite? lite1, Lite? lite2) where T : class, IEntity { if (lite1 == null && lite2 == null) diff --git a/Signum.Test/Environment/Entities.cs b/Signum.Test/Environment/Entities.cs index 07a33eafb6..02100c07f4 100644 --- a/Signum.Test/Environment/Entities.cs +++ b/Signum.Test/Environment/Entities.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Signum.Entities; @@ -16,14 +16,14 @@ namespace Signum.Test.Environment public class NoteWithDateEntity : Entity { [Nullable] - [StringLengthValidator(AllowNulls = false, Min = 3, MultiLine = true)] + [StringLengthValidator(Min = 3, MultiLine = true)] public string Text { get; set; } [ImplementedByAll] public IEntity Target { get; set; } [ImplementedByAll] - public Lite OtherTarget { get; set; } + public Lite? OtherTarget { get; set; } public DateTime CreationTime { get; set; } @@ -38,7 +38,7 @@ public class ColaboratorsMixin : MixinEntity { ColaboratorsMixin(Entity mainEntity, MixinEntity next) : base(mainEntity, next) { } - [NotNullValidator, NoRepeatValidator] + [NoRepeatValidator] public MList Colaborators { get; set; } = new MList(); } @@ -53,7 +53,7 @@ public interface IAuthorEntity : IEntity { string Name { get; } - AwardEntity LastAward { get; } + AwardEntity? LastAward { get; } string FullName { get; } @@ -63,7 +63,7 @@ public interface IAuthorEntity : IEntity [Serializable, EntityKind(EntityKind.Shared, EntityData.Transactional)] public class ArtistEntity : Entity, IAuthorEntity { - [StringLengthValidator(AllowNulls = false, Min = 3, Max = 100)] + [StringLengthValidator(Min = 3, Max = 100)] public string Name { get; set; } public bool Dead { get; set; } @@ -80,7 +80,7 @@ public bool IsMale } [ImplementedByAll] - public AwardEntity LastAward { get; set; } + public AwardEntity? LastAward { get; set; } static Expression>>> FriendsCovariantExpression = a => a.Friends; @@ -93,7 +93,7 @@ public IEnumerable> FriendsCovariant() public MList> Friends { get; set; } = new MList>(); [Ignore] - [NotNullValidator, NoRepeatValidator] + [NoRepeatValidator] public MList Nominations { get; set; } = new MList(); @@ -157,16 +157,16 @@ public enum Status public class BandEntity : Entity, IAuthorEntity { [UniqueIndex] - [StringLengthValidator(AllowNulls = false, Min = 3, Max = 100)] + [StringLengthValidator(Min = 3, Max = 100)] public string Name { get; set; } [NotNullValidator] public MList Members { get; set; } = new MList(); [ImplementedBy(typeof(GrammyAwardEntity), typeof(AmericanMusicAwardEntity))] - public AwardEntity LastAward { get; set; } + public AwardEntity? LastAward { get; set; } - [NotNullValidator, ImplementedBy(typeof(GrammyAwardEntity), typeof(AmericanMusicAwardEntity))] + [ImplementedBy(typeof(GrammyAwardEntity), typeof(AmericanMusicAwardEntity))] public MList OtherAwards { get; set; } = new MList(); static Expression> FullNameExpression = @@ -204,7 +204,7 @@ public abstract class AwardEntity : Entity { public int Year { get; set; } - [StringLengthValidator(AllowNulls = false, Min = 3, Max = 100)] + [StringLengthValidator(Min = 3, Max = 100)] public string Category { get; set; } public AwardResult Result { get; set; } @@ -242,12 +242,12 @@ public class PersonalAwardEntity : AwardEntity public class LabelEntity : Entity { [UniqueIndex] - [StringLengthValidator(AllowNulls = false, Min = 3, Max = 100)] + [StringLengthValidator(Min = 3, Max = 100)] public string Name { get; set; } public CountryEntity Country { get; set; } - public Lite Owner { get; set; } + public Lite? Owner { get; set; } [UniqueIndex] public SqlHierarchyId Node { get; set; } @@ -270,7 +270,7 @@ public static class LabelOperation public class CountryEntity : Entity { [UniqueIndex] - [StringLengthValidator(AllowNulls = false, Min = 3, Max = 100)] + [StringLengthValidator(Min = 3, Max = 100)] public string Name { get; set; } public override string ToString() @@ -283,20 +283,19 @@ public override string ToString() public class AlbumEntity : Entity, ISecretContainer { [UniqueIndex] - [StringLengthValidator(AllowNulls = false, Min = 3, Max = 100)] + [StringLengthValidator(Min = 3, Max = 100)] public string Name { get; set; } [NumberBetweenValidator(1900, 2100)] public int Year { get; set; } [ImplementedBy(typeof(ArtistEntity), typeof(BandEntity))] - [NotNullValidator] public IAuthorEntity Author { get; set; } - [NotNullValidator, PreserveOrder] + [PreserveOrder] public MList Songs { get; set; } = new MList(); - public SongEmbedded BonusTrack { get; set; } + public SongEmbedded? BonusTrack { get; set; } public LabelEntity Label { get; set; } @@ -339,7 +338,7 @@ public static class AlbumOperation [Serializable] public class SongEmbedded : EmbeddedEntity { - [StringLengthValidator(AllowNulls = false, Min = 3, Max = 100)] + [StringLengthValidator(Min = 3, Max = 100)] public string Name { get; set; } TimeSpan? duration; @@ -371,6 +370,7 @@ public class AwardNominationEntity : Entity, ICanBeOrdered [ImplementedBy(typeof(ArtistEntity), typeof(BandEntity))] public Lite Author { get; set; } + [Nullable] [ImplementedBy(typeof(GrammyAwardEntity), typeof(PersonalAwardEntity), typeof(AmericanMusicAwardEntity))] public Lite Award { get; set; } @@ -379,7 +379,7 @@ public class AwardNominationEntity : Entity, ICanBeOrdered public int Order { get; set; } [PreserveOrder] - [NotNullValidator, NoRepeatValidator] + [NoRepeatValidator] public MList Points { get; set; } = new MList(); } @@ -392,7 +392,7 @@ public class NominationPointEmbedded : EmbeddedEntity [Serializable, EntityKind(EntityKind.Main, EntityData.Transactional)] public class ConfigEntity : Entity { - public EmbeddedConfigEmbedded EmbeddedConfig { get; set; } + public EmbeddedConfigEmbedded? EmbeddedConfig { get; set; } } [AutoInit] @@ -403,9 +403,9 @@ public static class ConfigOperation public class EmbeddedConfigEmbedded : EmbeddedEntity { - public Lite DefaultLabel { get; set; } + public Lite? DefaultLabel { get; set; } - [NotNullValidator, NoRepeatValidator] + [NoRepeatValidator] public MList> Awards { get; set; } = new MList>(); } @@ -455,7 +455,7 @@ public class IntValue : IView public class FolderEntity : Entity { [UniqueIndex] - [StringLengthValidator(AllowNulls = false, Max = 100)] + [StringLengthValidator(Max = 100)] public string Name { get; set; } public Lite Parent { get; set; } diff --git a/Signum.Test/Environment/MusicLoader.cs b/Signum.Test/Environment/MusicLoader.cs index 89b69fbc1a..fed9f01952 100644 --- a/Signum.Test/Environment/MusicLoader.cs +++ b/Signum.Test/Environment/MusicLoader.cs @@ -1,4 +1,4 @@ -using Microsoft.SqlServer.Types; +using Microsoft.SqlServer.Types; using Signum.Engine; using Signum.Engine.Operations; using Signum.Entities; @@ -112,7 +112,7 @@ public static void Load() new NoteWithDateEntity { CreationTime = new DateTime(2009, 6, 25, 0, 0, 0), Text = "Death on June, 25th", Target = michael } .Execute(NoteWithDateOperation.Save); - new NoteWithDateEntity { CreationTime = new DateTime(2000, 1, 1, 0, 0, 0), Text = null, Target = michael } + new NoteWithDateEntity { CreationTime = new DateTime(2000, 1, 1, 0, 0, 0), Text = null!, Target = michael } .SetMixin((CorruptMixin c) => c.Corrupt, true) .Do(n => n.Mixin().Colaborators.Add(michael)) .Execute(NoteWithDateOperation.Save); @@ -235,7 +235,7 @@ public static void Load() new AwardNominationEntity { Author = smashingPumpkins.ToLite(), Award = ama.ToLite() }.Save(); new AwardNominationEntity { Author = michael.ToLite(), Award = pa.ToLite() }.Save(); - new AwardNominationEntity { Author = michael.ToLite(), Award = null}.Save(); + new AwardNominationEntity { Author = michael.ToLite(), Award = null!}.Save(); new ConfigEntity { diff --git a/Signum.Test/Environment/MusicLogic.cs b/Signum.Test/Environment/MusicLogic.cs index ae5190c96f..3e9b4e6f7e 100644 --- a/Signum.Test/Environment/MusicLogic.cs +++ b/Signum.Test/Environment/MusicLogic.cs @@ -1,4 +1,4 @@ -using Signum.Engine; +using Signum.Engine; using Signum.Engine.Basics; using Signum.Engine.DynamicQuery; using Signum.Engine.Maps; @@ -237,7 +237,7 @@ public static void Register() new ConstructFrom(AlbumOperation.CreateAlbumFromBand) { ToStates = { AlbumState.Saved }, - Construct = (BandEntity band, object[] args) => + Construct = (BandEntity band, object[]? args) => new AlbumEntity { Author = band, diff --git a/Signum.Test/Environment/MusicStarter.cs b/Signum.Test/Environment/MusicStarter.cs index b81a12eeb6..4459b16416 100644 --- a/Signum.Test/Environment/MusicStarter.cs +++ b/Signum.Test/Environment/MusicStarter.cs @@ -66,7 +66,7 @@ public static void Start(string connectionString) if (!Schema.Current.Settings.TypeValues.ContainsKey(typeof(TimeSpan))) { sb.Settings.FieldAttributes((AlbumEntity a) => a.Songs[0].Duration).Add(new Signum.Entities.IgnoreAttribute()); - sb.Settings.FieldAttributes((AlbumEntity a) => a.BonusTrack.Duration).Add(new Signum.Entities.IgnoreAttribute()); + sb.Settings.FieldAttributes((AlbumEntity a) => a.BonusTrack!.Duration).Add(new Signum.Entities.IgnoreAttribute()); } if(sqlVersion > SqlServerVersion.SqlServer2008) diff --git a/Signum.Test/ExtensionsTest.cs b/Signum.Test/ExtensionsTest.cs index ac809f6a38..919e4b9da9 100644 --- a/Signum.Test/ExtensionsTest.cs +++ b/Signum.Test/ExtensionsTest.cs @@ -18,7 +18,7 @@ public void CartesianProduct() [Fact] public void DelegateOrder() { - Action action = null; + Action action = null!; action += A; action += B; diff --git a/Signum.Test/LinqProvider/GroupByTest.cs b/Signum.Test/LinqProvider/GroupByTest.cs index f74b9b0d62..39290ac6d1 100644 --- a/Signum.Test/LinqProvider/GroupByTest.cs +++ b/Signum.Test/LinqProvider/GroupByTest.cs @@ -1,4 +1,4 @@ -using Xunit; +using Xunit; using Signum.Engine; using Signum.Entities; using Signum.Test.Environment; @@ -577,7 +577,7 @@ where a.Songs.Count > 1 Last = a.Songs.OrderByDescending(s => s.Name).FirstOrDefault() }).ToList(); - Assert.True(list.All(a => a.FirstName != a.Last.Name)); + Assert.True(list.All(a => a.FirstName != a.Last!/*CSBUG*/.Name)); } [Fact] @@ -593,7 +593,7 @@ where g.Count() > 1 Last = g.OrderByDescending(s => s.Name).FirstOrDefault() }).ToList(); - Assert.True(list.All(a => a.FirstName != a.Last.Name)); + Assert.True(list.All(a => a.FirstName != a.Last!/*CSBUG*/.Name)); } @@ -612,7 +612,7 @@ where songs.Count > 1 Last = songs.OrderByDescending(s => s.Name).FirstOrDefault() }).ToList(); - Assert.True(list.All(a => a.FirstName != a.Last.Name)); + Assert.True(list.All(a => a.FirstName != a.Last!/*CSBUG*/.Name)); } diff --git a/Signum.Test/LinqProvider/OrderByTest.cs b/Signum.Test/LinqProvider/OrderByTest.cs index 9c4b50c8aa..c72a6064ca 100644 --- a/Signum.Test/LinqProvider/OrderByTest.cs +++ b/Signum.Test/LinqProvider/OrderByTest.cs @@ -138,7 +138,7 @@ public void OrderByIgnore() Database.Query().Where(a => a.Songs.OrderBy(s => s.Name).All(s => s.Name.StartsWith("a"))).Select(a => a.Id).ToList(); using (AsserNoQueryWith("ORDER")) - Database.Query().Where(a => a.Songs.OrderBy(s => s.Name).Contains(null)).Select(a => a.Id).ToList(); + Database.Query().Where(a => a.Songs.OrderBy(s => s.Name).Contains(null!)).Select(a => a.Id).ToList(); @@ -155,7 +155,7 @@ public void OrderByIgnore() Database.Query().OrderBy(a => a.Name).All(s => s.Name.StartsWith("a")); using (AsserNoQueryWith("ORDER")) - Database.Query().OrderBy(a => a.Name).Contains(null); + Database.Query().OrderBy(a => a.Name).Contains(null!); } diff --git a/Signum.Test/LinqProvider/SelectImplementations.cs b/Signum.Test/LinqProvider/SelectImplementations.cs index 8c377fbc79..5588358959 100644 --- a/Signum.Test/LinqProvider/SelectImplementations.cs +++ b/Signum.Test/LinqProvider/SelectImplementations.cs @@ -1,4 +1,4 @@ -using Xunit; +using Xunit; using Signum.Engine; using Signum.Entities; using Signum.Test.Environment; @@ -30,7 +30,7 @@ public void SelectType() public void SelectTypeNull() { var list = Database.Query() - .Select(a => new { Label = a.ToLite(), Owner = a.Owner, OwnerType = a.Owner.Entity.GetType() }).ToList(); + .Select(a => new { Label = a.ToLite(), Owner = a.Owner, OwnerType = a.Owner!.Entity.GetType() }).ToList(); } [Fact] @@ -266,21 +266,21 @@ public void SelectCastIBPolymorphicSwitch() public void SelectCastIBPolymorphicForceNullify() { var list = (from a in Database.Query() - select (int?)a.Award.Entity.Year).ToList(); + select (int?)a.Award!.Entity.Year).ToList(); } [Fact] public void SelectCastIBPolymorphicIBUnion() { var list = (from a in Database.Query() - select a.Author.CombineUnion().LastAward.ToLite()).ToList(); + select a.Author.CombineUnion().LastAward.Try(la => la.ToLite())).ToList(); } [Fact] public void SelectCastIBPolymorphicIBSwitch() { var list = (from a in Database.Query() - select a.Author.CombineCase().LastAward.ToLite()).ToList(); + select a.Author.CombineCase().LastAward.Try(la => la.ToLite())).ToList(); } [Fact] diff --git a/Signum.Test/LinqProvider/SelectNestedTest.cs b/Signum.Test/LinqProvider/SelectNestedTest.cs index 93c6134244..ecb33c31d1 100644 --- a/Signum.Test/LinqProvider/SelectNestedTest.cs +++ b/Signum.Test/LinqProvider/SelectNestedTest.cs @@ -1,4 +1,4 @@ -using System.Linq; +using System.Linq; using Xunit; using Signum.Engine; using Signum.Entities; @@ -40,7 +40,7 @@ public void SelecteNestedIB() public void SelecteNullableLookupColumns() { var neasted = (from l in Database.Query() - join o in Database.Query().DefaultIfEmpty() on l.Owner.Entity equals o + join o in Database.Query().DefaultIfEmpty() on l.Owner!.Entity equals o group l.ToLite() by o.ToLite() into g select new { diff --git a/Signum.Test/LinqProvider/SelectTest.cs b/Signum.Test/LinqProvider/SelectTest.cs index f587b85d75..c717aeae04 100644 --- a/Signum.Test/LinqProvider/SelectTest.cs +++ b/Signum.Test/LinqProvider/SelectTest.cs @@ -90,7 +90,7 @@ public void SelectAnonymous() [Fact] public void SelectNoColumns() { - var list = Database.Query().Select(a => new { DateTime.Now, Album = (AlbumEntity)null, Artist = (Lite)null }).ToList(); + var list = Database.Query().Select(a => new { DateTime.Now, Album = (AlbumEntity?)null, Artist = (Lite?)null }).ToList(); } [Fact] @@ -146,7 +146,7 @@ public void SelectConditionalToLite() public void SelectConditionalToLiteNull() { var list = (from l in Database.Query() - let owner = (l.Owner == null ? null : l.Owner).Entity + let owner = (l.Owner == null ? null : l.Owner)!.Entity select owner.ToLite(owner.Name)).ToList(); } #pragma warning restore IDE0029 // Use coalesce expression @@ -162,7 +162,7 @@ public void SelectConditionalGetType() public void SelectCoallesceMember() { var list = (from l in Database.Query() - select (l.Owner.Entity ?? l).Name).ToList(); + select (l.Owner!.Entity ?? l).Name).ToList(); } @@ -170,7 +170,7 @@ public void SelectCoallesceMember() public void SelectCoallesceToLite() { var list = (from l in Database.Query() - select (l.Owner.Entity ?? l).ToLite()).ToList(); + select (l.Owner!.Entity ?? l).ToLite()).ToList(); } @@ -178,7 +178,7 @@ public void SelectCoallesceToLite() public void SelectCoallesceGetType() { var list = (from l in Database.Query() - select (l.Owner.Entity ?? l).GetType()).ToList(); + select (l.Owner!.Entity ?? l).GetType()).ToList(); } @@ -400,7 +400,7 @@ public void SelectAvoidNominateEntity() select new { a.Name, - Friend = (Lite)null + Friend = (Lite?)null }).ToList(); } @@ -506,14 +506,14 @@ where mich.Name.Contains("Michael") [Fact] public void SelectIBAId() { - var list = Database.Query().Select(a => (PrimaryKey?)a.LastAward.Id).ToList(); + var list = Database.Query().Select(a => a.LastAward.Try(la => la.Id)).ToList(); } [Fact] public void SelectIBAIdObject() { var e = Assert.Throws(() => - Database.Query().Select(a => ((int?)a.LastAward.Id).InSql()).ToList()); + Database.Query().Select(a => a.LastAward.Try(la => (int?)la.Id).InSql()).ToList()); Assert.Contains("translated", e.Message); } @@ -562,7 +562,7 @@ public void SelectToStringLite() public void SelectConditionEnum() { var results = from b in Database.Query() - let ga = (GrammyAwardEntity)b.LastAward + let ga = (GrammyAwardEntity?)b.LastAward select (AwardResult?)(ga.Result < ga.Result ? (int)ga.Result : (int)ga.Result).InSql(); results.ToList(); @@ -633,7 +633,7 @@ public void SelectView() [Fact] public void SelectRetrieve() { - var e = Assert.Throws(() => Database.Query().Select(l => l.Owner.Retrieve()).ToList()); + var e = Assert.Throws(() => Database.Query().Select(l => l.Owner!.Retrieve()).ToList()); Assert.Contains("not supported", e.Message); } diff --git a/Signum.Test/LinqProvider/UnsafeUpdateTest.cs b/Signum.Test/LinqProvider/UnsafeUpdateTest.cs index 09a0ef5ffa..43e3d6b395 100644 --- a/Signum.Test/LinqProvider/UnsafeUpdateTest.cs +++ b/Signum.Test/LinqProvider/UnsafeUpdateTest.cs @@ -51,7 +51,7 @@ public void UpdateValueNull() { using (Transaction tr = new Transaction()) { - int count = Database.Query().UnsafeUpdate().Set(a => a.Text, a => null).Execute(); + int count = Database.Query().UnsafeUpdate().Set(a => a.Text, a => null!).Execute(); //tr.Commit(); } @@ -112,7 +112,7 @@ public void UpdateEfie() .Execute(); Assert.False(Database.Query().Any(a => a.BonusTrack == null)); - Assert.Equal("Mana Mana", Database.Query().Select(a => a.BonusTrack.Name).Distinct().SingleEx()); + Assert.Equal("Mana Mana", Database.Query().Select(a => a.BonusTrack.Try(b => b.Name)).Distinct().SingleEx()); //tr.Commit(); } @@ -129,7 +129,7 @@ public void UpdateEfieNull() .Execute(); Assert.True(Database.Query().All(a => a.BonusTrack == null)); - Assert.True(Database.Query().All(a => a.BonusTrack.Name == null)); + Assert.True(Database.Query().All(a => a.BonusTrack.Try(bt => bt.Name) == null)); //tr.Commit(); } } @@ -150,7 +150,7 @@ public void UpdateEfieConditional() .Set(a => a.BonusTrack, a => (int)a.Id % 2 == 0 ? song : null) .Execute(); - Assert.True(Database.Query().All(a => (int)a.Id % 2 == 0 ? a.BonusTrack.Name == "Mana Mana" : a.BonusTrack.Name == null)); + Assert.True(Database.Query().All(a => (int)a.Id % 2 == 0 ? a.BonusTrack.Try(b => b.Name) == "Mana Mana" : a.BonusTrack.Try(b => b.Name) == null)); //tr.Commit(); } @@ -252,7 +252,7 @@ public void UpdateFieNull() using (Transaction tr = new Transaction()) { int count = Database.Query().UnsafeUpdate() - .Set(a => a.Label, a => null) + .Set(a => a.Label, a => null!) .Execute(); //tr.Commit(); } @@ -283,7 +283,7 @@ public void UpdateIbFieConditional() ArtistEntity michael = Database.Query().SingleEx(a => a.Dead); int count = Database.Query().UnsafeUpdate() - .Set(a => a.Author, a => a.Id > 1 ? michael : null) + .Set(a => a.Author, a => a.Id > 1 ? michael : null!) .Execute(); //tr.Commit(); } @@ -295,7 +295,7 @@ public void UpdateIbNull() using (Transaction tr = new Transaction()) { int count = Database.Query().UnsafeUpdate() - .Set(a => a.Author, a => null) + .Set(a => a.Author, a => null!) .Execute(); //tr.Commit(); } @@ -336,7 +336,7 @@ public void UpdateIbaNull() using (Transaction tr = new Transaction()) { int count = Database.Query().UnsafeUpdate() - .Set(a => a.Target, a => null) + .Set(a => a.Target, a => null!) .Execute(); //tr.Commit(); } @@ -364,7 +364,7 @@ public void UpdateIbaConditional() ArtistEntity michael = Database.Query().SingleEx(a => a.Dead); int count = Database.Query().UnsafeUpdate() - .Set(a => a.Target, a => a.CreationTime > DateTime.Now ? michael : null) + .Set(a => a.Target, a => a.CreationTime > DateTime.Now ? michael : null!) .Execute(); //tr.Commit(); } @@ -420,7 +420,7 @@ public void UpdateEmbeddedField() using (Transaction tr = new Transaction()) { int count = Database.Query().UnsafeUpdate() - .Set(a => a.BonusTrack.Name, a => a.BonusTrack.Name + " - ") + .Set(a => a.BonusTrack!.Name, a => a.BonusTrack!.Name + " - ") .Execute(); //tr.Commit(); } @@ -447,8 +447,8 @@ public void UnsafeUpdatePart() { int count = Database.Query() .Select(a => new { a.Label, Album = a }) - .UnsafeUpdatePart(p => p.Label) - .Set(a => a.Name, p => p.Label.Name + "/" + p.Album.Id) + .UnsafeUpdatePart(p => p.Label!) + .Set(a => a.Name, p => p.Label!.Name + "/" + p.Album!.Id) .Execute(); var list = Database.Query().Select(a => a.Name); @@ -515,7 +515,7 @@ from mle in a.MListElements(_ => _.Songs) { LabelId = a.Label.Id, mle - }).UnsafeUpdateMListPart(p => p.mle) + }).UnsafeUpdateMListPart(p => p.mle!) /*CSBUG*/ .Set(mle => mle.Element.Seconds, p => (int)p.LabelId) .Execute(); @@ -542,7 +542,7 @@ public void UnsafeUpdatePartExpand() using (Transaction tr = new Transaction()) { Database.Query() - .UnsafeUpdatePart(lb => lb.Owner.Entity.Country) + .UnsafeUpdatePart(lb => lb.Owner!.Entity.Country) .Set(ctr => ctr.Name, lb => lb.Name) .Execute(); } @@ -556,7 +556,7 @@ public void UnsafeUpdateNullableEmbeddedValue() { Database.Query() .UnsafeUpdate() - .Set(ctr => ctr.BonusTrack.Index, lb => 2) + .Set(ctr => ctr.BonusTrack!.Index, lb => 2) .Execute(); } } diff --git a/Signum.Test/LinqProvider/WhereTest.cs b/Signum.Test/LinqProvider/WhereTest.cs index 47ee8fdb2a..7f5fbfde62 100644 --- a/Signum.Test/LinqProvider/WhereTest.cs +++ b/Signum.Test/LinqProvider/WhereTest.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using Xunit; using Signum.Engine; @@ -201,7 +201,7 @@ where a.Author is ArtistEntity [Fact] public void WhereRefersTo1() { - var lite = (Lite)null; + var lite = (Lite?)null; var first = Database.Query().Where(b => lite.Is(b)).FirstOrDefault(); @@ -211,7 +211,7 @@ public void WhereRefersTo1() [Fact] public void WhereRefersTo2() { - var entity = (BandEntity)null; + var entity = (BandEntity?)null; var first = Database.Query().Where(b => b.ToLite().Is(entity)).FirstOrDefault(); @@ -340,7 +340,7 @@ public void WhereOutsideIs() [Fact] public void WhereOutsideCast() { - var albums = Database.Query().Where(a => ((PersonalAwardEntity)a.LastAward) != null).ToList(); + var albums = Database.Query().Where(a => ((PersonalAwardEntity?)a.LastAward) != null).ToList(); } [Fact] diff --git a/Signum.Test/MetaTest.cs b/Signum.Test/MetaTest.cs index 5df6a643ca..c8d8957a37 100644 --- a/Signum.Test/MetaTest.cs +++ b/Signum.Test/MetaTest.cs @@ -66,7 +66,7 @@ join a in Database.Query() on l equals a.Label Assert.IsType(dic["Name"]); Assert.IsType(dic["Sum"]); - var metas = ((DirtyMeta)dic["Sum"]).CleanMetas; + var metas = ((DirtyMeta)dic["Sum"]!).CleanMetas; Assert.Equal("(Album).Name,(Label).Name", metas.SelectMany(cm => cm.PropertyRoutes).Distinct().ToString(",")); } @@ -81,7 +81,7 @@ join a in Database.Query() on l equals a.Label into g Assert.IsType(dic["Name"]); Assert.IsType(dic["Num"]); - Assert.True(((DirtyMeta)dic["Num"]).CleanMetas.Count == 0); + Assert.True(((DirtyMeta)dic["Num"]!).CleanMetas.Count == 0); } [Fact] @@ -95,7 +95,7 @@ group a by a.Label into g Assert.IsType(dic["Key"]); Assert.IsType(dic["Num"]); - Assert.True(((DirtyMeta)dic["Num"]).CleanMetas.Count == 0); + Assert.True(((DirtyMeta)dic["Num"]!).CleanMetas.Count == 0); } [Fact] @@ -110,7 +110,7 @@ from s in a.Songs Assert.IsType(dic["Name"]); Assert.IsType(dic["Song"]); - Assert.Equal("(Album).Songs/Name", ((CleanMeta)dic["Song"]).PropertyRoutes[0].ToString()); + Assert.Equal("(Album).Songs/Name", ((CleanMeta)dic["Song"]!).PropertyRoutes[0].ToString()); } [Fact] @@ -121,7 +121,7 @@ from a in Database.Query() select new { Author = (ArtistEntity)a.Author ?? (IAuthorEntity)(BandEntity)a.Author } ); - DirtyMeta meta = (DirtyMeta)dic["Author"]; + DirtyMeta meta = (DirtyMeta)dic["Author"]!; Assert.Equal(meta.Implementations, Implementations.By(typeof(ArtistEntity), typeof(BandEntity))); } @@ -134,7 +134,7 @@ from a in Database.Query() select new { Author = a.Id > 1 ? (ArtistEntity)a.Author : (IAuthorEntity)(BandEntity)a.Author } ); - DirtyMeta meta = (DirtyMeta)dic["Author"]; + DirtyMeta meta = (DirtyMeta)dic["Author"]!; Assert.Equal(meta.Implementations, Implementations.By(typeof(ArtistEntity), typeof(BandEntity))); } diff --git a/Signum.Test/ObjectNameTest.cs b/Signum.Test/ObjectNameTest.cs index 52d6f8f8d8..28cacc0161 100644 --- a/Signum.Test/ObjectNameTest.cs +++ b/Signum.Test/ObjectNameTest.cs @@ -1,4 +1,4 @@ -using Xunit; +using Xunit; using Signum.Engine.Maps; namespace Signum.Test @@ -45,8 +45,8 @@ public void ParseServerName() var simple = ObjectName.Parse("[FROM].[SELECT].[WHERE].[TOP]"); Assert.Equal("TOP", simple.Name); Assert.Equal("WHERE", simple.Schema.Name); - Assert.Equal("SELECT", simple.Schema.Database.Name); - Assert.Equal("FROM", simple.Schema.Database.Server.Name); + Assert.Equal("SELECT", simple.Schema.Database!.Name); + Assert.Equal("FROM", simple.Schema.Database!.Server!.Name); } @@ -56,8 +56,8 @@ public void ParseServerNameSuperComplex() var simple = ObjectName.Parse("[FROM].[SELECT].[WHERE].[TOP.DISTINCT]"); Assert.Equal("TOP.DISTINCT", simple.Name); Assert.Equal("WHERE", simple.Schema.Name); - Assert.Equal("SELECT", simple.Schema.Database.Name); - Assert.Equal("FROM", simple.Schema.Database.Server.Name); + Assert.Equal("SELECT", simple.Schema.Database!.Name); + Assert.Equal("FROM", simple.Schema.Database!.Server!.Name); } } } diff --git a/Signum.Test/Signum.Test.csproj b/Signum.Test/Signum.Test.csproj index 96ecf5bd41..785fd30a99 100644 --- a/Signum.Test/Signum.Test.csproj +++ b/Signum.Test/Signum.Test.csproj @@ -2,12 +2,18 @@ netcoreapp2.2 - latest + 8.0 SignumTest true + enable + true x64 + + 1701;1702;8629;8618 + + From ad1d2dd9361764fd7b8d7d793ef9e7a0ae0a7526 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Tue, 29 Jan 2019 07:48:09 +0100 Subject: [PATCH 14/25] remove many CSBUG --- Signum.Engine/Connection/SqlConnector.cs | 2 +- Signum.Engine/DynamicQuery/DynamicQuery.cs | 8 +-- Signum.Engine/Engine/SchemaSynchronizer.cs | 4 +- Signum.Engine/Engine/SqlBuilder.cs | 3 +- Signum.Engine/Engine/SqlPreCommand.cs | 6 +-- Signum.Engine/Linq/DbQueryProvider.cs | 2 +- .../ChildProjectionFlattener.cs | 2 +- .../Linq/ExpressionVisitor/ColumnProjector.cs | 1 - .../ExpressionVisitor/ConditionsRewriter.cs | 4 +- .../DbExpressionNominator.cs | 10 ++-- .../Linq/ExpressionVisitor/EntityCompleter.cs | 2 +- .../OverloadingSimplifier.cs | 2 +- .../Linq/ExpressionVisitor/QueryBinder.cs | 53 ++++++++----------- .../Linq/ExpressionVisitor/QueryFormatter.cs | 2 +- .../ExpressionVisitor/TranslatorBuilder.cs | 2 +- Signum.Engine/Linq/Meta/MetadataVisitor.cs | 10 ++-- Signum.Engine/Patterns/DeletePart.cs | 4 +- Signum.Engine/Schema/Schema.Basics.cs | 6 +-- Signum.Engine/Schema/Schema.Expressions.cs | 6 +-- .../Schema/SchemaBuilder/SchemaBuilder.cs | 15 +++--- Signum.React/Signum.React.csproj | 6 +-- Signum.Utilities/ExpressionTrees/Query.cs | 2 +- .../ExpressionTrees/QueryProvider.cs | 4 +- 23 files changed, 69 insertions(+), 87 deletions(-) diff --git a/Signum.Engine/Connection/SqlConnector.cs b/Signum.Engine/Connection/SqlConnector.cs index cb7dbfaf8e..ecf73140f0 100644 --- a/Signum.Engine/Connection/SqlConnector.cs +++ b/Signum.Engine/Connection/SqlConnector.cs @@ -387,7 +387,7 @@ Exception ReplaceException(Exception ex, SqlPreCommandSimple command) } } - return ex! /*CSBUG*/; + return ex; } protected internal override void BulkCopy(DataTable dt, ObjectName destinationTable, SqlBulkCopyOptions options, int? timeout) diff --git a/Signum.Engine/DynamicQuery/DynamicQuery.cs b/Signum.Engine/DynamicQuery/DynamicQuery.cs index 0db3f0f21e..b384e4f294 100644 --- a/Signum.Engine/DynamicQuery/DynamicQuery.cs +++ b/Signum.Engine/DynamicQuery/DynamicQuery.cs @@ -678,7 +678,7 @@ public static async Task> TryPaginateAsync(this DQueryabl return new DEnumerableCount(listTask, query.Context, countTask); } - throw new InvalidOperationException("pagination type {0} not expexted".FormatWith(pagination!.GetType().Name)); /*CSBUG*/ + throw new InvalidOperationException("pagination type {0} not expexted".FormatWith(pagination.GetType().Name)); } public static DEnumerableCount TryPaginate(this DQueryable query, Pagination pagination) @@ -713,7 +713,7 @@ public static DEnumerableCount TryPaginate(this DQueryable query, Pagin return new DEnumerableCount(list, query.Context, count); } - throw new InvalidOperationException("pagination type {0} not expexted".FormatWith(pagination!.GetType().Name)); /*CSBUG*/ + throw new InvalidOperationException("pagination type {0} not expexted".FormatWith(pagination.GetType().Name)); } public static DEnumerableCount TryPaginate(this DEnumerable collection, Pagination pagination) @@ -751,7 +751,7 @@ public static DEnumerableCount TryPaginate(this DEnumerable collection, return new DEnumerableCount(list, collection.Context, totalElements ?? collection.Collection.Count()); } - throw new InvalidOperationException("pagination type {0} not expexted".FormatWith(pagination!.GetType().Name)); /*CSBUG*/ + throw new InvalidOperationException("pagination type {0} not expexted".FormatWith(pagination.GetType().Name)); } public static DEnumerableCount TryPaginate(this DEnumerableCount collection, Pagination pagination) @@ -780,7 +780,7 @@ public static DEnumerableCount TryPaginate(this DEnumerableCount collec return new DEnumerableCount(c, collection.Context, collection.TotalElements); } - throw new InvalidOperationException("pagination type {0} not expexted".FormatWith(pagination!.GetType().Name));/*CSBUG*/ + throw new InvalidOperationException("pagination type {0} not expexted".FormatWith(pagination.GetType().Name)); } #endregion diff --git a/Signum.Engine/Engine/SchemaSynchronizer.cs b/Signum.Engine/Engine/SchemaSynchronizer.cs index d132c09c00..80a2d1c1a2 100644 --- a/Signum.Engine/Engine/SchemaSynchronizer.cs +++ b/Signum.Engine/Engine/SchemaSynchronizer.cs @@ -518,9 +518,7 @@ public static string GetDefaultValue(ITable table, IColumn column, Replacements return $"CONVERT(datetime2, '{date:yyyy-MM-dd HH:mm:ss.fffffff}')"; } - - column = column!; /*CSBUG*/ - + string typeDefault = forceDefaultValue ?? (SqlBuilder.IsNumber(column.SqlDbType) ? "0" : SqlBuilder.IsString(column.SqlDbType) ? "''" : diff --git a/Signum.Engine/Engine/SqlBuilder.cs b/Signum.Engine/Engine/SqlBuilder.cs index c132db966b..a68e036227 100644 --- a/Signum.Engine/Engine/SqlBuilder.cs +++ b/Signum.Engine/Engine/SqlBuilder.cs @@ -211,7 +211,6 @@ public static string CreateColumn(IColumn c, DefaultConstraint? constraint) null; var defaultConstraint = constraint != null ? $"CONSTRAINT {constraint.Name} DEFAULT " + constraint.QuotedDefinition : null; - c = c!;/*CSBUG*/ return $" ".Combine( c.Name.SqlEscape(), @@ -316,7 +315,7 @@ public static SqlPreCommand CreateIndex(Index index, Replacements? checkUnique) } else { - return CreateIndexBasic(index! /*CSBUG*/, forHistoryTable: false); + return CreateIndexBasic(index, forHistoryTable: false); } } diff --git a/Signum.Engine/Engine/SqlPreCommand.cs b/Signum.Engine/Engine/SqlPreCommand.cs index a4953cedd9..97a7e6e5ad 100644 --- a/Signum.Engine/Engine/SqlPreCommand.cs +++ b/Signum.Engine/Engine/SqlPreCommand.cs @@ -179,16 +179,16 @@ internal static string Encode(object value) if (value is bool b) return (b ? 1 : 0).ToString(); - if (Schema.Current.Settings.UdtSqlName.TryGetValue(value!.GetType() /*CSBUG*/, out var name)) + if (Schema.Current.Settings.UdtSqlName.TryGetValue(value.GetType(), out var name)) return "CAST('{0}' AS {1})".FormatWith(value, name); - if (value!.GetType().IsEnum /*CSBUG*/) + if (value.GetType().IsEnum) return Convert.ToInt32(value).ToString(); if (value is byte[] bytes) return "0x" + BitConverter.ToString(bytes).Replace("-", ""); - return value!.ToString(); /*CSBUG*/ + return value.ToString(); } protected internal override void PlainSql(StringBuilder sb) diff --git a/Signum.Engine/Linq/DbQueryProvider.cs b/Signum.Engine/Linq/DbQueryProvider.cs index 1cde442546..5f50200e3a 100644 --- a/Signum.Engine/Linq/DbQueryProvider.cs +++ b/Signum.Engine/Linq/DbQueryProvider.cs @@ -31,7 +31,7 @@ public SqlPreCommandSimple GetMainSqlCommand(Expression expression) return this.Translate(expression, tr => tr.MainCommand); } - public override object Execute(Expression expression) /*CSBUG*/ + public override object? Execute(Expression expression) { using (HeavyProfiler.Log("DBQuery", () => expression.Type.TypeName())) return this.Translate(expression, tr => tr.Execute()!); diff --git a/Signum.Engine/Linq/ExpressionVisitor/ChildProjectionFlattener.cs b/Signum.Engine/Linq/ExpressionVisitor/ChildProjectionFlattener.cs index a24344c1a7..ebcc154314 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/ChildProjectionFlattener.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/ChildProjectionFlattener.cs @@ -248,7 +248,7 @@ private static IEnumerable KeysTable(TableExpression table) if (table.Table is Table t && t.IsView) yield return new ColumnExpression(typeof(int), table.Alias, t.Columns.Values.Single(a => a.PrimaryKey).Name); else - yield return new ColumnExpression(typeof(int), table.Alias, table!.Table.PrimaryKey.Name); /*CSBUG*/ + yield return new ColumnExpression(typeof(int), table.Alias, table.Table.PrimaryKey.Name); } private static IEnumerable KeysSelect(SelectExpression select) diff --git a/Signum.Engine/Linq/ExpressionVisitor/ColumnProjector.cs b/Signum.Engine/Linq/ExpressionVisitor/ColumnProjector.cs index 9ee029e943..57bc2bcb2f 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/ColumnProjector.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/ColumnProjector.cs @@ -135,7 +135,6 @@ public override Expression Visit(Expression expression) } else { - expression = expression! /*CSBUG*/; if (expression.Type.UnNullify().IsEnum) { var convert = expression.TryConvert(expression.Type.IsNullable() ? typeof(int?) : typeof(int)); diff --git a/Signum.Engine/Linq/ExpressionVisitor/ConditionsRewriter.cs b/Signum.Engine/Linq/ExpressionVisitor/ConditionsRewriter.cs index 149dacebf9..f0c30b34fc 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/ConditionsRewriter.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/ConditionsRewriter.cs @@ -113,8 +113,8 @@ static bool IsSqlCondition(Expression expression) return false; } - var exp = expression as DbExpression; - switch (exp!.DbNodeType) /*CSBUG*/ + var exp = (DbExpression)expression; + switch (exp.DbNodeType) { case DbExpressionType.Exists: case DbExpressionType.Like: diff --git a/Signum.Engine/Linq/ExpressionVisitor/DbExpressionNominator.cs b/Signum.Engine/Linq/ExpressionVisitor/DbExpressionNominator.cs index e168f98f94..3d519cb28e 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/DbExpressionNominator.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/DbExpressionNominator.cs @@ -667,8 +667,8 @@ private bool ExtractDayOfWeek(Expression exp, out Expression? result) return true; } - if (exp!/*CSBUG*/.NodeType == ExpressionType.Convert && exp!/*CSBUG*/.Type.UnNullify() == typeof(DayOfWeek)) - return ExtractDayOfWeek(((UnaryExpression)exp!/*CSBUG*/).Operand, out result); + if (exp.NodeType == ExpressionType.Convert && exp.Type.UnNullify() == typeof(DayOfWeek)) + return ExtractDayOfWeek(((UnaryExpression)exp).Operand, out result); result = null; return false; @@ -732,12 +732,12 @@ private Expression ConvertToSqlCoallesce(BinaryExpression b) if (left is SqlFunctionExpression fLeft && fLeft.SqlFunction == SqlFunction.COALESCE.ToString()) expressions.AddRange(fLeft.Arguments); else - expressions.Add(left!/*CSBUG*/); + expressions.Add(left); if (right is SqlFunctionExpression fRight && fRight.SqlFunction == SqlFunction.COALESCE.ToString()) expressions.AddRange(fRight.Arguments); else - expressions.Add(right!/*CSBUG*/); + expressions.Add(right); return Add(new SqlFunctionExpression(b.Type, null, SqlFunction.COALESCE.ToString(), expressions)); } @@ -901,8 +901,6 @@ protected override Expression VisitConditional(ConditionalExpression c) } else { - ifFalse = ifFalse!; /*CSBUG*/ - if (ifTrue.IsNull() && ifFalse.IsNull()) return ifTrue; //cond? null: null doesn't work in sql diff --git a/Signum.Engine/Linq/ExpressionVisitor/EntityCompleter.cs b/Signum.Engine/Linq/ExpressionVisitor/EntityCompleter.cs index 8819a55069..bb282d13b4 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/EntityCompleter.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/EntityCompleter.cs @@ -184,7 +184,7 @@ protected internal override Expression VisitAdditionalField(AdditionalFieldExpre if (newEx is ProjectionExpression newProj && newProj.Projector.Type.IsInstantiationOf(typeof(MList<>.RowIdElement))) return new MListProjectionExpression(afe.Type, newProj); - return newEx!; /*CSBUG*/ + return newEx; } protected internal override Expression VisitProjection(ProjectionExpression proj) diff --git a/Signum.Engine/Linq/ExpressionVisitor/OverloadingSimplifier.cs b/Signum.Engine/Linq/ExpressionVisitor/OverloadingSimplifier.cs index e1eb73d666..eb780e0653 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/OverloadingSimplifier.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/OverloadingSimplifier.cs @@ -471,7 +471,7 @@ private Expression CallToString(Expression expression) var visitedToStrExp = Visit(toStrExp); return Expression.Condition( - Expression.Equal(expression, Expression.Constant(null, expression!/*CSBUG*/.Type.Nullify())), + Expression.Equal(expression, Expression.Constant(null, expression.Type.Nullify())), Expression.Constant(null, typeof(string)), Visit(visitedToStrExp)); } diff --git a/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs b/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs index 2466d16d64..6cb6754b98 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs @@ -224,7 +224,7 @@ private Expression BindExpandEntity(Type type, Expression source, LambdaExpressi kvp => kvp.Key, kvp => kvp.Value.WithExpandEntity(expandEntity))); - throw new NotImplementedException("Expand Entity not supported for " + e!/*CSBUG*/.GetType()); + throw new NotImplementedException("Expand Entity not supported for " + e.GetType()); }); return new ProjectionExpression(projection.Select, newProjector, projection.UniqueFunction, projection.Type); @@ -279,7 +279,7 @@ private Expression ChangeProjector(int index, MemberInfo[] members, Expression p ee = Completed(ee); - var fi = m as FieldInfo ?? Reflector.FindFieldInfo(m!/*CSBUG*/.DeclaringType, (PropertyInfo)m! /*CSBUG*/); + var fi = m as FieldInfo ?? Reflector.FindFieldInfo(m.DeclaringType, (PropertyInfo)m); var newBinding = ChangeProjector(index + 1, members, ee.GetBinding(fi), changeExpression); @@ -291,7 +291,7 @@ private Expression ChangeProjector(int index, MemberInfo[] members, Expression p } else if (projector is NewExpression ne) { - var p = (PropertyInfo)m! /*CSBUG*/; + var p = (PropertyInfo)m; var mIndex = ne.Members.IndexOf(pi => ReflectionTools.PropertyEquals((PropertyInfo)pi, p)); @@ -322,7 +322,7 @@ private Expression ChangeProjector(int index, MemberInfo[] members, Expression p } } - throw new NotImplementedException($"ChangeProjector not implemented for projector of type {projector!/*CSBUG*/.Type} and member {m}"); + throw new NotImplementedException($"ChangeProjector not implemented for projector of type {projector.Type} and member {m}"); } string? currentTableHint; @@ -366,7 +366,7 @@ private Expression MapVisitExpand(LambdaExpression lambda, ProjectionExpression return MapVisitExpand(lambda, projection.Projector, projection.Select); } - internal Expression MapVisitExpand(LambdaExpression lambda, Expression projector, SourceExpression? source) + internal Expression MapVisitExpand(LambdaExpression lambda, Expression projector, SourceExpression source) { using (SetCurrentSource(source)) { @@ -890,7 +890,7 @@ private Expression BindAnyAll(Type resultType, Expression source, LambdaExpressi if (predicate != null) source = Expression.Call(typeof(Enumerable), "Where", method.GetGenericArguments(), source, predicate); - ProjectionExpression projection = this.VisitCastProjection(source!/*CSBUG*/); + ProjectionExpression projection = this.VisitCastProjection(source); Expression result = new ExistsExpression(projection.Select); if (isAll) result = Expression.Not(result); @@ -1231,14 +1231,14 @@ private Expression GetOrderExpression(LambdaExpression lambda, ProjectionExpress { expr = ((MethodCallExpression)expr).Arguments[0]; } - else if (expr!/*CSBUG*/.Type == typeof(Type)) + else if (expr.Type == typeof(Type)) { - expr = ExtractTypeId(expr!/*CSBUG*/); + expr = ExtractTypeId(expr); } - if (expr!/*CSBUG*/.Type.UnNullify() == typeof(PrimaryKey)) + if (expr.Type.UnNullify() == typeof(PrimaryKey)) { - expr = SmartEqualizer.UnwrapPrimaryKey(expr!/*CSBUG*/); + expr = SmartEqualizer.UnwrapPrimaryKey(expr); } return DbExpressionNominator.FullNominate(expr)!; @@ -1460,14 +1460,14 @@ public Expression BindMethodCall(MethodCallExpression m) return toStr; } - else if (source!/*CSBUG*/.NodeType == ExpressionType.Convert && source!/*CSBUG*/.Type.UnNullify().IsEnum) + else if (source.NodeType == ExpressionType.Convert && source.Type.UnNullify().IsEnum) { - var table = Schema.Current.Table(EnumEntity.Generate(source!/*CSBUG*/.Type.UnNullify())); + var table = Schema.Current.Table(EnumEntity.Generate(source.Type.UnNullify())); if (table != null) { - var ee = new EntityExpression(EnumEntity.Generate(source!/*CSBUG*/.Type.UnNullify()), - new PrimaryKeyExpression(((UnaryExpression)source!/*CSBUG*/).Operand.Nullify()), null, null, null, null, null, false); + var ee = new EntityExpression(EnumEntity.Generate(source.Type.UnNullify()), + new PrimaryKeyExpression(((UnaryExpression)source).Operand.Nullify()), null, null, null, null, null, false); return Completed(ee).GetBinding(EntityExpression.ToStrField); } @@ -1573,7 +1573,7 @@ private ConditionalExpression DispatchConditional(MethodCallExpression m, Expres } } - source = RemoveProjectionConvert(source!/*CSBUG*/); + source = RemoveProjectionConvert(source); switch (source.NodeType) { @@ -1968,7 +1968,7 @@ internal static PrimaryKeyExpression ExtractTypeId(Expression exp) TypeConstant(imp.Key).Nullify(), acum))); } - throw new InvalidOperationException("Impossible to extract TypeId from {0}".FormatWith(exp!/*CSBUG*/.ToString())); + throw new InvalidOperationException("Impossible to extract TypeId from {0}".FormatWith(exp.ToString())); } protected override Expression VisitInvocation(InvocationExpression iv) @@ -2217,7 +2217,7 @@ internal CommandExpression BindDelete(Expression source) commands.Add(new DeleteExpression(vn, false, pr.Select, SmartEqualizer.EqualNullable(id, eee.GetViewId()))); } else - throw new InvalidOperationException("Delete not supported for {0}".FormatWith(pr.Projector!/*CSBUG*/.GetType().TypeName())); + throw new InvalidOperationException("Delete not supported for {0}".FormatWith(pr.Projector.GetType().TypeName())); commands.Add(new SelectRowCountExpression()); @@ -2242,7 +2242,7 @@ internal CommandExpression BindUpdate(Expression source, LambdaExpression? partS entity is EntityExpression entEx ? (ITable)entEx.Table : entity is EmbeddedEntityExpression eeEx ? (ITable)eeEx.ViewTable!: entity is MListElementExpression mlistEx ? (ITable)mlistEx.Table!: - throw new UnexpectedValueException(entity!/*CSBUG*/); + throw new UnexpectedValueException(entity); Alias alias = aliasGenerator.Table(table.Name); @@ -2303,7 +2303,7 @@ internal CommandExpression BindUpdate(Expression source, LambdaExpression? partS table = eee.ViewTable!; } else - throw new InvalidOperationException("Update not supported for {0}".FormatWith(entity!/*CSBUG*/.GetType().TypeName())); + throw new InvalidOperationException("Update not supported for {0}".FormatWith(entity.GetType().TypeName())); var result = new CommandAggregateExpression(new CommandExpression[] @@ -2349,8 +2349,6 @@ internal CommandExpression BindInsert(Expression source, LambdaExpression constr assignments.Add(new ColumnAssignment(entityTable.Ticks.Name, Expression.Constant(0L, typeof(long)))); } - table = table!; /*CSBUG*/ - var isHistory = this.systemTime is SystemTime.HistoryTable; var result = new CommandAggregateExpression(new CommandExpression[] @@ -2554,9 +2552,9 @@ public UnionAllRequest Completed(ImplementedByExpression ib) ImmutableStack currentSource = ImmutableStack.Empty; - public IDisposable SetCurrentSource(SourceExpression? source) + public IDisposable SetCurrentSource(SourceExpression source) { - this.currentSource = currentSource.Push(source!/*CSBUG*/); + this.currentSource = currentSource.Push(source); return new Disposable(() => currentSource = currentSource.Pop()); } @@ -2690,8 +2688,6 @@ public PrimaryKeyExpression GetId(Expression expression) return aggregate; } - expression = expression!;/*CSBUG*/ - if (expression.NodeType == ExpressionType.Conditional) { var con = (ConditionalExpression)expression; @@ -2735,8 +2731,6 @@ public Expression GetIdString(Expression expression) if (expression is ImplementedByAllExpression iba) return iba.Id; - expression = expression!; /*CSBUG*/ - if (expression.NodeType == ExpressionType.Conditional) { var con = (ConditionalExpression)expression; @@ -2781,7 +2775,6 @@ public Expression GetEntityType(Expression expression) return iba.TypeId; } - expression = expression!; /*CSBUG*/ if (expression.NodeType == ExpressionType.Conditional) { var con = (ConditionalExpression)expression; @@ -2866,7 +2859,7 @@ internal ProjectionExpression MListProjection(MListExpression mle, bool withRowI var parentEntity = new EntityExpression(af.Route.RootType, af.BackID, af.ExternalPeriod, null, null, null, null, false); - var expression = this.MapVisitExpand(cleanLambda, parentEntity, null); + var expression = this.MapVisitExpand(cleanLambda, parentEntity, null!); if(expression is MethodCallExpression mce) { @@ -3213,7 +3206,7 @@ select Expression.Or( source = new JoinExpression(JoinType.SingleRowLeftOuterJoin, source, unionAll, condition); } - r!/*CSBUG*/.Consumed = true; + r.Consumed = true; } return source; } diff --git a/Signum.Engine/Linq/ExpressionVisitor/QueryFormatter.cs b/Signum.Engine/Linq/ExpressionVisitor/QueryFormatter.cs index 51a76f2db7..8cc7ffb875 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/QueryFormatter.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/QueryFormatter.cs @@ -674,7 +674,7 @@ protected internal override SourceExpression VisitSource(SourceExpression source else this.VisitJoin((JoinExpression)source); - return source!; /*CSBUG*/ + return source; } protected internal override Expression VisitJoin(JoinExpression join) diff --git a/Signum.Engine/Linq/ExpressionVisitor/TranslatorBuilder.cs b/Signum.Engine/Linq/ExpressionVisitor/TranslatorBuilder.cs index 1c9d1d6855..bc7aed2a05 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/TranslatorBuilder.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/TranslatorBuilder.cs @@ -189,7 +189,7 @@ static internal Expression> Build(Expression expressi Expression NullifyColumn(Expression exp) { if (!(exp is ColumnExpression ce)) - return exp!; /*CSBUG*/ + return exp; if (ce.Type.IsNullable() || ce.Type.IsClass) return ce; diff --git a/Signum.Engine/Linq/Meta/MetadataVisitor.cs b/Signum.Engine/Linq/Meta/MetadataVisitor.cs index ba3d5be742..6aba1266c4 100644 --- a/Signum.Engine/Linq/Meta/MetadataVisitor.cs +++ b/Signum.Engine/Linq/Meta/MetadataVisitor.cs @@ -224,8 +224,6 @@ public static MetaProjectorExpression AsProjection(Expression expression) if (expression is MetaProjectorExpression mpe) return mpe; - expression = expression!; /*CSBUG*/ - if (expression.NodeType == ExpressionType.New) { NewExpression nex = (NewExpression)expression; @@ -245,7 +243,7 @@ public static MetaProjectorExpression AsProjection(Expression expression) new CleanMeta(route.TryGetImplementations(), route))); } - return new MetaProjectorExpression(expression!/*CSBUG*/.Type, MakeVoidMeta(elementType)); + return new MetaProjectorExpression(expression.Type, MakeVoidMeta(elementType)); } throw new InvalidOperationException(); @@ -450,8 +448,6 @@ static Expression BindMember(Expression source, MemberInfo member, Type memberTy throw new InvalidOperationException("Property {0} not found on {1}".FormatWith(member.Name, mme.Type.TypeName())); } - source = source! /*CSBUG*/; - if (typeof(ModifiableEntity).IsAssignableFrom(source.Type) || typeof(IEntity).IsAssignableFrom(source.Type)) { var pi = member as PropertyInfo ?? Reflector.TryFindPropertyInfo((FieldInfo)member); @@ -581,7 +577,7 @@ protected override Expression VisitBinary(BinaryExpression b) mLeft.Meta.Implementations.Value }) : (Implementations?)null; - return MakeDirtyMeta(b.Type, imps, left!, right!); /*CSBUG*/ + return MakeDirtyMeta(b.Type, imps, left, right); } protected override Expression VisitConditional(ConditionalExpression c) @@ -598,7 +594,7 @@ protected override Expression VisitConditional(ConditionalExpression c) mIfFalse.Meta.Implementations.Value }) : (Implementations?)null; - return MakeDirtyMeta(c.Type, imps, Visit(c.Test), ifTrue!, ifFalse!); /*CSBUG*/ + return MakeDirtyMeta(c.Type, imps, Visit(c.Test), ifTrue, ifFalse); } } } diff --git a/Signum.Engine/Patterns/DeletePart.cs b/Signum.Engine/Patterns/DeletePart.cs index 2e31ad37ef..062317efe0 100644 --- a/Signum.Engine/Patterns/DeletePart.cs +++ b/Signum.Engine/Patterns/DeletePart.cs @@ -10,7 +10,7 @@ namespace Signum.Engine { public static class DeletePart { - static readonly Variable> avoidTypes = Statics.ThreadVariable>("avoidDeletePart"); /*CSBUG*/ + static readonly Variable> avoidTypes = Statics.ThreadVariable>("avoidDeletePart"); /*CSBUG*/ public static bool ShouldAvoidDeletePart(Type partType) { @@ -21,7 +21,7 @@ public static bool ShouldAvoidDeletePart(Type partType) /// Use null for every type public static IDisposable AvoidDeletePart(Type partType) { - avoidTypes.Value = (avoidTypes.Value ?? ImmutableStack.Empty).Push(partType); + avoidTypes.Value = (avoidTypes.Value ?? ImmutableStack.Empty).Push(partType); return new Disposable(() => avoidTypes.Value = avoidTypes.Value.Pop()); } diff --git a/Signum.Engine/Schema/Schema.Basics.cs b/Signum.Engine/Schema/Schema.Basics.cs index 6926fe18fe..e64e20fd81 100644 --- a/Signum.Engine/Schema/Schema.Basics.cs +++ b/Signum.Engine/Schema/Schema.Basics.cs @@ -162,9 +162,7 @@ public Field GetField(MemberInfo member) return Mixins.GetOrThrow(mi.GetGenericArguments().Single()); } } - - member = member! /*CSBUG*/; - + FieldInfo fi = member as FieldInfo ?? Reflector.FindFieldInfo(Type, (PropertyInfo)member); if (fi == null) @@ -192,8 +190,6 @@ public Field GetField(MemberInfo member) return Mixins?.TryGetC((Type)member); } - member = member!; /*CSBUG*/ - FieldInfo fi = member as FieldInfo ?? Reflector.TryFindFieldInfo(Type, (PropertyInfo)member)!; if (fi == null) diff --git a/Signum.Engine/Schema/Schema.Expressions.cs b/Signum.Engine/Schema/Schema.Expressions.cs index 78861c1f8b..f1c6746231 100644 --- a/Signum.Engine/Schema/Schema.Expressions.cs +++ b/Signum.Engine/Schema/Schema.Expressions.cs @@ -108,12 +108,12 @@ ColumnExpression ITablePrivate.GetPrimaryOrder(Alias alias) { var res = GetIdExpression(alias); - return res is PrimaryKeyExpression ? - (ColumnExpression)((PrimaryKeyExpression)res!).Value : /*CSBUG*/ + return res is PrimaryKeyExpression pe? + (ColumnExpression)pe.Value : (ColumnExpression)res!; } } - + public partial class TableMList { internal PrimaryKeyExpression RowIdExpression(Alias tableAlias) diff --git a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs index 80a0a30c36..40cd0bb8e5 100644 --- a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs +++ b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs @@ -637,13 +637,16 @@ protected virtual FieldImplementedBy GenerateFieldImplementedBy(ITable table, Pr bool avoidForeignKey = Settings.FieldAttribute(route) != null; - var implementations = types.ToDictionary(t => t, t => new ImplementationColumn( - name: name.Add(TypeLogic.GetCleanName(t)).ToString(), - referenceTable: Include(t, route) - ) + var implementations = types.ToDictionary(t => t, t => { - Nullable = nullable, - AvoidForeignKey = avoidForeignKey, + var rt = Include(t, route); + + string impName = name.Add(TypeLogic.GetCleanName(t)).ToString(); + return new ImplementationColumn(impName, referenceTable: rt) + { + Nullable = nullable, + AvoidForeignKey = avoidForeignKey, + }; }); return new FieldImplementedBy(route, implementations) diff --git a/Signum.React/Signum.React.csproj b/Signum.React/Signum.React.csproj index 19eee7f830..05cf381940 100644 --- a/Signum.React/Signum.React.csproj +++ b/Signum.React/Signum.React.csproj @@ -3,10 +3,10 @@ netcoreapp2.2 3.2 - latest - Library + 8.0 true - + enable + true x64 diff --git a/Signum.Utilities/ExpressionTrees/Query.cs b/Signum.Utilities/ExpressionTrees/Query.cs index f5d77cbdbd..9dd97aab83 100644 --- a/Signum.Utilities/ExpressionTrees/Query.cs +++ b/Signum.Utilities/ExpressionTrees/Query.cs @@ -53,7 +53,7 @@ public IQueryProvider Provider [DebuggerStepThrough] public IEnumerator GetEnumerator() { - return ((IEnumerable)this.provider.Execute(this.expression)).GetEnumerator(); + return ((IEnumerable)this.provider.Execute(this.expression)!).GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() diff --git a/Signum.Utilities/ExpressionTrees/QueryProvider.cs b/Signum.Utilities/ExpressionTrees/QueryProvider.cs index aa5c60823d..e24dd963b0 100644 --- a/Signum.Utilities/ExpressionTrees/QueryProvider.cs +++ b/Signum.Utilities/ExpressionTrees/QueryProvider.cs @@ -37,7 +37,7 @@ IQueryable IQueryProvider.CreateQuery(Expression expression) S IQueryProvider.Execute(Expression expression) { - return (S)this.Execute(expression); + return (S)this.Execute(expression)!; } object? IQueryProvider.Execute(Expression expression) @@ -46,6 +46,6 @@ S IQueryProvider.Execute(Expression expression) } public abstract string GetQueryText(Expression expression); - public abstract object Execute(Expression expression); + public abstract object? Execute(Expression expression); } } From 305f1e9978fd85ac04b3392b3935d12254076a1b Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Tue, 29 Jan 2019 19:31:11 +0100 Subject: [PATCH 15/25] more on not nullables --- Signum.Engine/DynamicQuery/AutoDynamicQuery.cs | 2 +- Signum.Engine/DynamicQuery/DynamicQuery.cs | 2 +- .../Linq/ExpressionVisitor/QueryBinder.cs | 3 +++ .../RedundantSubqueryRemover.cs | 6 +++--- .../Linq/ExpressionVisitor/SmartEqualizer.cs | 8 ++++---- Signum.Engine/Linq/Meta/MetadataVisitor.cs | 10 ++++++---- .../SchemaBuilder/SchemaBuilderSettings.cs | 6 +++--- Signum.Entities/Basics/Exception.cs | 2 +- Signum.Entities/FieldAttributes.cs | 4 ++-- .../Filters/SignumExceptionFilterAttribute.cs | 12 ++++++------ Signum.Test/Environment/Entities.cs | 4 ++-- Signum.Test/MetaTest.cs | 18 +++++++++--------- Signum.Test/ObjectNameTest.cs | 1 + Signum.Utilities/NotNullAttributes.cs | 16 ++++++++++++++++ 14 files changed, 58 insertions(+), 36 deletions(-) diff --git a/Signum.Engine/DynamicQuery/AutoDynamicQuery.cs b/Signum.Engine/DynamicQuery/AutoDynamicQuery.cs index 84a40fdea5..5d5915dbd3 100644 --- a/Signum.Engine/DynamicQuery/AutoDynamicQuery.cs +++ b/Signum.Engine/DynamicQuery/AutoDynamicQuery.cs @@ -21,7 +21,7 @@ public AutoDynamicQueryCore(IQueryable query) { this.Query = query; - metas = DynamicQueryCore.QueryMetadata(Query); + metas = DynamicQueryCore.QueryMetadata(Query).ThrowIfNull("Query should be an anoynmous type"); StaticColumns = MemberEntryFactory.GenerateList(MemberOptions.Properties | MemberOptions.Fields) .Select((e, i) => new ColumnDescriptionFactory(i, e.MemberInfo, metas[e.MemberInfo.Name])).ToArray(); diff --git a/Signum.Engine/DynamicQuery/DynamicQuery.cs b/Signum.Engine/DynamicQuery/DynamicQuery.cs index b384e4f294..da11b3f249 100644 --- a/Signum.Engine/DynamicQuery/DynamicQuery.cs +++ b/Signum.Engine/DynamicQuery/DynamicQuery.cs @@ -113,7 +113,7 @@ public static AutoDynamicQueryCore FromSelector(Expression> return new AutoDynamicQueryCore(Database.Query().Select(selector)); } - public static Dictionary QueryMetadata(IQueryable query) + public static Dictionary? QueryMetadata(IQueryable query) { return MetadataVisitor.GatherMetadata(query.Expression); } diff --git a/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs b/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs index 6cb6754b98..9a4080d9ab 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs @@ -3153,6 +3153,9 @@ public static Expression ExpandJoins(Expression expression, QueryBinder binder, protected internal override SourceExpression VisitSource(SourceExpression source) { + if (source == null) + return null!; + var reqs = requests.TryGetC(source); //if (reqs != null) diff --git a/Signum.Engine/Linq/ExpressionVisitor/RedundantSubqueryRemover.cs b/Signum.Engine/Linq/ExpressionVisitor/RedundantSubqueryRemover.cs index 53173dbd49..2089253b0b 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/RedundantSubqueryRemover.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/RedundantSubqueryRemover.cs @@ -160,7 +160,7 @@ protected internal override Expression VisitSelect(SelectExpression select) // logic except for the existence of a where clause while (CanMergeWithFrom(select, wasTopLevel)) { - SelectExpression? fromSelect = GetLeftMostSelect(select.From!); + SelectExpression fromSelect = GetLeftMostSelect(select.From!)!; // remove the redundant subquery select = (SelectExpression)SubqueryRemover.Remove(select, new[] { fromSelect }); @@ -253,7 +253,7 @@ static bool CanMergeWithFrom(SelectExpression select, bool isTopLevel) return true; } - static SelectExpression GetLeftMostSelect(Expression source) + static SelectExpression? GetLeftMostSelect(Expression source) { if (source is SelectExpression select) return select; @@ -261,7 +261,7 @@ static SelectExpression GetLeftMostSelect(Expression source) if (source is JoinExpression join) return GetLeftMostSelect(join.Left); - throw new UnexpectedValueException(source); + return null; } static bool HasApplyJoin(SourceExpression source) diff --git a/Signum.Engine/Linq/ExpressionVisitor/SmartEqualizer.cs b/Signum.Engine/Linq/ExpressionVisitor/SmartEqualizer.cs index 3804d4d2df..f5ec035b3a 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/SmartEqualizer.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/SmartEqualizer.cs @@ -318,8 +318,8 @@ public static Expression UnwrapPrimaryKey(Expression unary) private static Expression? ConditionalEquals(Expression exp1, Expression exp2) { - if (Schema.Current.Settings.IsDbType(exp1.Type)|| - Schema.Current.Settings.IsDbType(exp2.Type)) + if (Schema.Current.Settings.IsDbType(exp1.Type.UnNullify())|| + Schema.Current.Settings.IsDbType(exp2.Type.UnNullify())) return null; if (exp1 is ConditionalExpression ce1) @@ -341,8 +341,8 @@ private static Expression DispachConditional(ConditionalExpression ce, Expressio private static Expression? CoalesceEquals(Expression exp1, Expression exp2) { - if (Schema.Current.Settings.IsDbType(exp1.Type)|| - Schema.Current.Settings.IsDbType(exp2.Type)) + if (Schema.Current.Settings.IsDbType(exp1.Type.UnNullify()) || + Schema.Current.Settings.IsDbType(exp2.Type.UnNullify())) return null; if (exp1.NodeType == ExpressionType.Coalesce) diff --git a/Signum.Engine/Linq/Meta/MetadataVisitor.cs b/Signum.Engine/Linq/Meta/MetadataVisitor.cs index 6aba1266c4..f9a6573e27 100644 --- a/Signum.Engine/Linq/Meta/MetadataVisitor.cs +++ b/Signum.Engine/Linq/Meta/MetadataVisitor.cs @@ -24,7 +24,7 @@ internal class MetadataVisitor : ExpressionVisitor private MetadataVisitor() { } - static internal Dictionary GatherMetadata(Expression expression) + static internal Dictionary? GatherMetadata(Expression expression) { if (expression == null) throw new ArgumentException("expression"); @@ -34,14 +34,16 @@ private MetadataVisitor() { } Expression? simplified = MetaEvaluator.Clean(expression); - var meta = (MetaProjectorExpression)new MetadataVisitor().Visit(simplified!); - + var meta = (MetaProjectorExpression?)new MetadataVisitor().Visit(simplified!); + if (meta == null) + return null; + var proj = meta.Projector; if (proj.NodeType != ExpressionType.New && //anonymous types proj.NodeType != ExpressionType.MemberInit && // not-anonymous type !(proj is MetaExpression && ((MetaExpression)proj).IsEntity)) // raw-entity! - throw new UnexpectedValueException(proj); + return null; PropertyInfo[] props = proj.Type.GetProperties(BindingFlags.Public | BindingFlags.Instance); diff --git a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs index 4f1349e974..0b5b0b9be8 100644 --- a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs +++ b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs @@ -211,10 +211,10 @@ internal IsNullable GetIsNullable(PropertyRoute propertyRoute, bool forceNull) private IsNullable GetIsNullablePrivate(PropertyRoute propertyRoute) { - if (FieldAttribute(propertyRoute) != null) + if (FieldAttribute(propertyRoute) != null) return IsNullable.No; - if (FieldAttribute(propertyRoute) != null) + if (FieldAttribute(propertyRoute) != null) return IsNullable.Yes; if (propertyRoute.PropertyRouteType == PropertyRouteType.MListItems) @@ -366,7 +366,7 @@ public SqlDbTypePair GetSqlDbTypePair(Type type) public bool IsDbType(Type type) { - return type.IsEnum || GetSqlDbTypePair(type) != null; + return type.IsEnum || TryGetSqlDbTypePair(type) != null; } } diff --git a/Signum.Entities/Basics/Exception.cs b/Signum.Entities/Basics/Exception.cs index 49c40de353..282a85c521 100644 --- a/Signum.Entities/Basics/Exception.cs +++ b/Signum.Entities/Basics/Exception.cs @@ -28,7 +28,7 @@ public ExceptionEntity(Exception ex) public DateTime CreationDate { get; private set; } = TimeZoneManager.Now; - [NotNullable, SqlDbType(Size = 100)] + [ForceNotNullable, SqlDbType(Size = 100)] public string? ExceptionType { get; set; } [SqlDbType(Size = int.MaxValue)] diff --git a/Signum.Entities/FieldAttributes.cs b/Signum.Entities/FieldAttributes.cs index b076e3d841..b3ee96e33a 100644 --- a/Signum.Entities/FieldAttributes.cs +++ b/Signum.Entities/FieldAttributes.cs @@ -226,7 +226,7 @@ public sealed class FieldWithoutPropertyAttribute : Attribute } [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] - public sealed class NotNullableAttribute : Attribute + public sealed class ForceNotNullableAttribute : Attribute { } @@ -236,7 +236,7 @@ public sealed class NotNullableAttribute : Attribute /// This attribute is only necessary in the case an entity field is not-nullable but you can not make the DB column nullable because of legacy data, or cycles in a graph of entities. /// [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] - public sealed class NullableAttribute : Attribute + public sealed class ForceNullableAttribute: Attribute { } diff --git a/Signum.React/Filters/SignumExceptionFilterAttribute.cs b/Signum.React/Filters/SignumExceptionFilterAttribute.cs index 3e2b6b4a5e..73ef544505 100644 --- a/Signum.React/Filters/SignumExceptionFilterAttribute.cs +++ b/Signum.React/Filters/SignumExceptionFilterAttribute.cs @@ -72,11 +72,11 @@ public async Task OnResourceExecutionAsync(ResourceExecutingContext precontext, } } - private string Try(int size, Func getValue) + private string? Try(int size, Func getValue) { try { - return getValue().TryStart(size); + return getValue()?.TryStart(size); } catch(Exception e) { @@ -96,9 +96,9 @@ public string ReadAllBody(HttpContext httpContext) return Encoding.UTF8.GetString(httpContext.Request.Body.ReadAllBytes()); } - private object TryGetProp(HttpContext context, string key) + private object? TryGetProp(HttpContext context, string key) { - object result = null; + object? result; context.Items.TryGetValue(key, out result); return result; } @@ -134,10 +134,10 @@ public HttpError(Exception e) this.InnerException = e.InnerException == null ? null : new HttpError(e.InnerException); } - public string ExceptionId; + public string? ExceptionId; public string ExceptionMessage; public string ExceptionType; public string StackTrace; - public HttpError InnerException; + public HttpError? InnerException; } } diff --git a/Signum.Test/Environment/Entities.cs b/Signum.Test/Environment/Entities.cs index 02100c07f4..91a05885e6 100644 --- a/Signum.Test/Environment/Entities.cs +++ b/Signum.Test/Environment/Entities.cs @@ -15,7 +15,7 @@ namespace Signum.Test.Environment Mixin(typeof(ColaboratorsMixin)), PrimaryKey(typeof(Guid))] public class NoteWithDateEntity : Entity { - [Nullable] + [ForceNullable] [StringLengthValidator(Min = 3, MultiLine = true)] public string Text { get; set; } @@ -370,7 +370,7 @@ public class AwardNominationEntity : Entity, ICanBeOrdered [ImplementedBy(typeof(ArtistEntity), typeof(BandEntity))] public Lite Author { get; set; } - [Nullable] + [ForceNullable] [ImplementedBy(typeof(GrammyAwardEntity), typeof(PersonalAwardEntity), typeof(AmericanMusicAwardEntity))] public Lite Award { get; set; } diff --git a/Signum.Test/MetaTest.cs b/Signum.Test/MetaTest.cs index c8d8957a37..a101ba23f2 100644 --- a/Signum.Test/MetaTest.cs +++ b/Signum.Test/MetaTest.cs @@ -26,14 +26,14 @@ public void MetaNoMetadata() [Fact] public void MetaRawEntity() { - var dic = DynamicQueryCore.QueryMetadata(Database.Query()); + var dic = DynamicQueryCore.QueryMetadata(Database.Query())!; Assert.NotNull(dic); } [Fact] public void MetaAnonymousType() { - var dic = DynamicQueryCore.QueryMetadata(Database.Query().Select(a => new { a.Target, a.Text, a.ToString().Length, Sum = a.ToString() + a.ToString() })); + var dic = DynamicQueryCore.QueryMetadata(Database.Query().Select(a => new { a.Target, a.Text, a.ToString().Length, Sum = a.ToString() + a.ToString() }))!; Assert.IsType(dic["Target"]); Assert.IsType(dic["Text"]); Assert.IsType(dic["Length"]); @@ -49,7 +49,7 @@ public class Bla [Fact] public void MetaNamedType() { - var dic = DynamicQueryCore.QueryMetadata(Database.Query().Select(a => new Bla { ToStr = a.ToString(), Length = a.ToString().Length })); + var dic = DynamicQueryCore.QueryMetadata(Database.Query().Select(a => new Bla { ToStr = a.ToString(), Length = a.ToString().Length }))!; Assert.IsType(dic["ToStr"]); Assert.IsType(dic["Length"]); } @@ -60,7 +60,7 @@ public void MetaComplexJoin() var dic = DynamicQueryCore.QueryMetadata( from l in Database.Query() join a in Database.Query() on l equals a.Label - select new { Label = l.Name, Name = a.Name, Sum = l.Name.Length + a.Name }); + select new { Label = l.Name, Name = a.Name, Sum = l.Name.Length + a.Name })!; Assert.IsType(dic["Label"]); Assert.IsType(dic["Name"]); @@ -76,7 +76,7 @@ public void MetaComplexJoinGroup() var dic = DynamicQueryCore.QueryMetadata( from l in Database.Query() join a in Database.Query() on l equals a.Label into g - select new { l.Name, Num = g.Count() }); + select new { l.Name, Num = g.Count() })!; Assert.IsType(dic["Name"]); Assert.IsType(dic["Num"]); @@ -90,7 +90,7 @@ public void MetaComplexGroup() var dic = DynamicQueryCore.QueryMetadata( from a in Database.Query() group a by a.Label into g - select new { g.Key, Num = g.Count() }); + select new { g.Key, Num = g.Count() })!; Assert.IsType(dic["Key"]); Assert.IsType(dic["Num"]); @@ -105,7 +105,7 @@ public void MetaSelectMany() from a in Database.Query() from s in a.Songs select new { a.Name, Song = s.Name } - ); + )!; Assert.IsType(dic["Name"]); Assert.IsType(dic["Song"]); @@ -119,7 +119,7 @@ public void MetaCoallesce() var dic = DynamicQueryCore.QueryMetadata( from a in Database.Query() select new { Author = (ArtistEntity)a.Author ?? (IAuthorEntity)(BandEntity)a.Author } - ); + )!; DirtyMeta meta = (DirtyMeta)dic["Author"]!; @@ -132,7 +132,7 @@ public void MetaConditional() var dic = DynamicQueryCore.QueryMetadata( from a in Database.Query() select new { Author = a.Id > 1 ? (ArtistEntity)a.Author : (IAuthorEntity)(BandEntity)a.Author } - ); + )!; DirtyMeta meta = (DirtyMeta)dic["Author"]!; diff --git a/Signum.Test/ObjectNameTest.cs b/Signum.Test/ObjectNameTest.cs index 28cacc0161..c102e71c29 100644 --- a/Signum.Test/ObjectNameTest.cs +++ b/Signum.Test/ObjectNameTest.cs @@ -1,5 +1,6 @@ using Xunit; using Signum.Engine.Maps; +using System.Globalization; namespace Signum.Test { diff --git a/Signum.Utilities/NotNullAttributes.cs b/Signum.Utilities/NotNullAttributes.cs index 038a2f56d4..91db8e26c7 100644 --- a/Signum.Utilities/NotNullAttributes.cs +++ b/Signum.Utilities/NotNullAttributes.cs @@ -5,6 +5,22 @@ namespace System.Runtime.CompilerServices { + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] + public class NullableAttribute : Attribute + { + public NullableAttribute(byte b) { + B = b; + } + + public NullableAttribute(byte[] bs) + { + Bs = bs; + } + + public byte? B { get; } + public byte[]? Bs { get; } + } + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] public class AssertsTrueAttribute : Attribute { From e6f1fc5b7c5bc040c9412218250f681d4712d711 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Thu, 31 Jan 2019 00:04:05 +0100 Subject: [PATCH 16/25] more on not nullable (including TSGenerator) --- Signum.Engine/Engine/SchemaSynchronizer.cs | 6 +- .../Linq/ExpressionVisitor/QueryBinder.cs | 2 +- Signum.Entities/DynamicQuery/Filter.cs | 6 +- Signum.Entities/DynamicQuery/QueryUtils.cs | 4 +- Signum.Entities/DynamicQuery/Requests.cs | 4 +- Signum.Entities/PropertyAttributes.cs | 2 +- Signum.Entities/SystemTime.cs | 9 +- Signum.Entities/Validator.cs | 3 + Signum.Framework.sln | 61 ++++++-------- .../ApiControllers/OperationController.cs | 37 ++++++--- .../ApiControllers/QueryController.cs | 31 ++++--- .../ApiControllers/ReflectionController.cs | 4 +- .../Facades/LambdaToJavascriptConverter.cs | 12 +-- Signum.React/Facades/ReflectionServer.cs | 56 +++++++------ Signum.React/Facades/SignumServer.cs | 20 +++-- .../Filters/ProfilerFilterAttribute.cs | 10 +-- Signum.React/Filters/SignumFilters.cs | 16 ++-- .../JsonConverters/ArgsJsonConverter.cs | 17 ++-- .../JsonConverters/EntityJsonConverter.cs | 83 +++++++++++-------- .../JsonSerializerExtensions.cs | 8 +- .../JsonConverters/LiteJsonConverter.cs | 20 ++--- .../JsonConverters/MListJsonConverter.cs | 20 ++--- .../JsonConverters/TimeSpanConverter.cs | 6 +- .../JsonModelValidators/DefaultValidator.cs | 52 ++++++------ .../SignumObjectValidator.cs | 7 +- .../Scripts/Signum.Entities.Basics.ts | 32 +++---- Signum.React/Scripts/Signum.Entities.ts | 2 +- Signum.React/Signum.React.csproj | 8 +- .../EntityDeclarationGenerator.cs | 19 +++-- .../Properties/launchSettings.json | 4 +- Signum.TSGenerator/Signum.TSGenerator.csproj | 2 +- Signum.TSGenerator/Signum.TSGenerator.nuspec | 2 +- .../Reflection/ReflectionTools.cs | 2 +- Signum.Utilities/Tsv.cs | 2 +- 34 files changed, 303 insertions(+), 266 deletions(-) diff --git a/Signum.Engine/Engine/SchemaSynchronizer.cs b/Signum.Engine/Engine/SchemaSynchronizer.cs index 4c29d91781..3cd83fcb66 100644 --- a/Signum.Engine/Engine/SchemaSynchronizer.cs +++ b/Signum.Engine/Engine/SchemaSynchronizer.cs @@ -449,9 +449,9 @@ private static SqlPreCommand UpdateCompatible(Replacements replacements, ITable return SqlPreCommand.Combine(Spacing.Simple, NotNullUpdate(tab.Name, tabCol, defaultValue, goBefore), SqlBuilder.AlterTableAlterColumn(tab, tabCol, difCol.DefaultConstraint?.Name), - history ? NotNullUpdate(tab.SystemVersioned.TableName, tabCol, defaultValue, goBefore) : null, - history ? SqlBuilder.AlterTableAlterColumn(tab, tabCol, difCol.DefaultConstraint?.Name, tab.SystemVersioned.TableName) : null - ); + history ? NotNullUpdate(tab.SystemVersioned!.TableName, tabCol, defaultValue, goBefore) : null, + history ? SqlBuilder.AlterTableAlterColumn(tab, tabCol, difCol.DefaultConstraint?.Name, tab.SystemVersioned!.TableName) : null + )!; } private static SqlPreCommandSimple NotNullUpdate(ObjectName tab, IColumn tabCol, string defaultValue, bool goBefore) diff --git a/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs b/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs index 9a4080d9ab..30ef635e43 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs @@ -31,7 +31,7 @@ internal class QueryBinder : ExpressionVisitor internal AliasGenerator aliasGenerator; - internal SystemTime systemTime; + internal SystemTime? systemTime; public QueryBinder(AliasGenerator aliasGenerator) { diff --git a/Signum.Entities/DynamicQuery/Filter.cs b/Signum.Entities/DynamicQuery/Filter.cs index 7624f28872..6f3d69488d 100644 --- a/Signum.Entities/DynamicQuery/Filter.cs +++ b/Signum.Entities/DynamicQuery/Filter.cs @@ -30,10 +30,10 @@ public abstract class Filter public class FilterGroup : Filter { public FilterGroupOperation GroupOperation { get; } - public QueryToken Token { get; } + public QueryToken? Token { get; } public List Filters { get; } - public FilterGroup(FilterGroupOperation groupOperation, QueryToken token, List filters) + public FilterGroup(FilterGroupOperation groupOperation, QueryToken? token, List filters) { this.GroupOperation = groupOperation; this.Token = token; @@ -91,7 +91,7 @@ public class FilterCondition : Filter public FilterOperation Operation { get; } public object? Value { get; } - public FilterCondition(QueryToken token, FilterOperation operation, object value) + public FilterCondition(QueryToken token, FilterOperation operation, object? value) { this.Token = token; this.Operation = operation; diff --git a/Signum.Entities/DynamicQuery/QueryUtils.cs b/Signum.Entities/DynamicQuery/QueryUtils.cs index 5bd960d680..c0ef15ae9d 100644 --- a/Signum.Entities/DynamicQuery/QueryUtils.cs +++ b/Signum.Entities/DynamicQuery/QueryUtils.cs @@ -217,7 +217,7 @@ public static List GetFilterOperations(FilterType filtertype) return null; } - public static List SubTokens(this QueryToken token, QueryDescription qd, SubTokensOptions options) + public static List SubTokens(this QueryToken? token, QueryDescription qd, SubTokensOptions options) { var result = SubTokensBasic(token, qd, options); @@ -299,7 +299,7 @@ private static IEnumerable AggregateTokens(QueryToken? token, QueryD } public static Func MergeEntityColumns = null; - static List SubTokensBasic(QueryToken token, QueryDescription qd, SubTokensOptions options) + static List SubTokensBasic(QueryToken? token, QueryDescription qd, SubTokensOptions options) { if (token == null) { diff --git a/Signum.Entities/DynamicQuery/Requests.cs b/Signum.Entities/DynamicQuery/Requests.cs index c5ac1a62f7..0e4b629390 100644 --- a/Signum.Entities/DynamicQuery/Requests.cs +++ b/Signum.Entities/DynamicQuery/Requests.cs @@ -194,8 +194,8 @@ public Paginate WithCurrentPage(int newPage) [Serializable] public class QueryValueRequest : BaseQueryRequest { - public QueryToken ValueToken { get; set; } - public SystemTime SystemTime { get; set; } + public QueryToken? ValueToken { get; set; } + public SystemTime? SystemTime { get; set; } public List Multiplications { diff --git a/Signum.Entities/PropertyAttributes.cs b/Signum.Entities/PropertyAttributes.cs index 36ca411d7b..fc7607cf69 100644 --- a/Signum.Entities/PropertyAttributes.cs +++ b/Signum.Entities/PropertyAttributes.cs @@ -29,7 +29,7 @@ public class UnitAttribute : Attribute { public static Dictionary> UnitTranslations = new Dictionary>(); - public static string? GetTranslation(string unitName) + public static string? GetTranslation(string? unitName) { if (string.IsNullOrEmpty(unitName)) return null; diff --git a/Signum.Entities/SystemTime.cs b/Signum.Entities/SystemTime.cs index 6d6fc991b2..c7f5e49ec3 100644 --- a/Signum.Entities/SystemTime.cs +++ b/Signum.Entities/SystemTime.cs @@ -9,13 +9,12 @@ namespace Signum.Entities { public abstract class SystemTime { - static Variable currentVariable = Statics.ThreadVariable("systemTime"); - - public static SystemTime Current => currentVariable.Value; - + static Variable currentVariable = Statics.ThreadVariable("systemTime"); + public static SystemTime? Current => currentVariable.Value; + public static IDisposable Override(DateTime asOf) => Override(new SystemTime.AsOf(asOf)); - public static IDisposable Override(SystemTime systemTime) + public static IDisposable Override(SystemTime? systemTime) { var old = currentVariable.Value; currentVariable.Value = systemTime; diff --git a/Signum.Entities/Validator.cs b/Signum.Entities/Validator.cs index b4745de5de..4349d01bd5 100644 --- a/Signum.Entities/Validator.cs +++ b/Signum.Entities/Validator.cs @@ -136,6 +136,7 @@ public interface IPropertyValidator { PropertyInfo PropertyInfo { get; } List Validators { get; } + bool Required { get; } string? PropertyCheck(ModifiableEntity modifiableEntity); object? GetValueUntyped(ModifiableEntity entity); @@ -156,6 +157,8 @@ public class PropertyValidator : IPropertyValidator public Func? StaticPropertyValidation { get; set; } + public bool Required => throw new NotImplementedException(); + internal PropertyValidator(PropertyInfo pi) { this.PropertyInfo = pi; diff --git a/Signum.Framework.sln b/Signum.Framework.sln index 78e912af38..262d9e42c4 100644 --- a/Signum.Framework.sln +++ b/Signum.Framework.sln @@ -1,53 +1,46 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Signum.Utilities", "Signum.Utilities\Signum.Utilities.csproj", "{F7D3F72D-741D-4F67-8CF8-CD41B9035FED}" +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28516.95 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Signum.Utilities", "Signum.Utilities\Signum.Utilities.csproj", "{F7D3F72D-741D-4F67-8CF8-CD41B9035FED}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Signum.Entities", "Signum.Entities\Signum.Entities.csproj", "{F2B51D08-498D-4C9F-8112-9521A7762B02}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Signum.Entities", "Signum.Entities\Signum.Entities.csproj", "{F2B51D08-498D-4C9F-8112-9521A7762B02}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Signum.Engine", "Signum.Engine\Signum.Engine.csproj", "{7F2DB6FE-C109-4057-B207-C62A767F905D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Signum.Engine", "Signum.Engine\Signum.Engine.csproj", "{7F2DB6FE-C109-4057-B207-C62A767F905D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Signum.Test", "Signum.Test\Signum.Test.csproj", "{DE565EB3-EE44-469D-B6B9-C8F3CA0712EF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Signum.Test", "Signum.Test\Signum.Test.csproj", "{DE565EB3-EE44-469D-B6B9-C8F3CA0712EF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Signum.TSGenerator", "Signum.TSGenerator\Signum.TSGenerator.csproj", "{32990F1A-6A78-439E-8194-68F05AA1CCB1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Signum.TSGenerator", "Signum.TSGenerator\Signum.TSGenerator.csproj", "{32990F1A-6A78-439E-8194-68F05AA1CCB1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Signum.MSBuildTask", "Signum.MSBuildTask\Signum.MSBuildTask.csproj", "{5D992EC2-1F54-4B7B-AF47-CB76E340B658}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Signum.MSBuildTask", "Signum.MSBuildTask\Signum.MSBuildTask.csproj", "{5D992EC2-1F54-4B7B-AF47-CB76E340B658}" EndProject Global - GlobalSection(TestCaseManagementSettings) = postSolution - CategoryFile = Signum.Framework.vsmdi - EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {F7D3F72D-741D-4F67-8CF8-CD41B9035FED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F7D3F72D-741D-4F67-8CF8-CD41B9035FED}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F7D3F72D-741D-4F67-8CF8-CD41B9035FED}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F7D3F72D-741D-4F67-8CF8-CD41B9035FED}.Release|Any CPU.Build.0 = Release|Any CPU - {F2B51D08-498D-4C9F-8112-9521A7762B02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F2B51D08-498D-4C9F-8112-9521A7762B02}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F2B51D08-498D-4C9F-8112-9521A7762B02}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F2B51D08-498D-4C9F-8112-9521A7762B02}.Release|Any CPU.Build.0 = Release|Any CPU - {7F2DB6FE-C109-4057-B207-C62A767F905D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7F2DB6FE-C109-4057-B207-C62A767F905D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7F2DB6FE-C109-4057-B207-C62A767F905D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7F2DB6FE-C109-4057-B207-C62A767F905D}.Release|Any CPU.Build.0 = Release|Any CPU - {DE565EB3-EE44-469D-B6B9-C8F3CA0712EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DE565EB3-EE44-469D-B6B9-C8F3CA0712EF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DE565EB3-EE44-469D-B6B9-C8F3CA0712EF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DE565EB3-EE44-469D-B6B9-C8F3CA0712EF}.Release|Any CPU.Build.0 = Release|Any CPU - {32990F1A-6A78-439E-8194-68F05AA1CCB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {32990F1A-6A78-439E-8194-68F05AA1CCB1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {32990F1A-6A78-439E-8194-68F05AA1CCB1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {32990F1A-6A78-439E-8194-68F05AA1CCB1}.Release|Any CPU.Build.0 = Release|Any CPU - {5D992EC2-1F54-4B7B-AF47-CB76E340B658}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5D992EC2-1F54-4B7B-AF47-CB76E340B658}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5D992EC2-1F54-4B7B-AF47-CB76E340B658}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5D992EC2-1F54-4B7B-AF47-CB76E340B658}.Release|Any CPU.Build.0 = Release|Any CPU + {F7D3F72D-741D-4F67-8CF8-CD41B9035FED}.Debug|Any CPU.ActiveCfg = Debug|x64 + {F7D3F72D-741D-4F67-8CF8-CD41B9035FED}.Release|Any CPU.ActiveCfg = Release|x64 + {F2B51D08-498D-4C9F-8112-9521A7762B02}.Debug|Any CPU.ActiveCfg = Debug|x64 + {F2B51D08-498D-4C9F-8112-9521A7762B02}.Release|Any CPU.ActiveCfg = Release|x64 + {7F2DB6FE-C109-4057-B207-C62A767F905D}.Debug|Any CPU.ActiveCfg = Debug|x64 + {7F2DB6FE-C109-4057-B207-C62A767F905D}.Release|Any CPU.ActiveCfg = Release|x64 + {DE565EB3-EE44-469D-B6B9-C8F3CA0712EF}.Debug|Any CPU.ActiveCfg = Debug|x64 + {DE565EB3-EE44-469D-B6B9-C8F3CA0712EF}.Release|Any CPU.ActiveCfg = Release|x64 + {32990F1A-6A78-439E-8194-68F05AA1CCB1}.Debug|Any CPU.ActiveCfg = Debug|x64 + {32990F1A-6A78-439E-8194-68F05AA1CCB1}.Release|Any CPU.ActiveCfg = Release|x64 + {5D992EC2-1F54-4B7B-AF47-CB76E340B658}.Debug|Any CPU.ActiveCfg = Debug|x64 + {5D992EC2-1F54-4B7B-AF47-CB76E340B658}.Release|Any CPU.ActiveCfg = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {43C7947A-C55C-455D-AB21-DD8E9242E72F} + EndGlobalSection + GlobalSection(TestCaseManagementSettings) = postSolution + CategoryFile = Signum.Framework.vsmdi + EndGlobalSection EndGlobal diff --git a/Signum.React/ApiControllers/OperationController.cs b/Signum.React/ApiControllers/OperationController.cs index 6dbafb2245..d565443e17 100644 --- a/Signum.React/ApiControllers/OperationController.cs +++ b/Signum.React/ApiControllers/OperationController.cs @@ -20,7 +20,7 @@ namespace Signum.React.ApiControllers public class OperationController : Controller { [HttpPost("api/operation/construct"), ValidateModelFilter, ProfilerActionSplitter] - public EntityPackTS Construct([Required, FromBody]ConstructOperationRequest request) + public EntityPackTS? Construct([Required, FromBody]ConstructOperationRequest request) { var entityType = TypeLogic.GetType(request.type); @@ -30,7 +30,7 @@ public EntityPackTS Construct([Required, FromBody]ConstructOperationRequest requ } [HttpPost("api/operation/constructFromEntity"), ProfilerActionSplitter] - public EntityPackTS ConstructFromEntity([Required, FromBody]EntityOperationRequest request) + public EntityPackTS? ConstructFromEntity([Required, FromBody]EntityOperationRequest request) { var entity = OperationLogic.ServiceConstructFrom(request.entity, request.GetOperationSymbol(request.entity.GetType()), request.args); @@ -38,7 +38,7 @@ public EntityPackTS ConstructFromEntity([Required, FromBody]EntityOperationReque } [HttpPost("api/operation/constructFromLite"), ProfilerActionSplitter] - public EntityPackTS ConstructFromLite([Required, FromBody]LiteOperationRequest request) + public EntityPackTS? ConstructFromLite([Required, FromBody]LiteOperationRequest request) { var entity = OperationLogic.ServiceConstructFromLite(request.lite, request.GetOperationSymbol(request.lite.EntityType), request.args); return entity == null ? null: SignumServer.GetEntityPack(entity); @@ -87,11 +87,11 @@ public void DeleteLite([Required, FromBody]LiteOperationRequest request) } +#pragma warning disable CS8618 // Non-nullable field is uninitialized. [JsonConverter(typeof(ArgsJsonConverter))] public class ConstructOperationRequest : BaseOperationRequest { public string type { get; set; } - } @@ -113,11 +113,11 @@ public class BaseOperationRequest { public string operationKey { get; set; } - public object[] args { get; set; } + public object[]? args { get; set; } public OperationSymbol GetOperationSymbol(Type entityType) => ParseOperationAssert(this.operationKey, entityType, this.args); - public static OperationSymbol ParseOperationAssert(string operationKey, Type entityType, object[] args = null) + public static OperationSymbol ParseOperationAssert(string operationKey, Type entityType, object[]? args = null) { var symbol = SymbolLogic.ToSymbol(operationKey); @@ -128,6 +128,7 @@ public static OperationSymbol ParseOperationAssert(string operationKey, Type ent public override string ToString() => operationKey; } +#pragma warning restore CS8618 // Non-nullable field is uninitialized. [HttpPost("api/operation/constructFromMany"), ProfilerActionSplitter] public EntityPackTS ConstructFromMany([Required, FromBody]MultiOperationRequest request) @@ -145,7 +146,7 @@ public MultiOperationResponse ConstructFromMultiple([Required, FromBody]MultiOpe var errors = ForeachMultiple(request.lites, lite => OperationLogic.ServiceConstructFromLite(lite, request.GetOperationSymbol(lite.EntityType), request.args)); - return new MultiOperationResponse { errors = errors }; + return new MultiOperationResponse(errors); } @@ -155,7 +156,7 @@ public MultiOperationResponse ExecuteMultiple([Required, FromBody]MultiOperation var errors = ForeachMultiple(request.lites, lite => OperationLogic.ServiceExecuteLite(lite, request.GetOperationSymbol(lite.EntityType), request.args)); - return new MultiOperationResponse { errors = errors }; + return new MultiOperationResponse(errors); } [HttpPost("api/operation/deleteMultiple"), ProfilerActionSplitter] @@ -164,7 +165,7 @@ public MultiOperationResponse DeleteMultiple([Required, FromBody]MultiOperationR var errors = ForeachMultiple(request.lites, lite => OperationLogic.ServiceDelete(lite, request.GetOperationSymbol(lite.EntityType), request.args)); - return new MultiOperationResponse { errors = errors }; + return new MultiOperationResponse(errors); } static Dictionary ForeachMultiple(IEnumerable> lites, Action> action) @@ -188,15 +189,22 @@ static Dictionary ForeachMultiple(IEnumerable> lite } +#pragma warning disable CS8618 // Non-nullable field is uninitialized. [JsonConverter(typeof(ArgsJsonConverter))] public class MultiOperationRequest : BaseOperationRequest { public string type { get; set; } public Lite[] lites { get; set; } } +#pragma warning restore CS8618 // Non-nullable field is uninitialized. public class MultiOperationResponse { + public MultiOperationResponse(Dictionary errors) + { + this.errors = errors; + } + public Dictionary errors { get; set; } } @@ -209,19 +217,26 @@ public StateCanExecuteResponse StateCanExecutes([Required, FromBody]StateCanExec .Select(operationKey => types.Select(t => BaseOperationRequest.ParseOperationAssert(operationKey, t)).Distinct().SingleEx()) .ToList(); - var result = OperationLogic.GetContextualCanExecute(request.lites, operationSymbols); + var result = OperationLogic.GetContextualCanExecute(request.lites, operationSymbols)!; - return new StateCanExecuteResponse { canExecutes = result.SelectDictionary(a => a.Key, v => v) }; + return new StateCanExecuteResponse(result.SelectDictionary(a => a.Key, v => v)); } +#pragma warning disable CS8618 // Non-nullable field is uninitialized. public class StateCanExecuteRequest { public string[] operationKeys { get; set; } public Lite[] lites { get; set; } } +#pragma warning restore CS8618 // Non-nullable field is uninitialized. public class StateCanExecuteResponse { + public StateCanExecuteResponse(Dictionary canExecutes) + { + this.canExecutes = canExecutes; + } + public Dictionary canExecutes { get; set; } } diff --git a/Signum.React/ApiControllers/QueryController.cs b/Signum.React/ApiControllers/QueryController.cs index 058bc0edbb..53bced9496 100644 --- a/Signum.React/ApiControllers/QueryController.cs +++ b/Signum.React/ApiControllers/QueryController.cs @@ -23,6 +23,8 @@ namespace Signum.React.ApiControllers { +#pragma warning disable CS8618 // Non-nullable field is uninitialized. + [ValidateModelFilter] public class QueryController : ControllerBase { @@ -111,7 +113,6 @@ public class ParseTokensRequest { public string queryKey; public List tokens; - } [HttpPost("api/query/subTokens")] @@ -131,7 +132,7 @@ public List SubTokens([Required, FromBody]SubTokensRequest request public class SubTokensRequest { public string queryKey; - public string token; + public string? token; public SubTokensOptions options; } @@ -149,7 +150,7 @@ public async Task>> GetEntitiesWithFilter([Required, FromBody] } [HttpPost("api/query/queryValue"), ProfilerActionSplitter] - public async Task QueryValue([Required, FromBody]QueryValueRequestTS request, CancellationToken token) + public async Task QueryValue([Required, FromBody]QueryValueRequestTS request, CancellationToken token) { return await QueryLogic.Queries.ExecuteQueryValueAsync(request.ToQueryCountRequest(), token); } @@ -277,7 +278,7 @@ public static FilterTS FromFilter(Filter filter) if (filter is FilterGroup fg) return new FilterGroupTS { - token = fg.Token.FullKey(), + token = fg.Token?.FullKey(), groupOperation = fg.GroupOperation, filters = fg.Filters.Select(f => FromFilter(f)).ToList(), }; @@ -290,16 +291,14 @@ public class FilterConditionTS : FilterTS { public string token; public FilterOperation operation; - public object value; + public object? value; public override Filter ToFilter(QueryDescription qd, bool canAggregate) { var options = SubTokensOptions.CanElement | SubTokensOptions.CanAnyAll | (canAggregate ? SubTokensOptions.CanAggregate : 0); var parsedToken = QueryUtils.Parse(token, qd, options); var expectedValueType = operation.IsList() ? typeof(ObservableCollection<>).MakeGenericType(parsedToken.Type.Nullify()) : parsedToken.Type; - - - + var val = value is JToken ? ((JToken)value).ToObject(expectedValueType, JsonSerializer.Create(SignumServer.JsonSerializerSettings)) : value; @@ -313,7 +312,7 @@ public override Filter ToFilter(QueryDescription qd, bool canAggregate) public class FilterGroupTS : FilterTS { public FilterGroupOperation groupOperation; - public string token; + public string? token; public List filters; public override Filter ToFilter(QueryDescription qd, bool canAggregate) @@ -461,15 +460,15 @@ public class ColumnDescriptionTS public string typeColor; public string niceTypeName; public FilterType? filterType; - public string unit; - public string format; + public string? unit; + public string? format; public string displayName; public bool isGroupable; [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool hasOrderAdapter; [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool preferEquals; - public string propertyRoute; + public string? propertyRoute; public ColumnDescriptionTS(ColumnDescription a, object queryName) { @@ -545,15 +544,15 @@ public QueryTokenTS(QueryToken qt, bool recursive) public QueryTokenType? queryTokenType; public TypeReferenceTS type; public FilterType? filterType; - public string format; - public string unit; + public string? format; + public string? unit; public bool isGroupable; [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool hasOrderAdapter; [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool preferEquals; - public QueryTokenTS parent; - public string propertyRoute; + public QueryTokenTS? parent; + public string? propertyRoute; } public enum QueryTokenType diff --git a/Signum.React/ApiControllers/ReflectionController.cs b/Signum.React/ApiControllers/ReflectionController.cs index 0c78365347..06284d57c7 100644 --- a/Signum.React/ApiControllers/ReflectionController.cs +++ b/Signum.React/ApiControllers/ReflectionController.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Signum.React.Facades; using Signum.Entities.Basics; using Signum.Engine.Basics; @@ -16,7 +16,7 @@ public Dictionary Types() } [HttpGet("api/reflection/typeEntity/{typeName}")] - public TypeEntity GetTypeEntity(string typeName) + public TypeEntity? GetTypeEntity(string typeName) { return TypeLogic.TryGetType(typeName)?.ToTypeEntity(); } diff --git a/Signum.React/Facades/LambdaToJavascriptConverter.cs b/Signum.React/Facades/LambdaToJavascriptConverter.cs index 092fae82e8..5703cdaf0c 100644 --- a/Signum.React/Facades/LambdaToJavascriptConverter.cs +++ b/Signum.React/Facades/LambdaToJavascriptConverter.cs @@ -1,4 +1,4 @@ -using Signum.Entities; +using Signum.Entities; using Signum.Entities.Reflection; using Signum.Utilities; using Signum.Utilities.ExpressionTrees; @@ -12,7 +12,7 @@ namespace Signum.React.Facades { internal class LambdaToJavascriptConverter { - public static string ToJavascript(LambdaExpression lambdaExpression) + public static string? ToJavascript(LambdaExpression lambdaExpression) { if (lambdaExpression == null) return null; @@ -32,7 +32,7 @@ public static string ToJavascript(LambdaExpression lambdaExpression) { "\r", ""}, }; - private static string ToJavascript(ParameterExpression param, Expression expr) + private static string? ToJavascript(ParameterExpression param, Expression expr) { if (param == expr) return "e"; @@ -126,7 +126,7 @@ private static string ToJavascript(ParameterExpression param, Expression expr) return null; } - private static string ToJavascriptToString(ParameterExpression param, Expression expr, string format = null) + private static string? ToJavascriptToString(ParameterExpression param, Expression expr, string? format = null) { var r = ToJavascript(param, expr); @@ -139,7 +139,7 @@ private static string ToJavascriptToString(ParameterExpression param, Expression if (expr.Type.IsModifiableEntity() || expr.Type.IsLite() || expr.Type.IsIEntity()) return "getToString(" + r + ")"; - string formatFull = format == null ? null : (", '" + format + "'"); + string? formatFull = format == null ? null : (", '" + format + "'"); if (expr.Type.UnNullify() == typeof(DateTime)) return "dateToString(" + r + formatFull + ")"; @@ -153,4 +153,4 @@ private static string ToJavascriptToString(ParameterExpression param, Expression return "valToString(" + r + ")"; } } -} \ No newline at end of file +} diff --git a/Signum.React/Facades/ReflectionServer.cs b/Signum.React/Facades/ReflectionServer.cs index 82bb905432..85316d5a3d 100644 --- a/Signum.React/Facades/ReflectionServer.cs +++ b/Signum.React/Facades/ReflectionServer.cs @@ -181,18 +181,19 @@ select KVP.Create(GetTypeName(type), OnAddTypeExtension(new TypeInfoTS EntityData = type.IsIEntity() ? EntityKindCache.GetEntityData(type) : (EntityData?)null, IsLowPopulation = type.IsIEntity() ? EntityKindCache.IsLowPopulation(type) : false, IsSystemVersioned = type.IsIEntity() ? schema.Table(type).SystemVersioned != null : false, - ToStringFunction = typeof(Symbol).IsAssignableFrom(type) ? null : LambdaToJavascriptConverter.ToJavascript(ExpressionCleaner.GetFieldExpansion(type, miToString)), + ToStringFunction = typeof(Symbol).IsAssignableFrom(type) ? null : LambdaToJavascriptConverter.ToJavascript(ExpressionCleaner.GetFieldExpansion(type, miToString)!), QueryDefined = queries.QueryDefined(type), - Members = PropertyRoute.GenerateRoutes(type).Where(pr => InTypeScript(pr)) + Members = PropertyRoute.GenerateRoutes(type) + .Where(pr => InTypeScript(pr)) .ToDictionary(p => p.PropertyString(), p => { var mi = new MemberInfoTS { - NiceName = p.PropertyInfo?.NiceName(), - TypeNiceName = GetTypeNiceName(p.PropertyInfo?.PropertyType), + NiceName = p.PropertyInfo!.NiceName(), + TypeNiceName = GetTypeNiceName(p.PropertyInfo!.PropertyType), Format = p.PropertyRouteType == PropertyRouteType.FieldOrProperty ? Reflector.FormatString(p) : null, IsReadOnly = !IsId(p) && (p.PropertyInfo?.IsReadOnly() ?? false), - Required = !IsId(p) && ((p.Type.IsValueType && !p.Type.IsNullable()) || Validator.TryGetPropertyValidator(p).Validators.Any(v => !v.DisabledInModelBinder && (v is NotNullValidatorAttribute || v is StringLengthValidatorAttribute s && s.AllowNulls == false))), + Required = !IsId(p) && ((p.Type.IsValueType && !p.Type.IsNullable()) || Validator.TryGetPropertyValidator(p)!.Validators.Any(v => (v is NotNullValidatorAttribute) && !v.DisabledInModelBinder)), Unit = UnitAttribute.GetTranslation(p.PropertyInfo?.GetCustomAttribute()?.UnitName), Type = new TypeReferenceTS(IsId(p) ? PrimaryKey.Type(type).Nullify() : p.PropertyInfo?.PropertyType, p.Type.IsMList() ? p.Add("Item").TryGetImplementations() : p.TryGetImplementations()), IsMultiline = Validator.TryGetPropertyValidator(p)?.Validators.OfType().FirstOrDefault()?.MultiLine ?? false, @@ -214,7 +215,8 @@ select KVP.Create(GetTypeName(type), OnAddTypeExtension(new TypeInfoTS public static bool InTypeScript(PropertyRoute pr) { - return (pr.Parent == null || InTypeScript(pr.Parent)) && (pr.PropertyInfo == null || (pr.PropertyInfo.GetCustomAttribute()?.GetInTypeScript() ?? !IsExpression(pr.Parent.Type, pr.PropertyInfo))); + return (pr.Parent == null || InTypeScript(pr.Parent)) && + (pr.PropertyInfo == null || (pr.PropertyInfo.GetCustomAttribute()?.GetInTypeScript() ?? !IsExpression(pr.Parent!.Type, pr.PropertyInfo))); } private static bool IsExpression(Type type, PropertyInfo propertyInfo) @@ -222,7 +224,7 @@ private static bool IsExpression(Type type, PropertyInfo propertyInfo) return propertyInfo.SetMethod == null && ExpressionCleaner.HasExpansions(type, propertyInfo); } - static string GetTypeNiceName(Type type) + static string? GetTypeNiceName(Type type) { if (type.IsModifiableEntity() && !type.IsEntity()) return type.NiceName(); @@ -232,8 +234,8 @@ static string GetTypeNiceName(Type type) public static bool IsId(PropertyRoute p) { return p.PropertyRouteType == PropertyRouteType.FieldOrProperty && - p.PropertyInfo.Name == nameof(Entity.Id) && - p.Parent.PropertyRouteType == PropertyRouteType.Root; + p.PropertyInfo!.Name == nameof(Entity.Id) && + p.Parent!.PropertyRouteType == PropertyRouteType.Root; } public static Dictionary GetEnums(IEnumerable allTypes) @@ -300,7 +302,7 @@ private static (FieldInfo FieldInfo, PrimaryKey? IdOrNull) GetSymbolInfo(FieldIn return (s.FieldInfo, s.IdOrNull); if(v is SemiSymbol semiS) - return (semiS.FieldInfo, semiS.IdOrNull); + return (semiS.FieldInfo!, semiS.IdOrNull); throw new InvalidOperationException(); } @@ -320,13 +322,13 @@ public class TypeInfoTS [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "kind")] public KindOfType Kind { get; set; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "fullName")] - public string FullName { get; set; } + public string FullName { get; set; } = null!; [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "niceName")] - public string NiceName { get; set; } + public string? NiceName { get; set; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "nicePluralName")] - public string NicePluralName { get; set; } + public string? NicePluralName { get; set; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "gender")] - public string Gender { get; set; } + public string? Gender { get; set; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "entityKind")] public EntityKind? EntityKind { get; set; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "entityData")] @@ -336,13 +338,13 @@ public class TypeInfoTS [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore, PropertyName = "isSystemVersioned")] public bool IsSystemVersioned { get; set; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "toStringFunction")] - public string ToStringFunction { get; set; } + public string? ToStringFunction { get; set; } [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore, PropertyName = "queryDefined")] public bool QueryDefined { get; internal set; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "members")] - public Dictionary Members { get; set; } + public Dictionary Members { get; set; } = null!; [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "operations")] - public Dictionary Operations { get; set; } + public Dictionary? Operations { get; set; } [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore, PropertyName = "requiresEntityPack")] public bool RequiresEntityPack { get; set; } @@ -356,19 +358,19 @@ public class TypeInfoTS public class MemberInfoTS { [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "type")] - public TypeReferenceTS Type { get; set; } + public TypeReferenceTS? Type { get; set; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "niceName")] - public string NiceName { get; set; } + public string? NiceName { get; set; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "typeNiceName")] - public string TypeNiceName { get; set; } + public string? TypeNiceName { get; set; } [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore, PropertyName = "isReadOnly")] public bool IsReadOnly { get; set; } [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore, PropertyName = "required")] public bool Required { get; set; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "unit")] - public string Unit { get; set; } + public string? Unit { get; set; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "format")] - public string Format { get; set; } + public string? Format { get; set; } [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore, PropertyName = "isIgnoredEnum")] public bool IsIgnoredEnum { get; set; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "maxLength")] @@ -379,7 +381,7 @@ public class MemberInfoTS public bool PreserveOrder { get; internal set; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "id")] - public object Id { get; set; } + public object? Id { get; set; } [JsonExtensionData] public Dictionary Extension { get; set; } = new Dictionary(); @@ -424,9 +426,11 @@ public class TypeReferenceTS [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "name")] public string Name { get; set; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "typeNiceName")] - public string TypeNiceName { get; set; } + public string? TypeNiceName { get; set; } +#pragma warning disable CS8618 // Non-nullable field is uninitialized. public TypeReferenceTS() { } +#pragma warning restore CS8618 // Non-nullable field is uninitialized. public TypeReferenceTS(Type type, Implementations? implementations) { this.IsCollection = type != typeof(string) && type != typeof(byte[]) && type.ElementType() != null; @@ -454,11 +458,11 @@ private static string TypeScriptType(Type type) private static Type CleanMList(Type type) { if (type.IsMList()) - type = type.ElementType(); + type = type.ElementType()!; return type; } - public static string BasicType(Type type) + public static string? BasicType(Type type) { if (type.IsEnum) return null; diff --git a/Signum.React/Facades/SignumServer.cs b/Signum.React/Facades/SignumServer.cs index 2e6a587dfd..060354d6eb 100644 --- a/Signum.React/Facades/SignumServer.cs +++ b/Signum.React/Facades/SignumServer.cs @@ -1,4 +1,4 @@ -using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; @@ -79,11 +79,9 @@ public static EntityPackTS GetEntityPack(Entity entity) { var canExecutes = OperationLogic.ServiceCanExecute(entity); - var result = new EntityPackTS - { - entity = entity, - canExecute = canExecutes.ToDictionary(a => a.Key.Key, a => a.Value) - }; + var result = new EntityPackTS(entity, + canExecutes.ToDictionary(a => a.Key.Key, a => a.Value) + ); foreach (var action in EntityPackTS.AddExtension.GetInvocationListTyped()) { @@ -100,8 +98,14 @@ public class EntityPackTS public Dictionary canExecute { get; set; } [JsonExtensionData] - public Dictionary Extension { get; set; } = new Dictionary(); + public Dictionary extension { get; set; } = new Dictionary(); public static Action AddExtension; + + public EntityPackTS(Entity entity, Dictionary canExecute) + { + this.entity = entity; + this.canExecute = canExecute; + } } -} \ No newline at end of file +} diff --git a/Signum.React/Filters/ProfilerFilterAttribute.cs b/Signum.React/Filters/ProfilerFilterAttribute.cs index 868b43f541..a29363f986 100644 --- a/Signum.React/Filters/ProfilerFilterAttribute.cs +++ b/Signum.React/Filters/ProfilerFilterAttribute.cs @@ -1,4 +1,4 @@ -using Microsoft.AspNetCore.Mvc.Controllers; +using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Filters; using Signum.Utilities; using Signum.Utilities.ExpressionTrees; @@ -10,14 +10,14 @@ namespace Signum.React.Filters [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)] public class ProfilerActionSplitterAttribute : Attribute { - readonly string requestKey; + readonly string? requestKey; - public ProfilerActionSplitterAttribute(string requestKey = null) + public ProfilerActionSplitterAttribute(string? requestKey = null) { this.requestKey = requestKey; } - public string RequestKey + public string? RequestKey { get { return requestKey; } } @@ -43,4 +43,4 @@ public static string GetActionDescription(FilterContext actionContext) return action; } } -} \ No newline at end of file +} diff --git a/Signum.React/Filters/SignumFilters.cs b/Signum.React/Filters/SignumFilters.cs index 299eb666ba..5225dfd50d 100644 --- a/Signum.React/Filters/SignumFilters.cs +++ b/Signum.React/Filters/SignumFilters.cs @@ -1,4 +1,4 @@ -using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.Mvc.Filters; using Signum.Entities.Basics; @@ -11,7 +11,7 @@ namespace Signum.React.Filters { public class SignumAuthenticationResult { - public IUserEntity User { get; set; } + public IUserEntity? User { get; set; } } public class SignumEnableBufferingFilter : IResourceFilter @@ -45,7 +45,7 @@ public SignumAuthenticationFilter() : base("Signum_User"){ } public static readonly IList> Authenticators = new List>(); - private static SignumAuthenticationResult Authenticate(ResourceExecutingContext actionContext) + private static SignumAuthenticationResult? Authenticate(ResourceExecutingContext actionContext) { foreach (var item in Authenticators) { @@ -57,7 +57,7 @@ private static SignumAuthenticationResult Authenticate(ResourceExecutingContext return null; } - public override IDisposable GetResource(ResourceExecutingContext context) + public override IDisposable? GetResource(ResourceExecutingContext context) { var result = Authenticate(context); @@ -98,7 +98,7 @@ public class SignumTimesTrackerFilter : SignumDisposableResourceFilter { public SignumTimesTrackerFilter() : base("Signum_TimesTracker") { } - public override IDisposable GetResource(ResourceExecutingContext context) + public override IDisposable? GetResource(ResourceExecutingContext context) { string action = ProfilerActionSplitterAttribute.GetActionDescription(context); return TimeTracker.Start(action); @@ -109,7 +109,7 @@ public class SignumHeavyProfilerFilter : SignumDisposableResourceFilter { public SignumHeavyProfilerFilter() : base("Signum_HeavyProfiler") { } - public override IDisposable GetResource(ResourceExecutingContext context) + public override IDisposable? GetResource(ResourceExecutingContext context) { return HeavyProfiler.Log("Web.API " + context.HttpContext.Request.Method, () => context.HttpContext.Request.GetDisplayUrl()); } @@ -124,7 +124,7 @@ public SignumDisposableResourceFilter(string key) this.ResourceKey = key; } - public abstract IDisposable GetResource(ResourceExecutingContext context); + public abstract IDisposable? GetResource(ResourceExecutingContext context); public void OnResourceExecuting(ResourceExecutingContext context) { @@ -140,4 +140,4 @@ public void OnResourceExecuted(ResourceExecutedContext context) } } } -} \ No newline at end of file +} diff --git a/Signum.React/JsonConverters/ArgsJsonConverter.cs b/Signum.React/JsonConverters/ArgsJsonConverter.cs index c7a7ea609d..49e78d5482 100644 --- a/Signum.React/JsonConverters/ArgsJsonConverter.cs +++ b/Signum.React/JsonConverters/ArgsJsonConverter.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Signum.Engine; using Signum.Entities; @@ -12,14 +12,13 @@ namespace Signum.React.Json { public class ArgsJsonConverter : JsonConverter { - public static Dictionary> CustomOperationArgsConverters = - new Dictionary>(); + public static Dictionary> CustomOperationArgsConverters = new Dictionary>(); - public static void RegisterCustomOperationArgsConverter(OperationSymbol operationSymbol, Func converter) + public static void RegisterCustomOperationArgsConverter(OperationSymbol operationSymbol, Func converter) { - CustomOperationArgsConverters[operationSymbol] = - CustomOperationArgsConverters.TryGetC(operationSymbol) + - converter; + Func? a = CustomOperationArgsConverters.TryGetC(operationSymbol); /*CSBUG*/ + + CustomOperationArgsConverters[operationSymbol] = a + converter; } public override bool CanConvert(Type objectType) @@ -50,7 +49,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist private object ConvertObject(JToken token, JsonSerializer serializer, OperationSymbol operationSymbol) { if (token == null) - return null; + return null!; if (token is JValue) { @@ -81,4 +80,4 @@ private object ConvertObject(JToken token, JsonSerializer serializer, OperationS return conv.GetInvocationListTyped().Select(f => conv(token)).NotNull().FirstOrDefault(); } } -} \ No newline at end of file +} diff --git a/Signum.React/JsonConverters/EntityJsonConverter.cs b/Signum.React/JsonConverters/EntityJsonConverter.cs index 6da6c32495..1497364526 100644 --- a/Signum.React/JsonConverters/EntityJsonConverter.cs +++ b/Signum.React/JsonConverters/EntityJsonConverter.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using Newtonsoft.Json; using Signum.Engine; using Signum.Engine.Basics; using Signum.Engine.Maps; @@ -27,7 +27,7 @@ public static Dictionary GetPropertyConverters(Type t Validator.GetPropertyValidators(_t).Values .Where(pv => ShouldSerialize(pv.PropertyInfo)) .Select(pv => new PropertyConverter(_t, pv)) - .ToDictionary(a => a.PropertyValidator.PropertyInfo.Name.FirstLower()) + .ToDictionary(a => a.PropertyValidator!.PropertyInfo.Name.FirstLower()) ); } @@ -47,13 +47,13 @@ static bool ShouldSerialize(PropertyInfo pi) return true; } - public readonly IPropertyValidator PropertyValidator; - public readonly Func GetValue; - public readonly Action SetValue; + public readonly IPropertyValidator? PropertyValidator; + public readonly Func? GetValue; + public readonly Action? SetValue; - public Action CustomReadJsonProperty { get; set; } - public Action CustomWriteJsonProperty { get; set; } + public Action? CustomReadJsonProperty { get; set; } + public Action? CustomWriteJsonProperty { get; set; } public bool AvoidValidate { get; set; } @@ -70,12 +70,12 @@ public PropertyConverter(Type type, IPropertyValidator pv) public override string ToString() { - return this.PropertyValidator?.PropertyInfo.Name; + return this.PropertyValidator?.PropertyInfo.Name ?? ""; } internal bool IsNotNull() { - var pi = this.PropertyValidator.PropertyInfo; + var pi = this.PropertyValidator!.PropertyInfo; return pi.PropertyType.IsValueType && !pi.PropertyType.IsNullable(); } @@ -83,6 +83,15 @@ internal bool IsNotNull() public class ReadJsonPropertyContext { + public ReadJsonPropertyContext(JsonReader jsonReader, JsonSerializer jsonSerializer, PropertyConverter propertyConverter, ModifiableEntity entity, PropertyRoute parentPropertyRoute) + { + JsonReader = jsonReader; + JsonSerializer = jsonSerializer; + PropertyConverter = propertyConverter; + Entity = entity; + ParentPropertyRoute = parentPropertyRoute; + } + public JsonReader JsonReader { get; internal set; } public JsonSerializer JsonSerializer { get; internal set; } @@ -93,6 +102,16 @@ public class ReadJsonPropertyContext public class WriteJsonPropertyContext { + public WriteJsonPropertyContext(ModifiableEntity entity, string lowerCaseName, PropertyConverter propertyConverter, PropertyRoute parentPropertyRoute, JsonWriter jsonWriter, JsonSerializer jsonSerializer) + { + Entity = entity; + LowerCaseName = lowerCaseName; + PropertyConverter = propertyConverter; + ParentPropertyRoute = parentPropertyRoute; + JsonWriter = jsonWriter; + JsonSerializer = jsonSerializer; + } + public ModifiableEntity Entity { get; internal set; } public string LowerCaseName { get; internal set; } public PropertyConverter PropertyConverter { get; internal set; } @@ -208,19 +227,18 @@ public void WriteJsonProperty(JsonWriter writer, JsonSerializer serializer, Modi { if (pc.CustomWriteJsonProperty != null) { - pc.CustomWriteJsonProperty(new WriteJsonPropertyContext - { - JsonWriter = writer, - JsonSerializer = serializer, - LowerCaseName = lowerCaseName, - Entity = mod, - ParentPropertyRoute = route, - PropertyConverter = pc - }); + pc.CustomWriteJsonProperty(new WriteJsonPropertyContext( + entity : mod, + lowerCaseName : lowerCaseName, + propertyConverter : pc, + parentPropertyRoute : route, + jsonWriter : writer, + jsonSerializer : serializer + )); } else { - var pr = route.Add(pc.PropertyValidator.PropertyInfo); + var pr = route.Add(pc.PropertyValidator!.PropertyInfo); string error = CanReadPropertyRoute?.Invoke(pr); @@ -230,7 +248,7 @@ public void WriteJsonProperty(JsonWriter writer, JsonSerializer serializer, Modi using (JsonSerializerExtensions.SetCurrentPropertyRoute(pr)) { writer.WritePropertyName(lowerCaseName); - serializer.Serialize(writer, pc.GetValue(mod)); + serializer.Serialize(writer, pc.GetValue!(mod)!); if (writer.WriteState == WriteState.Property) throw new InvalidOperationException($"Impossible to serialize '{mod}' to JSON. Maybe there is a cycle?"); } @@ -245,7 +263,7 @@ static EntityJsonConverter() AfterDeserilization.Register((ModifiableEntity e) => { }); } - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + public override object? ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { using (HeavyProfiler.LogNoStackTrace("ReadJson", () => objectType.Name)) { @@ -310,21 +328,20 @@ public void ReadJsonProperty(JsonReader reader, JsonSerializer serializer, Modif { if (pc.CustomReadJsonProperty != null) { - pc.CustomReadJsonProperty(new ReadJsonPropertyContext - { - JsonReader = reader, - JsonSerializer = serializer, - Entity = entity, - ParentPropertyRoute = parentRoute, - PropertyConverter = pc, - }); + pc.CustomReadJsonProperty(new ReadJsonPropertyContext( + jsonReader : reader, + jsonSerializer : serializer, + entity : entity, + parentPropertyRoute : parentRoute, + propertyConverter : pc + )); } else { - object oldValue = pc.GetValue(entity); + object? oldValue = pc.GetValue!(entity); - var pi = pc.PropertyValidator.PropertyInfo; + var pi = pc.PropertyValidator!.PropertyInfo; var pr = parentRoute.Add(pi); @@ -359,7 +376,7 @@ public void ReadJsonProperty(JsonReader reader, JsonSerializer serializer, Modif } } - private bool IsEquals(object newValue, object oldValue) + private bool IsEquals(object newValue, object? oldValue) { if (newValue is byte[] && oldValue is byte[]) return MemCompare.Compare((byte[])newValue, (byte[])oldValue); @@ -515,4 +532,4 @@ public static bool Compare(byte[] b1, byte[] b2) return b1.Length == b2.Length && memcmp(b1, b2, b1.Length) == 0; } } -} \ No newline at end of file +} diff --git a/Signum.React/JsonConverters/JsonSerializerExtensions.cs b/Signum.React/JsonConverters/JsonSerializerExtensions.cs index 49bb54bcc8..cff0f89f5b 100644 --- a/Signum.React/JsonConverters/JsonSerializerExtensions.cs +++ b/Signum.React/JsonConverters/JsonSerializerExtensions.cs @@ -8,7 +8,7 @@ namespace Signum.React.Json { public static class JsonSerializerExtensions { - public static object DeserializeValue(this JsonSerializer serializer, JsonReader reader, Type valueType, object oldValue) + public static object DeserializeValue(this JsonSerializer serializer, JsonReader reader, Type valueType, object? oldValue) { if (oldValue != null) { @@ -31,14 +31,14 @@ public static void Assert(this JsonReader reader, JsonToken expected) } - static readonly ThreadVariable currentPropertyRoute = Statics.ThreadVariable("jsonPropertyRoute"); + static readonly ThreadVariable currentPropertyRoute = Statics.ThreadVariable("jsonPropertyRoute"); - public static PropertyRoute CurrentPropertyRoute + public static PropertyRoute? CurrentPropertyRoute { get { return currentPropertyRoute.Value; } } - public static IDisposable SetCurrentPropertyRoute(PropertyRoute route) + public static IDisposable SetCurrentPropertyRoute(PropertyRoute? route) { var old = currentPropertyRoute.Value; diff --git a/Signum.React/JsonConverters/LiteJsonConverter.cs b/Signum.React/JsonConverters/LiteJsonConverter.cs index 89bada16a1..8db15e2258 100644 --- a/Signum.React/JsonConverters/LiteJsonConverter.cs +++ b/Signum.React/JsonConverters/LiteJsonConverter.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using Newtonsoft.Json; using Signum.Engine.Basics; using Signum.Entities; using System; @@ -36,17 +36,17 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s writer.WriteEndObject(); } - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + public override object? ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) return null; reader.Assert(JsonToken.StartObject); - string toString = null; - string idObj = null; - string typeStr = null; - Entity entity = null; + string? toString = null; + string? idObj = null; + string? typeStr = null; + Entity? entity = null; reader.Read(); while (reader.TokenType == JsonToken.PropertyName) @@ -68,12 +68,12 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist reader.Assert(JsonToken.EndObject); - Type type = TypeLogic.GetType(typeStr); + Type type = TypeLogic.GetType(typeStr!); PrimaryKey? idOrNull = idObj == null ? (PrimaryKey?)null : PrimaryKey.Parse(idObj, type); if (entity == null) - return Lite.Create(type, idOrNull.Value, toString); + return Lite.Create(type, idOrNull.Value, toString!); var result = entity.ToLiteFat(toString); @@ -85,7 +85,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist var existing = existingValue as Lite; - if (existing.Is(result) && existing.EntityOrNull == null && result.EntityOrNull != null) + if (existing.Is(result) && existing!.EntityOrNull == null && result.EntityOrNull != null) { existing.SetEntity(result.EntityOrNull); return existing; @@ -96,4 +96,4 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist } -} \ No newline at end of file +} diff --git a/Signum.React/JsonConverters/MListJsonConverter.cs b/Signum.React/JsonConverters/MListJsonConverter.cs index e254d0c5e6..f8077db8d0 100644 --- a/Signum.React/JsonConverters/MListJsonConverter.cs +++ b/Signum.React/JsonConverters/MListJsonConverter.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using Newtonsoft.Json; using Signum.Engine; using Signum.Engine.Maps; using Signum.Entities; @@ -20,7 +20,7 @@ public override bool CanConvert(Type objectType) public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { - giWriteJsonInternal.GetInvoker(value.GetType().ElementType())(writer, (IMListPrivate)value, serializer); + giWriteJsonInternal.GetInvoker(value.GetType().ElementType()!)(writer, (IMListPrivate)value, serializer); } static GenericInvoker> giWriteJsonInternal = new GenericInvoker>( @@ -29,7 +29,7 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s static void WriteJsonInternal(JsonWriter writer, MList value, JsonSerializer serializer) { writer.WriteStartArray(); - var pr = JsonSerializerExtensions.CurrentPropertyRoute; + var pr = JsonSerializerExtensions.CurrentPropertyRoute!; var elementPr = pr.Add("Item"); @@ -54,7 +54,7 @@ static void WriteJsonInternal(JsonWriter writer, MList value, JsonSerializ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { - return giReadJsonInternal.GetInvoker(objectType.ElementType())(reader, (IMListPrivate)existingValue, serializer); + return giReadJsonInternal.GetInvoker(objectType.ElementType()!)(reader, (IMListPrivate)existingValue, serializer); } static GenericInvoker> giReadJsonInternal = @@ -68,7 +68,7 @@ static MList ReadJsonInternal(JsonReader reader, IMListPrivate existing var newList = new List.RowIdElement>(); - var pr = JsonSerializerExtensions.CurrentPropertyRoute; + var pr = JsonSerializerExtensions.CurrentPropertyRoute!; var elementPr = pr.Add("Item"); @@ -99,7 +99,7 @@ static MList ReadJsonInternal(JsonReader reader, IMListPrivate existing reader.Read(); if (rowIdValue != null && !rowIdValue.Equals(GraphExplorer.DummyRowId.Object)) { - var rowId = new PrimaryKey((IComparable)ReflectionTools.ChangeType(rowIdValue, rowIdType)); + var rowId = new PrimaryKey((IComparable)ReflectionTools.ChangeType(rowIdValue, rowIdType)!); var oldValue = dic.TryGetS(rowId); @@ -113,7 +113,7 @@ static MList ReadJsonInternal(JsonReader reader, IMListPrivate existing { T newValue = (T)serializer.DeserializeValue(reader, typeof(T), oldValue.Value.Element); - if (oldValue.Value.Element.Equals(newValue)) + if (oldValue.Value.Element!.Equals(newValue)) newList.Add(new MList.RowIdElement(newValue, rowId, oldValue.Value.OldIndex)); else newList.Add(new MList.RowIdElement(newValue)); @@ -137,7 +137,7 @@ static MList ReadJsonInternal(JsonReader reader, IMListPrivate existing if (existingValue == null) //Strange case... { if (newList.IsEmpty()) - return null; + return null!; else existingValue = new MList(); } @@ -158,7 +158,7 @@ private static Type GetRowIdTypeFromAttribute(PropertyRoute route) { var settings = Schema.Current.Settings; var att = settings.FieldAttribute(route) ?? - (route.IsVirtualMList() ? settings.TypeAttribute(route.Type.ElementType()) : null) ?? + (route.IsVirtualMList() ? settings.TypeAttribute(route.Type.ElementType()!) : null) ?? settings.DefaultPrimaryKeyAttribute; return att.Type; @@ -173,4 +173,4 @@ private static bool GetPreserveOrderFromAttribute(PropertyRoute route) } -} \ No newline at end of file +} diff --git a/Signum.React/JsonConverters/TimeSpanConverter.cs b/Signum.React/JsonConverters/TimeSpanConverter.cs index 842a7584e5..253dc4ccc2 100644 --- a/Signum.React/JsonConverters/TimeSpanConverter.cs +++ b/Signum.React/JsonConverters/TimeSpanConverter.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using Newtonsoft.Json; using Signum.Utilities; using System; @@ -16,7 +16,7 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s writer.WriteValue(((TimeSpan?) value)?.ToString()); } - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + public override object? ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var str = reader.Value as string; return string.IsNullOrEmpty(str) ? (TimeSpan?)null : TimeSpan.Parse(str); @@ -24,4 +24,4 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist } -} \ No newline at end of file +} diff --git a/Signum.React/JsonModelValidators/DefaultValidator.cs b/Signum.React/JsonModelValidators/DefaultValidator.cs index 609c05e226..91e8e71796 100644 --- a/Signum.React/JsonModelValidators/DefaultValidator.cs +++ b/Signum.React/JsonModelValidators/DefaultValidator.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -73,11 +73,11 @@ public ValidationVisitor( protected ValidationStack CurrentPath { get; } #pragma warning restore PUB0001 - protected object Container { get; set; } - protected string Key { get; set; } - protected object Model { get; set; } - protected ModelMetadata Metadata { get; set; } - protected IValidationStrategy Strategy { get; set; } + protected object? Container { get; set; } + protected string? Key { get; set; } + protected object? Model { get; set; } + protected ModelMetadata? Metadata { get; set; } + protected IValidationStrategy? Strategy { get; set; } /// /// Indicates whether validation of a complex type should be performed if validation fails for any of its children. The default behavior is false. @@ -103,7 +103,7 @@ public bool Validate(ModelMetadata metadata, string key, object model) /// The model object. /// If true, applies validation rules even if the top-level value is null. /// true if the object is valid, otherwise false. - public virtual bool Validate(ModelMetadata metadata, string key, object model, bool alwaysValidateAtTopLevel) + public virtual bool Validate(ModelMetadata? metadata, string key, object model, bool alwaysValidateAtTopLevel) { if (model == null && key != null && !alwaysValidateAtTopLevel) { @@ -181,7 +181,7 @@ protected virtual bool ValidateNode() } } - protected virtual bool Visit(ModelMetadata metadata, string key, object model) + protected virtual bool Visit(ModelMetadata? metadata, string key, object model) { RuntimeHelpers.EnsureSufficientExecutionStack(); @@ -211,7 +211,7 @@ protected virtual bool Visit(ModelMetadata metadata, string key, object model) using (StateManager.Recurse(this, key ?? string.Empty, metadata, model, strategy)) { - if (Metadata.IsEnumerableType) + if (Metadata!.IsEnumerableType) { return VisitComplexType(DefaultCollectionValidationStrategy.Instance); } @@ -230,7 +230,7 @@ protected virtual bool VisitComplexType(IValidationStrategy defaultStrategy) { var isValid = true; - if (Model != null && Metadata.ValidateChildren) + if (Model != null && Metadata!.ValidateChildren) { var strategy = Strategy ?? defaultStrategy; isValid = VisitChildren(strategy); @@ -240,7 +240,7 @@ protected virtual bool VisitComplexType(IValidationStrategy defaultStrategy) // Suppress validation for the entries matching this prefix. This will temporarily set // the current node to 'skipped' but we're going to visit it right away, so subsequent // code will set it to 'valid' or 'invalid' - SuppressValidation(Key); + SuppressValidation(Key!); } // Double-checking HasReachedMaxErrors just in case this model has no properties. @@ -257,7 +257,7 @@ protected virtual bool VisitSimpleType() { if (ModelState.HasReachedMaxErrors) { - SuppressValidation(Key); + SuppressValidation(Key!); return false; } @@ -303,12 +303,10 @@ protected virtual void SuppressValidation(string key) } } - protected virtual ValidationStateEntry GetValidationEntry(object model) + protected virtual ValidationStateEntry? GetValidationEntry(object model) { if (model == null || ValidationState == null) - { return null; - } ValidationState.TryGetValue(model, out var entry); return entry; @@ -320,16 +318,16 @@ protected struct StateManager : IDisposable private readonly object _container; private readonly string _key; private readonly ModelMetadata _metadata; - private readonly object _model; - private readonly object _newModel; - private readonly IValidationStrategy _strategy; + private readonly object? _model; + private readonly object? _newModel; + private readonly IValidationStrategy? _strategy; public static StateManager Recurse( ValidationVisitor visitor, string key, - ModelMetadata metadata, - object model, - IValidationStrategy strategy) + ModelMetadata? metadata, + object? model, + IValidationStrategy? strategy) { var recursifier = new StateManager(visitor, model); @@ -342,15 +340,15 @@ public static StateManager Recurse( return recursifier; } - public StateManager(ValidationVisitor visitor, object newModel) + public StateManager(ValidationVisitor visitor, object? newModel) { _visitor = visitor; _newModel = newModel; - _container = _visitor.Container; - _key = _visitor.Key; - _metadata = _visitor.Metadata; - _model = _visitor.Model; + _container = _visitor.Container!; + _key = _visitor.Key!; + _metadata = _visitor.Metadata!; + _model = _visitor.Model!; _strategy = _visitor.Strategy; } @@ -366,4 +364,4 @@ public void Dispose() } } } -} \ No newline at end of file +} diff --git a/Signum.React/JsonModelValidators/SignumObjectValidator.cs b/Signum.React/JsonModelValidators/SignumObjectValidator.cs index b261f8d62d..036aabda62 100644 --- a/Signum.React/JsonModelValidators/SignumObjectValidator.cs +++ b/Signum.React/JsonModelValidators/SignumObjectValidator.cs @@ -174,7 +174,7 @@ private bool ValidateLite(Lite lite) private bool ValidateMList(IMListPrivate mlist) { bool isValid = true; - Type elementType = mlist.GetType().ElementType(); + Type elementType = mlist.GetType().ElementType()!; int i = 0; foreach (object element in (IEnumerable)mlist) @@ -212,15 +212,14 @@ private bool ValidateModifiableEntity(ModifiableEntity mod) if (kvp.Value.AvoidValidate) continue; - string error = kvp.Value.PropertyValidator.PropertyCheck(mod); - + string? error = kvp.Value.PropertyValidator!.PropertyCheck(mod); if (error != null) { isValid = false; ModelState.AddModelError(this.Key + "." + kvp.Key, error); } - var val = kvp.Value.GetValue(mod); + var val = kvp.Value.GetValue!(mod); if (this.CurrentPath.Push(val)) { using (StateManager.Recurse(this, this.Key + "." + kvp.Key, null, val, null)) diff --git a/Signum.React/Scripts/Signum.Entities.Basics.ts b/Signum.React/Scripts/Signum.Entities.Basics.ts index 98310ed3fa..5c01566fb3 100644 --- a/Signum.React/Scripts/Signum.Entities.Basics.ts +++ b/Signum.React/Scripts/Signum.Entities.Basics.ts @@ -24,7 +24,7 @@ export interface DeleteLogParametersEmbedded extends Entities.EmbeddedEntity { export const DeleteLogsTypeOverridesEmbedded = new Type("DeleteLogsTypeOverridesEmbedded"); export interface DeleteLogsTypeOverridesEmbedded extends Entities.EmbeddedEntity { Type: "DeleteLogsTypeOverridesEmbedded"; - type?: Entities.Lite | null; + type?: Entities.Lite; deleteLogsWithMoreThan?: number | null; cleanLogsWithMoreThan?: number | null; } @@ -34,12 +34,12 @@ export interface ExceptionEntity extends Entities.Entity { Type: "Exception"; creationDate?: string; exceptionType?: string | null; - exceptionMessage?: string | null; + exceptionMessage?: string; exceptionMessageHash?: number; - stackTrace?: string | null; + stackTrace?: string; stackTraceHash?: number; threadId?: number; - user?: Entities.Lite | null; + user?: Entities.Lite; environment?: string | null; version?: string | null; userAgent?: string | null; @@ -65,40 +65,40 @@ export interface IUserEntity extends Entities.Entity { export const OperationLogEntity = new Type("OperationLog"); export interface OperationLogEntity extends Entities.Entity { Type: "OperationLog"; - target: Entities.Lite | null; - origin: Entities.Lite | null; - operation: Entities.OperationSymbol | null; - user: Entities.Lite | null; + target: Entities.Lite; + origin: Entities.Lite; + operation: Entities.OperationSymbol; + user: Entities.Lite; start: string; end: string | null; - exception: Entities.Lite | null; + exception: Entities.Lite; } export const PropertyRouteEntity = new Type("PropertyRoute"); export interface PropertyRouteEntity extends Entities.Entity { Type: "PropertyRoute"; - path: string | null; + path: string; rootType: TypeEntity; } export const QueryEntity = new Type("Query"); export interface QueryEntity extends Entities.Entity { Type: "Query"; - key: string | null; + key: string; } export interface SemiSymbol extends Entities.Entity { key?: string | null; - name?: string | null; + name?: string; } export const TypeEntity = new Type("Type"); export interface TypeEntity extends Entities.Entity { Type: "Type"; - tableName: string | null; - cleanName: string | null; - namespace: string | null; - className: string | null; + tableName: string; + cleanName: string; + namespace: string; + className: string; } diff --git a/Signum.React/Scripts/Signum.Entities.ts b/Signum.React/Scripts/Signum.Entities.ts index 5cd7dbee18..b33677adbd 100644 --- a/Signum.React/Scripts/Signum.Entities.ts +++ b/Signum.React/Scripts/Signum.Entities.ts @@ -471,7 +471,7 @@ export module SelectorMessage { } export interface Symbol extends Entity { - key: string | null; + key: string; } export module SynchronizerMessage { diff --git a/Signum.React/Signum.React.csproj b/Signum.React/Signum.React.csproj index 1d59fccd5e..c33ebdbc2b 100644 --- a/Signum.React/Signum.React.csproj +++ b/Signum.React/Signum.React.csproj @@ -7,9 +7,15 @@ true enable true + Library + x64 + + 1701;1702;8629 + + @@ -24,7 +30,7 @@ - + diff --git a/Signum.TSGenerator/EntityDeclarationGenerator.cs b/Signum.TSGenerator/EntityDeclarationGenerator.cs index acb0020e04..f4c543959f 100644 --- a/Signum.TSGenerator/EntityDeclarationGenerator.cs +++ b/Signum.TSGenerator/EntityDeclarationGenerator.cs @@ -1,4 +1,4 @@ -using Mono.Cecil; +using Mono.Cecil; using System; using System.Collections; using System.Collections.Generic; @@ -480,14 +480,10 @@ public static bool GetTypescriptNull(this PropertyDefinition p) if (IsCollection(p.PropertyType)) return false; - if (GetTypescriptUndefined(p.DeclaringType) == false && - p.CustomAttributes.Any(a => - a.AttributeType.Name == "NotNullableAttribute" || - a.AttributeType.Name == "NotNullValidatorAttribute" || - a.AttributeType.Name == "StringLengthValidatorAttribute" && a.Properties.Any(na => na.Name == "AllowNulls" && false.Equals(na.Argument.Value)))) - return false; - - return !p.PropertyType.IsValueType || p.PropertyType.UnNullify() != p.PropertyType; + if (p.PropertyType.IsValueType) + return p.PropertyType.IsNullable(); + else + return p.CustomAttributes.Any(a => a.AttributeType.Name == "NullableAttribute" && ((byte)2).Equals(a.ConstructorArguments[0].Value)); } private static string FirstLower(string name) @@ -495,6 +491,11 @@ private static string FirstLower(string name) return char.ToLowerInvariant(name[0]) + name.Substring(1); } + public static bool IsNullable(this TypeReference type) + { + return type is GenericInstanceType gtype && gtype.ElementType.Name == "Nullable`1"; + } + public static TypeReference UnNullify(this TypeReference type) { return type is GenericInstanceType gtype && gtype.ElementType.Name == "Nullable`1" ? gtype.GenericArguments.Single() : type; diff --git a/Signum.TSGenerator/Properties/launchSettings.json b/Signum.TSGenerator/Properties/launchSettings.json index 631d48475e..c7ae0b7438 100644 --- a/Signum.TSGenerator/Properties/launchSettings.json +++ b/Signum.TSGenerator/Properties/launchSettings.json @@ -2,8 +2,8 @@ "profiles": { "Signum.TSGenerator": { "commandName": "Project", - "commandLineArgs": "\"obj\\Debug\\netcoreapp2.1\\Signum.React.Extensions.dll\" \"D:\\Signum\\SouthwindCore\\Extensions\\Signum.React.Extensions\\obj\\SignumReferences.txt\" \"D:\\Signum\\SouthwindCore\\Extensions\\Signum.React.Extensions\\obj\\SignumContent.txt\"", - "workingDirectory": "D:\\Signum\\SouthwindCore\\Extensions\\Signum.React.Extensions\\" + "commandLineArgs": "\"obj\\Debug\\netcoreapp2.1\\Signum.React.dll\" \"D:\\Signum\\Southwind\\Framework\\Signum.React\\obj\\SignumReferences.txt\" \"D:\\Signum\\Southwind\\Framework\\Signum.React\\obj\\SignumContent.txt\"", + "workingDirectory": "D:\\Signum\\Southwind\\Framework\\Signum.React\\" } } } \ No newline at end of file diff --git a/Signum.TSGenerator/Signum.TSGenerator.csproj b/Signum.TSGenerator/Signum.TSGenerator.csproj index 11cd4341d4..b9cf6bc8c8 100644 --- a/Signum.TSGenerator/Signum.TSGenerator.csproj +++ b/Signum.TSGenerator/Signum.TSGenerator.csproj @@ -9,7 +9,7 @@ true latest x64 - 1.0.3 + 2.0.0-beta diff --git a/Signum.TSGenerator/Signum.TSGenerator.nuspec b/Signum.TSGenerator/Signum.TSGenerator.nuspec index 7c67f6bd45..820edc202d 100644 --- a/Signum.TSGenerator/Signum.TSGenerator.nuspec +++ b/Signum.TSGenerator/Signum.TSGenerator.nuspec @@ -2,7 +2,7 @@ Signum.TSGenerator - 1.0.3 + 2.0.0-beta TypeScript generator for Signum Framework applications Olmo del Corral https://opensource.org/licenses/MIT diff --git a/Signum.Utilities/Reflection/ReflectionTools.cs b/Signum.Utilities/Reflection/ReflectionTools.cs index 0bcec9612f..98be3eed45 100644 --- a/Signum.Utilities/Reflection/ReflectionTools.cs +++ b/Signum.Utilities/Reflection/ReflectionTools.cs @@ -724,7 +724,7 @@ public static T ChangeType(object value) } } - public static object? ChangeType(object value, Type type) + public static object? ChangeType(object? value, Type type) { if (value == null) return null; diff --git a/Signum.Utilities/Tsv.cs b/Signum.Utilities/Tsv.cs index 11c6492552..af92cc2fae 100644 --- a/Signum.Utilities/Tsv.cs +++ b/Signum.Utilities/Tsv.cs @@ -120,7 +120,7 @@ public static void ToTsv(this IEnumerable collection, Stream stream, Encod } } - private static Func GetToString(TsvColumnInfo column, CultureInfo? culture, Func, Func>? toStringFactory) + private static Func GetToString(TsvColumnInfo column, CultureInfo culture, Func, Func>? toStringFactory) { if (toStringFactory != null) { From 0cdaaa2324948f264c9c00dc858995f4e0a38544 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Sun, 10 Feb 2019 13:45:13 +0100 Subject: [PATCH 17/25] remove AutoPropertyAnalyzer --- .../Signum.Analyzer.Test/AutoPropertyTest.cs | 234 ------------------ .../Signum.Analyzer/AutoPropertyAnalyzer.cs | 162 ------------ .../AutoPropertyCodeFixProvider.cs | 132 ---------- 3 files changed, 528 deletions(-) delete mode 100644 Signum.Analyzer/Signum.Analyzer.Test/AutoPropertyTest.cs delete mode 100644 Signum.Analyzer/Signum.Analyzer/AutoPropertyAnalyzer.cs delete mode 100644 Signum.Analyzer/Signum.Analyzer/AutoPropertyCodeFixProvider.cs diff --git a/Signum.Analyzer/Signum.Analyzer.Test/AutoPropertyTest.cs b/Signum.Analyzer/Signum.Analyzer.Test/AutoPropertyTest.cs deleted file mode 100644 index f4a913ac67..0000000000 --- a/Signum.Analyzer/Signum.Analyzer.Test/AutoPropertyTest.cs +++ /dev/null @@ -1,234 +0,0 @@ -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CodeFixes; -using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using TestHelper; -using Signum.Analyzer; - -namespace Signum.Analyzer.Test -{ - [TestClass] - public class AutoPropertyTest : CodeFixVerifier - { - protected override CodeFixProvider GetCSharpCodeFixProvider() - { - return new AutoPropertyCodeFixProvider(); - } - - protected override DiagnosticAnalyzer GetCSharpDiagnosticAnalyzer() - { - return new AutoPropertyAnalyzer(); - } - - //Diagnostic and CodeFix both triggered and checked for - [TestMethod] - public void AutoPropTest1() - { - var test = @" -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Diagnostics; -using Signum.Entities; - -namespace ConsoleApplication1 -{ - class MyEntity : Entity - { - [NotNullable, SqlDbType(Size = 24)] - string phone; - [StringLengthValidator(AllowNulls = false, Min = 3, Max = 24), TelephoneValidator] - public string Phone - { - get { return phone; } - set { Set(ref phone, value); } - } - } -}"; - - VerifyCSharpDiagnostic(test, new DiagnosticResult - { - Id = AutoPropertyAnalyzer.DiagnosticId, - Message = "Properties in 'MyEntity' could be transformed to auto-property", - Severity = DiagnosticSeverity.Warning, - }); - - var fixtest = @" -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Diagnostics; -using Signum.Entities; - -namespace ConsoleApplication1 -{ - class MyEntity : Entity - { - [NotNullable, SqlDbType(Size = 24)] - [StringLengthValidator(AllowNulls = false, Min = 3, Max = 24), TelephoneValidator] - public string Phone { get; set; } - } -}"; - VerifyCSharpFix(test, fixtest); - } - - - [TestMethod] - public void AutoPropTest2() - { - var test = @" -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Diagnostics; -using Signum.Entities; -using Signum.Utilities; -using System.Linq.Expressions; - -namespace ConsoleApplication1 -{ - class MyEntity : Entity - { - [NotNullable, SqlDbType(Size = 24)] - string phone; - [StringLengthValidator(AllowNulls = false, Min = 3, Max = 24), TelephoneValidator] - public string Phone - { - get { return phone; } - set { Set(ref phone, value); } - } - - string bla; - public string SuperPhone => Phone; - - [NotNullable, SqlDbType(Size = 24)] - string phone2; - [StringLengthValidator(AllowNulls = false, Min = 3, Max = 24), TelephoneValidator] - public string Phone2 - { - get { return phone2; } - internal set { SetToStr(ref phone2, value); } - } - - int number; - public int Number - { - get { return number; } - set { Set(ref number, value); } - } - - DateTime creationDate = TimeZoneManager.Now; - public DateTime CreationDate - { - get { return creationDate; } - private set { Set(ref creationDate, value); } - } - - int? synchronizeSchema; - [Unit(""ms"")] - public int? SynchronizeSchema - { - get { return synchronizeSchema; } - set { Set(ref synchronizeSchema, value); } - } - - object queryName; - [NotNullValidator] - public object QueryName - { - get { return queryName; } - } - - [NonSerialized] - bool needNewQuery; - public bool NeedNewQuery - { - get { return needNewQuery; } - set { Set(ref needNewQuery, value); } - } - - static Expression> ToStringExpressions = - entity => entity.phone2; - public override string ToString() - { - return ToStringExpressions.Evaluate(this); - } - } -}"; - - VerifyCSharpDiagnostic(test, new DiagnosticResult - { - Id = AutoPropertyAnalyzer.DiagnosticId, - Message = "Properties in 'MyEntity' could be transformed to auto-property", - Severity = DiagnosticSeverity.Warning - }); - - var fixtest = @" -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Diagnostics; -using Signum.Entities; -using Signum.Utilities; -using System.Linq.Expressions; - -namespace ConsoleApplication1 -{ - class MyEntity : Entity - { - [NotNullable, SqlDbType(Size = 24)] - [StringLengthValidator(AllowNulls = false, Min = 3, Max = 24), TelephoneValidator] - public string Phone { get; set; } - - string bla; - public string SuperPhone => Phone; - - [NotNullable, SqlDbType(Size = 24)] - [StringLengthValidator(AllowNulls = false, Min = 3, Max = 24), TelephoneValidator] - public string Phone2 { get; internal set; } - - public int Number { get; set; } - - public DateTime CreationDate { get; private set; } = TimeZoneManager.Now; - - [Unit(""ms"")] - public int? SynchronizeSchema { get; set; } - - object queryName; - [NotNullValidator] - public object QueryName - { - get { return queryName; } - } - - [NonSerialized] - bool needNewQuery; - public bool NeedNewQuery - { - get { return needNewQuery; } - set { Set(ref needNewQuery, value); } - } - - static Expression> ToStringExpressions = - entity => entity.Phone2; - public override string ToString() - { - return ToStringExpressions.Evaluate(this); - } - } -}"; - VerifyCSharpFix(test, fixtest); - } - - - } -} \ No newline at end of file diff --git a/Signum.Analyzer/Signum.Analyzer/AutoPropertyAnalyzer.cs b/Signum.Analyzer/Signum.Analyzer/AutoPropertyAnalyzer.cs deleted file mode 100644 index f17d567864..0000000000 --- a/Signum.Analyzer/Signum.Analyzer/AutoPropertyAnalyzer.cs +++ /dev/null @@ -1,162 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using System.Threading; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Diagnostics; - -namespace Signum.Analyzer -{ - [DiagnosticAnalyzer(LanguageNames.CSharp)] - public class AutoPropertyAnalyzer : DiagnosticAnalyzer - { - public const string DiagnosticId = "SF0001"; - - internal static DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, - "Use auto-properties in entities", - "Properties in '{0}' could be transformed to auto-property", "Entities", - DiagnosticSeverity.Warning, - isEnabledByDefault: true, - description: "Entities with auto-properties will be converted by a Signum.MsBuildTask into the expanded pattern"); - - public override ImmutableArray SupportedDiagnostics { get { return ImmutableArray.Create(Rule); } } - - public override void Initialize(AnalysisContext context) - { - context.RegisterSyntaxNodeAction(AnalyzePropertySymbol, SyntaxKind.ClassDeclaration); - } - - - static void AnalyzePropertySymbol(SyntaxNodeAnalysisContext context) - { - try - { - - var classDeclaration = (ClassDeclarationSyntax)context.Node; - var symbol = context.SemanticModel.GetDeclaredSymbol(classDeclaration); - - if (!InheritsFrom(symbol, "Signum.Entities.ModifiableEntity")) - return; - - var properties = classDeclaration.Members.OfType() - .Where(p => IsSimpleProperty(p, classDeclaration)) - .ToList(); - - if (properties.Count == 0) - return; - - var diagnostic = Diagnostic.Create(Rule, classDeclaration.Identifier.GetLocation(), - properties.Select(p => p.Identifier.GetLocation()), - classDeclaration.Identifier.ToString()); - - context.ReportDiagnostic(diagnostic); - } - catch (Exception e) - { - throw new Exception(context.SemanticModel.SyntaxTree.FilePath + "\r\n" + e.Message + "\r\n" + e.StackTrace); - } - } - - static string[] AvoidAttributes = new[] { "NonSerialized" }; - - public static bool IsSimpleProperty(PropertyDeclarationSyntax property, ClassDeclarationSyntax classParent) - { - FieldDeclarationSyntax field = PreviosField(classParent, property); - if (field == null) - return false; - - if (field.AttributeLists.Any(al => al.Attributes.Any(a => AvoidAttributes.Contains(LastName(a.Name))))) - return false; - - if (property.AccessorList == null) - return false; - - var getter = property.AccessorList.Accessors.Where(a => a.Kind() == SyntaxKind.GetAccessorDeclaration).Only(); - if (getter == null || !IsValidGetter(getter, field)) - return false; - - var setter = property.AccessorList.Accessors.Where(a => a.Kind() == SyntaxKind.SetAccessorDeclaration).Only(); - if (setter == null || !IsValidSetter(setter, field)) - return false; - - return true; - } - - private static string LastName(NameSyntax s) - { - if (s is IdentifierNameSyntax) - return ((IdentifierNameSyntax)s).Identifier.Text; - - if (s is QualifiedNameSyntax) - return LastName(((QualifiedNameSyntax)s).Right); - - return null; - } - - public static FieldDeclarationSyntax PreviosField(ClassDeclarationSyntax classParent, PropertyDeclarationSyntax property) - { - var index = classParent.Members.IndexOf(property); - if (index == -1 || index == 0) - return null; - - return classParent.Members[index - 1] as FieldDeclarationSyntax; - } - - static bool IsValidGetter(AccessorDeclarationSyntax getter, FieldDeclarationSyntax field) - { - var exp = (getter.Body?.Statements.Only() as ReturnStatementSyntax)?.Expression; - - if (exp == null) - return false; - - if (RemoveThis((exp as InvocationExpressionSyntax)?.Expression)?.Identifier.ToFullString() == "Get") - exp = ((InvocationExpressionSyntax)exp).ArgumentList.Arguments.FirstOrDefault()?.Expression; - - return RemoveThis(exp)?.Identifier.Text == field.Declaration.Variables.Only()?.Identifier.Text; - } - - private static IdentifierNameSyntax RemoveThis(ExpressionSyntax exp) - { - if (((exp as MemberAccessExpressionSyntax)?.Expression is ThisExpressionSyntax)) - exp = (exp as MemberAccessExpressionSyntax).Name; - return exp as IdentifierNameSyntax; - } - - static bool IsValidSetter(AccessorDeclarationSyntax setter, FieldDeclarationSyntax field) - { - var exp = (setter.Body?.Statements.Only() as ExpressionStatementSyntax)?.Expression; - - if (exp == null) - return false; - - var inv = exp as InvocationExpressionSyntax; - if (inv == null) - return false; - - var methodName = RemoveThis(inv.Expression)?.Identifier.ToFullString(); - if (methodName != "Set" && methodName != "SetToStr") - return false; - - var firsArg = ((InvocationExpressionSyntax)exp).ArgumentList.Arguments.FirstOrDefault()?.Expression; - - return RemoveThis(firsArg)?.Identifier.Text == field.Declaration.Variables.Only()?.Identifier.Text; - } - - static bool InheritsFrom(INamedTypeSymbol symbol, string fullName) - { - while (true) - { - if (symbol.ToString() == fullName) - return true; - - if (symbol.BaseType == null) - return false; - - symbol = symbol.BaseType; - } - } - } -} diff --git a/Signum.Analyzer/Signum.Analyzer/AutoPropertyCodeFixProvider.cs b/Signum.Analyzer/Signum.Analyzer/AutoPropertyCodeFixProvider.cs deleted file mode 100644 index aa922315af..0000000000 --- a/Signum.Analyzer/Signum.Analyzer/AutoPropertyCodeFixProvider.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Composition; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CodeFixes; -using Microsoft.CodeAnalysis.CodeActions; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Rename; -using Microsoft.CodeAnalysis.Text; -using Microsoft.CodeAnalysis.Options; -using Microsoft.CodeAnalysis.Formatting; - -namespace Signum.Analyzer -{ - [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(AutoPropertyCodeFixProvider)), Shared] - public class AutoPropertyCodeFixProvider : CodeFixProvider - { - public sealed override ImmutableArray FixableDiagnosticIds - { - get { return ImmutableArray.Create(AutoPropertyAnalyzer.DiagnosticId); } - } - - public sealed override FixAllProvider GetFixAllProvider() - { - return WellKnownFixAllProviders.BatchFixer; - } - - public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) - { - var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); - - var diagnostic = context.Diagnostics.First(); - var diagnosticSpan = diagnostic.Location.SourceSpan; - - var declaration = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType().First(); - - context.RegisterCodeFix( - CodeAction.Create("Convert to auto-property", c => AutoPropertyFixer.FixAllProperties(context.Document, declaration, c), "Convert to auto-property"), - diagnostic); - - //context.RegisterCodeFix( - // CodeAction.Create("Convert to auto-property", c => AutoPropertyFixer.FixProperty(context.Document, declaration, c), "Convert to auto-property"), - // diagnostic); - } - } - - - - public static class AutoPropertyFixer - { - public static async Task FixAllProperties(Document document, ClassDeclarationSyntax parentClass, CancellationToken cancellationToken) - { - var currentSolution = document.Project.Solution; - var currentDocument = document; - var currentClass = parentClass; - - while(true) - { - var property = currentClass.Members.OfType().FirstOrDefault(p => AutoPropertyAnalyzer.IsSimpleProperty(p, currentClass)); - if (property == null) - return currentSolution; - try { - currentSolution = await FixProperty(currentDocument, property, cancellationToken); - currentDocument = currentSolution.GetDocument(currentDocument.Id); - currentClass = (await currentDocument.GetSyntaxRootAsync()).DescendantNodes().OfType() - .FirstOrDefault(a => a.Identifier.ToString() == currentClass.Identifier.ToString()); - } - catch (Exception) - { - return currentSolution; - } - } - } - - public static async Task FixProperty(Document document, PropertyDeclarationSyntax property, CancellationToken cancellationToken) - { - var classParent = (ClassDeclarationSyntax)property.Parent; - - var field = AutoPropertyAnalyzer.PreviosField(classParent, property); - var fieldVariable = field.Declaration.Variables.Single(); - - var semanticModel = await document.GetSemanticModelAsync(); - var symbol = semanticModel.GetDeclaredSymbol(fieldVariable); - var solution = document.Project.Solution; - solution = await Renamer.RenameSymbolAsync(solution, symbol, property.Identifier.ToString(), solution.Workspace.Options, cancellationToken); - - document = solution.GetDocument(document.Id); - var root = await document.GetSyntaxRootAsync(); - classParent = root.DescendantNodes().OfType().SingleOrDefault(c => c.Identifier.IsEquivalentTo(classParent.Identifier)); - field = classParent.Members.OfType().SingleOrDefault(f => f.Declaration.Variables.Any(v => v.Identifier.ToString() == property.Identifier.ToString())); - fieldVariable = field.Declaration.Variables.Single(); - - var oldProperty = classParent.Members.OfType().SingleOrDefault(a => a.Identifier.ToString() == property.Identifier.ToString()); - - var newProperty = SyntaxFactory.PropertyDeclaration( - new SyntaxList().AddRange(field.AttributeLists).AddRange(oldProperty.AttributeLists), - oldProperty.Modifiers, - oldProperty.Type, - null, - oldProperty.Identifier, - SyntaxFactory.AccessorList(SyntaxFactory.List( - property.AccessorList.Accessors.Select(a => a.WithBody(null).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))) - ))); - - var leading = field.DescendantTokens().First().LeadingTrivia; - - var first = newProperty.DescendantTokens().First(); - newProperty = newProperty.ReplaceToken(first, first.WithLeadingTrivia(leading)); - - - if (fieldVariable.Initializer != null) - newProperty = newProperty.WithInitializer(fieldVariable.Initializer).WithSemicolonToken(field.SemicolonToken); - - var members = classParent.Members.Replace(oldProperty, newProperty); - members = members.Remove(members.Single(m => m.IsEquivalentTo(field))); - var newClass = classParent.WithMembers(members); - - var docNode = await document.GetSyntaxRootAsync(cancellationToken); - docNode = docNode.ReplaceNode(classParent, newClass); - - docNode = Formatter.Format(docNode, solution.Workspace); - var resultSolution = solution.WithDocumentSyntaxRoot(document.Id, docNode); - - return resultSolution; - } - } -} \ No newline at end of file From f6c80727112f74423c60bfb0e9edc29d6ba51952 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Sun, 10 Feb 2019 13:45:59 +0100 Subject: [PATCH 18/25] fix Signum.Analyzer.Tests --- .../ExpressionFieldTest.cs | 95 ++++++++++--------- .../Helpers/CodeFixVerifier.Helper.cs | 6 +- .../Helpers/DiagnosticVerifier.Helper.cs | 36 +++++-- .../Signum.Analyzer.Test/LiteCastTest.cs | 10 +- .../Signum.Analyzer.Test/LiteEqualiyTest.cs | 19 ++-- .../Signum.Analyzer.Test.csproj | 9 +- .../Verifiers/CodeFixVerifier.cs | 24 ++--- .../Verifiers/DiagnosticVerifier.cs | 37 ++------ .../ExpressionFieldAnalyzer.cs | 13 ++- .../Signum.Analyzer/LiteEqualityAnalyzer.cs | 8 +- 10 files changed, 125 insertions(+), 132 deletions(-) diff --git a/Signum.Analyzer/Signum.Analyzer.Test/ExpressionFieldTest.cs b/Signum.Analyzer/Signum.Analyzer.Test/ExpressionFieldTest.cs index b43b55df9e..2df3e414e0 100644 --- a/Signum.Analyzer/Signum.Analyzer.Test/ExpressionFieldTest.cs +++ b/Signum.Analyzer/Signum.Analyzer.Test/ExpressionFieldTest.cs @@ -1,4 +1,4 @@ -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -63,7 +63,7 @@ public void ExpressionNoReturn() public static int OperationLogs(this Entity e) { var a = 2; - }"); + }", assertErrors: false); } [TestMethod] @@ -74,7 +74,7 @@ public void ExpressionNoReturnExpression() public static int OperationLogs(this Entity e) { return; - }"); + }", assertErrors: false); } [TestMethod] @@ -82,7 +82,7 @@ public void ExpressionNoGetter() { TestDiagnostic("no getter", @" [ExpressionField] - public static int OperationLogs { set; }"); + public static int OperationLogs { set; }", assertErrors: false); } [TestMethod] @@ -98,7 +98,7 @@ public void ExpressionMethodExpressionBody() { TestDiagnostic("no invocation", @" [ExpressionField] - public static int OperationLogs => 1"); + public static int OperationLogs => 1;"); } [TestMethod] @@ -106,7 +106,7 @@ public void ExpressionGetterExpressionBody() { TestDiagnostic("no invocation", @" [ExpressionField] - public static int OperationLogs(this Entity e) => 1"); + public static int OperationLogs(this Entity e) => 1;"); } [TestMethod] @@ -115,7 +115,7 @@ public void ExpressionNoEvaluate() TestDiagnostic("no Evaluate", @" static Expression> MyExpression; [ExpressionField] - public static int OperationLogs(this Entity e) => MyExpression.Invoke(e)"); + public static int OperationLogs(this Entity e) => MyExpression.Invoke(e)", assertErrors: false); } [TestMethod] @@ -124,7 +124,7 @@ public void ExpressionNoStaticField() TestDiagnostic("no static field", @" static Expression> MyExpression { get; } [ExpressionField] - public static int OperationLogs(this Entity e) => MyExpression.Evaluate(e)"); + public static int OperationLogs(this Entity e) => MyExpression.Evaluate(e)", assertErrors: false); } [TestMethod] @@ -133,25 +133,25 @@ public void ExpressionThis() TestDiagnostic("first argument should be 'this'", @" static Expression> MyExpression; [ExpressionField] - public int OperationLogs(this Entity e) => MyExpression.Evaluate(e)"); + public int OperationLogs(this Entity e) => MyExpression.Evaluate(e)", assertErrors: false); } [TestMethod] public void ExpressionMissingArgument() { TestDiagnostic("missing argument 'e'", @" - static Expression> MyExpression; + static Expression> MyExpression; [ExpressionField] - public int OperationLogs(this Entity e) => MyExpression.Evaluate(this)"); + public static int OperationLogs(this Entity e) => MyExpression.Evaluate();", includeExpression: true); } [TestMethod] public void ExpressionExtra() { TestDiagnostic("extra parameters", @" - static Expression> MyExpression; + static Expression> MyExpression; [ExpressionField] - public int OperationLogs(this Entity e) => MyExpression.Evaluate(this, e, e)"); + public static int OperationLogs(this Entity e) => MyExpression.Evaluate(e, e);", assertErrors: false); } [TestMethod] @@ -160,44 +160,44 @@ public void ExpressionCorrect() TestDiagnostic(null, @" static Expression> MyExpression; [ExpressionField] - public int OperationLogs(this Entity e) => MyExpression.Evaluate(this, e)"); + public int OperationLogs(Entity e) => MyExpression.Evaluate(this, e);", staticClass: false, includeExpression: true); } [TestMethod] public void ExpressionExplicitNotFound() { TestDiagnostic("field 'MyExpression' not found", @" - static Expression> MyExpressionBad; + static Expression> MyExpressionBad; [ExpressionField(""MyExpression"")] - public int OperationLogs(this Entity e) => 0"); + public static int OperationLogs(this Entity e) => 0;", assertErrors: false); } [TestMethod] public void ExpressionExplicitWrongType() { - TestDiagnostic("type of 'MyExpression' should be 'Expression>'", @" - static Expression> MyExpression; + TestDiagnostic("type of 'MyExpression' should be 'Expression>'", @" + static Expression> MyExpression; [ExpressionField(""MyExpression"")] - public int OperationLogs(this Entity e) => 0", withIncludes: true); + public static int OperationLogs(this Entity e) => 0;", includeExpression: true); } [TestMethod] public void ExpressionExplicitCorrect() { TestDiagnostic(null, @" - static Expression> MyExpression; + static Expression> MyExpression; [ExpressionField(""MyExpression"")] - public int OperationLogs(this Entity e) => 0", withIncludes: true); + public static int OperationLogs(this Entity e) => 0;", includeExpression: true); } - private void TestDiagnostic(string expectedError, string code, bool withIncludes = false) + private void TestDiagnostic(string expectedError, string code, bool includeExpression = false, bool staticClass = true, bool assertErrors = true) { - string test = Surround(code, withIncludes: withIncludes); + string test = Surround(code, includeExpression, staticClass); if (expectedError == null) - VerifyCSharpDiagnostic(test, new DiagnosticResult[0]); + VerifyCSharpDiagnostic(test, assertErrors, new DiagnosticResult[0]); else - VerifyCSharpDiagnostic(test, new DiagnosticResult + VerifyCSharpDiagnostic(test, assertErrors, new DiagnosticResult { Id = ExpressionFieldAnalyzer.DiagnosticId, Message = string.Format("'OperationLogs' should reference an static field of type Expression with the same signature ({0})", expectedError), @@ -205,9 +205,9 @@ private void TestDiagnostic(string expectedError, string code, bool withIncludes }); } - private static string Surround(string expression, bool withIncludes = false) + private static string Surround(string member, bool includeExpression = false, bool staticClass = true) { - return @" + return $@" using System; using System.Collections.Generic; using System.Linq; @@ -216,17 +216,17 @@ private static string Surround(string expression, bool withIncludes = false) using System.Diagnostics; using Signum.Entities; using Signum.Utilities; -using Signum.Utilities.ExpressionTrees;" + (withIncludes ? @" -using System.Linq.Expressions;" : null) + @" +using Signum.Utilities.ExpressionTrees; +{(includeExpression ? @"using System.Linq.Expressions; +" : null)} namespace ConsoleApplication1 -{ - class Bla - {" -+ expression + -@" - } -}"; +{{ + {(staticClass ? "static" : null)} class Bla + {{ +{member} + }} +}}"; } [TestMethod] @@ -252,23 +252,23 @@ public void ExpressionFixInstanceProperty() static Expression> GetIdExpression = @this => @this.ToString(); [ExpressionField] - public string GetId => GetIdExpression.Evaluate(this);"); + public string GetId => GetIdExpression.Evaluate(this);", staticClass: false); } [TestMethod] public void ExpressionFixInstancePropertyImplicitThis() { TestCodeFix(@" - string id; + string? id; [ExpressionField] - public string GetId => id;", + public string? GetId => id;", @" - string id; + string? id; - static Expression> GetIdExpression = @this => @this.id; + static Expression> GetIdExpression = @this => @this.id; [ExpressionField] - public string GetId => GetIdExpression.Evaluate(this);"); + public string? GetId => GetIdExpression.Evaluate(this);", staticClass: false); } [TestMethod] @@ -282,7 +282,7 @@ public void ExpressionFixInstancePropertyStatementImplicitThis() static Expression> GetIdExpression = @this => @this.ToString(); [ExpressionField] - public string GetId { get { return GetIdExpression.Evaluate(this); } }"); + public string GetId { get { return GetIdExpression.Evaluate(this); } }", staticClass: false); } @@ -302,9 +302,12 @@ public void ExpressionFixDiagnosticStatic2() public static int GetId(Entity e) => GetIdExpression2.Evaluate(e);"); } - private void TestCodeFix(string initial, string final) + private void TestCodeFix(string initial, string final, bool staticClass = true) { - VerifyCSharpFix(Surround(initial), Surround(final, withIncludes:true)); + VerifyCSharpFix( + Surround(initial, includeExpression: false, staticClass: staticClass), + Surround(final, includeExpression: true, staticClass: staticClass), + assertNoInitialErrors: false); } } -} \ No newline at end of file +} diff --git a/Signum.Analyzer/Signum.Analyzer.Test/Helpers/CodeFixVerifier.Helper.cs b/Signum.Analyzer/Signum.Analyzer.Test/Helpers/CodeFixVerifier.Helper.cs index c88cd4e68c..2acd1ebe4b 100644 --- a/Signum.Analyzer/Signum.Analyzer.Test/Helpers/CodeFixVerifier.Helper.cs +++ b/Signum.Analyzer/Signum.Analyzer.Test/Helpers/CodeFixVerifier.Helper.cs @@ -33,12 +33,12 @@ private static Document ApplyFix(Document document, CodeAction codeAction) /// Note: Considers Diagnostics to be the same if they have the same Ids. In the case of multiple diagnostics with the same Id in a row, /// this method may not necessarily return the new one. /// - /// The Diagnostics that existed in the code before the CodeFix was applied + /// The Diagnostics that existed in the code before the CodeFix was applied /// The Diagnostics that exist in the code after the CodeFix was applied /// A list of Diagnostics that only surfaced in the code after the CodeFix was applied - private static IEnumerable GetNewDiagnostics(IEnumerable diagnostics, IEnumerable newDiagnostics) + private static IEnumerable GetNewDiagnostics(IEnumerable oldDiagnostics, IEnumerable newDiagnostics) { - var oldArray = diagnostics.OrderBy(d => d.Location.SourceSpan.Start).ToArray(); + var oldArray = oldDiagnostics.OrderBy(d => d.Location.SourceSpan.Start).ToArray(); var newArray = newDiagnostics.OrderBy(d => d.Location.SourceSpan.Start).ToArray(); int oldIndex = 0; diff --git a/Signum.Analyzer/Signum.Analyzer.Test/Helpers/DiagnosticVerifier.Helper.cs b/Signum.Analyzer/Signum.Analyzer.Test/Helpers/DiagnosticVerifier.Helper.cs index 993c7c69e2..270a90b637 100644 --- a/Signum.Analyzer/Signum.Analyzer.Test/Helpers/DiagnosticVerifier.Helper.cs +++ b/Signum.Analyzer/Signum.Analyzer.Test/Helpers/DiagnosticVerifier.Helper.cs @@ -8,6 +8,8 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.ComponentModel; +using System.IO; using System.Linq; using System.Linq.Expressions; @@ -24,8 +26,14 @@ public abstract partial class DiagnosticVerifier private static readonly MetadataReference CSharpSymbolsReference = MetadataReference.CreateFromFile(typeof(CSharpCompilation).Assembly.Location); private static readonly MetadataReference CodeAnalysisReference = MetadataReference.CreateFromFile(typeof(Compilation).Assembly.Location); private static readonly MetadataReference SystemLinqExpression = MetadataReference.CreateFromFile(typeof(Expression).Assembly.Location); - private static readonly MetadataReference SystemRuntimeReference= MetadataReference.CreateFromFile(@"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.1.0\ref\netcoreapp2.1\System.Runtime.dll"/*typeof(ValueType).Assembly.Location*/); + + + + private static readonly MetadataReference SystemPrivateCorLib = MetadataReference.CreateFromFile(typeof(Func<>).Assembly.Location); + private static readonly MetadataReference SystemRuntimeReference = MetadataReference.CreateFromFile(Path.Combine(Path.GetDirectoryName(typeof(Func<>).Assembly.Location), "System.Runtime.dll")); private static readonly MetadataReference SystemRuntime = MetadataReference.CreateFromFile(typeof(DateTime).Assembly.Location); + private static readonly MetadataReference SystemObjectModel = MetadataReference.CreateFromFile(typeof(INotifyPropertyChanged).Assembly.Location); + private static readonly MetadataReference SystemComponentModelTypeConverter = MetadataReference.CreateFromFile(typeof(IDataErrorInfo).Assembly.Location); private static readonly MetadataReference SignumUtilitiesReference = MetadataReference.CreateFromFile(typeof(Csv).Assembly.Location); private static readonly MetadataReference SignumEntitiesReference = MetadataReference.CreateFromFile(typeof(Entity).Assembly.Location); private static readonly MetadataReference SignumEngineReference = MetadataReference.CreateFromFile(typeof(Database).Assembly.Location); @@ -44,9 +52,10 @@ public abstract partial class DiagnosticVerifier /// The language the source classes are in /// The analyzer to be run on the sources /// An IEnumerable of Diagnostics that surfaced in the source code, sorted by Location - private static Diagnostic[] GetSortedDiagnostics(string[] sources, string language, DiagnosticAnalyzer analyzer) + private static Diagnostic[] GetSortedDiagnostics(string[] sources, string language, bool assertErrors, DiagnosticAnalyzer analyzer) { - return GetSortedDiagnosticsFromDocuments(analyzer, GetDocuments(sources, language)); + var docs = GetDocuments(sources, language); + return GetSortedDiagnosticsFromDocuments(analyzer, assertErrors, docs); } /// @@ -56,7 +65,7 @@ private static Diagnostic[] GetSortedDiagnostics(string[] sources, string langua /// The analyzer to run on the documents /// The Documents that the analyzer will be run on /// An IEnumerable of Diagnostics that surfaced in the source code, sorted by Location - protected static Diagnostic[] GetSortedDiagnosticsFromDocuments(DiagnosticAnalyzer analyzer, Document[] documents) + protected static Diagnostic[] GetSortedDiagnosticsFromDocuments(DiagnosticAnalyzer analyzer, bool assertErrors, Document[] documents) { var projects = new HashSet(); foreach (var document in documents) @@ -67,7 +76,15 @@ protected static Diagnostic[] GetSortedDiagnosticsFromDocuments(DiagnosticAnalyz var diagnostics = new List(); foreach (var project in projects) { - var compilationWithAnalyzers = project.GetCompilationAsync().Result.WithAnalyzers(ImmutableArray.Create(analyzer)); + var compilation = project.GetCompilationAsync().Result; + if (assertErrors) + { + var errors = compilation.GetDiagnostics(); + if (errors.Any(a => a.Severity == DiagnosticSeverity.Error)) + throw new InvalidOperationException("Errors found:\n" + errors.Where(a => a.Severity == DiagnosticSeverity.Error).ToString("\n").Indent(2)); + } + + var compilationWithAnalyzers = compilation.WithAnalyzers(ImmutableArray.Create(analyzer)); var diags = compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync().Result; foreach (var diag in diags) { @@ -116,7 +133,7 @@ private static Diagnostic[] SortDiagnostics(IEnumerable diagnostics) /// A Tuple containing the Documents produced from the sources and their TextSpans if relevant private static Document[] GetDocuments(string[] sources, string language) { - if (language != LanguageNames.CSharp && language != LanguageNames.VisualBasic) + if (language != LanguageNames.CSharp) { throw new ArgumentException("Unsupported Language"); } @@ -158,14 +175,19 @@ private static Project CreateProject(string[] sources, string language = Languag var solution = new AdhocWorkspace() .CurrentSolution - .AddProject(projectId, TestProjectName, TestProjectName, language) + .AddProject( projectId, TestProjectName, TestProjectName, language) + .WithProjectParseOptions(projectId, new CSharpParseOptions(LanguageVersion.CSharp8)) + .WithProjectCompilationOptions(projectId, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary).WithNullableContextOptions(NullableContextOptions.Enable)) .AddMetadataReference(projectId, CorlibReference) .AddMetadataReference(projectId, SystemCoreReference) .AddMetadataReference(projectId, CSharpSymbolsReference) .AddMetadataReference(projectId, CodeAnalysisReference) + .AddMetadataReference(projectId, SystemPrivateCorLib) .AddMetadataReference(projectId, SystemRuntimeReference) .AddMetadataReference(projectId, SystemLinqExpression) .AddMetadataReference(projectId, SystemRuntime) + .AddMetadataReference(projectId, SystemObjectModel) + .AddMetadataReference(projectId, SystemComponentModelTypeConverter) .AddMetadataReference(projectId, SignumUtilitiesReference) .AddMetadataReference(projectId, SignumEntitiesReference) .AddMetadataReference(projectId, SignumEngineReference); diff --git a/Signum.Analyzer/Signum.Analyzer.Test/LiteCastTest.cs b/Signum.Analyzer/Signum.Analyzer.Test/LiteCastTest.cs index 459f59b107..325c926512 100644 --- a/Signum.Analyzer/Signum.Analyzer.Test/LiteCastTest.cs +++ b/Signum.Analyzer/Signum.Analyzer.Test/LiteCastTest.cs @@ -1,4 +1,4 @@ -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -74,13 +74,13 @@ public void IsToLite() "); } - private void TestDiagnostic(string expectedError, string code, bool withIncludes = false) + private void TestDiagnostic(string expectedError, string code, bool withIncludes = false, bool assertNoErrors = true) { string test = Surround(code, withIncludes: withIncludes); if (expectedError == null) - VerifyCSharpDiagnostic(test, new DiagnosticResult[0]); + VerifyCSharpDiagnostic(test, assertNoErrors, new DiagnosticResult[0]); else - VerifyCSharpDiagnostic(test, new DiagnosticResult + VerifyCSharpDiagnostic(test, assertNoErrors, new DiagnosticResult { Id = LiteCastAnalyzer.DiagnosticId, Message = expectedError, @@ -115,4 +115,4 @@ void Foo() }"; } } -} \ No newline at end of file +} diff --git a/Signum.Analyzer/Signum.Analyzer.Test/LiteEqualiyTest.cs b/Signum.Analyzer/Signum.Analyzer.Test/LiteEqualiyTest.cs index fefb9b8d91..135dc727c2 100644 --- a/Signum.Analyzer/Signum.Analyzer.Test/LiteEqualiyTest.cs +++ b/Signum.Analyzer/Signum.Analyzer.Test/LiteEqualiyTest.cs @@ -1,4 +1,4 @@ -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -30,7 +30,6 @@ public void CompareLiteAndEntity() [TestMethod] public void CompareIncompatibleTypes() { - TestDiagnostic("Impossible to compare Lite and Lite", @" Lite apple = null; Lite orange = null; @@ -41,7 +40,6 @@ public void CompareIncompatibleTypes() [TestMethod] public void CompareIncompatibleAbstractTypes() { - TestDiagnostic("Impossible to compare Lite and Lite", @" Lite banana = null; Lite orange = null; @@ -55,7 +53,7 @@ public void CompareBaseType() TestDiagnostic(null, @" Lite type = null; -Lite query = null; +Lite query = null; var condition = type == query; "); } @@ -81,16 +79,13 @@ public void CompareDifferentInterfaceEntity() "); } - - - - private void TestDiagnostic(string expectedError, string code, bool withIncludes = false) + private void TestDiagnostic(string expectedError, string code, bool withIncludes = false, bool assertErrors = true) { string test = Surround(code, withIncludes: withIncludes); if (expectedError == null) - VerifyCSharpDiagnostic(test, new DiagnosticResult[0]); + VerifyCSharpDiagnostic(test, assertErrors, new DiagnosticResult[0]); else - VerifyCSharpDiagnostic(test, new DiagnosticResult + VerifyCSharpDiagnostic(test, assertErrors, new DiagnosticResult { Id = LiteEqualityAnalyzer.DiagnosticId, Message = expectedError, @@ -119,7 +114,7 @@ public interface IMan : IEntity {} public class AppleEntity : Entity {} public class OrangeEntity : Entity {} - public abstracr class AbstractBananaEntity : Entity {} + public abstract class AbstractBananaEntity : Entity {} class Bla { @@ -132,4 +127,4 @@ void Foo() }"; } } -} \ No newline at end of file +} diff --git a/Signum.Analyzer/Signum.Analyzer.Test/Signum.Analyzer.Test.csproj b/Signum.Analyzer/Signum.Analyzer.Test/Signum.Analyzer.Test.csproj index 8055f444cf..8d0a2e7b6f 100644 --- a/Signum.Analyzer/Signum.Analyzer.Test/Signum.Analyzer.Test.csproj +++ b/Signum.Analyzer/Signum.Analyzer.Test/Signum.Analyzer.Test.csproj @@ -1,15 +1,18 @@  - netcoreapp2.1 + netcoreapp2.2 + true + - + all runtime; build; native; contentfiles; analyzers - + + diff --git a/Signum.Analyzer/Signum.Analyzer.Test/Verifiers/CodeFixVerifier.cs b/Signum.Analyzer/Signum.Analyzer.Test/Verifiers/CodeFixVerifier.cs index ececdea522..c40a0f70f5 100644 --- a/Signum.Analyzer/Signum.Analyzer.Test/Verifiers/CodeFixVerifier.cs +++ b/Signum.Analyzer/Signum.Analyzer.Test/Verifiers/CodeFixVerifier.cs @@ -41,23 +41,11 @@ protected virtual CodeFixProvider GetBasicCodeFixProvider() /// A class in the form of a string after the CodeFix was applied to it /// Index determining which codefix to apply if there are multiple /// A bool controlling whether or not the test will fail if the CodeFix introduces other warnings after being applied - protected void VerifyCSharpFix(string oldSource, string newSource, int? codeFixIndex = null, bool allowNewCompilerDiagnostics = false) + protected void VerifyCSharpFix(string oldSource, string newSource, int? codeFixIndex = null, bool assertNoInitialErrors = true, bool allowNewCompilerDiagnostics = false) { - VerifyFix(LanguageNames.CSharp, GetCSharpDiagnosticAnalyzer(), GetCSharpCodeFixProvider(), oldSource, newSource, codeFixIndex, allowNewCompilerDiagnostics); + VerifyFix(LanguageNames.CSharp, GetCSharpDiagnosticAnalyzer(), GetCSharpCodeFixProvider(), oldSource, newSource, codeFixIndex, assertNoInitialErrors, allowNewCompilerDiagnostics); } - - /// - /// Called to test a VB codefix when applied on the inputted string as a source - /// - /// A class in the form of a string before the CodeFix was applied to it - /// A class in the form of a string after the CodeFix was applied to it - /// Index determining which codefix to apply if there are multiple - /// A bool controlling whether or not the test will fail if the CodeFix introduces other warnings after being applied - protected void VerifyBasicFix(string oldSource, string newSource, int? codeFixIndex = null, bool allowNewCompilerDiagnostics = false) - { - VerifyFix(LanguageNames.VisualBasic, GetBasicDiagnosticAnalyzer(), GetBasicCodeFixProvider(), oldSource, newSource, codeFixIndex, allowNewCompilerDiagnostics); - } - + /// /// General verifier for codefixes. /// Creates a Document from the source string, then gets diagnostics on it and applies the relevant codefixes. @@ -71,10 +59,10 @@ protected void VerifyBasicFix(string oldSource, string newSource, int? codeFixIn /// A class in the form of a string after the CodeFix was applied to it /// Index determining which codefix to apply if there are multiple /// A bool controlling whether or not the test will fail if the CodeFix introduces other warnings after being applied - private void VerifyFix(string language, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider, string oldSource, string newSource, int? codeFixIndex, bool allowNewCompilerDiagnostics) + private void VerifyFix(string language, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider, string oldSource, string newSource, int? codeFixIndex, bool assertNoInitialErrors, bool allowNewCompilerDiagnostics) { var document = CreateDocument(oldSource, language); - var analyzerDiagnostics = GetSortedDiagnosticsFromDocuments(analyzer, new[] { document }); + var analyzerDiagnostics = GetSortedDiagnosticsFromDocuments(analyzer, assertNoInitialErrors, new[] { document }); var compilerDiagnostics = GetCompilerDiagnostics(document); var attempts = analyzerDiagnostics.Length; @@ -96,7 +84,7 @@ private void VerifyFix(string language, DiagnosticAnalyzer analyzer, CodeFixProv } document = ApplyFix(document, actions.ElementAt(0)); - analyzerDiagnostics = GetSortedDiagnosticsFromDocuments(analyzer, new[] { document }); + analyzerDiagnostics = GetSortedDiagnosticsFromDocuments(analyzer, false , new[] { document }); var newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, GetCompilerDiagnostics(document)); diff --git a/Signum.Analyzer/Signum.Analyzer.Test/Verifiers/DiagnosticVerifier.cs b/Signum.Analyzer/Signum.Analyzer.Test/Verifiers/DiagnosticVerifier.cs index 515da767aa..918b7bc11a 100644 --- a/Signum.Analyzer/Signum.Analyzer.Test/Verifiers/DiagnosticVerifier.cs +++ b/Signum.Analyzer/Signum.Analyzer.Test/Verifiers/DiagnosticVerifier.cs @@ -39,21 +39,11 @@ protected virtual DiagnosticAnalyzer GetBasicDiagnosticAnalyzer() /// /// A class in the form of a string to run the analyzer on /// DiagnosticResults that should appear after the analyzer is run on the source - protected void VerifyCSharpDiagnostic(string source, params DiagnosticResult[] expected) + protected void VerifyCSharpDiagnostic(string source, bool assertErrors, params DiagnosticResult[] expected) { - VerifyDiagnostics(new[] { source }, LanguageNames.CSharp, GetCSharpDiagnosticAnalyzer(), expected); - } - - /// - /// Called to test a VB DiagnosticAnalyzer when applied on the single inputted string as a source - /// Note: input a DiagnosticResult for each Diagnostic expected - /// - /// A class in the form of a string to run the analyzer on - /// DiagnosticResults that should appear after the analyzer is run on the source - protected void VerifyBasicDiagnostic(string source, params DiagnosticResult[] expected) - { - VerifyDiagnostics(new[] { source }, LanguageNames.VisualBasic, GetBasicDiagnosticAnalyzer(), expected); + VerifyDiagnostics(new[] { source }, LanguageNames.CSharp, assertErrors, GetCSharpDiagnosticAnalyzer(), expected); } + /// /// Called to test a C# DiagnosticAnalyzer when applied on the inputted strings as a source @@ -61,22 +51,11 @@ protected void VerifyBasicDiagnostic(string source, params DiagnosticResult[] ex /// /// An array of strings to create source documents from to run the analyzers on /// DiagnosticResults that should appear after the analyzer is run on the sources - protected void VerifyCSharpDiagnostic(string[] sources, params DiagnosticResult[] expected) - { - VerifyDiagnostics(sources, LanguageNames.CSharp, GetCSharpDiagnosticAnalyzer(), expected); - } - - /// - /// Called to test a VB DiagnosticAnalyzer when applied on the inputted strings as a source - /// Note: input a DiagnosticResult for each Diagnostic expected - /// - /// An array of strings to create source documents from to run the analyzers on - /// DiagnosticResults that should appear after the analyzer is run on the sources - protected void VerifyBasicDiagnostic(string[] sources, params DiagnosticResult[] expected) + protected void VerifyCSharpDiagnostic(string[] sources, bool assertNoErrors, params DiagnosticResult[] expected) { - VerifyDiagnostics(sources, LanguageNames.VisualBasic, GetBasicDiagnosticAnalyzer(), expected); + VerifyDiagnostics(sources, LanguageNames.CSharp, assertNoErrors, GetCSharpDiagnosticAnalyzer(), expected); } - + /// /// General method that gets a collection of actual diagnostics found in the source after the analyzer is run, /// then verifies each of them. @@ -85,9 +64,9 @@ protected void VerifyBasicDiagnostic(string[] sources, params DiagnosticResult[] /// The language of the classes represented by the source strings /// The analyzer to be run on the source code /// DiagnosticResults that should appear after the analyzer is run on the sources - private void VerifyDiagnostics(string[] sources, string language, DiagnosticAnalyzer analyzer, params DiagnosticResult[] expected) + private void VerifyDiagnostics(string[] sources, string language, bool assertErrors, DiagnosticAnalyzer analyzer, params DiagnosticResult[] expected) { - var diagnostics = GetSortedDiagnostics(sources, language, analyzer); + var diagnostics = GetSortedDiagnostics(sources, language, assertErrors, analyzer); VerifyDiagnosticResults(diagnostics, analyzer, expected); } diff --git a/Signum.Analyzer/Signum.Analyzer/ExpressionFieldAnalyzer.cs b/Signum.Analyzer/Signum.Analyzer/ExpressionFieldAnalyzer.cs index c439b45d90..bf42bec443 100644 --- a/Signum.Analyzer/Signum.Analyzer/ExpressionFieldAnalyzer.cs +++ b/Signum.Analyzer/Signum.Analyzer/ExpressionFieldAnalyzer.cs @@ -26,11 +26,11 @@ public class ExpressionFieldAnalyzer : DiagnosticAnalyzer public override void Initialize(AnalysisContext context) { - context.RegisterSyntaxNodeAction(AnalyzePropertySymbol, SyntaxKind.Attribute); + context.RegisterSyntaxNodeAction(AnalyzeAttributeSymbol, SyntaxKind.Attribute); } - static void AnalyzePropertySymbol(SyntaxNodeAnalysisContext context) + static void AnalyzeAttributeSymbol(SyntaxNodeAnalysisContext context) { try { @@ -92,9 +92,12 @@ static void AnalyzePropertySymbol(SyntaxNodeAnalysisContext context) if (!expressionType.Equals(fieldSymbol.Type)) { - var minimalParts = expressionType.ToMinimalDisplayString(context.SemanticModel, member.GetLocation().SourceSpan.Start); - Diagnostic(context, ident, att.GetLocation(), string.Format("type of '{0}' should be '{1}'", fieldName, minimalParts)); - return; + //if (!expressionType.ToString().Equals(fieldSymbol.Type.ToString())) // Till there is an API to express nullability + { + var minimalParts = expressionType.ToMinimalDisplayString(context.SemanticModel, member.GetLocation().SourceSpan.Start); + Diagnostic(context, ident, att.GetLocation(), string.Format("type of '{0}' should be '{1}'", fieldName, minimalParts)); + return; + } } } else diff --git a/Signum.Analyzer/Signum.Analyzer/LiteEqualityAnalyzer.cs b/Signum.Analyzer/Signum.Analyzer/LiteEqualityAnalyzer.cs index c627b6f347..c2fe501356 100644 --- a/Signum.Analyzer/Signum.Analyzer/LiteEqualityAnalyzer.cs +++ b/Signum.Analyzer/Signum.Analyzer/LiteEqualityAnalyzer.cs @@ -1,4 +1,4 @@ -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; @@ -18,7 +18,7 @@ public class LiteEqualityAnalyzer : DiagnosticAnalyzer private static DiagnosticDescriptor RuleLiteEntity = new DiagnosticDescriptor(DiagnosticId, "Prevents comparisons between Lite and T", - "Impossible to compare Lite and T. Consider using RefersTo method", "Lite", + "Impossible to compare Lite and T. Consider using 'Is' extension method", "Lite", DiagnosticSeverity.Error, isEnabledByDefault: true, description: "Checks that Lite and T are not compared directly. C# doesn't catch this because Lite is implemented as an interface to have co-variance"); @@ -61,8 +61,8 @@ private void AnalyzeNode(SyntaxNodeAnalysisContext context) if (tLeft != null && tRight != null && - !tLeft.IsAbstract && - !tRight.IsAbstract && + tLeft.TypeKind != TypeKind.Interface && + tRight.TypeKind != TypeKind.Interface && !tLeft.GetBaseTypesAndThis().Contains(tRight) && !tRight.GetBaseTypesAndThis().Contains(tLeft)) { From 9f87d04969d3c8e9ff6953da57a2825437551513 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Sun, 10 Feb 2019 13:46:58 +0100 Subject: [PATCH 19/25] update Analyzer but not working (waiting for https://github.com/dotnet/roslyn/issues/33078) --- Signum.Analyzer/Signum.Analyzer.sln | 9 ++------- .../PublishProfiles/FolderProfile.pubxml | 13 +++++++++++++ .../Signum.Analyzer/Signum.Analyzer.csproj | 17 +++++++++++------ 3 files changed, 26 insertions(+), 13 deletions(-) create mode 100644 Signum.Analyzer/Signum.Analyzer/Properties/PublishProfiles/FolderProfile.pubxml diff --git a/Signum.Analyzer/Signum.Analyzer.sln b/Signum.Analyzer/Signum.Analyzer.sln index 25588b883a..1647a07130 100644 --- a/Signum.Analyzer/Signum.Analyzer.sln +++ b/Signum.Analyzer/Signum.Analyzer.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28010.2041 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28516.95 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Signum.Engine", "..\Signum.Engine\Signum.Engine.csproj", "{7F2DB6FE-C109-4057-B207-C62A767F905D}" EndProject @@ -9,8 +9,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Signum.Entities", "..\Signu EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Signum.Utilities", "..\Signum.Utilities\Signum.Utilities.csproj", "{F7D3F72D-741D-4F67-8CF8-CD41B9035FED}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Signum.MSBuildTask", "..\Signum.MSBuildTask\Signum.MSBuildTask.csproj", "{7B29A947-1044-4F86-8A76-E1D2D6371CF3}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Signum.Analyzer", "Signum.Analyzer\Signum.Analyzer.csproj", "{C7E2DF3E-E66A-41E2-87E8-230F20CA533A}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Signum.Analyzer.Test", "Signum.Analyzer.Test\Signum.Analyzer.Test.csproj", "{AA518395-1E01-430A-9AC2-45CDB9476C8B}" @@ -30,9 +28,6 @@ Global {F7D3F72D-741D-4F67-8CF8-CD41B9035FED}.Debug|Any CPU.ActiveCfg = Debug|x64 {F7D3F72D-741D-4F67-8CF8-CD41B9035FED}.Debug|Any CPU.Build.0 = Debug|x64 {F7D3F72D-741D-4F67-8CF8-CD41B9035FED}.Release|Any CPU.ActiveCfg = Release|x64 - {7B29A947-1044-4F86-8A76-E1D2D6371CF3}.Debug|Any CPU.ActiveCfg = Debug|x64 - {7B29A947-1044-4F86-8A76-E1D2D6371CF3}.Debug|Any CPU.Build.0 = Debug|x64 - {7B29A947-1044-4F86-8A76-E1D2D6371CF3}.Release|Any CPU.ActiveCfg = Release|x64 {C7E2DF3E-E66A-41E2-87E8-230F20CA533A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C7E2DF3E-E66A-41E2-87E8-230F20CA533A}.Debug|Any CPU.Build.0 = Debug|Any CPU {C7E2DF3E-E66A-41E2-87E8-230F20CA533A}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/Signum.Analyzer/Signum.Analyzer/Properties/PublishProfiles/FolderProfile.pubxml b/Signum.Analyzer/Signum.Analyzer/Properties/PublishProfiles/FolderProfile.pubxml new file mode 100644 index 0000000000..fee35bb752 --- /dev/null +++ b/Signum.Analyzer/Signum.Analyzer/Properties/PublishProfiles/FolderProfile.pubxml @@ -0,0 +1,13 @@ + + + + + FileSystem + Release + Any CPU + netstandard2.0 + bin\Debug\netstandard2.0\publish\ + + \ No newline at end of file diff --git a/Signum.Analyzer/Signum.Analyzer/Signum.Analyzer.csproj b/Signum.Analyzer/Signum.Analyzer/Signum.Analyzer.csproj index 9e73c31d03..88c07fb76c 100644 --- a/Signum.Analyzer/Signum.Analyzer/Signum.Analyzer.csproj +++ b/Signum.Analyzer/Signum.Analyzer/Signum.Analyzer.csproj @@ -1,14 +1,14 @@  - netstandard1.3 + netstandard2.0 false True Signum.Analyzer - 1.0.1 + 2.0.0-beta Olmo del Corral http://www.signumframework.com https://github.com/signumsoftware/framework @@ -18,19 +18,24 @@ Signum.Analyzer, analyzers true https://opensource.org/licenses/MIT - 1.0.1 + 2.0.0-beta https://raw.githubusercontent.com/signumsoftware/framework/master/SignumLogo.png - - + + + + + + + + - From 2f5df3d2723146d828cfe04d7cc9a8d9f9612211 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Sun, 10 Feb 2019 13:47:18 +0100 Subject: [PATCH 20/25] more on nullability check --- Signum.Engine/Connection/SqlConnector.cs | 2 +- Signum.Engine/Database.cs | 4 ++-- .../DynamicQuery/DynamicQueryContainer.cs | 2 +- Signum.Engine/Engine/Synchronizer.cs | 4 ++-- Signum.Engine/LinqExpandHints.cs | 6 +++--- Signum.Engine/Operations/OperationLogic.cs | 2 +- Signum.Engine/Patterns/VirtualMList.cs | 10 +++++----- Signum.Engine/Retriever.cs | 8 ++++---- Signum.Engine/Schema/EntityEvents.cs | 8 ++++---- Signum.Engine/Schema/FluentInclude.cs | 4 ++-- Signum.Engine/Schema/Schema.cs | 12 +++++++----- .../Schema/SchemaBuilder/SchemaBuilder.cs | 4 ++-- .../SchemaBuilder/SchemaBuilderSettings.cs | 6 +++--- Signum.Engine/Schema/UniqueIndex.cs | 4 +--- Signum.Entities/Basics/OperationLog.cs | 2 +- Signum.Entities/DynamicQuery/ResultTable.cs | 18 +++++++++--------- Signum.Entities/Lite.cs | 8 ++++---- Signum.Entities/ModifiableEntity.cs | 14 +++++++------- Signum.Entities/PropertyRoute.cs | 4 ++-- Signum.Entities/Symbol.md | 1 - Signum.Entities/ValidationAttributes.cs | 4 ++-- Signum.Entities/Validator.cs | 8 ++++---- Signum.React/Signum.React.csproj | 2 +- Signum.Test/Signum.Test.csproj | 2 +- Signum.Utilities/DescriptionManager.cs | 2 +- Signum.Utilities/Disposable.cs | 2 +- .../Extensions/DictionaryExtensions.cs | 11 ++++++++++- .../Extensions/EnumerableExtensions.cs | 12 ++++++------ Signum.Utilities/Extensions/Extensions.cs | 2 +- .../Extensions/StringExtensions.cs | 12 ++++++++++++ Signum.Utilities/Reflection/ReflectionTools.cs | 6 +++--- Signum.Utilities/SafeConsole.cs | 14 +++++++------- 32 files changed, 110 insertions(+), 90 deletions(-) diff --git a/Signum.Engine/Connection/SqlConnector.cs b/Signum.Engine/Connection/SqlConnector.cs index ecf73140f0..8e3273bd0b 100644 --- a/Signum.Engine/Connection/SqlConnector.cs +++ b/Signum.Engine/Connection/SqlConnector.cs @@ -458,7 +458,7 @@ public override bool AllowsMultipleQueries get { return true; } } - public SqlConnector ForDatabase(Maps.DatabaseName database) + public SqlConnector ForDatabase(Maps.DatabaseName? database) { if (database == null) return this; diff --git a/Signum.Engine/Database.cs b/Signum.Engine/Database.cs index 3f2e460981..466ed2f2db 100644 --- a/Signum.Engine/Database.cs +++ b/Signum.Engine/Database.cs @@ -148,7 +148,7 @@ public static T Retrieve(PrimaryKey id) where T : Entity r.CompleteAll(); } - if (filter != null && !filter.InMemoryFunction(result)) + if (filter != null && !filter.InMemoryFunction!(result)) throw new EntityNotFoundException(typeof(T), id); return result; @@ -196,7 +196,7 @@ public static async Task RetrieveAsync(PrimaryKey id, CancellationToken to await r.CompleteAllAsync(token); } - if (filter != null && !filter.InMemoryFunction(result)) + if (filter != null && !filter.InMemoryFunction!(result)) throw new EntityNotFoundException(typeof(T), id); return result; diff --git a/Signum.Engine/DynamicQuery/DynamicQueryContainer.cs b/Signum.Engine/DynamicQuery/DynamicQueryContainer.cs index 7b59b6ff1d..cf52f9dd01 100644 --- a/Signum.Engine/DynamicQuery/DynamicQueryContainer.cs +++ b/Signum.Engine/DynamicQuery/DynamicQueryContainer.cs @@ -102,7 +102,7 @@ async Task ExecuteAsync(ExecuteType executeType, object queryName, BaseQue } } - public event Func QueryExecuted; + public event Func QueryExecuted; public enum ExecuteType { diff --git a/Signum.Engine/Engine/Synchronizer.cs b/Signum.Engine/Engine/Synchronizer.cs index e16993c802..f1f11dc963 100644 --- a/Signum.Engine/Engine/Synchronizer.cs +++ b/Signum.Engine/Engine/Synchronizer.cs @@ -315,9 +315,9 @@ public class AutoReplacementContext { public string ReplacementKey; public string OldValue; - public List NewValues; + public List? NewValues; - public AutoReplacementContext(string replacementKey, string oldValue, List newValues) + public AutoReplacementContext(string replacementKey, string oldValue, List? newValues) { ReplacementKey = replacementKey; OldValue = oldValue; diff --git a/Signum.Engine/LinqExpandHints.cs b/Signum.Engine/LinqExpandHints.cs index 98de5d86ea..cf76196200 100644 --- a/Signum.Engine/LinqExpandHints.cs +++ b/Signum.Engine/LinqExpandHints.cs @@ -1,4 +1,4 @@ -using Signum.Entities; +using Signum.Entities; using System; using System.Linq; using System.Linq.Expressions; @@ -8,7 +8,7 @@ namespace Signum.Engine { public static class LinqHintsExpand { - public static IQueryable ExpandLite(this IQueryable source, Expression>> liteSelector, ExpandLite expandLite) + public static IQueryable ExpandLite(this IQueryable source, Expression?>> liteSelector, ExpandLite expandLite) where L : class, IEntity { if (source == null) @@ -17,7 +17,7 @@ public static IQueryable ExpandLite(this IQueryable source, Expressi return source.Provider.CreateQuery(Expression.Call(null, ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new Type[] { typeof(T), typeof(L) }), new Expression[] { source.Expression, Expression.Quote(liteSelector), Expression.Constant(expandLite) })); } - public static IQueryable ExpandEntity(this IQueryable source, Expression> entitySelector, ExpandEntity expandEntity) + public static IQueryable ExpandEntity(this IQueryable source, Expression> entitySelector, ExpandEntity expandEntity) where L : class, IEntity { if (source == null) diff --git a/Signum.Engine/Operations/OperationLogic.cs b/Signum.Engine/Operations/OperationLogic.cs index 2bac7068ac..8d02b3f42e 100644 --- a/Signum.Engine/Operations/OperationLogic.cs +++ b/Signum.Engine/Operations/OperationLogic.cs @@ -767,7 +767,7 @@ public interface IEntityOperation : IOperation } - public delegate IDisposable SurroundOperationHandler(IOperation operation, OperationLogEntity log, Entity? entity, object[]? args); + public delegate IDisposable? SurroundOperationHandler(IOperation operation, OperationLogEntity log, Entity? entity, object[]? args); public delegate void OperationHandler(IOperation operation, Entity entity); public delegate void ErrorOperationHandler(IOperation operation, Entity entity, Exception ex); public delegate bool AllowOperationHandler(OperationSymbol operationSymbol, Type entityType, bool inUserInterface); diff --git a/Signum.Engine/Patterns/VirtualMList.cs b/Signum.Engine/Patterns/VirtualMList.cs index 3a46098ec4..cc0deab22b 100644 --- a/Signum.Engine/Patterns/VirtualMList.cs +++ b/Signum.Engine/Patterns/VirtualMList.cs @@ -56,14 +56,14 @@ public static IDisposable ConsiderNewType(Type parentType) public static FluentInclude WithVirtualMList(this FluentInclude fi, Expression>> mListField, - Expression>> getBackReference, + Expression?>> backReference, ExecuteSymbol saveOperation, DeleteSymbol deleteOperation) where T : Entity where L : Entity { - return fi.WithVirtualMList(mListField, getBackReference, + return fi.WithVirtualMList(mListField, backReference, onSave: saveOperation == null ? null : new Action((line, e) => { line.Execute(saveOperation); @@ -76,7 +76,7 @@ public static FluentInclude WithVirtualMList(this FluentInclude fi, public static FluentInclude WithVirtualMList(this FluentInclude fi, Expression>> mListField, - Expression>> backReference, + Expression?>> backReference, Action? onSave = null, Action? onRemove = null, bool? lazyRetrieve = null, @@ -259,7 +259,7 @@ public static FluentInclude WithVirtualMList(this FluentInclude fi, public static FluentInclude WithVirtualMListInitializeOnly(this FluentInclude fi, Expression>> mListField, - Expression>> backReference, + Expression?>> backReference, Action? onSave = null) where T : Entity where L : Entity @@ -345,7 +345,7 @@ private static Expression SafeAccess(ParameterExpression param, MemberExpression ); } - public static Action>? CreateSetter(Expression>> getBackReference) + public static Action>? CreateSetter(Expression?>> getBackReference) where T : Entity where L : Entity { diff --git a/Signum.Engine/Retriever.cs b/Signum.Engine/Retriever.cs index 77873335d0..eba81a4d62 100644 --- a/Signum.Engine/Retriever.cs +++ b/Signum.Engine/Retriever.cs @@ -18,7 +18,7 @@ public interface IRetriever : IDisposable T? Complete(PrimaryKey? id, Action complete) where T : Entity; T? Request(PrimaryKey? id) where T : Entity; - T? RequestIBA(PrimaryKey? typeId, string id) where T : class, IEntity; + T? RequestIBA(PrimaryKey? typeId, string? id) where T : class, IEntity; Lite? RequestLite(Lite? lite) where T : class, IEntity; T? ModifiablePostRetrieving(T? entity) where T : Modifiable; IRetriever? Parent { get; } @@ -126,7 +126,7 @@ bool TryGetRequest((Type type, PrimaryKey id) key, out Entity value) return entity; } - public T? RequestIBA(PrimaryKey? typeId, string id) where T : class, IEntity + public T? RequestIBA(PrimaryKey? typeId, string? id) where T : class, IEntity { if (id == null) return null; @@ -307,7 +307,7 @@ static async Task> GetStrings(List if (cc != null && cc.Enabled) { cc.Load(); - return ids.ToDictionary(a => a, a => cc.TryGetToString(a)); + return ids.ToDictionary(a => a, a => cc.TryGetToString(a)!); } else if (token != null) { @@ -364,7 +364,7 @@ public ChildRetriever(IRetriever parent, EntityCache.RealEntityCache entityCache return parent.Request(id); } - public T? RequestIBA(PrimaryKey? typeId, string id) where T : class, IEntity + public T? RequestIBA(PrimaryKey? typeId, string? id) where T : class, IEntity { return parent.RequestIBA(typeId, id); } diff --git a/Signum.Engine/Schema/EntityEvents.cs b/Signum.Engine/Schema/EntityEvents.cs index a7b2047402..3d0311763a 100644 --- a/Signum.Engine/Schema/EntityEvents.cs +++ b/Signum.Engine/Schema/EntityEvents.cs @@ -53,7 +53,7 @@ internal IEnumerable> OnFilterQuery() if (FilterQuery == null) return Enumerable.Empty>(); - return FilterQuery.GetInvocationListTyped().Select(f => f()).ToList(); + return FilterQuery.GetInvocationListTyped().Select(f => f()).NotNull().ToList(); } internal IDisposable? OnPreUnsafeDelete(IQueryable entityQuery) @@ -246,7 +246,7 @@ Action CreateSetter() public delegate void RetrievedEventHandler(T ident) where T : Entity; public delegate void SavingEventHandler(T ident) where T : Entity; public delegate void SavedEventHandler(T ident, SavedEventArgs args) where T : Entity; - public delegate FilterQueryResult FilterQueryEventHandler() where T : Entity; + public delegate FilterQueryResult? FilterQueryEventHandler() where T : Entity; public delegate void AlternativeRetriveEventHandler(PrimaryKey id, AlternativeRetrieveArgs args) where T : Entity; public delegate IDisposable? PreUnsafeDeleteHandler(IQueryable entityQuery); @@ -276,14 +276,14 @@ public interface IFilterQueryResult public class FilterQueryResult : IFilterQueryResult where T : Entity { - public FilterQueryResult(Expression> inDatabaseExpression, Func inMemoryFunction) + public FilterQueryResult(Expression> inDatabaseExpression, Func? inMemoryFunction) { this.InDatabaseExpresson = inDatabaseExpression; this.InMemoryFunction = inMemoryFunction; } public readonly Expression> InDatabaseExpresson; - public readonly Func InMemoryFunction; + public readonly Func? InMemoryFunction; LambdaExpression IFilterQueryResult.InDatabaseExpression { get { return this.InDatabaseExpresson; } } } diff --git a/Signum.Engine/Schema/FluentInclude.cs b/Signum.Engine/Schema/FluentInclude.cs index 056880f8fb..5709087fe2 100644 --- a/Signum.Engine/Schema/FluentInclude.cs +++ b/Signum.Engine/Schema/FluentInclude.cs @@ -15,13 +15,13 @@ public FluentInclude(Table table, SchemaBuilder schemaBuilder) SchemaBuilder = schemaBuilder; } - public FluentInclude WithUniqueIndex(Expression> fields, Expression>? where = null, Expression>? includeFields = null) + public FluentInclude WithUniqueIndex(Expression> fields, Expression>? where = null, Expression>? includeFields = null) { this.SchemaBuilder.AddUniqueIndex(fields, where, includeFields); return this; } - public FluentInclude WithIndex(Expression> fields, + public FluentInclude WithIndex(Expression> fields, Expression>? where = null, Expression>? includeFields = null) { diff --git a/Signum.Engine/Schema/Schema.cs b/Signum.Engine/Schema/Schema.cs index e093da820b..db182d5547 100644 --- a/Signum.Engine/Schema/Schema.cs +++ b/Signum.Engine/Schema/Schema.cs @@ -66,7 +66,7 @@ public Dictionary Tables #region Events - public event Func IsAllowedCallback; + public event Func IsAllowedCallback; public string? IsAllowed(Type type, bool inUserInterface) { @@ -317,7 +317,7 @@ internal IEnumerable GetAdditionalQueryBindings(PropertyRoute pare return new FilterQueryResult( a => one!.InDatabaseExpresson.Evaluate(a) && two.InDatabaseExpresson.Evaluate(a), - a => one!.InMemoryFunction(a) && two!.InMemoryFunction(a)); + a => one!.InMemoryFunction!(a) && two!.InMemoryFunction!(a)); } public Func GetInMemoryFilter(bool userInterface) @@ -801,7 +801,7 @@ public interface ICacheController void Complete(Entity entity, IRetriever retriver); string GetToString(PrimaryKey id); - string TryGetToString(PrimaryKey id); + string? TryGetToString(PrimaryKey id); } public class InvalidateEventArgs : EventArgs { } @@ -823,9 +823,11 @@ void ICacheController.Complete(Entity entity, IRetriever retriver) public abstract void Complete(T entity, IRetriever retriver); public abstract string GetToString(PrimaryKey id); - public abstract string TryGetToString(PrimaryKey id); + public abstract string? TryGetToString(PrimaryKey id); - public abstract List RequestByBackReference(IRetriever retriever, Expression>> backReference, Lite lite) + public abstract List RequestByBackReference(IRetriever retriever, Expression?>> backReference, Lite lite) where R : Entity; } + + } diff --git a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs index 40cd0bb8e5..8444a348d4 100644 --- a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs +++ b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs @@ -66,7 +66,7 @@ public Schema Schema } - public UniqueIndex AddUniqueIndex(Expression> fields, Expression>? where = null, Expression>? includeFields = null) where T : Entity + public UniqueIndex AddUniqueIndex(Expression> fields, Expression>? where = null, Expression>? includeFields = null) where T : Entity { var table = Schema.Table(); @@ -89,7 +89,7 @@ public UniqueIndex AddUniqueIndex(Expression> fields, Express return index; } - public Index AddIndex(Expression> fields, + public Index AddIndex(Expression> fields, Expression>? where = null, Expression>? includeFields = null) where T : Entity { diff --git a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs index 0b5b0b9be8..20b0de01be 100644 --- a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs +++ b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs @@ -234,13 +234,13 @@ private IsNullable GetIsNullablePrivate(PropertyRoute propertyRoute) return !propertyRoute.Type.IsValueType || propertyRoute.Type.IsNullable() ? IsNullable.Yes : IsNullable.No; } - public bool ImplementedBy(Expression> propertyRoute, Type typeToImplement) where T : Entity + public bool ImplementedBy(Expression> propertyRoute, Type typeToImplement) where T : Entity { var imp = GetImplementations(propertyRoute); return !imp.IsByAll && imp.Types.Contains(typeToImplement); } - public void AssertImplementedBy(Expression> propertyRoute, Type typeToImplement) where T : Entity + public void AssertImplementedBy(Expression> propertyRoute, Type typeToImplement) where T : Entity { var route = PropertyRoute.Construct(propertyRoute); @@ -252,7 +252,7 @@ public void AssertImplementedBy(Expression> propertyRoute, Ty Implementations.ConsiderMessage(route, imp.Types.And(typeToImplement).ToString(t => $"typeof({t.TypeName()})", ", "))); } - public Implementations GetImplementations(Expression> propertyRoute) where T : Entity + public Implementations GetImplementations(Expression> propertyRoute) where T : Entity { return GetImplementations(PropertyRoute.Construct(propertyRoute)); } diff --git a/Signum.Engine/Schema/UniqueIndex.cs b/Signum.Engine/Schema/UniqueIndex.cs index d895e9fae8..c145105dbe 100644 --- a/Signum.Engine/Schema/UniqueIndex.cs +++ b/Signum.Engine/Schema/UniqueIndex.cs @@ -128,9 +128,7 @@ from c in GetColumns(finder, Expression.Lambda(Expression.Convert(a, typeof(obje return resultColumns.ToArray(); } - - - + return GetColumns(finder, columns); } diff --git a/Signum.Entities/Basics/OperationLog.cs b/Signum.Entities/Basics/OperationLog.cs index 76733b745f..3596cea406 100644 --- a/Signum.Entities/Basics/OperationLog.cs +++ b/Signum.Entities/Basics/OperationLog.cs @@ -24,7 +24,7 @@ public class OperationLogEntity : Entity static Expression> DurationExpression = log => (double?)(log.End - log.Start).Value.TotalMilliseconds; -#pragma warning disable SF0002 // Use ExpressionFieldAttribute in non-trivial method or property CSBUG +#pragma warning disable SF0002 // Use ExpressionFieldAttribute in non-trivial method or property [ExpressionField("DurationExpression"), Unit("ms")] #pragma warning restore SF0002 // Use ExpressionFieldAttribute in non-trivial method or property public double? Duration diff --git a/Signum.Entities/DynamicQuery/ResultTable.cs b/Signum.Entities/DynamicQuery/ResultTable.cs index 762f2d85f7..97278e028a 100644 --- a/Signum.Entities/DynamicQuery/ResultTable.cs +++ b/Signum.Entities/DynamicQuery/ResultTable.cs @@ -276,7 +276,7 @@ public DataTable ToDataTablePivot(int rowColumnIndex, int columnColumnIndex, int string Null = "- NULL -"; - Dictionary> dictionary = + Dictionary> dictionary = this.Rows .AgGroupToDictionary( row => row[rowColumnIndex] ?? Null, @@ -298,7 +298,7 @@ public DataTable ToDataTablePivot(int rowColumnIndex, int columnColumnIndex, int foreach (var kvp in dictionary) { result.Rows.Add( - allColumns.Select(val => defConverter.ConvertValue(kvp.Value.TryGetC(val), valueColumn.Column)) + allColumns.Select(val => defConverter.ConvertValue(kvp.Value.TryGetCN(val), valueColumn.Column)) .PreAnd(defConverter.ConvertValue(kvp.Key, rowColumn.Column)) .ToArray()); } @@ -417,12 +417,12 @@ public bool IsDirty } } - public object this[int columnIndex] + public object? this[int columnIndex] { get { return Table.Columns[columnIndex].Values[Index]; } } - public object this[ResultColumn column] + public object? this[ResultColumn column] { get { return column.Values[Index]; } } @@ -445,22 +445,22 @@ public Lite? TryEntity public T GetValue(string columnName) { - return (T)this[Table.Columns.Where(c => c.Column.Name == columnName).SingleEx(() => columnName)]; + return (T)this[Table.Columns.Where(c => c.Column.Name == columnName).SingleEx(() => columnName)]!; } public T GetValue(int columnIndex) { - return (T)this[columnIndex]; + return (T)this[columnIndex]!; } public T GetValue(ResultColumn column) { - return (T)this[column]; + return (T)this[column]!; } - public object[] GetValues(ResultColumn[] columnArray) + public object?[] GetValues(ResultColumn[] columnArray) { - var result = new object[columnArray.Length]; + var result = new object?[columnArray.Length]; for (int i = 0; i < columnArray.Length; i++) { result[i] = this[columnArray[i]]; diff --git a/Signum.Entities/Lite.cs b/Signum.Entities/Lite.cs index 480a095c86..f7b915a099 100644 --- a/Signum.Entities/Lite.cs +++ b/Signum.Entities/Lite.cs @@ -345,7 +345,7 @@ public static Lite Create(Type type, PrimaryKey id) return giNewLite.GetInvoker(type)(id, null); } - public static Lite Create(Type type, PrimaryKey id, string toStr) + public static Lite Create(Type type, PrimaryKey id, string? toStr) { return giNewLite.GetInvoker(type)(id, toStr); } @@ -361,7 +361,7 @@ public static Lite ToLite(this T entity) } [DebuggerStepThrough] - public static Lite ToLite(this T entity, string toStr) + public static Lite ToLite(this T entity, string? toStr) where T : class, IEntity { if (entity.IsNew) @@ -471,7 +471,7 @@ public Expression Expand(Expression instance, Expression[] arguments, MethodInfo } [MethodExpander(typeof(IsEntityLiteExpander))] - public static bool Is(this T entity1, Lite lite2) + public static bool Is(this T? entity1, Lite? lite2) where T : class, IEntity { if (entity1 == null && lite2 == null) @@ -511,7 +511,7 @@ public Expression Expand(Expression instance, Expression[] arguments, MethodInfo } [MethodExpander(typeof(IsLiteEntityExpander))] - public static bool Is(this Lite lite1, T entity2) + public static bool Is(this Lite? lite1, T? entity2) where T : class, IEntity { if (lite1 == null && entity2 == null) diff --git a/Signum.Entities/ModifiableEntity.cs b/Signum.Entities/ModifiableEntity.cs index 4e0dd5908d..aaecbc8e32 100644 --- a/Signum.Entities/ModifiableEntity.cs +++ b/Signum.Entities/ModifiableEntity.cs @@ -77,7 +77,7 @@ protected virtual bool Set(ref T field, T value, [CallerMemberName]string? au SetSelfModified(); field = value; - + if (field is INotifyCollectionChanged cola) { if (AttributeManager.FieldContainsAttribute(GetType(), pi)) @@ -87,7 +87,7 @@ protected virtual bool Set(ref T field, T value, [CallerMemberName]string? au foreach (ModifiableEntity item in (IEnumerable)cola) item.SetParentEntity(this); } - + if (field is ModifiableEntity moda) { if (AttributeManager.FieldContainsAttribute(GetType(), pi)) @@ -102,7 +102,7 @@ protected virtual bool Set(ref T field, T value, [CallerMemberName]string? au return true; } - + struct PropertyKey : IEquatable { public PropertyKey(Type type, string propertyName) @@ -129,7 +129,7 @@ protected PropertyInfo GetPropertyInfo(string propertyName) } static Expression> ToStringPropertyExpression = m => m.ToString(); -#pragma warning disable SF0002 // Use ExpressionFieldAttribute in non-trivial method or property CSBUG +#pragma warning disable SF0002 // Use ExpressionFieldAttribute in non-trivial method or property [HiddenProperty, ExpressionField("ToStringPropertyExpression")] #pragma warning restore SF0002 // Use ExpressionFieldAttribute in non-trivial method or property public string ToStringProperty @@ -140,7 +140,7 @@ public string ToStringProperty return str.HasText() ? str : this.GetType().NiceName(); } } - + #region Collection Events protected internal override void PostRetrieving() @@ -327,7 +327,7 @@ public string? Error } } - public string? PropertyCheck(Expression> property) + public string? PropertyCheck(Expression> property) { return PropertyCheck(ReflectionTools.GetPropertyInfo(property).Name); } @@ -347,7 +347,7 @@ public string? Error return null; } - protected static void Validate(Expression> property, Func validate) where T : ModifiableEntity + protected static void Validate(Expression> property, Func validate) where T : ModifiableEntity { Validator.PropertyValidator(property).StaticPropertyValidation += validate; } diff --git a/Signum.Entities/PropertyRoute.cs b/Signum.Entities/PropertyRoute.cs index 701e63c050..39e7f1b1e5 100644 --- a/Signum.Entities/PropertyRoute.cs +++ b/Signum.Entities/PropertyRoute.cs @@ -367,12 +367,12 @@ public Implementations GetImplementations() return FindImplementations(this); } - public static void SetIsAllowedCallback(Func isAllowed) + public static void SetIsAllowedCallback(Func isAllowed) { IsAllowedCallback = isAllowed; } - static Func IsAllowedCallback; + static Func IsAllowedCallback; public string? IsAllowed() { diff --git a/Signum.Entities/Symbol.md b/Signum.Entities/Symbol.md index e0772c9844..6eb90c8d03 100644 --- a/Signum.Entities/Symbol.md +++ b/Signum.Entities/Symbol.md @@ -166,4 +166,3 @@ In fact, we could classify entities depending their *staticness-dynamicness* lik * **Log Entities:** Automatically created by the system, and removed after some time. (i.e.: `OperationLogEntity`) **DOWN: Dynamic and unfrequently used** - \ No newline at end of file diff --git a/Signum.Entities/ValidationAttributes.cs b/Signum.Entities/ValidationAttributes.cs index 8098f0925b..f887a6f714 100644 --- a/Signum.Entities/ValidationAttributes.cs +++ b/Signum.Entities/ValidationAttributes.cs @@ -851,11 +851,11 @@ public class StateValidator : IEnumerable Func getState; string[] propertyNames; PropertyInfo[] properties; - Func[] getters; + Func[] getters; Dictionary dictionary = new Dictionary(); - public StateValidator(Func getState, params Expression>[] propertyGetters) + public StateValidator(Func getState, params Expression>[] propertyGetters) { this.getState = getState; this.properties = propertyGetters.Select(p => ReflectionTools.GetPropertyInfo(p)).ToArray(); diff --git a/Signum.Entities/Validator.cs b/Signum.Entities/Validator.cs index 4349d01bd5..559bc02249 100644 --- a/Signum.Entities/Validator.cs +++ b/Signum.Entities/Validator.cs @@ -24,7 +24,7 @@ public static IDisposable ModelBinderScope() return new Disposable(() => inModelBinderVariable.Value = old); } - public static Func GlobalValidation { get; set; } + public static Func GlobalValidation { get; set; } static Polymorphic> validators = new Polymorphic>(PolymorphicMerger.InheritDictionary, typeof(ModifiableEntity)); @@ -54,7 +54,7 @@ static void GenerateType() where T : ModifiableEntity - public static PropertyValidator OverridePropertyValidator(Expression> property) where T : ModifiableEntity + public static PropertyValidator OverridePropertyValidator(Expression> property) where T : ModifiableEntity { GenerateType(); @@ -74,7 +74,7 @@ public static PropertyValidator OverridePropertyValidator(Expression PropertyValidator(Expression> property) where T : ModifiableEntity + public static PropertyValidator PropertyValidator(Expression> property) where T : ModifiableEntity { GenerateType(); @@ -155,7 +155,7 @@ public class PropertyValidator : IPropertyValidator public Func? IsApplicableParentChildPropertyValidation { get; set; } public Func? IsApplicableStaticPropertyValidation { get; set; } - public Func? StaticPropertyValidation { get; set; } + public Func? StaticPropertyValidation { get; set; } public bool Required => throw new NotImplementedException(); diff --git a/Signum.React/Signum.React.csproj b/Signum.React/Signum.React.csproj index c33ebdbc2b..35dcec7fe0 100644 --- a/Signum.React/Signum.React.csproj +++ b/Signum.React/Signum.React.csproj @@ -18,7 +18,7 @@ - + runtime; build; native; contentfiles; analyzers all diff --git a/Signum.Test/Signum.Test.csproj b/Signum.Test/Signum.Test.csproj index 785fd30a99..a379b5febb 100644 --- a/Signum.Test/Signum.Test.csproj +++ b/Signum.Test/Signum.Test.csproj @@ -20,6 +20,7 @@ + all @@ -34,7 +35,6 @@ - diff --git a/Signum.Utilities/DescriptionManager.cs b/Signum.Utilities/DescriptionManager.cs index d77b6310e1..2e878a970e 100644 --- a/Signum.Utilities/DescriptionManager.cs +++ b/Signum.Utilities/DescriptionManager.cs @@ -200,7 +200,7 @@ public static string NicePluralName(this Type type) NaturalLanguageTools.Pluralize(DefaultTypeDescription(type)); } - public static string NiceToString(this Enum a, params object[] args) + public static string NiceToString(this Enum a, params object?[] args) { return a.NiceToString().FormatWith(args); } diff --git a/Signum.Utilities/Disposable.cs b/Signum.Utilities/Disposable.cs index 9819eeed35..7d900d835b 100644 --- a/Signum.Utilities/Disposable.cs +++ b/Signum.Utilities/Disposable.cs @@ -39,7 +39,7 @@ public void Dispose() () => { try { first!.Dispose(); } finally { second!.Dispose(); } }); } - public static IDisposable? Combine(Del delegated, Func invoke) where Del : class, ICloneable, ISerializable + public static IDisposable? Combine(Del delegated, Func invoke) where Del : class, ICloneable, ISerializable { if (delegated == null) return null; diff --git a/Signum.Utilities/Extensions/DictionaryExtensions.cs b/Signum.Utilities/Extensions/DictionaryExtensions.cs index 2c102d9b36..fd344075a0 100644 --- a/Signum.Utilities/Extensions/DictionaryExtensions.cs +++ b/Signum.Utilities/Extensions/DictionaryExtensions.cs @@ -23,6 +23,13 @@ public static V TryGet(this IReadOnlyDictionary dictionary, K key, V return null; } + public static V? TryGetCN(this IReadOnlyDictionary dictionary, K key) where V : class + { + if (dictionary.TryGetValue(key, out V? result)) + return result; + return null; + } + public static V? TryGetS(this IReadOnlyDictionary dictionary, K key) where V : struct { if (dictionary.TryGetValue(key, out V result)) @@ -47,7 +54,9 @@ public static V TryGet(this IReadOnlyDictionary dictionary, K key, V return result; } - public static V GetOrAdd(this ConcurrentDictionary dictionary, K key) where V : new() + public static V GetOrAdd(this ConcurrentDictionary dictionary, K key) + where K : object + where V : new() { return dictionary.GetOrAdd(key, k => new V()); } diff --git a/Signum.Utilities/Extensions/EnumerableExtensions.cs b/Signum.Utilities/Extensions/EnumerableExtensions.cs index 312f2d95f1..0b8a9fcc71 100644 --- a/Signum.Utilities/Extensions/EnumerableExtensions.cs +++ b/Signum.Utilities/Extensions/EnumerableExtensions.cs @@ -500,7 +500,7 @@ public static string ToString(this IEnumerable source, string separator) return sb.ToString(); // Remove at the end is faster } - public static string ToString(this IEnumerable source, Func toString, string separator) + public static string ToString(this IEnumerable source, Func toString, string separator) { StringBuilder? sb = null; foreach (var item in source) @@ -519,7 +519,7 @@ public static string ToString(this IEnumerable source, Func toS return sb.ToString(); // Remove at the end is faster } - public static string ToString(this IQueryable source, Expression> toString, string separator) + public static string ToString(this IQueryable source, Expression> toString, string separator) { return source.Select(toString).ToString(separator); } @@ -529,17 +529,17 @@ public static string CommaAnd(this IEnumerable collection) return CommaString(collection.Select(a => a!.ToString()).ToArray(), CollectionMessage.And.NiceToString()); } - public static string CommaAnd(this IEnumerable collection, Func toString) + public static string CommaAnd(this IEnumerable collection, Func toString) { return CommaString(collection.Select(toString).ToArray(), CollectionMessage.And.NiceToString()); } public static string CommaOr(this IEnumerable collection) { - return CommaString(collection.Select(a => a!.ToString()).ToArray(), CollectionMessage.Or.NiceToString()); + return CommaString(collection.Select(a => a?.ToString()).ToArray(), CollectionMessage.Or.NiceToString()); } - public static string CommaOr(this IEnumerable collection, Func toString) + public static string CommaOr(this IEnumerable collection, Func toString) { return CommaString(collection.Select(toString).ToArray(), CollectionMessage.Or.NiceToString()); } @@ -554,7 +554,7 @@ public static string Comma(this IEnumerable collection, Func to return CommaString(collection.Select(toString).ToArray(), lastSeparator); } - static string CommaString(this string[] values, string lastSeparator) + static string CommaString(this string?[] values, string lastSeparator) { if (values.Length == 0) return ""; diff --git a/Signum.Utilities/Extensions/Extensions.cs b/Signum.Utilities/Extensions/Extensions.cs index ced4c0fa34..8f7602a60a 100644 --- a/Signum.Utilities/Extensions/Extensions.cs +++ b/Signum.Utilities/Extensions/Extensions.cs @@ -421,7 +421,7 @@ public static IEnumerable Follow(this T? start, FuncSN next) where yield return i.Value; } - public static IEnumerable GetInvocationListTyped(this D multicastDelegate) + public static IEnumerable GetInvocationListTyped(this D? multicastDelegate) where D : class, ICloneable, ISerializable { if (multicastDelegate == null) diff --git a/Signum.Utilities/Extensions/StringExtensions.cs b/Signum.Utilities/Extensions/StringExtensions.cs index 2f6cd282d7..ceae580bd7 100644 --- a/Signum.Utilities/Extensions/StringExtensions.cs +++ b/Signum.Utilities/Extensions/StringExtensions.cs @@ -33,6 +33,18 @@ public static string DefaultText(this string? str, string defaultText) return defaultText; } +#pragma warning disable IDE0052 // Remove unread private members + static readonly Expression> EmtpyToNullExpression = a => a == null || a.Length == 0 ? null : a; +#pragma warning restore IDE0052 // Remove unread private members + [ExpressionField("EmtpyToNullExpression")] + public static string? EmtpyToNull(this string? str) + { + if (!str.HasText()) + return null; + + return str; + } + public static string AssertHasText(this string? str, string errorMessage) { if (str.HasText()) diff --git a/Signum.Utilities/Reflection/ReflectionTools.cs b/Signum.Utilities/Reflection/ReflectionTools.cs index 98be3eed45..75625d332d 100644 --- a/Signum.Utilities/Reflection/ReflectionTools.cs +++ b/Signum.Utilities/Reflection/ReflectionTools.cs @@ -505,12 +505,12 @@ public static bool TryParse(string value, CultureInfo ci, out T result) } } - public static bool TryParse(string value, Type type, out object? result) + public static bool TryParse(string? value, Type type, out object? result) { return TryParse(value, type, CultureInfo.CurrentCulture, out result); } - public static bool TryParse(string value, Type type, CultureInfo ci, out object? result) + public static bool TryParse(string? value, Type type, CultureInfo ci, out object? result) { if (type == typeof(string)) { @@ -698,7 +698,7 @@ public static bool TryParse(string value, Type type, CultureInfo ci, out object? } } - public static T ChangeType(object value) + public static T ChangeType(object? value) { if (value == null) return (T)(object?)null!; diff --git a/Signum.Utilities/SafeConsole.cs b/Signum.Utilities/SafeConsole.cs index f29af664a0..b0913eb5cc 100644 --- a/Signum.Utilities/SafeConsole.cs +++ b/Signum.Utilities/SafeConsole.cs @@ -12,17 +12,17 @@ public static class SafeConsole public static readonly object SyncKey = new object(); static bool needToClear = false; - public static void WriteSameLine(string format, params object[] parameters) + public static void WriteSameLine(string? format, params object?[] parameters) { WriteSameLine(string.Format(format, parameters)); } - public static void WriteSameLine(string str) + public static void WriteSameLine(string? str) { if (needToClear) - str = str.PadChopRight(Console.BufferWidth - 1); + str = str?.PadChopRight(Console.BufferWidth - 1); else - str = str.TryStart(Console.BufferWidth - 1)!; + str = str?.TryStart(Console.BufferWidth - 1)!; Console.WriteLine(str); @@ -57,12 +57,12 @@ public static void WriteColor(ConsoleColor color, string str) - public static void WriteLineColor(ConsoleColor color, string format, params object[] parameters) + public static void WriteLineColor(ConsoleColor color, string? format, params object?[] parameters) { WriteLineColor(color, string.Format(format, parameters)); } - public static void WriteLineColor(ConsoleColor color, string str) + public static void WriteLineColor(ConsoleColor color, string? str) { ConsoleColor old = Console.ForegroundColor; Console.ForegroundColor = color; @@ -70,7 +70,7 @@ public static void WriteLineColor(ConsoleColor color, string str) Console.ForegroundColor = old; } - public static void WriteSameLineColor(ConsoleColor color, string str) + public static void WriteSameLineColor(ConsoleColor color, string? str) { ConsoleColor old = Console.ForegroundColor; Console.ForegroundColor = color; From d50cc89683daf155ac225468786d46710d2de43d Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Wed, 13 Feb 2019 17:01:46 +0100 Subject: [PATCH 21/25] more on no nullable --- Signum.Engine/Database.cs | 5 +- .../DynamicQuery/ManualDynamicQuery.cs | 2 +- Signum.Engine/Engine/SchemaSynchronizer.cs | 2 +- .../OverloadingSimplifier.cs | 18 +- Signum.Engine/Operations/OperationLogic.cs | 2 +- Signum.Engine/Patterns/VirtualMList.cs | 16 +- Signum.Engine/Retriever.cs | 4 +- Signum.Engine/Schema/Schema.Delete.cs | 2 +- Signum.Engine/Schema/Schema.Save.cs | 2824 ++++++++--------- .../Schema/SchemaBuilder/SchemaBuilder.cs | 4 +- .../SchemaBuilder/SchemaBuilderSettings.cs | 17 +- Signum.Engine/Signum.Engine.csproj | 4 - Signum.Entities/Basics/Exception.cs | 3 +- Signum.Entities/Basics/OperationLog.cs | 2 +- Signum.Entities/Basics/PropertyRouteEntity.cs | 1 - Signum.Entities/DynamicQuery/ResultTable.cs | 2 +- .../DynamicQuery/Tokens/QueryToken.cs | 4 +- Signum.Entities/FieldAttributes.cs | 6 +- Signum.Entities/MList.cs | 8 +- Signum.Entities/Signum.Entities.csproj | 4 - Signum.Entities/ValidationAttributes.cs | 7 +- Signum.Entities/Validator.cs | 7 +- .../ApiControllers/QueryController.cs | 12 +- Signum.React/Facades/ReflectionServer.cs | 2 +- Signum.React/Filters/SignumFilters.cs | 2 +- .../JsonConverters/LiteJsonConverter.cs | 2 +- .../JsonConverters/MListJsonConverter.cs | 2 +- .../Scripts/Signum.Entities.Basics.ts | 68 +- .../Scripts/Signum.Entities.Patterns.ts | 2 +- Signum.React/Scripts/Signum.Entities.ts | 4 +- Signum.React/Signum.React.csproj | 8 +- .../EntityDeclarationGenerator.cs | 24 +- .../Properties/launchSettings.json | 14 +- .../Signum.TSGenerator.2.0.0-beta2.nupkg | Bin 0 -> 261558 bytes Signum.TSGenerator/Signum.TSGenerator.csproj | 2 +- Signum.TSGenerator/Signum.TSGenerator.nuspec | 2 +- Signum.Test/Environment/Entities.cs | 1 - Signum.Utilities/Csv.cs | 7 +- Signum.Utilities/DescriptionManager.cs | 6 +- .../ExpressionExpanderAttributes.cs | 3 +- .../ExpressionTrees/ExpressionCleaner.cs | 14 +- .../Extensions/EnumerableExtensions.cs | 2 + Signum.Utilities/Extensions/FileExtensions.cs | 4 +- Signum.Utilities/Extensions/TreeHelper.cs | 5 +- .../NaturalLanguage/NaturalLanguageTools.cs | 2 + Signum.Utilities/NotNullAttributes.cs | 15 +- Signum.Utilities/Profiler/HeavyProfiler.cs | 2 +- Signum.Utilities/Reflection/GenericInvoker.cs | 13 +- Signum.Utilities/Signum.Utilities.csproj | 4 - Signum.Utilities/Statics.cs | 8 +- Signum.Utilities/StringDistance.cs | 2 +- 51 files changed, 1594 insertions(+), 1582 deletions(-) create mode 100644 Signum.TSGenerator/Signum.TSGenerator.2.0.0-beta2.nupkg diff --git a/Signum.Engine/Database.cs b/Signum.Engine/Database.cs index 466ed2f2db..44a85af0e3 100644 --- a/Signum.Engine/Database.cs +++ b/Signum.Engine/Database.cs @@ -314,11 +314,8 @@ public static async Task> RetrieveLiteAsync(PrimaryKey id, Cancellati } } - public static Lite? FillToString(this Lite lite) where T : class, IEntity + public static Lite FillToString(this Lite lite) where T : class, IEntity { - if (lite == null) - return null; - lite.SetToString(GetToStr(lite.EntityType, lite.Id)); return lite; diff --git a/Signum.Engine/DynamicQuery/ManualDynamicQuery.cs b/Signum.Engine/DynamicQuery/ManualDynamicQuery.cs index 7f15801a4a..9077d2b5a8 100644 --- a/Signum.Engine/DynamicQuery/ManualDynamicQuery.cs +++ b/Signum.Engine/DynamicQuery/ManualDynamicQuery.cs @@ -83,7 +83,7 @@ public override async Task ExecuteQueryGroupAsync(QueryRequest requ req.Pagination = new Pagination.Paginate(1, 1); req.Columns.Add(new Column(this.EntityColumnFactory().BuildColumnDescription(), QueryName)); var result = await Execute(req, GetQueryDescription(), cancellationToken); - return result.TotalElements.Value; + return result.TotalElements!.Value; } else if (request.ValueToken is AggregateToken) diff --git a/Signum.Engine/Engine/SchemaSynchronizer.cs b/Signum.Engine/Engine/SchemaSynchronizer.cs index 3cd83fcb66..9301583cb3 100644 --- a/Signum.Engine/Engine/SchemaSynchronizer.cs +++ b/Signum.Engine/Engine/SchemaSynchronizer.cs @@ -911,7 +911,7 @@ private static Entity Clone(Entity current) { var instance = (Entity)Activator.CreateInstance(current.GetType()); instance.toStr = current.toStr; - instance.id = (int)current.id.Value + 1000000; + instance.id = (int)current.id!.Value + 1000000; return instance; } diff --git a/Signum.Engine/Linq/ExpressionVisitor/OverloadingSimplifier.cs b/Signum.Engine/Linq/ExpressionVisitor/OverloadingSimplifier.cs index eb780e0653..9f38bad865 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/OverloadingSimplifier.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/OverloadingSimplifier.cs @@ -50,10 +50,7 @@ internal class OverloadingSimplifier : ExpressionVisitor static MethodInfo miWhereIndexQ = ReflectionTools.GetMethodInfo(() => Queryable.Where((IQueryable)null, (a, i) => false)).GetGenericMethodDefinition(); static MethodInfo miWhereIndexE = ReflectionTools.GetMethodInfo(() => Enumerable.Where((IEnumerable)null, (a, i) => false)).GetGenericMethodDefinition(); - - static MethodInfo miContainsQ = ReflectionTools.GetMethodInfo(() => Queryable.Contains((IQueryable)null, null)).GetGenericMethodDefinition(); - static MethodInfo miContainsE = ReflectionTools.GetMethodInfo(() => Enumerable.Contains((IEnumerable)null, null)).GetGenericMethodDefinition(); - + static MethodInfo miElementAtQ = ReflectionTools.GetMethodInfo(() => Queryable.ElementAt((IQueryable)null, 0)).GetGenericMethodDefinition(); static MethodInfo miElementAtE = ReflectionTools.GetMethodInfo(() => Enumerable.ElementAt((IEnumerable)null, 0)).GetGenericMethodDefinition(); @@ -405,6 +402,19 @@ protected override Expression VisitMethodCall(MethodCallExpression m) } } + if(m.Method.DeclaringType == typeof (Signum.Utilities.Extensions) && m.Method.Name == "Try") + { + var t = m.GetArgument("t"); + var func = (LambdaExpression)m.GetArgument("func"); + + var result = ExpressionReplacer.Replace(func.Body, new Dictionary + { + { func.Parameters.SingleEx(), t.UnNullify() } + }).Nullify(); + + return Visit(result); + } + if (m.Method.DeclaringType == typeof(string) && m.Method.Name == nameof(string.Format)) return VisitFormat(m); diff --git a/Signum.Engine/Operations/OperationLogic.cs b/Signum.Engine/Operations/OperationLogic.cs index 8d02b3f42e..c1c9b4c13e 100644 --- a/Signum.Engine/Operations/OperationLogic.cs +++ b/Signum.Engine/Operations/OperationLogic.cs @@ -160,7 +160,7 @@ public static void ExceptionLogic_DeleteLogs(DeleteLogParametersEmbedded paramet if (dateLimit == null) return; - Database.Query().Where(o => o.Start < dateLimit.Value).UnsafeDeleteChunksLog(parameters, sb, token); + Database.Query().Where(o => o.Start < dateLimit!.Value).UnsafeDeleteChunksLog(parameters, sb, token); } static void OperationLogic_Initializing() diff --git a/Signum.Engine/Patterns/VirtualMList.cs b/Signum.Engine/Patterns/VirtualMList.cs index cc0deab22b..5edb7c6f84 100644 --- a/Signum.Engine/Patterns/VirtualMList.cs +++ b/Signum.Engine/Patterns/VirtualMList.cs @@ -87,11 +87,9 @@ public static FluentInclude WithVirtualMList(this FluentInclude fi, var mListPropertRoute = PropertyRoute.Construct(mListField); RegisteredVirtualMLists.GetOrCreate(typeof(T)).Add(typeof(L), mListPropertRoute); - if (lazyRetrieve == null) - lazyRetrieve = (typeof(L) == typeof(T)); - - if (lazyDelete == null) - lazyDelete = (typeof(L) == typeof(T)); + + var defLazyRetrieve = lazyRetrieve ?? (typeof(L) == typeof(T)); + var defLazyDelete = lazyDelete ?? (typeof(L) == typeof(T)); Func> getMList = GetAccessor(mListField); Action>? setter = null; @@ -104,7 +102,7 @@ public static FluentInclude WithVirtualMList(this FluentInclude fi, var sb = fi.SchemaBuilder; - if (lazyRetrieve.Value) + if (defLazyRetrieve) { sb.Schema.EntityEvents().Retrieved += (T e) => { @@ -130,7 +128,7 @@ public static FluentInclude WithVirtualMList(this FluentInclude fi, if (preserveOrder) { sb.Schema.EntityEvents().RegisterBinding>(mListField, - shouldSet: () => !lazyRetrieve.Value && !VirtualMList.ShouldAvoidMListType(typeof(L)), + shouldSet: () => !defLazyRetrieve && !VirtualMList.ShouldAvoidMListType(typeof(L)), valueExpression: e => Database.Query().Where(line => backReference.Evaluate(line) == e.ToLite()).ExpandLite(line => backReference.Evaluate(line), ExpandLite.ToStringLazy).ToVirtualMListWithOrder(), valueFunction: (e, retriever) => Schema.Current.CacheController()!.Enabled ? Schema.Current.CacheController()!.RequestByBackReference(retriever, backReference, e.ToLite()).ToVirtualMListWithOrder(): @@ -141,7 +139,7 @@ public static FluentInclude WithVirtualMList(this FluentInclude fi, else { sb.Schema.EntityEvents().RegisterBinding(mListField, - shouldSet: () => !lazyRetrieve.Value && !VirtualMList.ShouldAvoidMListType(typeof(L)), + shouldSet: () => !defLazyRetrieve && !VirtualMList.ShouldAvoidMListType(typeof(L)), valueExpression: e => Database.Query().Where(line => backReference.Evaluate(line) == e.ToLite()).ExpandLite(line => backReference.Evaluate(line), ExpandLite.ToStringLazy).ToVirtualMList(), valueFunction: (e, retriever) => Schema.Current.CacheController()!.Enabled ? Schema.Current.CacheController()!.RequestByBackReference(retriever, backReference, e.ToLite()).ToVirtualMList() : @@ -242,7 +240,7 @@ public static FluentInclude WithVirtualMList(this FluentInclude fi, //You can do a VirtualMList to itself at the table level, but there should not be cycles inside the instances var toDelete = Database.Query().Where(se => query.Any(e => backReference.Evaluate(se).Is(e))); - if (lazyDelete.Value) + if (defLazyDelete) { if (toDelete.Any()) toDelete.UnsafeDelete(); diff --git a/Signum.Engine/Retriever.cs b/Signum.Engine/Retriever.cs index eba81a4d62..fbff836006 100644 --- a/Signum.Engine/Retriever.cs +++ b/Signum.Engine/Retriever.cs @@ -131,7 +131,7 @@ bool TryGetRequest((Type type, PrimaryKey id) key, out Entity value) if (id == null) return null; - Type type = TypeLogic.IdToType[typeId.Value]; + Type type = TypeLogic.IdToType[typeId!.Value]; var parsedId = PrimaryKey.Parse(id, type); @@ -312,7 +312,7 @@ static async Task> GetStrings(List else if (token != null) { var tasks = ids.GroupsOf(Schema.Current.Settings.MaxNumberOfParameters) - .Select(gr => Database.Query().Where(e => gr.Contains(e.Id)).Select(a => KVP.Create(a.Id, a.ToString())).ToListAsync(token.Value)) + .Select(gr => Database.Query().Where(e => gr.Contains(e.Id)).Select(a => KVP.Create(a.Id, a.ToString())).ToListAsync(token!.Value)) .ToList(); var list = await Task.WhenAll(tasks); diff --git a/Signum.Engine/Schema/Schema.Delete.cs b/Signum.Engine/Schema/Schema.Delete.cs index 41561cf92e..8064bfd690 100644 --- a/Signum.Engine/Schema/Schema.Delete.cs +++ b/Signum.Engine/Schema/Schema.Delete.cs @@ -36,7 +36,7 @@ private SqlPreCommand DeclarePrimaryKeyVariable(T entity, Expression().Where(where).Select(a => a.Id).Expression); string variableName = SqlParameterBuilder.GetParameterName(this.Name.Name + "Id_" + (parameterIndex++)); - entity.SetId(new Entities.PrimaryKey(entity.id.Value.Object, variableName)); + entity.SetId(new Entities.PrimaryKey(entity.id!.Value.Object, variableName)); string queryString = query.PlainSql().Lines().ToString(" "); diff --git a/Signum.Engine/Schema/Schema.Save.cs b/Signum.Engine/Schema/Schema.Save.cs index b2f37c0c97..154a57fe6d 100644 --- a/Signum.Engine/Schema/Schema.Save.cs +++ b/Signum.Engine/Schema/Schema.Save.cs @@ -1,104 +1,104 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Signum.Entities; -using Signum.Utilities; -using Signum.Entities.Reflection; -using System.Linq.Expressions; -using System.Reflection; -using Signum.Utilities.Reflection; -using System.Data; -using Signum.Utilities.ExpressionTrees; -using System.Text; -using Signum.Utilities.DataStructures; -using System.Data.Common; -using System.Collections.Concurrent; -using Signum.Engine.Basics; - -namespace Signum.Engine.Maps -{ - public struct Forbidden - { - public Forbidden(HashSet? set) - { - this.set = set; - } - - public Forbidden(DirectedGraph? graph, Entity entity) - { - this.set = graph?.TryRelatedTo(entity); - } - - readonly HashSet? set; - - public bool IsEmpty - { - get { return set == null || set.Count == 0; } - } - - public bool Contains(Entity entity) - { - return set != null && set.Contains(entity); - } - } - - public struct EntityForbidden - { - public readonly Entity Entity; - public readonly Forbidden Forbidden; - - public EntityForbidden(Entity entity, Forbidden forbidden) - { - this.Entity = (Entity)entity; - this.Forbidden = forbidden; - } - - public EntityForbidden(Entity entity, DirectedGraph? graph) - { - this.Entity = (Entity)entity; - this.Forbidden = new Forbidden(graph, entity); - } - } - - public partial class Table - { - ResetLazy inserterIdentity; - ResetLazy inserterDisableIdentity; - - internal void InsertMany(List list, DirectedGraph? backEdges) - { - using (HeavyProfiler.LogNoStackTrace("InsertMany", () => this.Type.TypeName())) - { - if (IdentityBehaviour) - { - InsertCacheIdentity ic = inserterIdentity.Value; - list.SplitStatements(this.Columns.Count, ls => ic.GetInserter(ls.Count)(ls, backEdges)); - } - else - { - InsertCacheDisableIdentity ic = inserterDisableIdentity.Value; - list.SplitStatements(this.Columns.Count, ls => ic.GetInserter(ls.Count)(ls, backEdges)); - } - } - } - - internal object[] BulkInsertDataRow(object/*Entity or IView*/ entity) - { - var parameters = IdentityBehaviour ? - inserterIdentity.Value.InsertParameters((Entity)entity, new Forbidden(), "") : - inserterDisableIdentity.Value.InsertParameters(entity, new Forbidden(), ""); - - return parameters.Select(a => a.Value).ToArray(); - } - - class InsertCacheDisableIdentity - { - internal Table table; - - public Func SqlInsertPattern; - public Func> InsertParameters; - - ConcurrentDictionary, DirectedGraph?>> insertDisableIdentityCache = +using System; +using System.Collections.Generic; +using System.Linq; +using Signum.Entities; +using Signum.Utilities; +using Signum.Entities.Reflection; +using System.Linq.Expressions; +using System.Reflection; +using Signum.Utilities.Reflection; +using System.Data; +using Signum.Utilities.ExpressionTrees; +using System.Text; +using Signum.Utilities.DataStructures; +using System.Data.Common; +using System.Collections.Concurrent; +using Signum.Engine.Basics; + +namespace Signum.Engine.Maps +{ + public struct Forbidden + { + public Forbidden(HashSet? set) + { + this.set = set; + } + + public Forbidden(DirectedGraph? graph, Entity entity) + { + this.set = graph?.TryRelatedTo(entity); + } + + readonly HashSet? set; + + public bool IsEmpty + { + get { return set == null || set.Count == 0; } + } + + public bool Contains(Entity entity) + { + return set != null && set.Contains(entity); + } + } + + public struct EntityForbidden + { + public readonly Entity Entity; + public readonly Forbidden Forbidden; + + public EntityForbidden(Entity entity, Forbidden forbidden) + { + this.Entity = (Entity)entity; + this.Forbidden = forbidden; + } + + public EntityForbidden(Entity entity, DirectedGraph? graph) + { + this.Entity = (Entity)entity; + this.Forbidden = new Forbidden(graph, entity); + } + } + + public partial class Table + { + ResetLazy inserterIdentity; + ResetLazy inserterDisableIdentity; + + internal void InsertMany(List list, DirectedGraph? backEdges) + { + using (HeavyProfiler.LogNoStackTrace("InsertMany", () => this.Type.TypeName())) + { + if (IdentityBehaviour) + { + InsertCacheIdentity ic = inserterIdentity.Value; + list.SplitStatements(this.Columns.Count, ls => ic.GetInserter(ls.Count)(ls, backEdges)); + } + else + { + InsertCacheDisableIdentity ic = inserterDisableIdentity.Value; + list.SplitStatements(this.Columns.Count, ls => ic.GetInserter(ls.Count)(ls, backEdges)); + } + } + } + + internal object[] BulkInsertDataRow(object/*Entity or IView*/ entity) + { + var parameters = IdentityBehaviour ? + inserterIdentity.Value.InsertParameters((Entity)entity, new Forbidden(), "") : + inserterDisableIdentity.Value.InsertParameters(entity, new Forbidden(), ""); + + return parameters.Select(a => a.Value).ToArray(); + } + + class InsertCacheDisableIdentity + { + internal Table table; + + public Func SqlInsertPattern; + public Func> InsertParameters; + + ConcurrentDictionary, DirectedGraph?>> insertDisableIdentityCache = new ConcurrentDictionary, DirectedGraph?>>(); public InsertCacheDisableIdentity(Table table, Func sqlInsertPattern, Func> insertParameters) @@ -106,115 +106,115 @@ public InsertCacheDisableIdentity(Table table, Func sqlInsertPat this.table = table; SqlInsertPattern = sqlInsertPattern; InsertParameters = insertParameters; - } - - internal Action, DirectedGraph?> GetInserter(int numElements) - { - return insertDisableIdentityCache.GetOrAdd(numElements, (int num) => num == 1 ? GetInsertDisableIdentity() : GetInsertMultiDisableIdentity(num)); - } - - - Action, DirectedGraph?> GetInsertDisableIdentity() - { - string sqlSingle = SqlInsertPattern(""); - - return (list, graph) => - { - Entity entity = list.Single(); - - AssertHasId(entity); - - entity.Ticks = TimeZoneManager.Now.Ticks; - - table.SetToStrField(entity); - - var forbidden = new Forbidden(graph, entity); - - new SqlPreCommandSimple(sqlSingle, InsertParameters(entity, forbidden, "")).ExecuteNonQuery(); - - entity.IsNew = false; - if (table.saveCollections.Value != null) - table.saveCollections.Value.InsertCollections(new List { new EntityForbidden(entity, forbidden) }); - }; - } - - - - Action, DirectedGraph?> GetInsertMultiDisableIdentity(int num) - { - string sqlMulti = Enumerable.Range(0, num).ToString(i => SqlInsertPattern(i.ToString()), ";\r\n"); - - return (entities, graph) => - { - for (int i = 0; i < num; i++) - { - var entity = entities[i]; - AssertHasId(entity); - - entity.Ticks = TimeZoneManager.Now.Ticks; - - table.SetToStrField(entity); - } - - List result = new List(); - for (int i = 0; i < entities.Count; i++) - result.AddRange(InsertParameters(entities[i], new Forbidden(graph, entities[i]), i.ToString())); - - new SqlPreCommandSimple(sqlMulti, result).ExecuteNonQuery(); - for (int i = 0; i < num; i++) - { - Entity ident = entities[i]; - - ident.IsNew = false; - } - - if (table.saveCollections.Value != null) - table.saveCollections.Value.InsertCollections(entities.Select(e => new EntityForbidden(e, graph)).ToList()); - }; - } - - internal static InsertCacheDisableIdentity InitializeInsertDisableIdentity(Table table) - { - using (HeavyProfiler.LogNoStackTrace("InitializeInsertDisableIdentity", () => table.Type.TypeName())) - { - var trios = new List(); - var assigments = new List(); - var paramIdent = Expression.Parameter(typeof(object) /*Entity*/, "ident"); - var paramForbidden = Expression.Parameter(typeof(Forbidden), "forbidden"); - var paramSuffix = Expression.Parameter(typeof(string), "suffix"); - - var cast = Expression.Parameter(table.Type, "casted"); - assigments.Add(Expression.Assign(cast, Expression.Convert(paramIdent, table.Type))); - - foreach (var item in table.Fields.Values) - item.Field.CreateParameter(trios, assigments, Expression.Field(cast, item.FieldInfo), paramForbidden, paramSuffix); - - if (table.Mixins != null) - foreach (var item in table.Mixins.Values) - item.CreateParameter(trios, assigments, cast, paramForbidden, paramSuffix); - - Func insertPattern = (suffix) => - "INSERT {0} ({1})\r\n VALUES ({2})".FormatWith(table.Name, - trios.ToString(p => p.SourceColumn.SqlEscape(), ", "), - trios.ToString(p => p.ParameterName + suffix, ", ")); - - var expr = Expression.Lambda>>( - CreateBlock(trios.Select(a => a.ParameterBuilder), assigments), paramIdent, paramForbidden, paramSuffix); - - - return new InsertCacheDisableIdentity(table, insertPattern, expr.Compile()); - } - } - } - - class InsertCacheIdentity - { - internal Table table; - - public Func SqlInsertPattern; - public Func> InsertParameters; - - ConcurrentDictionary, DirectedGraph?>> insertIdentityCache = + } + + internal Action, DirectedGraph?> GetInserter(int numElements) + { + return insertDisableIdentityCache.GetOrAdd(numElements, (int num) => num == 1 ? GetInsertDisableIdentity() : GetInsertMultiDisableIdentity(num)); + } + + + Action, DirectedGraph?> GetInsertDisableIdentity() + { + string sqlSingle = SqlInsertPattern(""); + + return (list, graph) => + { + Entity entity = list.Single(); + + AssertHasId(entity); + + entity.Ticks = TimeZoneManager.Now.Ticks; + + table.SetToStrField(entity); + + var forbidden = new Forbidden(graph, entity); + + new SqlPreCommandSimple(sqlSingle, InsertParameters(entity, forbidden, "")).ExecuteNonQuery(); + + entity.IsNew = false; + if (table.saveCollections.Value != null) + table.saveCollections.Value.InsertCollections(new List { new EntityForbidden(entity, forbidden) }); + }; + } + + + + Action, DirectedGraph?> GetInsertMultiDisableIdentity(int num) + { + string sqlMulti = Enumerable.Range(0, num).ToString(i => SqlInsertPattern(i.ToString()), ";\r\n"); + + return (entities, graph) => + { + for (int i = 0; i < num; i++) + { + var entity = entities[i]; + AssertHasId(entity); + + entity.Ticks = TimeZoneManager.Now.Ticks; + + table.SetToStrField(entity); + } + + List result = new List(); + for (int i = 0; i < entities.Count; i++) + result.AddRange(InsertParameters(entities[i], new Forbidden(graph, entities[i]), i.ToString())); + + new SqlPreCommandSimple(sqlMulti, result).ExecuteNonQuery(); + for (int i = 0; i < num; i++) + { + Entity ident = entities[i]; + + ident.IsNew = false; + } + + if (table.saveCollections.Value != null) + table.saveCollections.Value.InsertCollections(entities.Select(e => new EntityForbidden(e, graph)).ToList()); + }; + } + + internal static InsertCacheDisableIdentity InitializeInsertDisableIdentity(Table table) + { + using (HeavyProfiler.LogNoStackTrace("InitializeInsertDisableIdentity", () => table.Type.TypeName())) + { + var trios = new List(); + var assigments = new List(); + var paramIdent = Expression.Parameter(typeof(object) /*Entity*/, "ident"); + var paramForbidden = Expression.Parameter(typeof(Forbidden), "forbidden"); + var paramSuffix = Expression.Parameter(typeof(string), "suffix"); + + var cast = Expression.Parameter(table.Type, "casted"); + assigments.Add(Expression.Assign(cast, Expression.Convert(paramIdent, table.Type))); + + foreach (var item in table.Fields.Values) + item.Field.CreateParameter(trios, assigments, Expression.Field(cast, item.FieldInfo), paramForbidden, paramSuffix); + + if (table.Mixins != null) + foreach (var item in table.Mixins.Values) + item.CreateParameter(trios, assigments, cast, paramForbidden, paramSuffix); + + Func insertPattern = (suffix) => + "INSERT {0} ({1})\r\n VALUES ({2})".FormatWith(table.Name, + trios.ToString(p => p.SourceColumn.SqlEscape(), ", "), + trios.ToString(p => p.ParameterName + suffix, ", ")); + + var expr = Expression.Lambda>>( + CreateBlock(trios.Select(a => a.ParameterBuilder), assigments), paramIdent, paramForbidden, paramSuffix); + + + return new InsertCacheDisableIdentity(table, insertPattern, expr.Compile()); + } + } + } + + class InsertCacheIdentity + { + internal Table table; + + public Func SqlInsertPattern; + public Func> InsertParameters; + + ConcurrentDictionary, DirectedGraph?>> insertIdentityCache = new ConcurrentDictionary, DirectedGraph?>>(); public InsertCacheIdentity(Table table, Func sqlInsertPattern, Func> insertParameters) @@ -224,152 +224,152 @@ public InsertCacheIdentity(Table table, Func sqlInsertPatt InsertParameters = insertParameters; } - internal Action, DirectedGraph?> GetInserter(int numElements) - { - return insertIdentityCache.GetOrAdd(numElements, (int num) => GetInsertMultiIdentity(num)); - } - - Action, DirectedGraph?> GetInsertMultiIdentity(int num) - { - string sqlMulti = new StringBuilder() - .AppendLine("DECLARE @MyTable TABLE (Id " + this.table.PrimaryKey.SqlDbType.ToString().ToUpperInvariant() + ");") - .AppendLines(Enumerable.Range(0, num).Select(i => SqlInsertPattern(i.ToString(), true))) - .AppendLine("SELECT Id from @MyTable").ToString(); - - return (entities, graph) => - { - for (int i = 0; i < num; i++) - { - var entity = entities[i]; - AssertNoId(entity); - - entity.Ticks = TimeZoneManager.Now.Ticks; - - table.SetToStrField(entity); - } - - List result = new List(); - for (int i = 0; i < entities.Count; i++) - result.AddRange(InsertParameters(entities[i], new Forbidden(graph, entities[i]), i.ToString())); - - DataTable dt = new SqlPreCommandSimple(sqlMulti, result).ExecuteDataTable(); - - for (int i = 0; i < num; i++) - { - Entity ident = entities[i]; - - ident.id = new PrimaryKey((IComparable)dt.Rows[i][0]); - ident.IsNew = false; - } - - if (table.saveCollections.Value != null) - table.saveCollections.Value.InsertCollections(entities.Select(e => new EntityForbidden(e, graph)).ToList()); - }; - - } - - internal static InsertCacheIdentity InitializeInsertIdentity(Table table) - { - using (HeavyProfiler.LogNoStackTrace("InitializeInsertIdentity", () => table.Type.TypeName())) - { - var trios = new List(); - var assigments = new List(); - var paramIdent = Expression.Parameter(typeof(Entity), "ident"); - var paramForbidden = Expression.Parameter(typeof(Forbidden), "forbidden"); - var paramSuffix = Expression.Parameter(typeof(string), "suffix"); - - var cast = Expression.Parameter(table.Type, "casted"); - assigments.Add(Expression.Assign(cast, Expression.Convert(paramIdent, table.Type))); - - foreach (var item in table.Fields.Values.Where(a => !(a.Field is FieldPrimaryKey))) - item.Field.CreateParameter(trios, assigments, Expression.Field(cast, item.FieldInfo), paramForbidden, paramSuffix); - - if (table.Mixins != null) - foreach (var item in table.Mixins.Values) - item.CreateParameter(trios, assigments, cast, paramForbidden, paramSuffix); - - Func sqlInsertPattern = (suffix, output) => - "INSERT {0} ({1})\r\n{2} VALUES ({3})".FormatWith(table.Name, - trios.ToString(p => p.SourceColumn.SqlEscape(), ", "), - output ? "OUTPUT INSERTED.Id into @MyTable \r\n" : null, - trios.ToString(p => p.ParameterName + suffix, ", ")); - - - var expr = Expression.Lambda>>( - CreateBlock(trios.Select(a => a.ParameterBuilder), assigments), paramIdent, paramForbidden, paramSuffix); - - return new InsertCacheIdentity(table, sqlInsertPattern, expr.Compile()); - } - } + internal Action, DirectedGraph?> GetInserter(int numElements) + { + return insertIdentityCache.GetOrAdd(numElements, (int num) => GetInsertMultiIdentity(num)); + } + + Action, DirectedGraph?> GetInsertMultiIdentity(int num) + { + string sqlMulti = new StringBuilder() + .AppendLine("DECLARE @MyTable TABLE (Id " + this.table.PrimaryKey.SqlDbType.ToString().ToUpperInvariant() + ");") + .AppendLines(Enumerable.Range(0, num).Select(i => SqlInsertPattern(i.ToString(), true))) + .AppendLine("SELECT Id from @MyTable").ToString(); + + return (entities, graph) => + { + for (int i = 0; i < num; i++) + { + var entity = entities[i]; + AssertNoId(entity); + + entity.Ticks = TimeZoneManager.Now.Ticks; + + table.SetToStrField(entity); + } + + List result = new List(); + for (int i = 0; i < entities.Count; i++) + result.AddRange(InsertParameters(entities[i], new Forbidden(graph, entities[i]), i.ToString())); + + DataTable dt = new SqlPreCommandSimple(sqlMulti, result).ExecuteDataTable(); + + for (int i = 0; i < num; i++) + { + Entity ident = entities[i]; + + ident.id = new PrimaryKey((IComparable)dt.Rows[i][0]); + ident.IsNew = false; + } + + if (table.saveCollections.Value != null) + table.saveCollections.Value.InsertCollections(entities.Select(e => new EntityForbidden(e, graph)).ToList()); + }; + + } + + internal static InsertCacheIdentity InitializeInsertIdentity(Table table) + { + using (HeavyProfiler.LogNoStackTrace("InitializeInsertIdentity", () => table.Type.TypeName())) + { + var trios = new List(); + var assigments = new List(); + var paramIdent = Expression.Parameter(typeof(Entity), "ident"); + var paramForbidden = Expression.Parameter(typeof(Forbidden), "forbidden"); + var paramSuffix = Expression.Parameter(typeof(string), "suffix"); + + var cast = Expression.Parameter(table.Type, "casted"); + assigments.Add(Expression.Assign(cast, Expression.Convert(paramIdent, table.Type))); + + foreach (var item in table.Fields.Values.Where(a => !(a.Field is FieldPrimaryKey))) + item.Field.CreateParameter(trios, assigments, Expression.Field(cast, item.FieldInfo), paramForbidden, paramSuffix); + + if (table.Mixins != null) + foreach (var item in table.Mixins.Values) + item.CreateParameter(trios, assigments, cast, paramForbidden, paramSuffix); + + Func sqlInsertPattern = (suffix, output) => + "INSERT {0} ({1})\r\n{2} VALUES ({3})".FormatWith(table.Name, + trios.ToString(p => p.SourceColumn.SqlEscape(), ", "), + output ? "OUTPUT INSERTED.Id into @MyTable \r\n" : null, + trios.ToString(p => p.ParameterName + suffix, ", ")); + + + var expr = Expression.Lambda>>( + CreateBlock(trios.Select(a => a.ParameterBuilder), assigments), paramIdent, paramForbidden, paramSuffix); + + return new InsertCacheIdentity(table, sqlInsertPattern, expr.Compile()); + } + } + } + + static void AssertHasId(Entity ident) + { + if (ident.IdOrNull == null) + throw new InvalidOperationException("{0} should have an Id, since the table has no Identity".FormatWith(ident, ident.IdOrNull)); + } + + static void AssertNoId(Entity ident) + { + if (ident.IdOrNull != null) + throw new InvalidOperationException("{0} is new, but has Id {1}".FormatWith(ident, ident.IdOrNull)); + } + + + public IColumn? ToStrColumn + { + get + { + + if (Fields.TryGetValue("toStr", out EntityField entity)) + return (IColumn)entity.Field; + + return null; + } } - - static void AssertHasId(Entity ident) - { - if (ident.IdOrNull == null) - throw new InvalidOperationException("{0} should have an Id, since the table has no Identity".FormatWith(ident, ident.IdOrNull)); - } - - static void AssertNoId(Entity ident) - { - if (ident.IdOrNull != null) - throw new InvalidOperationException("{0} is new, but has Id {1}".FormatWith(ident, ident.IdOrNull)); - } - - - public IColumn? ToStrColumn - { - get - { - - if (Fields.TryGetValue("toStr", out EntityField entity)) - return (IColumn)entity.Field; - - return null; - } - } - - internal bool SetToStrField(Entity entity) - { - var toStrColumn = ToStrColumn; - if (toStrColumn != null) - { - string newStr; - using (CultureInfoUtils.ChangeCultureUI(Schema.Current.ForceCultureInfo)) - newStr = entity.ToString(); - - if (newStr.HasText() && toStrColumn.Size.HasValue && newStr.Length > toStrColumn.Size) - newStr = newStr.Substring(0, toStrColumn.Size.Value); - - if (entity.toStr != newStr) - { - entity.toStr = newStr; - return true; - } - } - - return false; - } - - - internal static FieldInfo fiId = ReflectionTools.GetFieldInfo((Entity i) => i.id); - - internal void UpdateMany(List list, DirectedGraph? backEdges) - { - using (HeavyProfiler.LogNoStackTrace("UpdateMany", () => this.Type.TypeName())) - { - var uc = updater.Value; - list.SplitStatements(this.Columns.Count + 2, ls => uc.GetUpdater(ls.Count)(ls, backEdges)); - } - } - - class UpdateCache - { - internal Table table; - - public Func SqlUpdatePattern; - public Func> UpdateParameters; - - ConcurrentDictionary, DirectedGraph?>> updateCache = + + internal bool SetToStrField(Entity entity) + { + var toStrColumn = ToStrColumn; + if (toStrColumn != null) + { + string newStr; + using (CultureInfoUtils.ChangeCultureUI(Schema.Current.ForceCultureInfo)) + newStr = entity.ToString(); + + if (newStr.HasText() && toStrColumn.Size.HasValue && newStr.Length > toStrColumn.Size) + newStr = newStr.Substring(0, toStrColumn.Size.Value); + + if (entity.toStr != newStr) + { + entity.toStr = newStr; + return true; + } + } + + return false; + } + + + internal static FieldInfo fiId = ReflectionTools.GetFieldInfo((Entity i) => i.id); + + internal void UpdateMany(List list, DirectedGraph? backEdges) + { + using (HeavyProfiler.LogNoStackTrace("UpdateMany", () => this.Type.TypeName())) + { + var uc = updater.Value; + list.SplitStatements(this.Columns.Count + 2, ls => uc.GetUpdater(ls.Count)(ls, backEdges)); + } + } + + class UpdateCache + { + internal Table table; + + public Func SqlUpdatePattern; + public Func> UpdateParameters; + + ConcurrentDictionary, DirectedGraph?>> updateCache = new ConcurrentDictionary, DirectedGraph?>>(); public UpdateCache(Table table, Func sqlUpdatePattern, Func> updateParameters) @@ -377,189 +377,189 @@ public UpdateCache(Table table, Func sqlUpdatePattern, Fun this.table = table; SqlUpdatePattern = sqlUpdatePattern; UpdateParameters = updateParameters; - } - - public Action, DirectedGraph?> GetUpdater(int numElements) - { - return updateCache.GetOrAdd(numElements, num => num == 1 ? GenerateUpdate() : GetUpdateMultiple(num)); - } - - Action, DirectedGraph?> GenerateUpdate() - { - string sqlUpdate = SqlUpdatePattern("", false); - - if (table.Ticks != null) - { - return (uniList, graph) => - { - Entity ident = uniList.Single(); - Entity entity = (Entity)ident; - - long oldTicks = entity.Ticks; - entity.Ticks = TimeZoneManager.Now.Ticks; - - table.SetToStrField(ident); - - var forbidden = new Forbidden(graph, ident); - - int num = (int)new SqlPreCommandSimple(sqlUpdate, UpdateParameters(ident, oldTicks, forbidden, "")).ExecuteNonQuery(); - if (num != 1) - throw new ConcurrencyException(ident.GetType(), ident.Id); - - if (table.saveCollections.Value != null) - table.saveCollections.Value.UpdateCollections(new List { new EntityForbidden(ident, forbidden) }); - }; - } - else - { - return (uniList, graph) => - { - Entity ident = uniList.Single(); - - table.SetToStrField(ident); - - var forbidden = new Forbidden(graph, ident); - - int num = (int)new SqlPreCommandSimple(sqlUpdate, UpdateParameters(ident, -1, forbidden, "")).ExecuteNonQuery(); - if (num != 1) - throw new EntityNotFoundException(ident.GetType(), ident.Id); - }; - } - } - - Action, DirectedGraph?> GetUpdateMultiple(int num) - { - string sqlMulti = new StringBuilder() - .AppendLine("DECLARE @NotFound TABLE (Id " + this.table.PrimaryKey.SqlDbType.ToString().ToUpperInvariant() + ");") - .AppendLines(Enumerable.Range(0, num).Select(i => SqlUpdatePattern(i.ToString(), true))) - .AppendLine("SELECT Id from @NotFound").ToString(); - - if (table.Ticks != null) - { - return (idents, graph) => - { - List parameters = new List(); - for (int i = 0; i < num; i++) - { - Entity entity = (Entity)idents[i]; - - long oldTicks = entity.Ticks; - entity.Ticks = TimeZoneManager.Now.Ticks; - - parameters.AddRange(UpdateParameters(entity, oldTicks, new Forbidden(graph, entity), i.ToString())); - } - - DataTable dt = new SqlPreCommandSimple(sqlMulti, parameters).ExecuteDataTable(); - - if (dt.Rows.Count > 0) - throw new ConcurrencyException(table.Type, dt.Rows.Cast().Select(r => new PrimaryKey((IComparable)r[0])).ToArray()); - - if (table.saveCollections.Value != null) - table.saveCollections.Value.UpdateCollections(idents.Select(e => new EntityForbidden(e, new Forbidden(graph, e))).ToList()); - }; - } - else - { - return (idents, graph) => - { - List parameters = new List(); - for (int i = 0; i < num; i++) - { - var ident = idents[i]; - parameters.AddRange(UpdateParameters(ident, -1, new Forbidden(graph, ident), i.ToString())); - } - - DataTable dt = new SqlPreCommandSimple(sqlMulti, parameters).ExecuteDataTable(); - - if (dt.Rows.Count > 0) - throw new EntityNotFoundException(table.Type, dt.Rows.Cast().Select(r => new PrimaryKey((IComparable)r[0])).ToArray()); - - for (int i = 0; i < num; i++) - { - Entity ident = idents[i]; - } - - if (table.saveCollections.Value != null) - table.saveCollections.Value.UpdateCollections(idents.Select(e => new EntityForbidden(e, new Forbidden(graph, e))).ToList()); - }; - } - } - - internal static UpdateCache InitializeUpdate(Table table) - { - using (HeavyProfiler.LogNoStackTrace("InitializeUpdate", () => table.Type.TypeName())) - { - var trios = new List(); - var assigments = new List(); - var paramIdent = Expression.Parameter(typeof(Entity), "ident"); - var paramForbidden = Expression.Parameter(typeof(Forbidden), "forbidden"); - var paramOldTicks = Expression.Parameter(typeof(long), "oldTicks"); - var paramSuffix = Expression.Parameter(typeof(string), "suffix"); - - var cast = Expression.Parameter(table.Type); - assigments.Add(Expression.Assign(cast, Expression.Convert(paramIdent, table.Type))); - - foreach (var item in table.Fields.Values.Where(a => !(a.Field is FieldPrimaryKey))) - item.Field.CreateParameter(trios, assigments, Expression.Field(cast, item.FieldInfo), paramForbidden, paramSuffix); - - if (table.Mixins != null) - foreach (var item in table.Mixins.Values) - item.CreateParameter(trios, assigments, cast, paramForbidden, paramSuffix); - - var pb = Connector.Current.ParameterBuilder; - - string idParamName = ParameterBuilder.GetParameterName("id"); - - string oldTicksParamName = ParameterBuilder.GetParameterName("old_ticks"); - - Func sqlUpdatePattern = (suffix, output) => - { - string update = "UPDATE {0} SET \r\n{1}\r\n WHERE {2} = {3}".FormatWith( - table.Name, - trios.ToString(p => "{0} = {1}".FormatWith(p.SourceColumn.SqlEscape(), p.ParameterName + suffix).Indent(2), ",\r\n"), - table.PrimaryKey.Name.SqlEscape(), - idParamName + suffix); - - - if (table.Ticks != null) - update += " AND {0} = {1}".FormatWith(table.Ticks.Name.SqlEscape(), oldTicksParamName + suffix); - - if (!output) - return update; - else - return update + "\r\nIF @@ROWCOUNT = 0 INSERT INTO @NotFound (id) VALUES ({0})".FormatWith(idParamName + suffix); - }; - - List parameters = new List(); - - parameters.Add(pb.ParameterFactory(Trio.Concat(idParamName, paramSuffix), table.PrimaryKey.SqlDbType, null, false, - Expression.Field(Expression.Property(Expression.Field(paramIdent, fiId), "Value"), "Object"))); - - if (table.Ticks != null) - { - parameters.Add(pb.ParameterFactory(Trio.Concat(oldTicksParamName, paramSuffix), table.Ticks.SqlDbType, null, false, table.Ticks.ConvertTicks(paramOldTicks))); - } - - parameters.AddRange(trios.Select(a => (Expression)a.ParameterBuilder)); - - var expr = Expression.Lambda>>( - CreateBlock(parameters, assigments), paramIdent, paramOldTicks, paramForbidden, paramSuffix); - - - return new UpdateCache(table, sqlUpdatePattern, expr.Compile()); - } - } - - } - - ResetLazy updater; - - - class CollectionsCache - { - public Func InsertCollectionsSync; - - public Action> InsertCollections; + } + + public Action, DirectedGraph?> GetUpdater(int numElements) + { + return updateCache.GetOrAdd(numElements, num => num == 1 ? GenerateUpdate() : GetUpdateMultiple(num)); + } + + Action, DirectedGraph?> GenerateUpdate() + { + string sqlUpdate = SqlUpdatePattern("", false); + + if (table.Ticks != null) + { + return (uniList, graph) => + { + Entity ident = uniList.Single(); + Entity entity = (Entity)ident; + + long oldTicks = entity.Ticks; + entity.Ticks = TimeZoneManager.Now.Ticks; + + table.SetToStrField(ident); + + var forbidden = new Forbidden(graph, ident); + + int num = (int)new SqlPreCommandSimple(sqlUpdate, UpdateParameters(ident, oldTicks, forbidden, "")).ExecuteNonQuery(); + if (num != 1) + throw new ConcurrencyException(ident.GetType(), ident.Id); + + if (table.saveCollections.Value != null) + table.saveCollections.Value.UpdateCollections(new List { new EntityForbidden(ident, forbidden) }); + }; + } + else + { + return (uniList, graph) => + { + Entity ident = uniList.Single(); + + table.SetToStrField(ident); + + var forbidden = new Forbidden(graph, ident); + + int num = (int)new SqlPreCommandSimple(sqlUpdate, UpdateParameters(ident, -1, forbidden, "")).ExecuteNonQuery(); + if (num != 1) + throw new EntityNotFoundException(ident.GetType(), ident.Id); + }; + } + } + + Action, DirectedGraph?> GetUpdateMultiple(int num) + { + string sqlMulti = new StringBuilder() + .AppendLine("DECLARE @NotFound TABLE (Id " + this.table.PrimaryKey.SqlDbType.ToString().ToUpperInvariant() + ");") + .AppendLines(Enumerable.Range(0, num).Select(i => SqlUpdatePattern(i.ToString(), true))) + .AppendLine("SELECT Id from @NotFound").ToString(); + + if (table.Ticks != null) + { + return (idents, graph) => + { + List parameters = new List(); + for (int i = 0; i < num; i++) + { + Entity entity = (Entity)idents[i]; + + long oldTicks = entity.Ticks; + entity.Ticks = TimeZoneManager.Now.Ticks; + + parameters.AddRange(UpdateParameters(entity, oldTicks, new Forbidden(graph, entity), i.ToString())); + } + + DataTable dt = new SqlPreCommandSimple(sqlMulti, parameters).ExecuteDataTable(); + + if (dt.Rows.Count > 0) + throw new ConcurrencyException(table.Type, dt.Rows.Cast().Select(r => new PrimaryKey((IComparable)r[0])).ToArray()); + + if (table.saveCollections.Value != null) + table.saveCollections.Value.UpdateCollections(idents.Select(e => new EntityForbidden(e, new Forbidden(graph, e))).ToList()); + }; + } + else + { + return (idents, graph) => + { + List parameters = new List(); + for (int i = 0; i < num; i++) + { + var ident = idents[i]; + parameters.AddRange(UpdateParameters(ident, -1, new Forbidden(graph, ident), i.ToString())); + } + + DataTable dt = new SqlPreCommandSimple(sqlMulti, parameters).ExecuteDataTable(); + + if (dt.Rows.Count > 0) + throw new EntityNotFoundException(table.Type, dt.Rows.Cast().Select(r => new PrimaryKey((IComparable)r[0])).ToArray()); + + for (int i = 0; i < num; i++) + { + Entity ident = idents[i]; + } + + if (table.saveCollections.Value != null) + table.saveCollections.Value.UpdateCollections(idents.Select(e => new EntityForbidden(e, new Forbidden(graph, e))).ToList()); + }; + } + } + + internal static UpdateCache InitializeUpdate(Table table) + { + using (HeavyProfiler.LogNoStackTrace("InitializeUpdate", () => table.Type.TypeName())) + { + var trios = new List(); + var assigments = new List(); + var paramIdent = Expression.Parameter(typeof(Entity), "ident"); + var paramForbidden = Expression.Parameter(typeof(Forbidden), "forbidden"); + var paramOldTicks = Expression.Parameter(typeof(long), "oldTicks"); + var paramSuffix = Expression.Parameter(typeof(string), "suffix"); + + var cast = Expression.Parameter(table.Type); + assigments.Add(Expression.Assign(cast, Expression.Convert(paramIdent, table.Type))); + + foreach (var item in table.Fields.Values.Where(a => !(a.Field is FieldPrimaryKey))) + item.Field.CreateParameter(trios, assigments, Expression.Field(cast, item.FieldInfo), paramForbidden, paramSuffix); + + if (table.Mixins != null) + foreach (var item in table.Mixins.Values) + item.CreateParameter(trios, assigments, cast, paramForbidden, paramSuffix); + + var pb = Connector.Current.ParameterBuilder; + + string idParamName = ParameterBuilder.GetParameterName("id"); + + string oldTicksParamName = ParameterBuilder.GetParameterName("old_ticks"); + + Func sqlUpdatePattern = (suffix, output) => + { + string update = "UPDATE {0} SET \r\n{1}\r\n WHERE {2} = {3}".FormatWith( + table.Name, + trios.ToString(p => "{0} = {1}".FormatWith(p.SourceColumn.SqlEscape(), p.ParameterName + suffix).Indent(2), ",\r\n"), + table.PrimaryKey.Name.SqlEscape(), + idParamName + suffix); + + + if (table.Ticks != null) + update += " AND {0} = {1}".FormatWith(table.Ticks.Name.SqlEscape(), oldTicksParamName + suffix); + + if (!output) + return update; + else + return update + "\r\nIF @@ROWCOUNT = 0 INSERT INTO @NotFound (id) VALUES ({0})".FormatWith(idParamName + suffix); + }; + + List parameters = new List(); + + parameters.Add(pb.ParameterFactory(Trio.Concat(idParamName, paramSuffix), table.PrimaryKey.SqlDbType, null, false, + Expression.Field(Expression.Property(Expression.Field(paramIdent, fiId), "Value"), "Object"))); + + if (table.Ticks != null) + { + parameters.Add(pb.ParameterFactory(Trio.Concat(oldTicksParamName, paramSuffix), table.Ticks.SqlDbType, null, false, table.Ticks.ConvertTicks(paramOldTicks))); + } + + parameters.AddRange(trios.Select(a => (Expression)a.ParameterBuilder)); + + var expr = Expression.Lambda>>( + CreateBlock(parameters, assigments), paramIdent, paramOldTicks, paramForbidden, paramSuffix); + + + return new UpdateCache(table, sqlUpdatePattern, expr.Compile()); + } + } + + } + + ResetLazy updater; + + + class CollectionsCache + { + public Func InsertCollectionsSync; + + public Action> InsertCollections; public Action> UpdateCollections; public CollectionsCache(Func insertCollectionsSync, @@ -571,889 +571,889 @@ public CollectionsCache(Func insertCollecti UpdateCollections = updateCollections; } - internal static CollectionsCache? InitializeCollections(Table table) - { - using (HeavyProfiler.LogNoStackTrace("InitializeCollections", () => table.Type.TypeName())) - { - var caches = - (from rt in table.TablesMList() - select rt.cache.Value).ToList(); - - if (caches.IsEmpty()) - return null; - else - { + internal static CollectionsCache? InitializeCollections(Table table) + { + using (HeavyProfiler.LogNoStackTrace("InitializeCollections", () => table.Type.TypeName())) + { + var caches = + (from rt in table.TablesMList() + select rt.cache.Value).ToList(); + + if (caches.IsEmpty()) + return null; + else + { return new CollectionsCache( - insertCollections: (entities) => - { - foreach (var rc in caches) - rc.RelationalInserts(entities); + insertCollections: (entities) => + { + foreach (var rc in caches) + rc.RelationalInserts(entities); }, updateCollections: (entities) => { foreach (var rc in caches) rc.RelationalUpdates(entities); }, - insertCollectionsSync: (ident, suffix, replaceParameter) => - caches.Select((rc, i) => rc.RelationalUpdateSync(ident, suffix + "_" + i.ToString(), replaceParameter)).Combine(Spacing.Double)! - ); - } - } - } - } - - ResetLazy saveCollections; - - - public SqlPreCommand InsertSqlSync(Entity ident, bool includeCollections = true, string? comment = null, string suffix = "") - { - PrepareEntitySync(ident); - SetToStrField(ident); - - SqlPreCommandSimple insert = IdentityBehaviour ? - new SqlPreCommandSimple( - inserterIdentity.Value.SqlInsertPattern(suffix, false), - inserterIdentity.Value.InsertParameters(ident, new Forbidden(), suffix)).AddComment(comment) : - new SqlPreCommandSimple( - inserterDisableIdentity.Value.SqlInsertPattern(suffix), - inserterDisableIdentity.Value.InsertParameters(ident, new Forbidden(), suffix)).AddComment(comment); - - if (!includeCollections) - return insert; - - var cc = saveCollections.Value; - if (cc == null) - return insert; - - SqlPreCommand collections = cc.InsertCollectionsSync((Entity)ident, suffix, false); - - if (collections == null) - return insert; - - SqlPreCommand declareParent = new SqlPreCommandSimple("DECLARE @parentId INT") { GoBefore = true }; - - SqlPreCommand setParent = new SqlPreCommandSimple("SET @parentId = @@Identity"); - - return SqlPreCommand.Combine(Spacing.Simple, declareParent, insert, setParent, collections)!; - } - - public SqlPreCommand? UpdateSqlSync(T entity, Expression>? where, bool includeCollections = true, string? comment = null, string suffix = "") - where T : Entity - { - if (typeof(T) != Type && where != null) - throw new InvalidOperationException("Invalid table"); - - PrepareEntitySync(entity); - - if (SetToStrField(entity)) - entity.SetSelfModified(); - - if (entity.Modified == ModifiedState.Clean || entity.Modified == ModifiedState.Sealed) - return null; - - var uc = updater.Value; - var sql = uc.SqlUpdatePattern(suffix, false); - var parameters = uc.UpdateParameters(entity, (entity as Entity)?.Ticks ?? -1, new Forbidden(), suffix); - - SqlPreCommand? update; - if (where != null) - { - update = SqlPreCommand.Combine(Spacing.Simple, - DeclarePrimaryKeyVariable(entity, where), - new SqlPreCommandSimple(sql, parameters).AddComment(comment).ReplaceFirstParameter(entity.Id.VariableName)); - } - else - { - update = new SqlPreCommandSimple(sql, parameters).AddComment(comment); - } - - if (!includeCollections) - return update; - - var cc = saveCollections.Value; - if (cc == null) - return update; - - SqlPreCommand collections = cc.InsertCollectionsSync((Entity)entity, suffix, where != null); - - return SqlPreCommand.Combine(Spacing.Simple, update, collections); - } - - void PrepareEntitySync(Entity entity) - { - Schema current = Schema.Current; - DirectedGraph modifiables = Saver.PreSaving(() => GraphExplorer.FromRoot(entity)); - - var error = GraphExplorer.FullIntegrityCheck(modifiables); - if (error != null) - { -#if DEBUG - throw new IntegrityCheckException(error.WithEntities(modifiables)); -#else - throw new IntegrityCheckException(error); -#endif - } - GraphExplorer.PropagateModifications(modifiables.Inverse()); - } - - public class Trio - { - public Trio(IColumn column, Expression value, Expression suffix) - { - this.SourceColumn = column.Name; - this.ParameterName = Engine.ParameterBuilder.GetParameterName(column.Name); - this.ParameterBuilder = Connector.Current.ParameterBuilder.ParameterFactory(Concat(this.ParameterName, suffix), column.SqlDbType, column.UserDefinedTypeName, column.Nullable.ToBool(), value); - } - - public string SourceColumn; - public string ParameterName; - public MemberInitExpression ParameterBuilder; //Expression - - public override string ToString() - { - return "{0} {1} {2}".FormatWith(SourceColumn, ParameterName, ParameterBuilder.ToString()); - } - - static MethodInfo miConcat = ReflectionTools.GetMethodInfo(() => string.Concat("", "")); - - internal static Expression Concat(string baseName, Expression suffix) - { - return Expression.Call(null, miConcat, Expression.Constant(baseName), suffix); - } - } - - static ConstructorInfo ciNewList = ReflectionTools.GetConstuctorInfo(() => new List(1)); - - public static Expression CreateBlock(IEnumerable parameters, IEnumerable assigments) - { - return Expression.Block(assigments.OfType().Select(a => (ParameterExpression)a.Left), - assigments.And( - Expression.ListInit(Expression.New(ciNewList, Expression.Constant(parameters.Count())), - parameters))); - } - } - - - public partial class TableMList - { - internal interface IMListCache - { - SqlPreCommand? RelationalUpdateSync(Entity parent, string suffix, bool replaceParameter); - void RelationalInserts(List entities); - void RelationalUpdates(List entities); - - object[] BulkInsertDataRow(Entity entity, object value, int order); + insertCollectionsSync: (ident, suffix, replaceParameter) => + caches.Select((rc, i) => rc.RelationalUpdateSync(ident, suffix + "_" + i.ToString(), replaceParameter)).Combine(Spacing.Double)! + ); + } + } + } + } + + ResetLazy saveCollections; + + + public SqlPreCommand InsertSqlSync(Entity ident, bool includeCollections = true, string? comment = null, string suffix = "") + { + PrepareEntitySync(ident); + SetToStrField(ident); + + SqlPreCommandSimple insert = IdentityBehaviour ? + new SqlPreCommandSimple( + inserterIdentity.Value.SqlInsertPattern(suffix, false), + inserterIdentity.Value.InsertParameters(ident, new Forbidden(), suffix)).AddComment(comment) : + new SqlPreCommandSimple( + inserterDisableIdentity.Value.SqlInsertPattern(suffix), + inserterDisableIdentity.Value.InsertParameters(ident, new Forbidden(), suffix)).AddComment(comment); + + if (!includeCollections) + return insert; + + var cc = saveCollections.Value; + if (cc == null) + return insert; + + SqlPreCommand collections = cc.InsertCollectionsSync((Entity)ident, suffix, false); + + if (collections == null) + return insert; + + SqlPreCommand declareParent = new SqlPreCommandSimple("DECLARE @parentId INT") { GoBefore = true }; + + SqlPreCommand setParent = new SqlPreCommandSimple("SET @parentId = @@Identity"); + + return SqlPreCommand.Combine(Spacing.Simple, declareParent, insert, setParent, collections)!; + } + + public SqlPreCommand? UpdateSqlSync(T entity, Expression>? where, bool includeCollections = true, string? comment = null, string suffix = "") + where T : Entity + { + if (typeof(T) != Type && where != null) + throw new InvalidOperationException("Invalid table"); + + PrepareEntitySync(entity); + + if (SetToStrField(entity)) + entity.SetSelfModified(); + + if (entity.Modified == ModifiedState.Clean || entity.Modified == ModifiedState.Sealed) + return null; + + var uc = updater.Value; + var sql = uc.SqlUpdatePattern(suffix, false); + var parameters = uc.UpdateParameters(entity, (entity as Entity)?.Ticks ?? -1, new Forbidden(), suffix); + + SqlPreCommand? update; + if (where != null) + { + update = SqlPreCommand.Combine(Spacing.Simple, + DeclarePrimaryKeyVariable(entity, where), + new SqlPreCommandSimple(sql, parameters).AddComment(comment).ReplaceFirstParameter(entity.Id.VariableName)); + } + else + { + update = new SqlPreCommandSimple(sql, parameters).AddComment(comment); + } + + if (!includeCollections) + return update; + + var cc = saveCollections.Value; + if (cc == null) + return update; + + SqlPreCommand collections = cc.InsertCollectionsSync((Entity)entity, suffix, where != null); + + return SqlPreCommand.Combine(Spacing.Simple, update, collections); + } + + void PrepareEntitySync(Entity entity) + { + Schema current = Schema.Current; + DirectedGraph modifiables = Saver.PreSaving(() => GraphExplorer.FromRoot(entity)); + + var error = GraphExplorer.FullIntegrityCheck(modifiables); + if (error != null) + { +#if DEBUG + throw new IntegrityCheckException(error.WithEntities(modifiables)); +#else + throw new IntegrityCheckException(error); +#endif + } + GraphExplorer.PropagateModifications(modifiables.Inverse()); + } + + public class Trio + { + public Trio(IColumn column, Expression value, Expression suffix) + { + this.SourceColumn = column.Name; + this.ParameterName = Engine.ParameterBuilder.GetParameterName(column.Name); + this.ParameterBuilder = Connector.Current.ParameterBuilder.ParameterFactory(Concat(this.ParameterName, suffix), column.SqlDbType, column.UserDefinedTypeName, column.Nullable.ToBool(), value); + } + + public string SourceColumn; + public string ParameterName; + public MemberInitExpression ParameterBuilder; //Expression + + public override string ToString() + { + return "{0} {1} {2}".FormatWith(SourceColumn, ParameterName, ParameterBuilder.ToString()); + } + + static MethodInfo miConcat = ReflectionTools.GetMethodInfo(() => string.Concat("", "")); + + internal static Expression Concat(string baseName, Expression suffix) + { + return Expression.Call(null, miConcat, Expression.Constant(baseName), suffix); + } + } + + static ConstructorInfo ciNewList = ReflectionTools.GetConstuctorInfo(() => new List(1)); + + public static Expression CreateBlock(IEnumerable parameters, IEnumerable assigments) + { + return Expression.Block(assigments.OfType().Select(a => (ParameterExpression)a.Left), + assigments.And( + Expression.ListInit(Expression.New(ciNewList, Expression.Constant(parameters.Count())), + parameters))); + } + } + + + public partial class TableMList + { + internal interface IMListCache + { + SqlPreCommand? RelationalUpdateSync(Entity parent, string suffix, bool replaceParameter); + void RelationalInserts(List entities); + void RelationalUpdates(List entities); + + object[] BulkInsertDataRow(Entity entity, object value, int order); } #pragma warning disable CS8618 // Non-nullable field is uninitialized. internal class TableMListCache : IMListCache #pragma warning restore CS8618 // Non-nullable field is uninitialized. - { - internal TableMList table; - - internal Func sqlDelete; - public Func DeleteParameter; - public ConcurrentDictionary>> deleteCache = new ConcurrentDictionary>>(); - - Action> GetDelete(int numEntities) - { - return deleteCache.GetOrAdd(numEntities, num => - { - string sql = Enumerable.Range(0, num).ToString(i => sqlDelete(i.ToString()), ";\r\n"); - - return list => - { - List parameters = new List(); - for (int i = 0; i < num; i++) - { - parameters.Add(DeleteParameter(list[i], i.ToString())); - } - new SqlPreCommandSimple(sql, parameters).ExecuteNonQuery(); - }; - }); - } - - internal Func sqlDeleteExcept; - public Func> DeleteExceptParameter; - public ConcurrentDictionary> deleteExceptCache = new ConcurrentDictionary>(); - - Action GetDeleteExcept(int numExceptions) - { - return deleteExceptCache.GetOrAdd(numExceptions, num => - { - string sql = sqlDeleteExcept(numExceptions); Enumerable.Range(0, num).ToString(i => sqlDelete(i.ToString()), ";\r\n"); - - return delete => - { - new SqlPreCommandSimple(sql, DeleteExceptParameter(delete)).ExecuteNonQuery(); - }; - }); - } - - public struct MListDelete - { - public readonly Entity Entity; - public readonly PrimaryKey[] ExceptRowIds; - - public MListDelete(Entity ident, PrimaryKey[] exceptRowIds) - { - this.Entity = ident; - this.ExceptRowIds = exceptRowIds; - } - } - - internal bool hasOrder = false; - internal bool isEmbeddedEntity = false; - internal Func sqlUpdate; - public Func> UpdateParameters; - public ConcurrentDictionary>> updateCache = - new ConcurrentDictionary>>(); - - Action> GetUpdate(int numElements) - { - return updateCache.GetOrAdd(numElements, num => - { - string sql = Enumerable.Range(0, num).ToString(i => sqlUpdate(i.ToString()), ";\r\n"); - - return (List list) => - { - List parameters = new List(); - for (int i = 0; i < num; i++) - { - var pair = list[i]; - - var row = pair.MList.InnerList[pair.Index]; - - parameters.AddRange(UpdateParameters(pair.Entity, row.RowId.Value, row.Element, pair.Index, pair.Forbidden, i.ToString())); - } - new SqlPreCommandSimple(sql, parameters).ExecuteNonQuery(); - }; - }); - } - - public struct MListUpdate - { - public readonly Entity Entity; - public readonly Forbidden Forbidden; - public readonly IMListPrivate MList; - public readonly int Index; - - public MListUpdate(EntityForbidden ef, MList mlist, int index) - { - this.Entity = ef.Entity; - this.Forbidden = ef.Forbidden; - this.MList = mlist; - this.Index = index; - } - } - - internal Func sqlInsert; - public Func> InsertParameters; - public ConcurrentDictionary>> insertCache = - new ConcurrentDictionary>>(); - - Action> GetInsert(int numElements) - { - return insertCache.GetOrAdd(numElements, num => - { - string sqlMulti = new StringBuilder() - .AppendLine("DECLARE @MyTable TABLE (Id " + this.table.PrimaryKey.SqlDbType.ToString().ToUpperInvariant() + ");") - .AppendLines(Enumerable.Range(0, num).Select(i => sqlInsert(i.ToString(), true))) - .AppendLine("SELECT Id from @MyTable").ToString(); - - return (List list) => - { - List result = new List(); - for (int i = 0; i < num; i++) - { - var pair = list[i]; - result.AddRange(InsertParameters(pair.Entity, pair.MList.InnerList[pair.Index].Element, pair.Index, pair.Forbidden, i.ToString())); - } - - DataTable dt = new SqlPreCommandSimple(sqlMulti, result).ExecuteDataTable(); - - for (int i = 0; i < num; i++) - { - var pair = list[i]; - - pair.MList.SetRowId(pair.Index, new PrimaryKey((IComparable)dt.Rows[i][0])); - - if (this.hasOrder) - pair.MList.SetOldIndex(pair.Index); - } - }; - }); - } - - public struct MListInsert - { - public readonly Entity Entity; - public readonly Forbidden Forbidden; - public readonly IMListPrivate MList; - public readonly int Index; - - public MListInsert(EntityForbidden ef, MList mlist, int index) - { - this.Entity = ef.Entity; - this.Forbidden = ef.Forbidden; - this.MList = mlist; - this.Index = index; - } - } - - public object[] BulkInsertDataRow(Entity entity, object value, int order) - { - return InsertParameters(entity, (T)value, order, new Forbidden(null), "").Select(a => a.Value).ToArray(); - } - - public Func> Getter; - - public void RelationalInserts(List entities) - { - List toInsert = new List(); - - foreach (var ef in entities) - { - if (!ef.Forbidden.IsEmpty) - continue; //Will be called again - - MList collection = Getter(ef.Entity); - - if (collection == null) - continue; - - if (collection.Modified == ModifiedState.Clean) - continue; - - for (int i = 0; i < collection.Count; i++) - { - toInsert.Add(new MListInsert(ef, collection, i)); - } - } - - toInsert.SplitStatements(this.table.Columns.Count, list => GetInsert(list.Count)(list)); - } - - public void RelationalUpdates(List idents) - { - List toDelete = new List(); - List toDeleteExcept = new List(); - List toInsert = new List(); - List toUpdate = new List(); - - foreach (var ef in idents) - { - if (!ef.Forbidden.IsEmpty) - continue; //Will be called again - - MList collection = Getter(ef.Entity); - - if (collection == null) - toDelete.Add(ef.Entity); - else - { - if (collection.Modified == ModifiedState.Clean) - continue; - - var innerList = ((IMListPrivate)collection).InnerList; - - var exceptions = innerList.Select(a => a.RowId).NotNull().ToArray(); - - if (exceptions.IsEmpty()) - toDelete.Add(ef.Entity); - else - toDeleteExcept.Add(new MListDelete(ef.Entity, exceptions)); - - if (isEmbeddedEntity || hasOrder) - { - for (int i = 0; i < innerList.Count; i++) - { - var row = innerList[i]; - - if (row.RowId.HasValue) - { - if (hasOrder && row.OldIndex != i || - isEmbeddedEntity && ((ModifiableEntity)(object)row.Element!).IsGraphModified) - { - toUpdate.Add(new MListUpdate(ef, collection, i)); - } - } - } - } - - for (int i = 0; i < innerList.Count; i++) - { - if (innerList[i].RowId == null) - toInsert.Add(new MListInsert(ef, collection, i)); - } - } - } - - toDelete.SplitStatements(2, list => GetDelete(list.Count)(list)); - - toDeleteExcept.ForEach(e => GetDeleteExcept(e.ExceptRowIds.Length)(e)); - toUpdate.SplitStatements(this.table.Columns.Count + 2, listPairs => GetUpdate(listPairs.Count)(listPairs)); - toInsert.SplitStatements(this.table.Columns.Count, listPairs => GetInsert(listPairs.Count)(listPairs)); - } - - public SqlPreCommand? RelationalUpdateSync(Entity parent, string suffix, bool replaceParameter) - { - MList collection = Getter(parent); - - if (collection == null) - { - if (parent.IsNew) - return null; - - return new SqlPreCommandSimple(sqlDelete(suffix), new List { DeleteParameter(parent, suffix) }) - .ReplaceFirstParameter(replaceParameter ? parent.Id.VariableName : null); - } - - if (collection.Modified == ModifiedState.Clean) - return null; - - if (parent.IsNew) - { - return collection.Select((e, i) => - { - var parameters = InsertParameters(parent, e, i, new Forbidden(new HashSet { parent }), suffix + "_" + i); - var parentId = parameters.First(); // wont be replaced, generating @parentId - parameters.RemoveAt(0); - string script = sqlInsert(suffix + "_" + i, false); - script = script.Replace(parentId.ParameterName, "@parentId"); - return new SqlPreCommandSimple(script, parameters).AddComment(e?.ToString()); - }).Combine(Spacing.Simple); - } - else - { - return SqlPreCommand.Combine(Spacing.Simple, - new SqlPreCommandSimple(sqlDelete(suffix), new List { DeleteParameter(parent, suffix) }).ReplaceFirstParameter(replaceParameter ? parent.Id.VariableName : null), - collection.Select((e, i) => new SqlPreCommandSimple(sqlInsert(suffix + "_" + i, false), InsertParameters(parent, e, i, new Forbidden(), suffix + "_" + i)) - .AddComment(e?.ToString()) - .ReplaceFirstParameter(replaceParameter ? parent.Id.VariableName : null) - ).Combine(Spacing.Simple)); - } - } - } - - static GenericInvoker> giCreateCache = - new GenericInvoker>((TableMList rt) => rt.CreateCache()); - - internal Lazy cache; - - TableMListCache CreateCache() - { - var pb = Connector.Current.ParameterBuilder; - - TableMListCache result = new TableMListCache - { - table = this, - Getter = entity => (MList)Getter(entity), - - sqlDelete = suffix => "DELETE {0} WHERE {1} = {2}".FormatWith(Name, BackReference.Name.SqlEscape(), ParameterBuilder.GetParameterName(BackReference.Name + suffix)), - DeleteParameter = (ident, suffix) => pb.CreateReferenceParameter(ParameterBuilder.GetParameterName(BackReference.Name + suffix), ident.Id, this.BackReference.ReferenceTable.PrimaryKey), - - sqlDeleteExcept = num => - { - var sql = "DELETE {0} WHERE {1} = {2}" - .FormatWith(Name, BackReference.Name.SqlEscape(), ParameterBuilder.GetParameterName(BackReference.Name)); - - sql += " AND {0} NOT IN ({1})" - .FormatWith(PrimaryKey.Name.SqlEscape(), 0.To(num).Select(i => ParameterBuilder.GetParameterName("e" + i)).ToString(", ")); - - return sql; - }, - - DeleteExceptParameter = delete => - { - var list = new List - { - pb.CreateReferenceParameter(ParameterBuilder.GetParameterName(BackReference.Name), delete.Entity.Id, BackReference) - }; - - list.AddRange(delete.ExceptRowIds.Select((e, i) => pb.CreateReferenceParameter(ParameterBuilder.GetParameterName("e" + i), e, PrimaryKey))); - - return list; - } - }; - var paramIdent = Expression.Parameter(typeof(Entity), "ident"); - var paramItem = Expression.Parameter(typeof(T), "item"); - var paramOrder = Expression.Parameter(typeof(int), "order"); - var paramForbidden = Expression.Parameter(typeof(Forbidden), "forbidden"); - var paramSuffix = Expression.Parameter(typeof(string), "suffix"); - - - { - var trios = new List(); - var assigments = new List(); - - BackReference.CreateParameter(trios, assigments, paramIdent, paramForbidden, paramSuffix); - if (this.Order != null) - Order.CreateParameter(trios, assigments, paramOrder, paramForbidden, paramSuffix); - Field.CreateParameter(trios, assigments, paramItem, paramForbidden, paramSuffix); - - result.sqlInsert = (suffix, output) => "INSERT {0} ({1})\r\n{2} VALUES ({3})".FormatWith(Name, - trios.ToString(p => p.SourceColumn.SqlEscape(), ", "), - output ? "OUTPUT INSERTED.Id into @MyTable \r\n" : null, - trios.ToString(p => p.ParameterName + suffix, ", ")); - - var expr = Expression.Lambda>>( - Table.CreateBlock(trios.Select(a => a.ParameterBuilder), assigments), paramIdent, paramItem, paramOrder, paramForbidden, paramSuffix); - - result.InsertParameters = expr.Compile(); - } - - result.hasOrder = this.Order != null; - result.isEmbeddedEntity = typeof(EmbeddedEntity).IsAssignableFrom(this.Field.FieldType); - - if (result.isEmbeddedEntity || result.hasOrder) - { - var trios = new List(); - var assigments = new List(); - - var paramRowId = Expression.Parameter(typeof(PrimaryKey), "rowId"); - - string parentId = "parentId"; - string rowId = "rowId"; - - //BackReference.CreateParameter(trios, assigments, paramIdent, paramForbidden, paramSuffix); - if (this.Order != null) - Order.CreateParameter(trios, assigments, paramOrder, paramForbidden, paramSuffix); - Field.CreateParameter(trios, assigments, paramItem, paramForbidden, paramSuffix); - - result.sqlUpdate = suffix => "UPDATE {0} SET \r\n{1}\r\n WHERE {2} = {3} AND {4} = {5}".FormatWith(Name, - trios.ToString(p => "{0} = {1}".FormatWith(p.SourceColumn.SqlEscape(), p.ParameterName + suffix).Indent(2), ",\r\n"), - this.BackReference.Name.SqlEscape(), ParameterBuilder.GetParameterName(parentId + suffix), - this.PrimaryKey.Name.SqlEscape(), ParameterBuilder.GetParameterName(rowId + suffix)); - - var parameters = trios.Select(a => a.ParameterBuilder).ToList(); - - parameters.Add(pb.ParameterFactory(Table.Trio.Concat(parentId, paramSuffix), this.BackReference.SqlDbType, null, false, - Expression.Field(Expression.Property(Expression.Field(paramIdent, Table.fiId), "Value"), "Object"))); - parameters.Add(pb.ParameterFactory(Table.Trio.Concat(rowId, paramSuffix), this.PrimaryKey.SqlDbType, null, false, - Expression.Field(paramRowId, "Object"))); - - var expr = Expression.Lambda>>( - Table.CreateBlock(parameters, assigments), paramIdent, paramRowId, paramItem, paramOrder, paramForbidden, paramSuffix); - result.UpdateParameters = expr.Compile(); - } - - return result; - } - } - - internal static class SaveUtils - { - public static void SplitStatements(this IList original, int numParametersPerElement, Action> action) - { - if (!Connector.Current.AllowsMultipleQueries) - { - List part = new List(1); - for (int i = 0; i < original.Count; i++) - { - part[0] = original[i]; - action(part); - } - } - else - { - var s = Schema.Current.Settings; - int max = Math.Min(s.MaxNumberOfStatementsInSaveQueries, s.MaxNumberOfParameters / numParametersPerElement); - - List part = new List(max); - int i = 0; - for (; i <= original.Count - max; i += max) - { - Fill(part, original, i, max); - action(part); - } - - int remaining = original.Count - i; - if (remaining > 0) - { - Fill(part, original, i, remaining); - action(part); - } - } - } - - static List Fill(List part, IList original, int pos, int count) - { - part.Clear(); - int max = pos + count; - for (int i = pos; i < max; i++) - part.Add(original[i]); - return part; - } - } - - - public abstract partial class Field - { - protected internal virtual void CreateParameter(List trios, List assigments, Expression value, Expression forbidden, Expression suffix) { } - } - - public partial class FieldPrimaryKey - { - protected internal override void CreateParameter(List trios, List assigments, Expression value, Expression forbidden, Expression suffix) - { - trios.Add(new Table.Trio(this, Expression.Field(Expression.Property(value, "Value"), "Object"), suffix)); - } - } - - public partial class FieldValue - { - protected internal override void CreateParameter(List trios, List assigments, Expression value, Expression forbidden, Expression suffix) - { - trios.Add(new Table.Trio(this, value, suffix)); - } - } - - public partial class FieldTicks - { - public static readonly ConstructorInfo ciDateTimeTicks = ReflectionTools.GetConstuctorInfo(() => new DateTime(0L)); - - protected internal override void CreateParameter(List trios, List assigments, Expression value, Expression forbidden, Expression suffix) - { - if (this.Type == this.FieldType) - trios.Add(new Table.Trio(this, value, suffix)); - else if (this.Type == typeof(DateTime)) - trios.Add(new Table.Trio(this, Expression.New(ciDateTimeTicks, value), suffix)); - else - throw new NotImplementedException("FieldTicks of type {0} not supported".FormatWith(this.Type)); - } - - internal Expression ConvertTicks(ParameterExpression paramOldTicks) - { - if (this.Type == this.FieldType) - return paramOldTicks; - - if (this.Type == typeof(DateTime)) - return Expression.New(ciDateTimeTicks, paramOldTicks); - - throw new NotImplementedException("FieldTicks of type {0} not supported".FormatWith(this.Type)); - } - } - - public static partial class FieldReferenceExtensions - { - static MethodInfo miGetIdForLite = ReflectionTools.GetMethodInfo(() => GetIdForLite(null, new Forbidden())); - static MethodInfo miGetIdForEntity = ReflectionTools.GetMethodInfo(() => GetIdForEntity(null, new Forbidden())); - static MethodInfo miGetIdForLiteCleanEntity = ReflectionTools.GetMethodInfo(() => GetIdForLiteCleanEntity(null, new Forbidden())); - - public static void AssertIsLite(this IFieldReference fr) - { - if (!fr.IsLite) - throw new InvalidOperationException("The field is not a lite"); - } - - public static Expression GetIdFactory(this IFieldReference fr, Expression value, Expression forbidden) - { - var mi = !fr.IsLite ? miGetIdForEntity : - fr.ClearEntityOnSaving ? miGetIdForLiteCleanEntity : - miGetIdForLite; - - return Expression.Call(mi, value, forbidden); - } - - static PrimaryKey? GetIdForLite(Lite lite, Forbidden forbidden) - { - if (lite == null) - return null; - - if (lite.EntityOrNull == null) - return lite.Id; - - if (forbidden.Contains((Entity)lite.EntityOrNull)) - return null; - - lite.RefreshId(); - - return lite.Id; - } - - static PrimaryKey? GetIdForLiteCleanEntity(Lite lite, Forbidden forbidden) - { - if (lite == null) - return null; - - if (lite.EntityOrNull == null) - return lite.Id; - - if (forbidden.Contains((Entity)lite.EntityOrNull)) - return null; - - lite.RefreshId(); - lite.ClearEntity(); - - return lite.Id; - } - - static PrimaryKey? GetIdForEntity(IEntity value, Forbidden forbidden) - { - if (value == null) - return null; - - Entity ie = (Entity)value; - return forbidden.Contains(ie) ? (PrimaryKey?)null : ie.Id; - } - - static MethodInfo miGetTypeForLite = ReflectionTools.GetMethodInfo(() => GetTypeForLite(null, new Forbidden())); - static MethodInfo miGetTypeForEntity = ReflectionTools.GetMethodInfo(() => GetTypeForEntity(null, new Forbidden())); - - public static Expression GetTypeFactory(this IFieldReference fr, Expression value, Expression forbidden) - { - return Expression.Call(fr.IsLite ? miGetTypeForLite : miGetTypeForEntity, value, forbidden); - } - - static Type? GetTypeForLite(Lite value, Forbidden forbidden) - { - if (value == null) - return null; - - Lite l = (Lite)value; - return l.EntityOrNull == null ? l.EntityType : - forbidden.Contains((Entity)l.EntityOrNull) ? null : - l.EntityType; - } - - static Type? GetTypeForEntity(IEntity value, Forbidden forbidden) - { - if (value == null) - return null; - - Entity ie = (Entity)value; - return forbidden.Contains(ie) ? null : ie.GetType(); - } - } - - public partial class FieldReference - { - protected internal override void CreateParameter(List trios, List assigments, Expression value, Expression forbidden, Expression suffix) - { - trios.Add(new Table.Trio(this, Expression.Call(miUnWrap, this.GetIdFactory(value, forbidden)), suffix)); - } - - static MethodInfo miUnWrap = ReflectionTools.GetMethodInfo(() => Signum.Entities.PrimaryKey.Unwrap(null)); - } - - public partial class FieldEnum - { - protected internal override void CreateParameter(List trios, List assigments, Expression value, Expression forbidden, Expression suffix) - { - trios.Add(new Table.Trio(this, Expression.Convert(value, this.Type), suffix)); - } - } - - - - public partial class FieldImplementedBy - { - protected internal override void CreateParameter(List trios, List assigments, Expression value, Expression forbidden, Expression suffix) - { - ParameterExpression ibType = Expression.Parameter(typeof(Type), "ibType"); - ParameterExpression ibId = Expression.Parameter(typeof(PrimaryKey?), "ibId"); - - assigments.Add(Expression.Assign(ibType, Expression.Call(Expression.Constant(this), miCheckType, this.GetTypeFactory(value, forbidden)))); - assigments.Add(Expression.Assign(ibId, this.GetIdFactory(value, forbidden))); - - foreach (var imp in ImplementationColumns) - { - trios.Add(new Table.Trio(imp.Value, - Expression.Condition(Expression.Equal(ibType, Expression.Constant(imp.Key)), - Expression.Field(Expression.Property(ibId, "Value"), "Object"), - Expression.Constant(null, typeof(IComparable))), - suffix)); - } - } - - static MethodInfo miCheckType = ReflectionTools.GetMethodInfo((FieldImplementedBy fe) => fe.CheckType(null)); - - Type CheckType(Type type) - { - if (type != null && !ImplementationColumns.ContainsKey(type)) - throw new InvalidOperationException("Type {0} is not in the list of ImplementedBy:\r\n{1}".FormatWith(type.Name, ImplementationColumns.ToString(kvp => "{0} -> {1}".FormatWith(kvp.Key.Name, kvp.Value.Name), "\r\n"))); - - return type; - } - } - - public partial class ImplementationColumn - { - - } - - public partial class FieldImplementedByAll - { - - protected internal override void CreateParameter(List trios, List assigments, Expression value, Expression forbidden, Expression suffix) - { - trios.Add(new Table.Trio(Column, Expression.Call(miUnWrapToString, this.GetIdFactory(value, forbidden)), suffix)); - trios.Add(new Table.Trio(ColumnType, Expression.Call(miConvertType, this.GetTypeFactory(value, forbidden)), suffix)); - } - - static MethodInfo miUnWrapToString = ReflectionTools.GetMethodInfo(() => PrimaryKey.UnwrapToString(null)); - static MethodInfo miConvertType = ReflectionTools.GetMethodInfo(() => ConvertType(null)); - - static IComparable? ConvertType(Type type) - { - if (type == null) - return null; - - return TypeLogic.TypeToId.GetOrThrow(type, "{0} not registered in the schema").Object; - } - } - - public partial class FieldMList - { - } - - public partial class FieldEmbedded - { - protected internal override void CreateParameter(List trios, List assigments, Expression value, Expression forbidden, Expression suffix) - { - ParameterExpression embedded = Expression.Parameter(this.FieldType, "embedded"); - - if (HasValue != null) - { - trios.Add(new Table.Trio(HasValue, Expression.NotEqual(value, Expression.Constant(null, FieldType)), suffix)); - } - - assigments.Add(Expression.Assign(embedded, Expression.Convert(value, this.FieldType))); - - foreach (var ef in EmbeddedFields.Values) - { - ef.Field.CreateParameter(trios, assigments, - Expression.Condition( - Expression.Equal(embedded, Expression.Constant(null, this.FieldType)), - Expression.Constant(null, ef.FieldInfo.FieldType.Nullify()), - Expression.Field(embedded, ef.FieldInfo).Nullify()), forbidden, suffix); - } - } - - static MethodInfo miCheckNull = ReflectionTools.GetMethodInfo((FieldEmbedded fe) => fe.CheckNull(null)); - object CheckNull(object obj) - { - if (obj == null) - throw new InvalidOperationException("Impossible to save 'null' on the not-nullable embedded field of type '{0}'".FormatWith(this.FieldType.Name)); - - return obj; - } - } - - public partial class FieldMixin - { - protected internal override void CreateParameter(List trios, List assigments, Expression value, Expression forbidden, Expression suffix) - { - ParameterExpression mixin = Expression.Parameter(this.FieldType, "mixin"); - - assigments.Add(Expression.Assign(mixin, Expression.Call(value, MixinDeclarations.miMixin.MakeGenericMethod(this.FieldType)))); - foreach (var ef in Fields.Values) - { - ef.Field.CreateParameter(trios, assigments, - Expression.Field(mixin, ef.FieldInfo), forbidden, suffix); - } - } - } - -} + { + internal TableMList table; + + internal Func sqlDelete; + public Func DeleteParameter; + public ConcurrentDictionary>> deleteCache = new ConcurrentDictionary>>(); + + Action> GetDelete(int numEntities) + { + return deleteCache.GetOrAdd(numEntities, num => + { + string sql = Enumerable.Range(0, num).ToString(i => sqlDelete(i.ToString()), ";\r\n"); + + return list => + { + List parameters = new List(); + for (int i = 0; i < num; i++) + { + parameters.Add(DeleteParameter(list[i], i.ToString())); + } + new SqlPreCommandSimple(sql, parameters).ExecuteNonQuery(); + }; + }); + } + + internal Func sqlDeleteExcept; + public Func> DeleteExceptParameter; + public ConcurrentDictionary> deleteExceptCache = new ConcurrentDictionary>(); + + Action GetDeleteExcept(int numExceptions) + { + return deleteExceptCache.GetOrAdd(numExceptions, num => + { + string sql = sqlDeleteExcept(numExceptions); Enumerable.Range(0, num).ToString(i => sqlDelete(i.ToString()), ";\r\n"); + + return delete => + { + new SqlPreCommandSimple(sql, DeleteExceptParameter(delete)).ExecuteNonQuery(); + }; + }); + } + + public struct MListDelete + { + public readonly Entity Entity; + public readonly PrimaryKey[] ExceptRowIds; + + public MListDelete(Entity ident, PrimaryKey[] exceptRowIds) + { + this.Entity = ident; + this.ExceptRowIds = exceptRowIds; + } + } + + internal bool hasOrder = false; + internal bool isEmbeddedEntity = false; + internal Func sqlUpdate; + public Func> UpdateParameters; + public ConcurrentDictionary>> updateCache = + new ConcurrentDictionary>>(); + + Action> GetUpdate(int numElements) + { + return updateCache.GetOrAdd(numElements, num => + { + string sql = Enumerable.Range(0, num).ToString(i => sqlUpdate(i.ToString()), ";\r\n"); + + return (List list) => + { + List parameters = new List(); + for (int i = 0; i < num; i++) + { + var pair = list[i]; + + var row = pair.MList.InnerList[pair.Index]; + + parameters.AddRange(UpdateParameters(pair.Entity, row.RowId!.Value, row.Element, pair.Index, pair.Forbidden, i.ToString())); + } + new SqlPreCommandSimple(sql, parameters).ExecuteNonQuery(); + }; + }); + } + + public struct MListUpdate + { + public readonly Entity Entity; + public readonly Forbidden Forbidden; + public readonly IMListPrivate MList; + public readonly int Index; + + public MListUpdate(EntityForbidden ef, MList mlist, int index) + { + this.Entity = ef.Entity; + this.Forbidden = ef.Forbidden; + this.MList = mlist; + this.Index = index; + } + } + + internal Func sqlInsert; + public Func> InsertParameters; + public ConcurrentDictionary>> insertCache = + new ConcurrentDictionary>>(); + + Action> GetInsert(int numElements) + { + return insertCache.GetOrAdd(numElements, num => + { + string sqlMulti = new StringBuilder() + .AppendLine("DECLARE @MyTable TABLE (Id " + this.table.PrimaryKey.SqlDbType.ToString().ToUpperInvariant() + ");") + .AppendLines(Enumerable.Range(0, num).Select(i => sqlInsert(i.ToString(), true))) + .AppendLine("SELECT Id from @MyTable").ToString(); + + return (List list) => + { + List result = new List(); + for (int i = 0; i < num; i++) + { + var pair = list[i]; + result.AddRange(InsertParameters(pair.Entity, pair.MList.InnerList[pair.Index].Element, pair.Index, pair.Forbidden, i.ToString())); + } + + DataTable dt = new SqlPreCommandSimple(sqlMulti, result).ExecuteDataTable(); + + for (int i = 0; i < num; i++) + { + var pair = list[i]; + + pair.MList.SetRowId(pair.Index, new PrimaryKey((IComparable)dt.Rows[i][0])); + + if (this.hasOrder) + pair.MList.SetOldIndex(pair.Index); + } + }; + }); + } + + public struct MListInsert + { + public readonly Entity Entity; + public readonly Forbidden Forbidden; + public readonly IMListPrivate MList; + public readonly int Index; + + public MListInsert(EntityForbidden ef, MList mlist, int index) + { + this.Entity = ef.Entity; + this.Forbidden = ef.Forbidden; + this.MList = mlist; + this.Index = index; + } + } + + public object[] BulkInsertDataRow(Entity entity, object value, int order) + { + return InsertParameters(entity, (T)value, order, new Forbidden(null), "").Select(a => a.Value).ToArray(); + } + + public Func> Getter; + + public void RelationalInserts(List entities) + { + List toInsert = new List(); + + foreach (var ef in entities) + { + if (!ef.Forbidden.IsEmpty) + continue; //Will be called again + + MList collection = Getter(ef.Entity); + + if (collection == null) + continue; + + if (collection.Modified == ModifiedState.Clean) + continue; + + for (int i = 0; i < collection.Count; i++) + { + toInsert.Add(new MListInsert(ef, collection, i)); + } + } + + toInsert.SplitStatements(this.table.Columns.Count, list => GetInsert(list.Count)(list)); + } + + public void RelationalUpdates(List idents) + { + List toDelete = new List(); + List toDeleteExcept = new List(); + List toInsert = new List(); + List toUpdate = new List(); + + foreach (var ef in idents) + { + if (!ef.Forbidden.IsEmpty) + continue; //Will be called again + + MList collection = Getter(ef.Entity); + + if (collection == null) + toDelete.Add(ef.Entity); + else + { + if (collection.Modified == ModifiedState.Clean) + continue; + + var innerList = ((IMListPrivate)collection).InnerList; + + var exceptions = innerList.Select(a => a.RowId).NotNull().ToArray(); + + if (exceptions.IsEmpty()) + toDelete.Add(ef.Entity); + else + toDeleteExcept.Add(new MListDelete(ef.Entity, exceptions)); + + if (isEmbeddedEntity || hasOrder) + { + for (int i = 0; i < innerList.Count; i++) + { + var row = innerList[i]; + + if (row.RowId.HasValue) + { + if (hasOrder && row.OldIndex != i || + isEmbeddedEntity && ((ModifiableEntity)(object)row.Element!).IsGraphModified) + { + toUpdate.Add(new MListUpdate(ef, collection, i)); + } + } + } + } + + for (int i = 0; i < innerList.Count; i++) + { + if (innerList[i].RowId == null) + toInsert.Add(new MListInsert(ef, collection, i)); + } + } + } + + toDelete.SplitStatements(2, list => GetDelete(list.Count)(list)); + + toDeleteExcept.ForEach(e => GetDeleteExcept(e.ExceptRowIds.Length)(e)); + toUpdate.SplitStatements(this.table.Columns.Count + 2, listPairs => GetUpdate(listPairs.Count)(listPairs)); + toInsert.SplitStatements(this.table.Columns.Count, listPairs => GetInsert(listPairs.Count)(listPairs)); + } + + public SqlPreCommand? RelationalUpdateSync(Entity parent, string suffix, bool replaceParameter) + { + MList collection = Getter(parent); + + if (collection == null) + { + if (parent.IsNew) + return null; + + return new SqlPreCommandSimple(sqlDelete(suffix), new List { DeleteParameter(parent, suffix) }) + .ReplaceFirstParameter(replaceParameter ? parent.Id.VariableName : null); + } + + if (collection.Modified == ModifiedState.Clean) + return null; + + if (parent.IsNew) + { + return collection.Select((e, i) => + { + var parameters = InsertParameters(parent, e, i, new Forbidden(new HashSet { parent }), suffix + "_" + i); + var parentId = parameters.First(); // wont be replaced, generating @parentId + parameters.RemoveAt(0); + string script = sqlInsert(suffix + "_" + i, false); + script = script.Replace(parentId.ParameterName, "@parentId"); + return new SqlPreCommandSimple(script, parameters).AddComment(e?.ToString()); + }).Combine(Spacing.Simple); + } + else + { + return SqlPreCommand.Combine(Spacing.Simple, + new SqlPreCommandSimple(sqlDelete(suffix), new List { DeleteParameter(parent, suffix) }).ReplaceFirstParameter(replaceParameter ? parent.Id.VariableName : null), + collection.Select((e, i) => new SqlPreCommandSimple(sqlInsert(suffix + "_" + i, false), InsertParameters(parent, e, i, new Forbidden(), suffix + "_" + i)) + .AddComment(e?.ToString()) + .ReplaceFirstParameter(replaceParameter ? parent.Id.VariableName : null) + ).Combine(Spacing.Simple)); + } + } + } + + static GenericInvoker> giCreateCache = + new GenericInvoker>((TableMList rt) => rt.CreateCache()); + + internal Lazy cache; + + TableMListCache CreateCache() + { + var pb = Connector.Current.ParameterBuilder; + + TableMListCache result = new TableMListCache + { + table = this, + Getter = entity => (MList)Getter(entity), + + sqlDelete = suffix => "DELETE {0} WHERE {1} = {2}".FormatWith(Name, BackReference.Name.SqlEscape(), ParameterBuilder.GetParameterName(BackReference.Name + suffix)), + DeleteParameter = (ident, suffix) => pb.CreateReferenceParameter(ParameterBuilder.GetParameterName(BackReference.Name + suffix), ident.Id, this.BackReference.ReferenceTable.PrimaryKey), + + sqlDeleteExcept = num => + { + var sql = "DELETE {0} WHERE {1} = {2}" + .FormatWith(Name, BackReference.Name.SqlEscape(), ParameterBuilder.GetParameterName(BackReference.Name)); + + sql += " AND {0} NOT IN ({1})" + .FormatWith(PrimaryKey.Name.SqlEscape(), 0.To(num).Select(i => ParameterBuilder.GetParameterName("e" + i)).ToString(", ")); + + return sql; + }, + + DeleteExceptParameter = delete => + { + var list = new List + { + pb.CreateReferenceParameter(ParameterBuilder.GetParameterName(BackReference.Name), delete.Entity.Id, BackReference) + }; + + list.AddRange(delete.ExceptRowIds.Select((e, i) => pb.CreateReferenceParameter(ParameterBuilder.GetParameterName("e" + i), e, PrimaryKey))); + + return list; + } + }; + var paramIdent = Expression.Parameter(typeof(Entity), "ident"); + var paramItem = Expression.Parameter(typeof(T), "item"); + var paramOrder = Expression.Parameter(typeof(int), "order"); + var paramForbidden = Expression.Parameter(typeof(Forbidden), "forbidden"); + var paramSuffix = Expression.Parameter(typeof(string), "suffix"); + + + { + var trios = new List(); + var assigments = new List(); + + BackReference.CreateParameter(trios, assigments, paramIdent, paramForbidden, paramSuffix); + if (this.Order != null) + Order.CreateParameter(trios, assigments, paramOrder, paramForbidden, paramSuffix); + Field.CreateParameter(trios, assigments, paramItem, paramForbidden, paramSuffix); + + result.sqlInsert = (suffix, output) => "INSERT {0} ({1})\r\n{2} VALUES ({3})".FormatWith(Name, + trios.ToString(p => p.SourceColumn.SqlEscape(), ", "), + output ? "OUTPUT INSERTED.Id into @MyTable \r\n" : null, + trios.ToString(p => p.ParameterName + suffix, ", ")); + + var expr = Expression.Lambda>>( + Table.CreateBlock(trios.Select(a => a.ParameterBuilder), assigments), paramIdent, paramItem, paramOrder, paramForbidden, paramSuffix); + + result.InsertParameters = expr.Compile(); + } + + result.hasOrder = this.Order != null; + result.isEmbeddedEntity = typeof(EmbeddedEntity).IsAssignableFrom(this.Field.FieldType); + + if (result.isEmbeddedEntity || result.hasOrder) + { + var trios = new List(); + var assigments = new List(); + + var paramRowId = Expression.Parameter(typeof(PrimaryKey), "rowId"); + + string parentId = "parentId"; + string rowId = "rowId"; + + //BackReference.CreateParameter(trios, assigments, paramIdent, paramForbidden, paramSuffix); + if (this.Order != null) + Order.CreateParameter(trios, assigments, paramOrder, paramForbidden, paramSuffix); + Field.CreateParameter(trios, assigments, paramItem, paramForbidden, paramSuffix); + + result.sqlUpdate = suffix => "UPDATE {0} SET \r\n{1}\r\n WHERE {2} = {3} AND {4} = {5}".FormatWith(Name, + trios.ToString(p => "{0} = {1}".FormatWith(p.SourceColumn.SqlEscape(), p.ParameterName + suffix).Indent(2), ",\r\n"), + this.BackReference.Name.SqlEscape(), ParameterBuilder.GetParameterName(parentId + suffix), + this.PrimaryKey.Name.SqlEscape(), ParameterBuilder.GetParameterName(rowId + suffix)); + + var parameters = trios.Select(a => a.ParameterBuilder).ToList(); + + parameters.Add(pb.ParameterFactory(Table.Trio.Concat(parentId, paramSuffix), this.BackReference.SqlDbType, null, false, + Expression.Field(Expression.Property(Expression.Field(paramIdent, Table.fiId), "Value"), "Object"))); + parameters.Add(pb.ParameterFactory(Table.Trio.Concat(rowId, paramSuffix), this.PrimaryKey.SqlDbType, null, false, + Expression.Field(paramRowId, "Object"))); + + var expr = Expression.Lambda>>( + Table.CreateBlock(parameters, assigments), paramIdent, paramRowId, paramItem, paramOrder, paramForbidden, paramSuffix); + result.UpdateParameters = expr.Compile(); + } + + return result; + } + } + + internal static class SaveUtils + { + public static void SplitStatements(this IList original, int numParametersPerElement, Action> action) + { + if (!Connector.Current.AllowsMultipleQueries) + { + List part = new List(1); + for (int i = 0; i < original.Count; i++) + { + part[0] = original[i]; + action(part); + } + } + else + { + var s = Schema.Current.Settings; + int max = Math.Min(s.MaxNumberOfStatementsInSaveQueries, s.MaxNumberOfParameters / numParametersPerElement); + + List part = new List(max); + int i = 0; + for (; i <= original.Count - max; i += max) + { + Fill(part, original, i, max); + action(part); + } + + int remaining = original.Count - i; + if (remaining > 0) + { + Fill(part, original, i, remaining); + action(part); + } + } + } + + static List Fill(List part, IList original, int pos, int count) + { + part.Clear(); + int max = pos + count; + for (int i = pos; i < max; i++) + part.Add(original[i]); + return part; + } + } + + + public abstract partial class Field + { + protected internal virtual void CreateParameter(List trios, List assigments, Expression value, Expression forbidden, Expression suffix) { } + } + + public partial class FieldPrimaryKey + { + protected internal override void CreateParameter(List trios, List assigments, Expression value, Expression forbidden, Expression suffix) + { + trios.Add(new Table.Trio(this, Expression.Field(Expression.Property(value, "Value"), "Object"), suffix)); + } + } + + public partial class FieldValue + { + protected internal override void CreateParameter(List trios, List assigments, Expression value, Expression forbidden, Expression suffix) + { + trios.Add(new Table.Trio(this, value, suffix)); + } + } + + public partial class FieldTicks + { + public static readonly ConstructorInfo ciDateTimeTicks = ReflectionTools.GetConstuctorInfo(() => new DateTime(0L)); + + protected internal override void CreateParameter(List trios, List assigments, Expression value, Expression forbidden, Expression suffix) + { + if (this.Type == this.FieldType) + trios.Add(new Table.Trio(this, value, suffix)); + else if (this.Type == typeof(DateTime)) + trios.Add(new Table.Trio(this, Expression.New(ciDateTimeTicks, value), suffix)); + else + throw new NotImplementedException("FieldTicks of type {0} not supported".FormatWith(this.Type)); + } + + internal Expression ConvertTicks(ParameterExpression paramOldTicks) + { + if (this.Type == this.FieldType) + return paramOldTicks; + + if (this.Type == typeof(DateTime)) + return Expression.New(ciDateTimeTicks, paramOldTicks); + + throw new NotImplementedException("FieldTicks of type {0} not supported".FormatWith(this.Type)); + } + } + + public static partial class FieldReferenceExtensions + { + static MethodInfo miGetIdForLite = ReflectionTools.GetMethodInfo(() => GetIdForLite(null, new Forbidden())); + static MethodInfo miGetIdForEntity = ReflectionTools.GetMethodInfo(() => GetIdForEntity(null, new Forbidden())); + static MethodInfo miGetIdForLiteCleanEntity = ReflectionTools.GetMethodInfo(() => GetIdForLiteCleanEntity(null, new Forbidden())); + + public static void AssertIsLite(this IFieldReference fr) + { + if (!fr.IsLite) + throw new InvalidOperationException("The field is not a lite"); + } + + public static Expression GetIdFactory(this IFieldReference fr, Expression value, Expression forbidden) + { + var mi = !fr.IsLite ? miGetIdForEntity : + fr.ClearEntityOnSaving ? miGetIdForLiteCleanEntity : + miGetIdForLite; + + return Expression.Call(mi, value, forbidden); + } + + static PrimaryKey? GetIdForLite(Lite lite, Forbidden forbidden) + { + if (lite == null) + return null; + + if (lite.EntityOrNull == null) + return lite.Id; + + if (forbidden.Contains((Entity)lite.EntityOrNull)) + return null; + + lite.RefreshId(); + + return lite.Id; + } + + static PrimaryKey? GetIdForLiteCleanEntity(Lite lite, Forbidden forbidden) + { + if (lite == null) + return null; + + if (lite.EntityOrNull == null) + return lite.Id; + + if (forbidden.Contains((Entity)lite.EntityOrNull)) + return null; + + lite.RefreshId(); + lite.ClearEntity(); + + return lite.Id; + } + + static PrimaryKey? GetIdForEntity(IEntity value, Forbidden forbidden) + { + if (value == null) + return null; + + Entity ie = (Entity)value; + return forbidden.Contains(ie) ? (PrimaryKey?)null : ie.Id; + } + + static MethodInfo miGetTypeForLite = ReflectionTools.GetMethodInfo(() => GetTypeForLite(null, new Forbidden())); + static MethodInfo miGetTypeForEntity = ReflectionTools.GetMethodInfo(() => GetTypeForEntity(null, new Forbidden())); + + public static Expression GetTypeFactory(this IFieldReference fr, Expression value, Expression forbidden) + { + return Expression.Call(fr.IsLite ? miGetTypeForLite : miGetTypeForEntity, value, forbidden); + } + + static Type? GetTypeForLite(Lite value, Forbidden forbidden) + { + if (value == null) + return null; + + Lite l = (Lite)value; + return l.EntityOrNull == null ? l.EntityType : + forbidden.Contains((Entity)l.EntityOrNull) ? null : + l.EntityType; + } + + static Type? GetTypeForEntity(IEntity value, Forbidden forbidden) + { + if (value == null) + return null; + + Entity ie = (Entity)value; + return forbidden.Contains(ie) ? null : ie.GetType(); + } + } + + public partial class FieldReference + { + protected internal override void CreateParameter(List trios, List assigments, Expression value, Expression forbidden, Expression suffix) + { + trios.Add(new Table.Trio(this, Expression.Call(miUnWrap, this.GetIdFactory(value, forbidden)), suffix)); + } + + static MethodInfo miUnWrap = ReflectionTools.GetMethodInfo(() => Signum.Entities.PrimaryKey.Unwrap(null)); + } + + public partial class FieldEnum + { + protected internal override void CreateParameter(List trios, List assigments, Expression value, Expression forbidden, Expression suffix) + { + trios.Add(new Table.Trio(this, Expression.Convert(value, this.Type), suffix)); + } + } + + + + public partial class FieldImplementedBy + { + protected internal override void CreateParameter(List trios, List assigments, Expression value, Expression forbidden, Expression suffix) + { + ParameterExpression ibType = Expression.Parameter(typeof(Type), "ibType"); + ParameterExpression ibId = Expression.Parameter(typeof(PrimaryKey?), "ibId"); + + assigments.Add(Expression.Assign(ibType, Expression.Call(Expression.Constant(this), miCheckType, this.GetTypeFactory(value, forbidden)))); + assigments.Add(Expression.Assign(ibId, this.GetIdFactory(value, forbidden))); + + foreach (var imp in ImplementationColumns) + { + trios.Add(new Table.Trio(imp.Value, + Expression.Condition(Expression.Equal(ibType, Expression.Constant(imp.Key)), + Expression.Field(Expression.Property(ibId, "Value"), "Object"), + Expression.Constant(null, typeof(IComparable))), + suffix)); + } + } + + static MethodInfo miCheckType = ReflectionTools.GetMethodInfo((FieldImplementedBy fe) => fe.CheckType(null)); + + Type CheckType(Type type) + { + if (type != null && !ImplementationColumns.ContainsKey(type)) + throw new InvalidOperationException("Type {0} is not in the list of ImplementedBy:\r\n{1}".FormatWith(type.Name, ImplementationColumns.ToString(kvp => "{0} -> {1}".FormatWith(kvp.Key.Name, kvp.Value.Name), "\r\n"))); + + return type; + } + } + + public partial class ImplementationColumn + { + + } + + public partial class FieldImplementedByAll + { + + protected internal override void CreateParameter(List trios, List assigments, Expression value, Expression forbidden, Expression suffix) + { + trios.Add(new Table.Trio(Column, Expression.Call(miUnWrapToString, this.GetIdFactory(value, forbidden)), suffix)); + trios.Add(new Table.Trio(ColumnType, Expression.Call(miConvertType, this.GetTypeFactory(value, forbidden)), suffix)); + } + + static MethodInfo miUnWrapToString = ReflectionTools.GetMethodInfo(() => PrimaryKey.UnwrapToString(null)); + static MethodInfo miConvertType = ReflectionTools.GetMethodInfo(() => ConvertType(null)); + + static IComparable? ConvertType(Type type) + { + if (type == null) + return null; + + return TypeLogic.TypeToId.GetOrThrow(type, "{0} not registered in the schema").Object; + } + } + + public partial class FieldMList + { + } + + public partial class FieldEmbedded + { + protected internal override void CreateParameter(List trios, List assigments, Expression value, Expression forbidden, Expression suffix) + { + ParameterExpression embedded = Expression.Parameter(this.FieldType, "embedded"); + + if (HasValue != null) + { + trios.Add(new Table.Trio(HasValue, Expression.NotEqual(value, Expression.Constant(null, FieldType)), suffix)); + } + + assigments.Add(Expression.Assign(embedded, Expression.Convert(value, this.FieldType))); + + foreach (var ef in EmbeddedFields.Values) + { + ef.Field.CreateParameter(trios, assigments, + Expression.Condition( + Expression.Equal(embedded, Expression.Constant(null, this.FieldType)), + Expression.Constant(null, ef.FieldInfo.FieldType.Nullify()), + Expression.Field(embedded, ef.FieldInfo).Nullify()), forbidden, suffix); + } + } + + static MethodInfo miCheckNull = ReflectionTools.GetMethodInfo((FieldEmbedded fe) => fe.CheckNull(null)); + object CheckNull(object obj) + { + if (obj == null) + throw new InvalidOperationException("Impossible to save 'null' on the not-nullable embedded field of type '{0}'".FormatWith(this.FieldType.Name)); + + return obj; + } + } + + public partial class FieldMixin + { + protected internal override void CreateParameter(List trios, List assigments, Expression value, Expression forbidden, Expression suffix) + { + ParameterExpression mixin = Expression.Parameter(this.FieldType, "mixin"); + + assigments.Add(Expression.Assign(mixin, Expression.Call(value, MixinDeclarations.miMixin.MakeGenericMethod(this.FieldType)))); + foreach (var ef in Fields.Values) + { + ef.Field.CreateParameter(trios, assigments, + Expression.Field(mixin, ef.FieldInfo), forbidden, suffix); + } + } + } + +} diff --git a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs index 8444a348d4..51d3a95482 100644 --- a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs +++ b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilder.cs @@ -787,7 +787,7 @@ protected static Type CleanType(Type type) return type; } - public virtual ObjectName GenerateTableName(Type type, TableNameAttribute tn) + public virtual ObjectName GenerateTableName(Type type, TableNameAttribute? tn) { SchemaName sn = tn != null ? GetSchemaName(tn) : SchemaName.Default; @@ -987,7 +987,7 @@ public Table NewView(Type type) } - public override ObjectName GenerateTableName(Type type, TableNameAttribute tn) + public override ObjectName GenerateTableName(Type type, TableNameAttribute? tn) { if (tn != null) { diff --git a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs index 20b0de01be..af84ea7072 100644 --- a/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs +++ b/Signum.Engine/Schema/SchemaBuilder/SchemaBuilderSettings.cs @@ -12,6 +12,7 @@ using System.Collections.ObjectModel; using System.Collections.Concurrent; using Signum.Utilities.ExpressionTrees; +using System.Runtime.CompilerServices; namespace Signum.Engine.Maps { @@ -220,18 +221,14 @@ private IsNullable GetIsNullablePrivate(PropertyRoute propertyRoute) if (propertyRoute.PropertyRouteType == PropertyRouteType.MListItems) return IsNullable.No; - if (ValidatorAttribute(propertyRoute) != null) - return IsNullable.No; - - //if (propertyRoute.Type == typeof(string)) - //{ - // var slv = ValidatorAttribute(propertyRoute); + if (propertyRoute.Type.IsValueType) + return propertyRoute.Type.IsNullable() ? IsNullable.Yes : IsNullable.No; - // if (slv != null) - // return slv.AllowNulls ? IsNullable.Yes : IsNullable.No; - //} + var nullable = FieldAttribute(propertyRoute); + if (nullable != null && nullable.IsNullableMain == true) + return IsNullable.Yes; - return !propertyRoute.Type.IsValueType || propertyRoute.Type.IsNullable() ? IsNullable.Yes : IsNullable.No; + return IsNullable.No; } public bool ImplementedBy(Expression> propertyRoute, Type typeToImplement) where T : Entity diff --git a/Signum.Engine/Signum.Engine.csproj b/Signum.Engine/Signum.Engine.csproj index 961a8f4250..90113cff7a 100644 --- a/Signum.Engine/Signum.Engine.csproj +++ b/Signum.Engine/Signum.Engine.csproj @@ -9,10 +9,6 @@ x64 - - - 1701;1702;8629 - diff --git a/Signum.Entities/Basics/Exception.cs b/Signum.Entities/Basics/Exception.cs index 282a85c521..04b0f1c538 100644 --- a/Signum.Entities/Basics/Exception.cs +++ b/Signum.Entities/Basics/Exception.cs @@ -128,7 +128,7 @@ public static string Dump(NameValueCollection nameValueCollection) public class DeleteLogParametersEmbedded : EmbeddedEntity { [PreserveOrder] - [NotNullValidator, NoRepeatValidator] + [NoRepeatValidator] public MList DeleteLogs { get; set; } = new MList(); public DateTime? GetDateLimitDelete(TypeEntity type) @@ -163,7 +163,6 @@ public class DeleteLogParametersEmbedded : EmbeddedEntity [Serializable] public class DeleteLogsTypeOverridesEmbedded : EmbeddedEntity { - [NotNullValidator] public Lite Type { get; set; } [Unit("Days"), NumberIsValidator(ComparisonType.GreaterThanOrEqualTo, 0)] diff --git a/Signum.Entities/Basics/OperationLog.cs b/Signum.Entities/Basics/OperationLog.cs index 3596cea406..c16352d81b 100644 --- a/Signum.Entities/Basics/OperationLog.cs +++ b/Signum.Entities/Basics/OperationLog.cs @@ -32,7 +32,7 @@ public double? Duration get { return End == null ? null : DurationExpression.Evaluate(this); } } - public Lite Exception { get; set; } + public Lite? Exception { get; set; } public override string ToString() { diff --git a/Signum.Entities/Basics/PropertyRouteEntity.cs b/Signum.Entities/Basics/PropertyRouteEntity.cs index 88aedb04ab..c4234f041e 100644 --- a/Signum.Entities/Basics/PropertyRouteEntity.cs +++ b/Signum.Entities/Basics/PropertyRouteEntity.cs @@ -20,7 +20,6 @@ public PropertyRoute Route [StringLengthValidator(Min = 1, Max = 100)] public string Path { get; set; } - [NotNullValidator] public TypeEntity RootType { get; set; } public static Func ToPropertyRouteFunc; diff --git a/Signum.Entities/DynamicQuery/ResultTable.cs b/Signum.Entities/DynamicQuery/ResultTable.cs index 97278e028a..4918c4274c 100644 --- a/Signum.Entities/DynamicQuery/ResultTable.cs +++ b/Signum.Entities/DynamicQuery/ResultTable.cs @@ -316,7 +316,7 @@ public DataTable ToDataTablePivot(int rowColumnIndex, int columnColumnIndex, int public int? TotalPages { - get { return Pagination is Pagination.Paginate ? ((Pagination.Paginate)Pagination).TotalPages(TotalElements.Value) : (int?)null; } + get { return Pagination is Pagination.Paginate ? ((Pagination.Paginate)Pagination).TotalPages(TotalElements!.Value) : (int?)null; } } public int? StartElementIndex diff --git a/Signum.Entities/DynamicQuery/Tokens/QueryToken.cs b/Signum.Entities/DynamicQuery/Tokens/QueryToken.cs index c478173303..948776cbf1 100644 --- a/Signum.Entities/DynamicQuery/Tokens/QueryToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/QueryToken.cs @@ -170,7 +170,7 @@ protected List SubTokensBase(Type type, SubTokensOptions options, Im Type cleanType = type.CleanType(); if (cleanType.IsIEntity()) { - if (implementations.Value.IsByAll) + if (implementations!.Value.IsByAll) return ImplementedByAllSubTokens(this, type, options); // new[] { EntityPropertyToken.IdProperty(this) }; var onlyType = implementations.Value.Types.Only(); @@ -397,7 +397,7 @@ static string GetNiceTypeName(Type type, Implementations? implementations) case FilterType.Lite: { var cleanType = type.CleanType(); - var imp = implementations.Value; + var imp = implementations!.Value; if (imp.IsByAll) return QueryTokenMessage.AnyEntity.NiceToString(); diff --git a/Signum.Entities/FieldAttributes.cs b/Signum.Entities/FieldAttributes.cs index b3ee96e33a..ca44378356 100644 --- a/Signum.Entities/FieldAttributes.cs +++ b/Signum.Entities/FieldAttributes.cs @@ -250,7 +250,7 @@ public class SqlDbTypeAttribute : Attribute public SqlDbType SqlDbType { - get { return sqlDbType.Value; } + get { return sqlDbType!.Value; } set { sqlDbType = value; } } @@ -261,7 +261,7 @@ public bool HasSqlDbType public int Size { - get { return size.Value; } + get { return size!.Value; } set { size = value; } } @@ -272,7 +272,7 @@ public bool HasSize public int Scale { - get { return scale.Value; } + get { return scale!.Value; } set { scale = value; } } diff --git a/Signum.Entities/MList.cs b/Signum.Entities/MList.cs index 73edeae855..1475f4d921 100644 --- a/Signum.Entities/MList.cs +++ b/Signum.Entities/MList.cs @@ -682,7 +682,7 @@ void IMListPrivate.SetOldIndex(int index) { var prev = this.innerList[index]; - this.innerList[index] = new RowIdElement(prev.Element, prev.RowId.Value, index); + this.innerList[index] = new RowIdElement(prev.Element, prev.RowId!.Value, index); } void IMListPrivate.ExecutePostRetrieving() @@ -695,11 +695,11 @@ protected internal override void PostRetrieving() if (this.innerList.Any(a => a.RowId == null)) return; //The MList was changed in the entity PostRetriever, like UserChart Columns - if (this.innerList.Select(a => a.RowId.Value).Duplicates().Any()) + if (this.innerList.Select(a => a.RowId!.Value).Duplicates().Any()) throw new InvalidOperationException("Duplicated RowId found, possible problem in LINQ provider"); if (this.innerList.Any(a => a.OldIndex.HasValue)) - this.innerList.Sort(a => a.OldIndex.Value); + this.innerList.Sort(a => a.OldIndex!.Value); } public bool AssignMList(MList list) @@ -758,7 +758,7 @@ bool IMListPrivate.IsEqualTo(List.RowIdElement> newList, bool orderM } else { - var current = innerList.ToDictionary(a => a.RowId.Value, a => a.Element); + var current = innerList.ToDictionary(a => a.RowId!.Value, a => a.Element); foreach (var item in newList) { diff --git a/Signum.Entities/Signum.Entities.csproj b/Signum.Entities/Signum.Entities.csproj index 8d977101ff..073a35f08c 100644 --- a/Signum.Entities/Signum.Entities.csproj +++ b/Signum.Entities/Signum.Entities.csproj @@ -9,10 +9,6 @@ x64 - - 1701;1702;8629 - - diff --git a/Signum.Entities/ValidationAttributes.cs b/Signum.Entities/ValidationAttributes.cs index f887a6f714..b4fb6f875e 100644 --- a/Signum.Entities/ValidationAttributes.cs +++ b/Signum.Entities/ValidationAttributes.cs @@ -66,9 +66,14 @@ public string? UnlocalizableErrorMessage public class NotNullValidatorAttribute : ValidatorAttribute { + public bool Disabled { get; set; } + protected override string? OverrideError(object? obj) { - if (obj == null) + if (Disabled) + return null; + + if (obj == null || obj is string s && s == "") return ValidationMessage._0IsNotSet.NiceToString(); return null; diff --git a/Signum.Entities/Validator.cs b/Signum.Entities/Validator.cs index 559bc02249..73aeee33cb 100644 --- a/Signum.Entities/Validator.cs +++ b/Signum.Entities/Validator.cs @@ -6,6 +6,7 @@ using System.Reflection; using System.Linq.Expressions; using Signum.Utilities.ExpressionTrees; +using System.Runtime.CompilerServices; namespace Signum.Entities { @@ -52,8 +53,6 @@ static void GenerateType() where T : ModifiableEntity validators.SetDefinition(typeof(T), dic); } - - public static PropertyValidator OverridePropertyValidator(Expression> property) where T : ModifiableEntity { GenerateType(); @@ -164,6 +163,10 @@ internal PropertyValidator(PropertyInfo pi) this.PropertyInfo = pi; this.Validators = pi.GetCustomAttributes(typeof(ValidatorAttribute), false).OfType().OrderBy(va => va.Order).ThenBy(va => va.GetType().Name).ToList(); + + var nullable = pi.GetCustomAttribute(); + if (nullable != null && nullable.IsNullableMain == false && this.Validators.Any(v => v is ValidatorAttribute)) + this.Validators.Add(new NotNullValidatorAttribute()); this.GetValue = ReflectionTools.CreateGetter(pi)!; this.SetValue = ReflectionTools.CreateSetter(pi)!; diff --git a/Signum.React/ApiControllers/QueryController.cs b/Signum.React/ApiControllers/QueryController.cs index 53bced9496..4ea361fc88 100644 --- a/Signum.React/ApiControllers/QueryController.cs +++ b/Signum.React/ApiControllers/QueryController.cs @@ -51,7 +51,7 @@ public async Task FindRowsLike([Required, FromBody]AutocompleteQuer }; var dqueryable = QueryLogic.Queries.GetDQueryable(dqRequest); - var entityType = qd.Columns.Single(a => a.IsEntity).Implementations.Value.Types.SingleEx(); + var entityType = qd.Columns.Single(a => a.IsEntity).Implementations!.Value.Types.SingleEx(); var result = await dqueryable.Query.AutocompleteUntypedAsync(dqueryable.Context.GetEntitySelector(), request.subString, request.count, entityType, token); @@ -365,8 +365,8 @@ public Pagination ToPagination() switch (mode) { case PaginationMode.All: return new Pagination.All(); - case PaginationMode.Firsts: return new Pagination.Firsts(this.elementsPerPage.Value); - case PaginationMode.Paginate: return new Pagination.Paginate(this.elementsPerPage.Value, this.currentPage.Value); + case PaginationMode.Firsts: return new Pagination.Firsts(this.elementsPerPage!.Value); + case PaginationMode.Paginate: return new Pagination.Paginate(this.elementsPerPage!.Value, this.currentPage!.Value); default:throw new InvalidOperationException($"Unexpected {mode}"); } } @@ -423,9 +423,9 @@ public SystemTime ToSystemTime() switch (mode) { case SystemTimeMode.All: return new SystemTime.All(); - case SystemTimeMode.AsOf: return new SystemTime.AsOf(startDate.Value); - case SystemTimeMode.Between: return new SystemTime.Between(startDate.Value, endDate.Value); - case SystemTimeMode.ContainedIn: return new SystemTime.ContainedIn(startDate.Value, endDate.Value); + case SystemTimeMode.AsOf: return new SystemTime.AsOf(startDate!.Value); + case SystemTimeMode.Between: return new SystemTime.Between(startDate!.Value, endDate!.Value); + case SystemTimeMode.ContainedIn: return new SystemTime.ContainedIn(startDate!.Value, endDate!.Value); default: throw new InvalidOperationException($"Unexpected {mode}"); } } diff --git a/Signum.React/Facades/ReflectionServer.cs b/Signum.React/Facades/ReflectionServer.cs index 85316d5a3d..49c1a2cf22 100644 --- a/Signum.React/Facades/ReflectionServer.cs +++ b/Signum.React/Facades/ReflectionServer.cs @@ -283,7 +283,7 @@ select KVP.Create(GetTypeName(type), OnAddTypeExtension(new TypeInfoTS .ToDictionary(s => s.FieldInfo.Name, s => OnAddFieldInfoExtension(new MemberInfoTS { NiceName = s.FieldInfo.NiceName(), - Id = s.IdOrNull.Value.Object + Id = s.IdOrNull!.Value.Object }, s.FieldInfo)) }, type))) .Where(a => a.Value.Members.Any()) diff --git a/Signum.React/Filters/SignumFilters.cs b/Signum.React/Filters/SignumFilters.cs index 5225dfd50d..ad6aef32d9 100644 --- a/Signum.React/Filters/SignumFilters.cs +++ b/Signum.React/Filters/SignumFilters.cs @@ -43,7 +43,7 @@ public class SignumAuthenticationFilter : SignumDisposableResourceFilter { public SignumAuthenticationFilter() : base("Signum_User"){ } - public static readonly IList> Authenticators = new List>(); + public static readonly IList> Authenticators = new List>(); private static SignumAuthenticationResult? Authenticate(ResourceExecutingContext actionContext) { diff --git a/Signum.React/JsonConverters/LiteJsonConverter.cs b/Signum.React/JsonConverters/LiteJsonConverter.cs index 8db15e2258..e585d1ef39 100644 --- a/Signum.React/JsonConverters/LiteJsonConverter.cs +++ b/Signum.React/JsonConverters/LiteJsonConverter.cs @@ -73,7 +73,7 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s PrimaryKey? idOrNull = idObj == null ? (PrimaryKey?)null : PrimaryKey.Parse(idObj, type); if (entity == null) - return Lite.Create(type, idOrNull.Value, toString!); + return Lite.Create(type, idOrNull!.Value, toString!); var result = entity.ToLiteFat(toString); diff --git a/Signum.React/JsonConverters/MListJsonConverter.cs b/Signum.React/JsonConverters/MListJsonConverter.cs index f8077db8d0..dd2042f9ce 100644 --- a/Signum.React/JsonConverters/MListJsonConverter.cs +++ b/Signum.React/JsonConverters/MListJsonConverter.cs @@ -64,7 +64,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist static MList ReadJsonInternal(JsonReader reader, IMListPrivate existingValue, JsonSerializer serializer) { var dic = existingValue == null ? new Dictionary.RowIdElement>() : - existingValue.InnerList.Where(a => a.RowId.HasValue).ToDictionary(a => a.RowId.Value, a => a); + existingValue.InnerList.Where(a => a.RowId.HasValue).ToDictionary(a => a.RowId!.Value, a => a); var newList = new List.RowIdElement>(); diff --git a/Signum.React/Scripts/Signum.Entities.Basics.ts b/Signum.React/Scripts/Signum.Entities.Basics.ts index 5c01566fb3..c802c1816e 100644 --- a/Signum.React/Scripts/Signum.Entities.Basics.ts +++ b/Signum.React/Scripts/Signum.Entities.Basics.ts @@ -9,54 +9,54 @@ import * as Entities from './Signum.Entities' export const ColorEmbedded = new Type("ColorEmbedded"); export interface ColorEmbedded extends Entities.EmbeddedEntity { Type: "ColorEmbedded"; - argb?: number; + argb: number; } export const DeleteLogParametersEmbedded = new Type("DeleteLogParametersEmbedded"); export interface DeleteLogParametersEmbedded extends Entities.EmbeddedEntity { Type: "DeleteLogParametersEmbedded"; deleteLogs: Entities.MList; - chunkSize?: number; - maxChunks?: number; - pauseTime?: number | null; + chunkSize: number; + maxChunks: number; + pauseTime: number | null; } export const DeleteLogsTypeOverridesEmbedded = new Type("DeleteLogsTypeOverridesEmbedded"); export interface DeleteLogsTypeOverridesEmbedded extends Entities.EmbeddedEntity { Type: "DeleteLogsTypeOverridesEmbedded"; - type?: Entities.Lite; - deleteLogsWithMoreThan?: number | null; - cleanLogsWithMoreThan?: number | null; + type: Entities.Lite; + deleteLogsWithMoreThan: number | null; + cleanLogsWithMoreThan: number | null; } export const ExceptionEntity = new Type("Exception"); export interface ExceptionEntity extends Entities.Entity { Type: "Exception"; - creationDate?: string; - exceptionType?: string | null; - exceptionMessage?: string; - exceptionMessageHash?: number; - stackTrace?: string; - stackTraceHash?: number; - threadId?: number; - user?: Entities.Lite; - environment?: string | null; - version?: string | null; - userAgent?: string | null; - requestUrl?: string | null; - controllerName?: string | null; - actionName?: string | null; - urlReferer?: string | null; - machineName?: string | null; - applicationName?: string | null; - userHostAddress?: string | null; - userHostName?: string | null; - form?: string | null; - queryString?: string | null; - session?: string | null; - data?: string | null; - hResult?: number; - referenced?: boolean; + creationDate: string; + exceptionType: string | null; + exceptionMessage: string; + exceptionMessageHash: number; + stackTrace: string; + stackTraceHash: number; + threadId: number; + user: Entities.Lite; + environment: string | null; + version: string | null; + userAgent: string | null; + requestUrl: string | null; + controllerName: string | null; + actionName: string | null; + urlReferer: string | null; + machineName: string | null; + applicationName: string | null; + userHostAddress: string | null; + userHostName: string | null; + form: string | null; + queryString: string | null; + session: string | null; + data: string | null; + hResult: number; + referenced: boolean; } export interface IUserEntity extends Entities.Entity { @@ -88,8 +88,8 @@ export interface QueryEntity extends Entities.Entity { } export interface SemiSymbol extends Entities.Entity { - key?: string | null; - name?: string; + key: string | null; + name: string; } export const TypeEntity = new Type("Type"); diff --git a/Signum.React/Scripts/Signum.Entities.Patterns.ts b/Signum.React/Scripts/Signum.Entities.Patterns.ts index 9aed945225..97291589f4 100644 --- a/Signum.React/Scripts/Signum.Entities.Patterns.ts +++ b/Signum.React/Scripts/Signum.Entities.Patterns.ts @@ -12,7 +12,7 @@ export module EntityMessage { } export interface LockableEntity extends Entities.Entity { - locked?: boolean; + locked: boolean; } diff --git a/Signum.React/Scripts/Signum.Entities.ts b/Signum.React/Scripts/Signum.Entities.ts index b33677adbd..a207a8a6ed 100644 --- a/Signum.React/Scripts/Signum.Entities.ts +++ b/Signum.React/Scripts/Signum.Entities.ts @@ -250,7 +250,7 @@ export module ConnectionMessage { export const CorruptMixin = new Type("CorruptMixin"); export interface CorruptMixin extends MixinEntity { Type: "CorruptMixin"; - corrupt?: boolean; + corrupt: boolean; } export interface EmbeddedEntity extends ModifiableEntity { @@ -281,7 +281,7 @@ export module EntityControlMessage { } export interface ImmutableEntity extends Entity { - allowChange?: boolean; + allowChange: boolean; } export module JavascriptMessage { diff --git a/Signum.React/Signum.React.csproj b/Signum.React/Signum.React.csproj index 35dcec7fe0..9f76b8e960 100644 --- a/Signum.React/Signum.React.csproj +++ b/Signum.React/Signum.React.csproj @@ -12,13 +12,9 @@ x64 - - 1701;1702;8629 - - - + runtime; build; native; contentfiles; analyzers all @@ -30,7 +26,7 @@ - + diff --git a/Signum.TSGenerator/EntityDeclarationGenerator.cs b/Signum.TSGenerator/EntityDeclarationGenerator.cs index f4c543959f..38f4319ebf 100644 --- a/Signum.TSGenerator/EntityDeclarationGenerator.cs +++ b/Signum.TSGenerator/EntityDeclarationGenerator.cs @@ -434,7 +434,6 @@ public static CustomAttribute GetAttributeInherit(this TypeDefinition type, stri return att; return GetAttributeInherit(type.BaseType?.Resolve(), attributeName); - } public static bool? InTypeScript(this MemberReference mr) @@ -455,13 +454,10 @@ public static bool GetTypescriptUndefined(this PropertyDefinition p) if (b != null) return b.Value; - - if (IsCollection(p.PropertyType)) - return false; - - return GetTypescriptUndefined(p.DeclaringType) ?? true; + + return GetTypescriptUndefined(p.DeclaringType) ?? false; } - + private static bool? GetTypescriptUndefined(TypeDefinition declaringType) { var attr = GetAttributeInherit(declaringType, Cache.InTypeScriptAttribute.FullName); @@ -476,10 +472,7 @@ public static bool GetTypescriptNull(this PropertyDefinition p) var b = attr == null ? null : (bool?)attr.Properties.SingleOrDefault(a => a.Name == "Null").Argument.Value; if (b != null) return b.Value; - - if (IsCollection(p.PropertyType)) - return false; - + if (p.PropertyType.IsValueType) return p.PropertyType.IsNullable(); else @@ -614,14 +607,7 @@ public static IEnumerable AllInterfaces(this TypeDefinition type) { return type.Interfaces.Select(a => a.InterfaceType).Concat(type.BaseType == null ? Enumerable.Empty() : AllInterfaces(type.BaseType.Resolve())); } - - public static bool IsCollection(this TypeReference type) - { - return type.FullName != typeof(string).FullName && - type.FullName != typeof(byte[]).FullName && - (type.IsArray || type.Resolve()?.Interfaces.Any(i => i.InterfaceType.FullName == typeof(IEnumerable).FullName) == true); - } - + public static NamespaceTSReference GetNamespaceReference(Options options, TypeDefinition type) { AssemblyReference assemblyReference; diff --git a/Signum.TSGenerator/Properties/launchSettings.json b/Signum.TSGenerator/Properties/launchSettings.json index c7ae0b7438..3d6a108df1 100644 --- a/Signum.TSGenerator/Properties/launchSettings.json +++ b/Signum.TSGenerator/Properties/launchSettings.json @@ -1,9 +1,19 @@ { "profiles": { - "Signum.TSGenerator": { + "Framework": { "commandName": "Project", - "commandLineArgs": "\"obj\\Debug\\netcoreapp2.1\\Signum.React.dll\" \"D:\\Signum\\Southwind\\Framework\\Signum.React\\obj\\SignumReferences.txt\" \"D:\\Signum\\Southwind\\Framework\\Signum.React\\obj\\SignumContent.txt\"", + "commandLineArgs": "\"obj\\Debug\\netcoreapp2.2\\Signum.React.dll\" \"D:\\Signum\\Southwind\\Framework\\Signum.React\\obj\\SignumReferences.txt\" \"D:\\Signum\\Southwind\\Framework\\Signum.React\\obj\\SignumContent.txt\"", "workingDirectory": "D:\\Signum\\Southwind\\Framework\\Signum.React\\" + }, + "Extensions": { + "commandName": "Project", + "commandLineArgs": "\"obj\\Debug\\netcoreapp2.2\\Signum.Extensions.React.dll\" \"D:\\Signum\\Southwind\\Extensions\\Signum.React.Extensions\\obj\\SignumReferences.txt\" \"D:\\Signum\\Southwind\\Extensions\\Signum.React.Extensions\\obj\\SignumContent.txt\"", + "workingDirectory": "D:\\Signum\\Southwind\\Extensions\\Signum.React.Extensions\\" + }, + "Southwind": { + "commandName": "Project", + "commandLineArgs": "\"obj\\Debug\\netcoreapp2.2\\Southwind.React.dll\" \"D:\\Signum\\Southwind\\Southwind.React\\obj\\SignumReferences.txt\" \"D:\\Signum\\Southwind\\Southwind.React\\obj\\SignumContent.txt\"", + "workingDirectory": "D:\\Signum\\Southwind\\Southwind.React\\" } } } \ No newline at end of file diff --git a/Signum.TSGenerator/Signum.TSGenerator.2.0.0-beta2.nupkg b/Signum.TSGenerator/Signum.TSGenerator.2.0.0-beta2.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..1fec0f6c94710be8701b0f80abff128602972dfb GIT binary patch literal 261558 zcmV)5K*_&QO9KQH0000805yqAPS@M9$r1qo0006201E&B0AF%tY;!Lza%F6Dm61(r z0x=MV?}h${kh`1gx*xH)dMv%Fe_))QtfA(EBue}5n}Y?V6x!o3^FF)}v)+E#GrLku z#=DW%mE?>Z`pLL?`$if=d1PwO3>A(xwUG9j@Na%tqJoWqL{2~T7pRX&g_8||Zo zT*f$y0Qe3wiAKs^#CrxWRK^~-?C=@r2h|#kK6#xh^!5fU?FzD%LJq=$Gn!K7>;Q45 zJaVx&v%A>puzw{-5wee!yQDzK+1oVoom%#Qx>3iWty|d)oQc1-`In=xlwpDl0)3=K zh$S7fp>)^vJDn(A4btx!fwCKPLlZ%dEy4=a5(ll6I`+Elw5~$36NZ~(*VmJ3S4Z8+ z;s`g#wRm{s<_l0u0|XQR000O8HHk}3x%1)q6aoMMzb!{$GQ%7ZP zWpZJ3Z*nefb#riKV|7!(ZqzUky(94tqg;Av?cIt)g}kXyMG;a<1-pEJ*O?@yiS2qE z()~6Ld=kIFWaE@Q&_g80^XAQX-kU$aeyi)}zJs3_$$Gab)?!rvI^!$rnoTjJ`r@j% zF5kXUL7PY2ATZp~rf5?N@1-QuVy{W`)7Q-4x>&!D#_OwkXtM-#Y(I$_MCpHm$`3lr4*%?02#>K;cQA3=xES)&tEkdkwDrqV-deWdcC>pfK1!HthmcS+e!A88Z1|8uCV=yG`43@R-2$g&_p7Xmo@I7|rGi2etfv@kHiIF5pj6RDSh9K}=e1iPqXygMx(^(Y#f+F?HsMh+%)v-C6L z(;9i4%7aNt?MH`FFU?tf7q3G}PkoILVFAhiff_#D0t7>|d0Bx2X|=^;#9lT*$C zlMzD6(`Ix3#)m_+O`FP_1QY-O00;o&d^JtkAk(CII|2XzAO!#v z0001Db!lv5FHLW5Z!SY+V`*$IWNd7_y$OI6#q~elQ{B_ubL_(GF|!vt3%E-&vpc{p z3#%w13MwipqG7#26ctq3?4U-6MWe>30gOg-5H-dlr$^M7ctjKLE8a2jM2%PO<9p=% z27mAKs;awZ4>jN4|Nld0yXsZdtEyM8UcGvC9dP*P4bw0Ti+&$`U>J8A^4|jEqyL>l zzuNrWwZ``oPfflvw*OO;m!G({+;QrVf5Ol)r*s^9%=-2IhK|*1I)+YL-?4Um$6f~> z(s7D^+?rBNO>!rN>v?X2@Zvp*Z8d`I*PZ86q z%#5pjRJ?^Fi@E0v83$z(M%?)R{=(SnEny@^#QR%MoZI`O{!J0N@(jaB7N&@-bj%m# zFtue;Si`g6-zF;XZeD5_t=&zc0$}&V2+;3BwBGC%c+TmCXO0+(8OEum*9TwyOw(wh zya<#LJtAA!)J${{b%sBif_p@+U>ACY*H0dQ4&zdux$qc9{mhs#iR(-0IV5TO14!!F z{?3SF`@2Nb&5L>lqMlu4c`TzoChK3`jUb)R9zmt^=99D8-<<(RX+Vnt9IXMZ3b0ZG z+7w`w224_bV>F;$0aj~3KA|9;0VJs)#|Ds;f*cn>(h9OBfYd0+@d2b(K~4xD6BJ~6 z0GX&DCkBu@hMa?TDYT2q0+4CQl#X7zya#>G5*6acqy*=TTar$%|%k=jG z^T@c?^&GiNdbh4EtT(g036*AsPGfqDkY6&Z{+~mT#hSaQ{acBDrYe3_*$UIT0ioXB z`4t#$2qmUpN#GAPv03Ya8IjgXn95 zx0x(DN}nTg{!*^14Db&OLWP7R?c55+WSdNA0u!zz0r4s9Lc}_l9F03-*&VUMGSw(q znb;$`6uECM8A01|ia||#2p1>kEg#v$BXTyFPQ+3Wf0;;|kHt$#VVnM;jJZ)_9)S$F zN}5KpN=du1j|7P@ZJE*@D`l>5x9|@OimL1V2|%(;w-GrVrXre_in>DOA2+5@{_&uV zw#ahJ*mgD&+b%4NRCkuDE^ye!p^DB{c1GN^1}DaJN0_9@p-H+z!p%WOsT$joO-+gG z6%$DC8mn%Cny(GUe8wyw>s@JOB%$qUb*3={<|L%A&)JQ~%K-S(z-jAg=K z3kK?I5dJ!p**^(6X3Hm|-MD6 zZQI@ug}=sqV`)|8$V?*97P$#n8#E zNRg6v2I%*8R*fsmRXTHsN^+|IDRjFK$22E9D{T(#9t4>h>2``CK~c2NnnQaAaSKtJ zv{hH+NL1uZt_VVWH%b#yEJ0LFle8(yyHa)mQ6^R6ItsYXVq6IE6TlVCyS+O8(THE+ z_z3ZnGVdo;cA|kZ$yX;@i9{PY5kmYF6159+Wp;;I=(V~nVXmSf^!Swww4frysaFz! zdYFYEYo!WAie0SkIHh=wlRQUCow;(IwVqNP9q&#vjFUa5(mh8ChkqQ}k^0o}^hHO{ zN}Wd-R4gOKZMb)&4c8(15!4Y?TkcIwH%vk4k!|Yw?@@p8b1ucFfc?V8Rw1L>dK23E zd*;xgVOwKffiWe`^ODB)WSy}iI}kI3e>R0neNLB`CNf41^Xe+uQHw29wsTN6)Ade3 zv&Aj<;DBR4jqF~x8V=4%{bfclcJ&ck^DKyD7|CLYifpo2E9^^6`_fQwY+c*?yIkRF zu^BSX1$%9+1?g^q(0#^C^(5Ili$3M4H z0w}?W)cUQQ0Qt}q5jKR3_seM*q?6|pqBW}}&#Eq1-dCam73I9T1afN>oeQ6Rih)K-FI`DJVfj5MKBk{M4 ziT`NPQ$Ha#E{!7T+dhnzk$9~iGv1`}<5{f#W$1rzGnB_VqvJLQN@#ftbe^sBCq)DB zCGRcW2IIT#7Y0~boH+|k<>%*l;eVL(b3)7Gn#p{4YXbbEF z$s%!f*73gp1;ftTTi5!RLoTPXGvAkemsBYlnS-_!%>|lvU4b&%`B{UDU_}zL=s?ZC zVn#G`l>E#R_4jO{snATyQxMmc-4tkzV%^Z6sRau|@fiL#^WPcxOMPK48^YP-vZJpw za$or(VP0GQ5=hd4X&hH1T}(J`)|M43&-C1kbhKW!3f$MxT) zukPnpp`X7d)qW-KA>*1D$C-{CV1<8{!q!IEu4ZiBg^-cn*SN`CjqVztd$pmkL^KWN zQ*#`VZyLEZ|S!NcFqohHD z_emDNAs~zM69yO6NnM10Y4uBv0ZWev9~lonJHJOMZs!;Eaq$-me;O5{lO%oluNI^Y z#yGq40kNkq;Y&O$9FmZQIJ_#n_m%hxVlgV7m5n*+WMJ zo@RUK%)pbjhrX#jgn5c+@`&?oQiJjnrHjXTn)gCZWa`9@#yS!~brd}OHQTV!(z0#_x8k>eM3ldc zLH9fKr(@wEOBU{krMA1m_P?vpDSY)tqbJSs;1g2fjmfM-ExELVxXW1CQv-L>G?(O7 zEH54bPkzD5o_3CL_6Hw)u(EwM)fd5+u0pgXiZ+`=cSmTxDG1I_T)m3jO)D;KSI%aY zs%6D;yCD19{WQgzf-)?EXoW3)5&cMKG2Wp0eS+lfzV!Ph{hp)WKk3&=YTp|AeV%@= z(l1W3bl_8z(rh{|X*RD+yNgVPYNBLJV_;A%GKkc`V&#mb2IeVeYieNTho^5=F|E{q zt(GOFY$c{ijt;)R`J%#jh?xCa}7{}3%=Ca0Fs?Ie086<)Y zVi@CA`u&K0kJ9gX`n^uSU!gFYRkn6&;7lth*Lo|c*RfVm+Z9$&+5?m`ks4U2oXOO{ zTykcq{t8l?8t4pb)uNmYseuW~nMn;;%Gr_{_`4ZU@DIw_ks5egIj5!uUQ*7k)WB29 zIW0BtfO2}NfgdVoAvJKLa(1T%zOJ0b)W8?XY37KsIU;O#!p)T?4qR*o)jq=vDtNN_ zp>24m8Bk@R8BlO;SnO`3Z>IEW;*n*UJ*M0rO9*k2X_eV!Jh>+ygH z=zEI@sDAwzF~1z*{EP@1@2oLmt``AqjtCPSBtDcjJBy&1xgO( z{-?&O`d{lfjW=HZJA;0t+Zv=s7&JZ_q@@`&Fc~DEja%sVL;C&LkbUtP`q9kJc!Pd4 znKS-~8vV@(it?@zG{7rHP?cwlpx6%?0n6TH1by;mBcLD+Y#`5-M$jiOH3IIqz|cHX z+=Oo?RXkl1vAABcTJd{YrY$a&jagibua_#$$G4Cw&cU}kRV?9KOclHE zotY}OIUGohsV+_LJ^W9)=FEX(!XLwEpzpG-;waK_;7=5cAG-F@(~n z90>OX^s4|nvCc~RZKEH0(R5)&LUUJVak@8 z`725_{B14O44jI2TXq$V&Gc(pRTw9!Rchp~Tgvb^M@jp~PTD#mX~V*6=r23%{=H;D z`m@f?JI53>Hm`-81MkI^U(Bo3LDsx~25IO04!rXd9V^-2B}+8#9UUbx?{)1=&igrH zU#4T%&U;!1W#&DnoelHuN34@|tf~F`^0%eGRn~Iel{#w6Jk(-f4;{62-W58iW8Nj& zId$Geh}EiNdHs|4+f_P~ztc*mOL(a~@E1!(DwIy*Z?SX=f4fVo241$RX=^vruZ4cC z^lPKvB>J_}FQ34lB>trECyhTf_*08N6Yysu{$%i{4u9(LrvZN&gGS4ZYVR7=-U%KH zby>z?524t@R_xJ1?2)y`WRK>NN&6cWbCwjUDFe_{6u!xl`U-z*sd3;wb8OO#QEIuPYl?a$3i#e%**0YQgqf1&?mB_6s|-~X?$@Bbm}`>b&0b*gD9&#rkd>L}CZ zVPqTlAMN+%J*1t5dG{gcE$yGF@+!{zo(6TZ2$G@mFyIc{uKj%~uikl^1JFDSegmJ^ z{@JBX{OvDQiktqQh!#7KT=K{!k9_jTC{H;>Y#o+y7tw2{syPiTjdSUDF#S$24RLSrqUKTXNzEx#v*>U{QpXv*o`$ofG~RlwiEfCeN_=Cdl~ zUt!2Uzz)eK8IWzcvNP9yC26Wg6wwD^^d~8xIoYZL{vHP0R)r_uK#1}=!nCal-Ue`z zz~_z1w(ZJP@zgNS9Rcd%;mxDc7Z*1rTU5-yhB0S`D4P_@NmOlJT*C=s+Ol1;>1<80 z!E_Rr`Ztl^<>mQwBDbO@;n1}GJvW!1Xb+O=xVl%g6q*WKvstyKc@9=R%h;B3&g8%~ zMeXXDj_(v<4o_Erf(Ec-z1WBV?`Af4h>Zp9;pJMHN?0=PeZspIW}V3r>t=bASTN*$JG;;(9*9a+?r4b_q5sz~{J z@3n{C4N%$~6AS!@3)AakgWzdY2$63Xh5?Z2ff>UzxmV_9L&vakeX)YD%6Dj5XOqPy zMemrTx5M;i6Oq;XPJogarCT!!JJv~nHh)W>|67=(dRZdp%A25Q+iGoe9po&xPf4|V ziQB!>gLG`w>y;j{5g}sJPTIgXl?{ArVBq@!8~707PlTyg#SPty$sqYeE;|%6d4qawQ z6f+eHeEqvepg2#Vm>Hs&8KO8Jq3v=Hnd~31y-yG5L|sr8{*x%K@a{0AZFQpU`1gQa z09Q8EAAwQcFDw&gc@9B4Eq@w)yq~aH(x}?w)sq_fbxiM8!`?NT6)T_Roe4(qyC`jQ zUuvjX=rteH@@{}Z7FO9#0XE?so8Lhu4;xHd)BA4VqoA9rf^H6c3#Dndvqyu_0=OT=Yp z3)^T5tA+QU=u;719$q9FpA!7nm_d}&Zumk_!XX-l7c2OD4WC~P-yL6SGH)qi9NxV; zaDgs1JLX704g-NrX_VK*HY>X-O13&mHX3EIgmqvil8m-mL_lLk6{Dky>Zl7vWe;X> zyGxSqZYnh(LI!vl>a8Sfz3m_zN5OWYpt4d%U~gQ3d4Hi!(>)MD&{GuNuh9eAc^xWc z+gsPR4?5X)-iw6qy%;MTiJFmwB?9rQvt;}9E>P|`&pl!Oa5_xVbNXEGJ_z!n?fsYq zdfJx7@ToT?YqlrdZrhb+??hmy&Kna-((av9>-~*H&~C=PSjjxjSq&1BS(Hd0nkoYE zJ~UlKMhfsmi+_JGHdIHQ7mW(ulB-It^c3Sm2Sg%A6CM?~g@@(+lp{&p?QHG#vT3Yu zxtD;-L&Fr)dmzZ)&8ag61s@giY1iYzf2Vu+>?^$}_hhtW80PufoSKc~n8 zm>wj81iQ%u^;X8(y0)p58v1>JJ7ZnD884RrL_J_6ka?Uka{~K=_g|?Aurdu=?La-|5wmY>YZYz z&HFDhPKJI>hd23;VZj7;Oz&}WU6~>IU+-ib8I2m|8Qny?zrW*y4_E;1sU^vtO0?{y z0edOHA`M{2#d=RPR7ok8cy3kR7zn%VYUi`(qf0A+XGP>#mNOfbj>Ix+37b?FX8BZ- z*28;qm&IRe_-iqWcbF-?erL?ENnU&ZF!b6TWre*o8Pne>hPAt%8X2{D_*+O>zL)u# zHAh>9IK#J5h$B72J%+aZS;qC4#<8B{r!kW3pfsHvEooLRphVpnTROZt?03DETxR97 z2uRz~F?=1vE(EO3mJZwZEvnTW9CDEkxrjqHAmsaSn%=*Vo&Q(*OP>G1$Nw8|xj|ua zeJQ(gHAVC@aSGveR#<&!aot;Nu6wQNw?TWd%l#<;x_1@!@HNQSZ^BCI1X~Dy83yiI z6ke>Mw&DQ4Hw7wn*9gb-+X48t4RT$D{GP!cm^vYSqI^=4g1=>J`tNJVwNuldf*f3t z^%t>z;_u648rlz>{)7}nD$E{QtAX9FXi^Ds@_Uw|AEsxq7rPO-RM?E5N;L%7MAJWwzMJ`siLAk} zPU>>BiuNYh`)Tb>vG;84O~<%eb}Xo!q^-%T5`EnEpHe#^GJ=%RpQ1X5r^BcxVMLK?^Vg~GsmO~?^?M`(fI~xv7vHo zl;s$>7{ig{KaZkNLU0q6D9)|ydP(-Kh|3%X<3XmI6zH&cm?`su%-i*ULIE`i|7DJs z@L$#O68;+s^k$GW5iRcvRFd7-eel5ty06lBA@_jtPC?LaXT9Ik^&hZhIUcfuqCKWS zkK1F?gLmuQr|7X5mN&+Iu4Vn(&W!UMg|nS- z{#@eRf9yv31rWSk7&0qgk1<~uQRVMxU1^w}^fvrVChxY|4 zb9f1Vco-bsk7pF+(-Ty_{V|9?O(7#w%Y>FpXhjmnhnK2J(!M+@JO=y360@bx5#Bdl zo?qYK>ODN96F@#>WaP?GCN@^}G|-T^4>_Aw4C5nb7PjzOslL9KQ1zQMW?EatHf2P` z|M@ZE3cJT_D%y7C=crXvOqMAQ`w4WP5qN8?hJ)j^R<<*>+*wZOE%Nx&k;T<2;*lm# z!~%DS*FOdEjvhNONWU_Yer0v~BanWn&?J2n``S3|GE>mVk&7w6x6KIaO!}8GKdc8D z(DYADVDPNWve>?7S4cOrn8*?q-5jw| z0^rGacvE6>*Hrlh-U=qU!T*E7Bls-zFX1(#w(m($FF=LcL{_CV3!=&UI_z-5n}m2j zwAr19dpX<%)-_33bl*CI1(NrCgmIxOGS6H? zkoOADk6u-_Jh>?l8kK)!hg{GSaKUSk(^YNwEOltF z7`7S^m0vUTSyRF15Ee7^ z-i~o9mmatWBAuI{Mt3`4~}@+^JGDcKlCl&x!(w-tTk9YQ{sl5FjiUm|4!3sZSJ zu?@WFp9Gz04hZAA}+1E{FpAA(qdbVcYuy1flx=Jr{}f7j!0Q*~#%Q+Bqj?re=tVp~tzNeHTi zw=2aA`_;Qqq1T$Nw~7;-jJ3`Cgv%zM6`%*={YKXbE2;aTOp{h7?WVz2x&2$pH0&wc zpXtAIK!3B&@F&IPPG=r$cqKu`hwM0Dy!eh;ejhwy%2efFNyAvNO^|l`Yw-L+h{Qy< z<0QC=B)@ZHv=Srp^MuOLGMA<$(9JUuR$y5*y^4J0-@uZKKn?gU0BtaCke*8-rHu&Q zK`GMeTO$&#w@aWK&w7)_QJH@vC)4s8iTVBZxUMP{Z*pAgW-U~<1KDOn1o$1B*vh}> zk-@^Koz!biH&VQV5U)w~UF_iJ9+H&ZAtgVKU49sRjr%@GDV1^+y0I%;eE4+{y0;5m zS=Vns`P|_H;1Q$_K*V`_pr5TLd@iZSE#7=cn;RH`+0-Vz-ypB-HQhBX%@uY-k_V8a zpy$|=1KOjK9dT89)l^gBtcWa(8M>}m%sv=<&W#<7=Tj|2oXMSXcrRP1ELp59)tCv^ zmik&FL2(XZII%}@o)mrcmeP3>tVpew3F55kts7h`l`556nludd*BQ=mT?}8>862($ zJ19QJxz}aP#|vO`2&W(^)&A`mOWb;vDWBE^#vnzk5?}`2fq7r%j10wHqCy-p6 z%KuL`I?I?cj!dm=eQW4@NXXOenx`jJ^Yni~1gD4FwMZyQF^kcRN42Y`*M%6k?xWTS*S?pJkh!K`A7`^2n#uI`lm!XpjBT@g!D>#Fi%phI zg_~7Xa;hrqlP#3=nv=gl}D&r0%*iX#k7Sk}jW~AJcD))^%?=@3nZR>L(C47uK+WhTIf) zsC1yv;ggWWX(&%|Lv1J)>9aB`8j7-%SDgs-gjin(^|U>tx|5bzVD6`R7FQ`%L{EgO zLAtZUT|Q&k{+kx-f31-=V{+?s-4&i|2AsZwmBS1@@ z=(xE-swrCeTB*%a!~MpI+}FYFmT!%)o78Z;{UE2FVG@QNwI%j3Om8^dCrs(v_c~l>R@%5fJElf1=s5Q;vY3CDtO33}wY6Eh`e$vf_U*+#!(q z&Xi!NlOsWmaGgZ?UntRmdcXs%Un*>>9`Yv1Auo#|Z>NAJjzMzVI0`nL$_;$3s{%m^ zV(d^N5q{XqlbRT!*{(qD%9iUBEm5y<3Ph}WAz|(c$2%Ar7!!g~&3&hs70oTSBX-yb zDjP8>dyb0ba6iSJR!4Ii-4KqUk~LB`364XM<}FimyEUp;x_%Q?&-G5h$QLV+KNd5p z#hvS&;6?;n(`dogA_d#w5Nrr843R7WXLkD6Qb1ct^%rJTF84|*%qlMTC#uIB)r^%6 z@N8Yo7cpE#l`WWjGSEAW1!1@8@X@nKRNsu@m^rntcPP5V_f7E4E3$l~*iWlg?AJoE zw_;H25#l#hDfUuczCdL>hHZcH6kp0|8e9b95KeL0>Z{%O>BD)o>ZjdBgAb_k_v8LX z#&1!-;`CgyIKL@b+@&R1oYS5x_QHgmOwyEe!&c14{u)>k3-;=iZ3ZxKa+luD@oy_#_UT zSVSDSF^B^t(27_$lwyN=zZMet`lwi#E%FT?E+&o~B_^5(2c?3bKwvomLD9^DLg`wV z`yM|^Rz!8=l%I#Exb{eB?vLo6i z_u*}`YOJ=&QYy3!0?V~%o0e$XKv!8ijvOa3zMs_pAWS>kS8Bsnz5{nD)VTh43Eo8` zE5vJgXGdyb2|w>Z8A4O$B27tJl5R`t2@_&U-i>O@X}T>N$7suGqua7EpBvGZU8CC) z$FA0KJ&zByDi4EgC?2S(CI(XfJGiXEu4H0ZC28-UOqvoO2HPM9Vgq}XKSy7;z0@#( zed=z0Vrjt5ca+-XZgOsyq<1Vt(C{sk-N0{0fxidv&qjf71^C_w_&5g7rLkb(8>7Gj z0AIqQdn1FPWY#3OCzX=?&6Q>skBjDkcBE+)4x`iGlQ z9~e;j^c{oMYk1wk8s3ij%5sQ~EM_gMVN^I2Wy|fTA6`CU_mqPv+iezgW%OC`mCxN3TMP-m4uc_^32s6%@>=lf^OIXr&AuLA% zYU56=<*ZcL8LOdcz&7yh8dD-ix+^d0)7-krs_EXWpZ9<4#PNe%KsXpqgZa4*mu z^j%M7D&HIr*MWvtpk%VS{l#%!3}W|Q(#>Yo*C}^qS35cj3PhjHJw;1cv#p(FS6bLo z<~z1m4g{3#w?IecDt2e3>7|C|H{Pj;l91+>Y6HQsZn##mueKdcvLY=uOSDJ5F7eEcSyN4nP(}%5~*F8g1(KlQ?=ZKEkkyN>Yk*6??j(+ zqZ5|lT>5@8lrht_jA^SL>pG>3na(mMS5rJ7kTLC2w8Vwi&LRd2H!O9Wx_BTd?Y<^> z&t#(n_6nA}P|9h6_Brd8i0yfZX>w+j&eE-Q9PgSK&PE6|R%0$)9xpzL4_tB<=r}#B z<1mKuZWNG`qQbonR!P(GJ{5?Ht!sPV59Glqa+uACe8C*asY@jxx-_%o(@c*p$u(Aa zz|vZzN^7r(D3gw#rSQ1xds=>&k|V!exLdVIp-M*N3naE4MER%l$O_?#7%Y>qqvkYu zu0kz;6FRVo%`Xkik?i|^*)0k zD(AQfuR;jxOp3|LDRQwYdSs1Z*0*$gX}7U?J$p#npV%maO(tj}aCKIgxh?1O*(2+E zeElBQN=@7H+F^7k#e#D!;EmI{tv6M*b#JgPF(VePOIR3xu_tlt_;z__jPFK5n({0j zSWLf}nq$L>5WdQOlVkf$Z%mnP{JvOVpFzUjH#Kj~4(&5I%kZhNPZf2a>aOlnv!SyT zrT*9~sA;+1=xNB=v0xqI?U6>AqBP3nL7%>OaE2nJ&$(6g?H`9e&@av$FTP#wkI-jM zEHva`@g}4S+mSCu!_6H*nqcu}Zd~(%sc+}dw3(`D(>w-krb^n(SGskVm?Vv^5zDEq zEh;LkMo=J_Ea9CO67ar}1e_Wn;GDQTyRko)^~^-ncUD5L>)^J73d;b^#*t+kjGf8y zBohL_c6h*aOuyBPtXaW6wQ-#E5esJ0=DE!zT`ilZG*~HVC^+TCNx8z==t@&(d2d|a zIiRKJI%j?FyRNkP;-Kkp*yoaJi3Yojx@+Xu^e<%V2oK|FQ9;|*DD_rbudV(`%8Xq) zP&!0uR~1w`xOj$iCi@$t!!GTuAfP7785OSMEij+0myM$e&lXzR$g{rtx+ek1=It6Xl-!y6sBNw&nUmR0w%xIV8;X0PT zTU-;#4wrPJC<@`)!P%qoXpZKwdAvO4NAlP>GLL4RhsC<}Im|1?sGVDKc-Y|rrHynn znodd`q!>~1H1FZQw@=G)A+$y2lbXk@atb?3NxS=LtZIMExm?f7BlT>J*7NhsuiXtc z--e2H3#lWv@rH0UcH$87d0dxdq%N&om2joAmAkc3#d<&cXI0-1aVu@#!__ z)G`h9kMl#?(!^ykYhhr{OWXRU*`4gn$+gJx`zEKy%1x*2!~Q$C=&k%PruU8v!9*$+ zksSrib6RqIj)@nPN>0t9MN{k6m6p*HjC@kgFwVvx*AkQaK`e{|*ryP*cOySDWthTA#JUi^X>wTb6#Z5JL}29j>v32Q>tFf zVn!WbS|1V%#$DX){8^^m7eiYPie~ampGMSOq3YOt>v3UJxW8MB&mdLiLkXeD?P##(ChINI zTD>yNX{NUb?eO0A+B$Pb_6q$pNaQ}Z0Y5T!PwitQARl)*5q>U=EFS`puE? zC)gp8PlsD1l8S&LXP2R_OX4{=L&ZDH)Ht)2aBX3}saypDDh1?MvXZus9t9g0A3&$s z6Z9KLZqcu?O^0X0{?9OGRHsS1aJuHkYtcj-uY>UTc`UR8z+AaC?BkPlAFrwI<9o|K zK3UtfJkcz>wxzmuyiV;9PddDhbf0iB<7ap${7P% z9V&QBITJVK@X+bVp)+49C4_ByHzAc%HHbQ_6Q|wsQgn3eb*oD_{#zJJ4c5CJJH<_W--f!vFsp!%Xpje{{qu?n%>)LmzVJ@t9(dIZdAS7 z7=NRx{Mx~WRi~leZKzMwIZ|&*Wl|W&rj{C{qpPGK(@M3)Nh0HTw;)xbm~kkH+^^v; zhlq4DG^3aG$|TC)gpQK%Pr@f-`DOmPzK`9o$xMNkIPy-!tO z&xCP#xKFieyUEm2(v^jrR4hg}oT%~EuZv6VU+y|Fz3;K+uV;I5E34WM3!UK#xo3Fv z-0YifV2w#eEMgESZBBv>Vrkd^0gPn9o*{XYiGLW+V&&%MG!2`dKrNL`1A6TjLmAes zW!TK>Eu4RoTR6M5o^qlRU6$N|k49~ljVk>P)Fa-?@*cddlgJHb-17DW+92*f$6woj zmA{VvVnV6?GZRw5{h@7yyRBzk7V4;9VwrI(Xqlg7`fri&s-XcfB$kscuVBjyRiQ&F z=RCV`!VufLJ;qC1Tte4>KO)mHj(s^Y*BJ=sI+X4Kh`l>)xzCk@=m_mz--J&JyE zA8fuiO2zUZdSQ<=2Arf8HPRyAuQqKu`QCgVTdj$#@XVH;xavU4SWdK+>v54RT|R&S zgQQbF9P+sX7J*%&%XOC&f<33(n1pZ4`c)6Z69nSM*!OoQ9ifFN~DS{ zPUR-5f5Q6#h@E!)hmtswc4TNXISSnNkW-Ln|F1Uq=2FUUvbrr;_(${phV?X0S{dWx zR}Us}6jtIg8FROlOK(5H^zTi|_Wdbt>#g$jmQ4T0RiRPe%!vvcmyB?=Qf{j-3SLB7 zld&Uvb)Yq63vQq{WsJ&Ztv6W)^(o^@tW`Wtm^#hMF|Z&#L+;`45D65(tgNQLDqt%?8CO7;2c|`Hy8*y!LWexe|%J-ZD?TEL0Jox5jii1}- zgbKl!=B)7UjPZ_;v|T|2*FS;6xXmL7=00gwP7IMRvm@T}S|Gm#$Z-lng#dYCg?Cp> zPGd<;svrtU(RErkiQt&~nA`(|_X4kC`PCQQ3>;a6P!naR{6>-|j;|$Ezwa|cQl+un z7W6c>133mMQQ#%QJv)k9?s%xOJ3S-EU~KTo*Y+)|n#gv1KzWts+IHn&YJ&9=y3WSq zRMz^z!L|PNJW}xlBV%Q8ivdqE(tP)3Lz?g2bcX(nQT78Ygk1z(eLxz!>S+f1E$kzW z{LRGW1E{01|Y#pV= zRag11Nj(PkJ8~37M$yKoDb~6EeU|gsP66{s9s9jVrcQ3qy;hkxzoxVAf4qAU6}ab-Rc>$*UWUY-Zn(`BD|xsb3M2Yya)dQ-McSM68^Fb| zLZAt+d{-+C$?7<`64vye1z87f8i65Q9d+x-;NscUu}5W9JbHX|#f2Y{ zxH@)2Rcuw_j8*;*u%$cv6eMI~_(^=6;V1C1hkt6Tz0(%KC2aet+I2??*($_9dM`Xz45JB?i3#|a&9IywaR*YX)`Xedri zu<*j|Dbj_@Pvm;%1X$`n753v7%k?R_i6vtVzhy&>j{9d)_&{c4-rIHFJAVfZIx2fo z-(AivH&~x2pM|0%EYM85;d|CH218o#JfQy9v!<9wV7H;ya}0F9%Whv>nAqU zXEGCd>NB;Oi9Ez)%PlBErdY{L$j;h7fR{I-q!ajZn)sBx|~K>AcQkIqeZSRBWAB<*75lnYJMur@f#OXQoK`)%EqkXzcQPR`;-S_$zCSX!8+Yw781V7<>G)>xZ3|KEv z%jNp6!fIv5(pD@rsqZQrt{1jjRD20uEGh@03k7rF!e4|Hp81X(cDIHRQJ8X_MtESW zVKl5dvx6rst-_qF4AFLD-c2+>HWyyc^?6svH2wWio`gxAluKmsdvKU8Omu|D3jx8>@;ZAx zAJhXL++z9-#={GKH}gePj58%aTku408iW2s7l)?-yIPOr?$))vzgF>ZnMX~wK3<%d zpvk^>BgczVJd!~P#IyYyaE$R>sN3~+@w7T;M8A#gMdP|ehe+paT za6u2}z|%gO0GV!iJ5KJ`+r#UjZC)K>~~>%Bb@72$5SSNaX&?bYu$Tzrc|H#-x~O z>bWJ2CElw9DrSVNKI7dCydf@}TWe-}w|oPun}}1}=Se~pOgWjI986|uJa|L3%bWbQ zB`fe)^o}l9)8L}CnmOUlk_M@t^SV9GH{fP$th20DGbx;@$K726m$QKx4VK#x+l+VR zRo^~g^UHY@Xt0M4Yq#IfrUlpaSt(!Zg8#D6F$4d9N;XY2fZ-RS` zbl(j3@o?iUzPI#M!{v*q`OZRp{}icjjjAsmnZrFc(+$3Bi~9$75$8wOD0z+j#CT`{ z7a_9sK}nVQ5ec(<#JwQm-Xr2(7;*0zaqkszFN(MqN8Ecy-1|h_`$pVYK^VL4@?3p$ zRNfubPnZvmpC}&G+yQaXR&l$9Z`HFS7yCG zJAwX#H7e|5F}=_6B{cp$PUNx)+xrYbxfiIuiS_6kx!lN`7gLnZ(xvpk=j@G#;GFqJ ztg3iFkI4-qs58j`<0ek~c8u#hX=a_B&&|WF?x_121KpTf{-2(E-GhYR~)q5QlhmjF1hMr&=uNjA(B%8&Bkf@Y|XcV^=9e6zFZbC@#FSXAB& z$!}uorHnOfNjIoH8~{o{wZD(RZ7ej}kN8v(dLHHmK6_QAmkAJ&ubGFUZ&J?6-3$ql*Z8TRR0V4vQ~%Yc$I&7OLR zL;8Izbxe$9Q@HCsS8tKxJn%M)k?+bGempy?Eo1jIjge>oN~4ppS11)7!+N(XRqmqF zA!yR>^vun;J$<%gmTzO*;~)OG!|=ZqI&XwC>wianZpJMA67awZQZXhfRYZ}XSf}u> z0I#v5CP3^;qzQ?MGF~B3Co=Ae5G_q1`1gpo|kH3HaWz+t!YoazAFCc3gGHB=r({ZiPY5BEHC@y>o+?^7AJFU!IzPW@D5VJH`aBhHWsVEqcf-yUxEHYZkQ$qE4C`&&gQTwE2nA`yc$Im$6;ey@!;= zHG-9ZP1E&>U5`)fo{ST_S3ny&2O<7c!zgwYF5{c4;{GluX00Wp%U?*53p5G$_ek+E z1poI`yp9iukUKv|?f_5I;ad<#VX!rrACwgK@RxX1ys%U>aWwX;0xpwrvl6}V zcEX{nT}-RwnpVGPEZ`m+s?0WE_@$ZkZ$&$ZjbFv8%av$`nTZf^6#%^esEG0d1XsuO zK9RvtC*IFwo=n=8Bw>QNhMf77-_IDM0bdU@ih{4zV0q@Navk}5Z$xg_M|9sCg8cZQ zGD2|!qi6++Zve&ZT&F1bn~@A7;BSo${x%4xiyeV~hny{b-zfNZ$=SwmRqz`Lu=}yN zE0fB8Q>5&l2x+x1;kcP`OazWwP!!o1QSkR7C5(V?1$b7N;ccMQ&B*Qcpk1yD>2!&t z)At!c4hZgu&?y4`L8KHB@DIlZ-x(=f1bmk+Ts8P^a<)gQbPuSsMp5ZULAgiJ=w8Oq z3=H>0iV*?-cx>=bMsU;p0gWCA@>&??HJegD$f;|P8hxQjw{--5Rlpkx?L$EOAkaP> z_U9EL-X){^MC-rVC1#E25;p~1VvM{V;lv3fel$Xu2>3B_=5!Gv@W)5w^@Pl8sW3T- z#eXr;Pa^-H>iiE6^WT4TU7N35pqe}Qd*r~^$ z`!6|tEz-Xop?d`UPNYjm!0(QfAnyfz`u+dQI^;g84kKjiuQ+`R(*HVAhY0vLkvc@c zza7E4zYApR?_=ZW1%KewO-TL6NL~@}pJI9#t%m=Z;SqxUM~w9X@Xw!_fAH7)PsKm~ z72%(cl1+VM%BD%&y@3*Z&QVe=jX3edp@9TH*2QE+l>aB6IDdTek_ScfRMHmpe$JRz)46g+Wka7I)MhC1@^ zK3VB_^a*<^13+8>r6`B!l@@9b!#NA2)J!* z@T5o)BH;G1!Fh7#6H$TD0a8>HDJF+}aB5h-)r4aTcSZ^l0e6im z$TSe?3Y5YVN}l}h^x&pZ9reMFP@u-B?{qF|9dH&R{2Bol#|C$!VrebYA^|;`5UOOQ zpuRK2$I@XYeSCc}RQrvO9=G#_k3FFnF>bF9@vfreGr6*9B%c-OwGnWy&@=ZcaNpRm zXY1Ii2>qbgmr#T`A)kIYkK|{LQ@2q>8#!0{b|?q0kaBP?m#hI821G>BA#5%6vrtjazg-FKzxzPpQY=kyC0MI%t`5nw&K#eYIW*zKznC@n*m`EPZv}O!ziQUxPObzO$vT(d&ip9O=t> zeeiu+`dYo&@SQ7tMXw*e^RVmbqy!%*FE6GJIeerf6r4xFslZ1|_dam1kYtnq4f26JHvO8^v(8mf$w7J>-Xlt_c`gC|7ZMM?n;F0{0SNB{QoNsD-XiCR#xo) zDe1V)lcKzTKs!4^yB}~>JF}vKiu?Of5ADF_&XSoe#@hW>1m^PlwEJ!9;*1k{)7E?# z<&V}^GvkKR;~2ibinWG)`@na!S=pN(-axDq7=DO^%U3o5H_O;k=pBm{k*9@syufk~ z(~a@^2Y`52@&Y2D{w@g}!Jm@|)}@qVuRQhXoxAQ|@*bicR zR{?@&b*1;}Fy$Kg44m|FJQaX9g}ZY?M7-V)QHga-H^@?!q$vkCx1FEVYr<)qs zgf;Et#j_+{q@j?a?f;(N1AG~q_XuC|Ipsbn;$9nZpCa9_@*_34=HK>?6YPG`P;?jk z7?pIF4*&yVa_Qq)VSYb2H;X89qEL5hEHLz2#6cN3D!;n22bRRLsbZ6Uig=I6D=5(? ziQgbxDZ?SYxFf`cm-v!+`G&^#VoDMA9QB$E$B?hd_}Gw~9=O)vhq@?2vL+#`#;=vS z(o?h({P<%wrlBx$2rkXk{oA8%7T;+Wn zl}XlHCa{}+e@AYkUql)cpCQ3T#JIt)cto8g5*wCd&HfbdJtmvQ{p+ke7rBeVPDj|u zpdYqTdtb%-pqNb-yAUg}A%i_RPk{mdY*dA7R?3iY5c=U++g}b1dNIEsr|)IBQ=Us@ zmNfmFu&pyEO#fyp;Ck7BhoS)w6a1`uKqP5@%sdlm-G88U?R@!(oS4&6pc+;1@ZdYVeyA=EiR@ z;FJImK7zSHR6T-u8hg*w-m(bK+IFdO%SSdpvdBSy{*e*911U=;-)Q7FFbGLeJq(Fj zVUs>eou-y&P00;w6@A|Er@B7_|Gh?VAE>OTyyP>A|9OR+ps^c@EUwxNAPAXrk?6v!rfgI;D=Lga=I236{4Cymt?enmxeuM&t@r+If z#Ux*Gzu?~VP2(QIeYC(m)6Q7i>fKb@_02nh4|HY zn9$?lZ36oYpOlT6;2NnC@WaA4$iB2juhqyG2fFc+&%Ue!l*#{`d<;2Ks`81*Z!PLW zT{jL+^-S*qLf+k>(`IwyBv9)^G^sZp<~?;_;vSJJh~U-V1|{76r%idWOjL@$ont=4 z8PZ3>aRm=*Em5jPKN0L|CRjrD;zU@IXrV^63itB|3ch{odJuNE7FyI;#&|iehaQ!{w zqX~JlCZwpqEK)uhMLPvWqrk09jvvLVMCm5&y@b6><5dLRKVBsVS7`6&B`Mdq>YNMB z*NrE*&bU{(a$1ZJOJr^DQgnk_k);B`n&w?5+bOOd#>PEVVA4*<<>N0k37H}zhzXxd zL=rJmI`Spv=lL8vwVv@L=XqFMzmT49^A6xi?w|2KYP*zyw*Q}ceq;Opjp^oHw$yI9 z`PPF*zU+j1_yEyVP^+*qzr1Efmn))Ysnm$R2Aq@9C1nUm< zNhrGa7VZ}Q+b9nkSn|TZ54vtn@Eg=U69hj`O&sq(fOo2aEL~ zWK>2*e6OM_WaG11yFOHFaksU_Sg8r6y}^=iVb=%>;Dblo82FfugC0}37AL$91m`!) zx>Eb!5p>uH^D7;fMkwPcBX}QMRA9)A^cPWqsV$L*nI|yo11u@sJu;8#8A4Qz-74 zAul?30~_Z*iH?ipMXBCbrA`lny(2FY$Vsgocd_0Uu+UjRRS9G|PJuoLJUwQC+T}BL@|4j<;pHr@UqckivI?iLhz&o6Z3WTC zg+%iR-si@-t{9&Wa`-G#^WdV1hBW%PhJ1a>QuM@rdYm^vcs>2H1|O#~+UPeW^21A3 z#g3*zYoVpkTxcsyDzq2!i9$YE$fpYVbRl1Z8k16mi4dPpFr;pB0)3xnzSvvo?aQe1 zJjZWfcxSl$0t{Ah%qA)FT)sk)rF%Z9_{H^Z57;Fl>l5DTZqWVi3iL`F@3P`OF3R%| zr5DVlJfB6LqJl*t*FOrHWs8!suJ`=_|0du+8~7FCyMg#81wC*58S4(GsCnx(lE;r8 zHE;d8nzx?J^VUc7tP?%Hb@beoFx^sB!!hQXB%03ru({^Zqvx7n{1noi=j&I_RZ?~4m1p4XCH#_D~`E*z$c*CtD6 za-71tkx(eaGH4eSWctqteKr++^cSfAX-62mLhA~fwemu6`Wgp*QKN#SjjRKyXU0om z9okc--wwfJJNb@P&y&i8D}y{hYE6H>gA-q@!ljAxxwbA>)Rsdgm(Ru1vY6mD+ca?t z4@Gle^oGbcqg8oc(^cS2cjM)-OlH2eKWTP1;zr))VkgP(!KOKmnQt3x>d%pA`#z3# zHQE;54v6``pd>|y#^aYTG#B*TEQ+skH5N*1QD)HeE|kAu=Xloy0bdsUc`Hc2+sO1Q zgi620QR$2A%J8x`RkUeFg2H|!3u5~3GoqzIO_$>c{BKd+#Y0~sNi8r{PnIt>Wd9V# zdz9ZRJXYD|WBHtCg$4n>JN`4wus@XTdbVuoTASY=l?5o#Aov3cKFb`#0-WrhE#ETk zuj6m5bhz}F4k`}Gw;4-|`D>Tv%M_($#TD$zsWc6xout3iR+MpCOAYdojgrizSjrT4 zf(+m%Zdo?LvxUz-3wiYQYa{t^fg%5qI+s#f!;?~#OKHslF7Ixs%;`9HNs%`hLH7w| z(-~0mO;k2Bxe&^?E+*>?sq-^}Dp2(t&^3NTI9_EO7gpoYvkt3*8}Q`ZPP)B^dD_Mc z*Oeibbh!KvPbT1cKZ`H>gYPN&_Dl@@2rZJV{GB~A&0zU_6zemvF7ec$*N$9UW^t7* z|KX(4_U~cuquTo;=z%rGoG>kQ<>3Vw)ImZ%crT&;XCa4PRkmu}MgE%9bB{OuN0OLv zT`2hJKrD1S{;Pa%;Y;-QIpO#(C-ofWA{6vu9^g>WK1qo1jvOHYq<1ob94@=O)PS?` zKZjy$*7`Qi#=b7gvC{M(<8o}4<=`cD$A2ps40Dcm?-1;!g(zrQ8bRQ~TtR%!;mV(={@ zxbuj#%75a9%ETf^DSFUVj#fV?aOk(VL$P?IyJ2b!cW?+ZV+ktszmjT!)O!e$aG@~W z4LeZ`?zaqzONeX=#<>FDZRt?|8ZtzD6 zBG2aTZY1}WXLCWnY1QMf&1c}P%6q8EmxRI@;vkO01N6sg7A)xZ<>Z;#Erz~`E?*;6 zOw0dAQtdX0hZ6!Rc;`k0uWrv<==(OyDAWJ%q*?`ngGU1DN~Zsx056aQ=7a3TR*HlB zB{OmV%e>s`Jp#2zT?Qq?{I8&0evVxTD18b~YhdFIY1-Hr;tN$-9f^aE!|XVO*|L&gkwwF$a7j$J?`lm5Y` zoSz%=)k~ajuHZ&Q?@^)nt3W7mIU=vy>(P=!#*T|?75(RgJS$y!sw#Y}6r&=Im2SKu z{BQI4x9T)j>adne_@ZTE8L%u1NXbtw8wsS|atZV1V+p<_aT`ynsFC?F&rDH~d(%ws zaXsh}OFd0-y{~KbCBQ2Qz0ZeqYq+n|f#t7)wXf7XVybb`ZAu=e!T1jDVUF(5-)FyZ7^-io?{+jD^BCq%P$65SXBxZZ$J6`z~ zz<1j5YU1el`&n`wBjtpb`K8_LEQ&gj6Ry({NE<0MN9$QHp5N`!Z5Js**eiQcygOS7W#`CuL-*U))>{w%!Q1!dcvO#YvPK0|k!RI=BcXE}ByqiJ1INF!-iH{=tNI zvYlU4I$_`+7-TlA!Uh#mCcwp5;7vJ=efkc4N0!r+wma+?Ml@nmtUmTw`MM(Z8#7Eu z%U)PJA|=}|Ot#w9s4PT6Mtfcc9mV&dVY@L0(n#`*48Z&B^>INI^s-F-u$!-Jgw9pWQrOj1VHV)}UPGt%E|)K1thW;K z8_(7!ip%XxLgG%6Mwh5dhB$C*;?)GG&Tta3W+Do`8bdfGy?ijY;_3`#S)a%x620G4 z?4GTMRi6^2E@yuxMKMyDl-v6o)f2MyX~c+U(wBR8B1W2Gq%-M6?{B!j&LCF$9rxEI z^8U*+s%V5Y1GPTSrWamg>-}wE8#RJ#8O#4myo!4)|F3b~n9|k#@m4f z$k$=wdLrB_$K0>VDohp8dtC%_3wOu;G14C0Q*meAVrk$?In@%MSm9~TdgN7hHNuhx znBQpXyul7jHkKjV9{X=&RWedq{sRlYzUU4bV3%YRqfcptXlyJT;~`tz0)or#copP& z%ofcXaKjx2g;?%+Rao-|Ty7V5aO<7-J>^*i&uz+s`|Z42l?S@Ri9rzhFE<@LxbIH2 zsCfe}w)1|ZJh=VN`+@S{`aACq<-whI-o0+H%n@B(0R5*LAARSVr5a4XtNAD9dFF{W z$r7nRemYXry%}-{TkVKVW{dp69A|X%B}D!p86@(DDv_z0Qg%&gD{NKs8Pofv;A=~t zW2(uAUcI-2cry*XekuHESeL7{gpt7x_a>PT;-6BHL5Y zF(KjmhPU(WO^W( zaOj>Hk_jXsUh^(=5*iupRjU?F*2utaSPk$=o14Eed~@(v;Cr2f?FC)SJl0Iz6K# zTbRDo1{9n9S!yI~ZBWzn*pmA>VyoMW5{R~ekO5N_O+$EAJL`UIt5%`5TrDS(5BYBX z1hhVWhjt(**%EAmEx{idY)f!$5q1PGGT4q_5_SY%Fz`_G+H=6vBr7l*SXedKAlOO7 zk`)*Z?3e){TvX%9O3Vkw0-*4LLIWl7iZT;hf%QN+MJkv3duD~!5p$GDRFV{1hO?6w z??eSQ1ZAcO4magW#v3O_xsp<8vP-9VF0pt{1y%#ekRWyesR5g|KBbJa4gnL{nK-?G zsXXrHP6d_)wHuZNsb5RCrQyYC!c-G$;8OC_rLrylBHN-P)sYtFy5C#sq@6Nl%9cEW zyM^Sk=Jdv}o=r(ZLc9jt5FSl=Fa_OyCzBZ5m4}Sv$+4knbDVx#4JIKuAfIR^(U8o} zm;%w??evNb5zLJcNdk=!Ua3)|aJ0DhK#H!>WNC({mmnnY9(okRy94ps;JS|icM-q_ zmrBvCffSzCBFYY2;G(STZrwt~=A5dSjMt;XWR{)`h1%>@fhh$|^V>009?!!?j{ljU zi@KF7uq~S_a4?DMY2=mQEAf>r((ZmF=p=8|{VT<}md0M%rnAe`+C!-)t^?Gu z-GzoxN?G>ISG3Mby?FQUDBkVrW?sJh0A$`{2gZ!ksVIG8rzVth9N8?6#l05Nii!&_ z1O2DCdk>BTad!wWoRp`+XPEvP0#;&(=Eya)+MWZwb(0Gn_e@j2g=>1RVYQrW(nX#1 zJ($}+fT==~ReEykPFz>qjrmcyc>Qhsm5auE!lzdLi*%o>>SIvP)7~3ML(YWjufZAL zg96Mj(rY!mhajCv3Yo1jyPtl&mds+nV^^stO<_^eR4I^zFw7^I-NiXEVxI_PUza9qi zd7Z!OkiWhhrLeh__2IXK;i~IT=!Ikxl^+x(1ey7t$bmpt%U-0d&<0(2hEmN1 zH6mw*oM%JZ3x_8#&UpLSW5D1&@bH(n*XW&4C2Acj?b79H+e@@FGDYjH?au0yAN zNIkWF9nCNg!>5BDi3B|w4tgvS^msVviLeLzI=oLo9%ztyKS+?QGk}<6t=*3SP_c`R z*>>?BFzOo;ZU&qv&bEEh&ww;8S7<> zB;&N3)kH>5L62WYC%E_pC!5Izx+=vBgo~%<&4KjT|HuX?AI8V?Ts{AeBJ~Kj+oW&h zD{4Ks9^WOVdnV0c;{c2J`1LAulltDEusp`v#8@||(3_P6aQtS~sQ8ld4?=IExWfH} zNw!$QFD-)7y6nlSA4AdVpLBK-;PeeNPZQ;DW9DIN_Etax&&RrpYiZmaqOsYh!3N^T zH%Dn~`Cri3QcYtE(OAj_g!x!1=xG6J!3p@UL=RAxLD$b!DhPg60@H7KJjd zjQKS~zf*dI+TV)`V3O0JZ&A3jO(Vpp&q3zbAxNw*X&bRcvJra*Y{Wi?O5KPM??~t-XL78@*%s`7Ff0A0&LxX8aEx8+C@!#mrjK? zD-gcm(o$Tp0B!L>T-vQhk>_~BXlXI_ms@wST)6)PYsvTc{}YS$t%kb0zh`6}7L{8m zOYid9_kDFTAvbN?X!jWkw!HsRDr3~{v-MgkN6wr6$T8_^GvTYqa^e6{yx~h;lgJdQ zPH zm7_C5cL8*h6XSQF4#I#t0XQoFl%Gdc-EOccjoVZo67)_m_n|vgAEKC|a);{D_|lna zQLICBGJ)LREh?a)Krf&?(_`v=r6SLXEVKD^lzsz$-9t>;-rk|or0j?3=jzk`!$|WOSjel2 zS}J@%U9_HRw4N~9ei~Y6VZ7xcfYhVcTb*ogwjRCSLT?p42?-+}#9-1Jb4T>B_Ccn* zv<4M&{wh>}>Y~PLQRCY|ZK*|V*$!%NEoyHR^-v8rOheVwDiMZ->tJappck_-M>tDV z!*>u#Y$uX1>eV(bG*p*Bg6bC5sV%ItoqCaVTSGOz9n{`h)ZPecU?+7F@k*GiNJ9ee zWxzvX8lJpp>ML37NvSC*r>3jhAqf6hPLpbe#LA`FXV8%|B%*=$!K5V_q$hc1auE|v z3BPdf#?I?}2zq|Y8Q|npFinT$ogKU`LFo>d?XdhpS)i!23V}BX_@3u6A|?jGMPp}x zW4&>}^cpJG@1_@!L0UjQiv{E-w16PQ8-WETig7Me%MRhnu6qxy-UOJ4W3At;gKc(1 zads0OMFq!1Ob)q6X_jl^+V7}UbiA4OqzU67KmRXOmkY+L8p^RCxSmCDnB-u9r51xUvAVJyqkEtzw%u|)g-Yh31mzw{InP9j@Q?q5`?dRosa~-qT&gj0 zNH*z52D3@{ZkJ6$pkkALWJKAd<)ZRakU-Na_|YoXPlH%L4Pp%&e4ai2Q?;I;U~)+v z)$0lSO?L%`+y8`-a#cvVdPw;yq|k zhLNzgEw4f9twQRphcv$mX?_^#AO`ZP<}<54s2*yR1@=L8QG07qd$)rcuSJb-2X$jD z>c%LlWTETx*7u9T1kD=wVz7zzJL|Clp8IX)xtR!Yv_I2hgdAfGsL# zx0sWI!u>5~8u0L`5D$No&j6=21B~c3cq_31M#d6_21ZQq6fHUBcTHk#XfXBp(h_f@ z#R9uu86iO=Jb@sRf*y$kJsJ*rEE4p1IOvJ6M++j!6A?uEkU$XWgM1I}&TUs5`9WA5 zN$7z%Qeja`a~M@O?bna0l0^ndu`H6CPPxOBw}w!*`6yA*<^7`ForyCnmRrfFM|dlZMGj0)RZjxVuKVKLp6ZW z^Z}BV1$!x6uxPnnsxH?{R4!QSwY_1&tzuNcHX#6$egYieP{mo&myRsmk3zh83_ zLz*+PcE4;?M0?`~&G}paGbJWZz<#nL^Gop+T z?-)?_tNArU2|Zp{nSOmotNH7}y8L?8YCgeL!Mp-o-VwO`J(yu1DLe6CQ~=z22?&T@d1{-I$|HK%mWIlq|PdZqOdTm=ehNTsuC2 zsgtZ6SRWWTX^a)mf*^m2?H_@)kAFZsi(5giZfC@Sc9ARp5`EtEeg#?i2Q;Tp7(?*J zAw{HL??osjjd(8!-yS#4W8yR~g%DDuJ=kw~FH3;F;M{Er+g*?O0-8$$jkfoV1TI9< z6Z5h}DJ#3%cX_m3z!&G~schz+uqjq|=ZSk#YXEH2Bx=*25l-LTNZQ>*$Mn-~a;nq* zFC}SjlQSdU4Yoj+=Ao3;Z*yjfLYJn&4zd`Q(Z}dgj*Ykjsa9j6qb%`dyz;qm8j!R_ zH+7f(5H$|%&z$>ty^p?1#$Q5bI+uYpOiD)c0=63_d)0-&;sNMwrIVx&sbRe@Q0W>a z+42k(qQUjl(F7P(iT<&vP(h%YR4NRI1OQg5)P5n(S59V9nxK4mD1DY1G-c77^J#7~*+XGmq_J6Y zLm2i@>&PXAlZkKQ+VW<`0v!|QveiSc+ii)hPP1^=$~G(`+@|t57$jPV_!0_xuSBM|wo2_h+FLiPTsiBgK~Yfw~(d=q-XqlC}B4PzRZc zOSH0D8%*y*iR;iYCr=NFxU(Rq&A`Dn@X(Lr?F+JWj*=kWImLDVuHW-g?4eqbUCg~E z4$UTA_2sur$}1Y2c>X>fe0`F}Uwj(guO(JGXaHN+f5{je;rj35tG4RHx=j1T3?ohT zb-kW1zUa>vo2ZBGD5uv_PHB4*$)Q>3b#Fkf9;T4OeD-16*QW_)gLx!v<_V#{$?l`= z;G|L72bw$=G}xy15t7A3(kvGOREv4$fs*ZNu$_T!@uT(Nz~;%SZB6i`nMqK7OO3+u z{u)%$zZ22F2^jOG{UlC3tcqy`-PpoMF4o4)t}v zt{*ne-#tckt=Ilr>AY3jpUhjPy@{vZGI*oF0;P!&B*y_4IK`8n8V4A&u#MY*cA`>~ zUNKKFmiIAN=5@4CmD6!pk)i5pbi70yMbuS>1KvCpH4z!b`T~~B!)s2P6)IWiEd3M4 zuB*5o$sNN#Fp@^I6J~LZ)_sY)=YhZBI{~~PEi~QFhQi#d0bE0xRy7f>(>zn$m>uJ} zw9s1qC)Sprb#vYX0hVb%UIC8PfKCNit^r*NFscEQ6kvr0bSuDd8ZcP_R%$?x0`zG> zA*mpr@gXS%Io^k)732gT(x4!#d`P2$oa95A6lARr(PiA=Lv$gVdf z$*52Ad4r4m#qD-p%wPbPIV4f}hsKP3F96~rYTqhhyWIX;|;wKKo8F(RX@ED!2G-S3wFZ>zxM}rLj%=&o!!uo z^nPv7EC^LUen-J3A$zIORO)}MA7NkCpJ7Or6eFNSlahbQmRcy7I@IMUGG6;4wejAvK3ihJ{UY3fY&F=R8TPk76#RFh{QFW2_6P%5 z`0pBpizc~VewRz!-RY|2zJqIV6LQg^UMM*P?`u2w$imF)rknfteJUq$jKZGg4J)#-yvADUnH4SAAPr z!f@ZS-^`?o(v2IKZ4H?;I~p^M-uZYstgWL|$~0s;_?Bcg)7YA&JCgGAHH?fc=iut zqpEdUesYq0E|bf&u&v==WSWb7!?vw8(@L|9UhSHN0?>X;x^efG`D7KNEz{=h9El<0 zFo?E~(oJ!Q`8L;KkW6G>!?XfvAM^9z(+&^#v|yS`RkLIyy{ux%-U#|sElZ}>(yTFf z0I#K3+vTinWMbOB8PCgiDb_2LxaP8gL`@R7D;|p^?95@Q%$USV5hIn>re$rOoHa*a z%OsxhyQE@|$N+4@Zi{bS!A4*kY}=vkT;7T|OWG3SYse%uUE=M-uE5&Cuu$w1Qy6+4 zbOQz>?$=4#IQv~g@lJ6=uDwR9UnkWz-z+jA7kBTZ@qk&MH@^?n1LbG8qVbo1q^d8lscq&e^tWVziDYNIZ{~`qH6dzg+8ItCs?qi z&)+9h_%!tNT_A@q>!51>-!?jX$u_2M>yBjt6WPOodo1x+$j{7JF#_#RkL>}0+eI{I z#TZG2FGsb`Yc|@$epw+6F*-@-gZp-q0erD9IK6LBwb!U?uTcS-G=LmMR%~dO487KI zc(zK%Ax3-g=|)Hg5ZiEiTn=(|5N7#3Tzr-$$AAifq8!2L=nUc<>h2H&akuv+NSx*S z6+v5-Q^h86UK>f?skFDSj;Z$tt`iDJ=~{H2VGpyNWPAXH1aj&y0Z^J`)3%%(8On3b z!(!|N8*)R?D}gP~eUyanfmxTBt~AdsE(?!pO9jP zl8-O;-}D%06X89Nw~kmU<}7vzYSwhW1UCNyBaknZG##}*aGa0hL2K|E0kRk}`nI?} zC&ugKhsbpPq(mrNbun zLs{5QW5pMCkp=y1|NmRL8)ofy3n1z{tp%3WK^CH>JZX#^cbkaQuG!z;B;MT&er&ig`e9HcBMg5;zMb> z(g@O)wi6-fOtA}mKz3mbX>T=9!?E(ASos~r z>I}!~48`i)QLL_TtgcY3t~#++at989<6f)Dh8HLx?zO>Ni|4hQu*k5IdwYa{h%td~ zCeWb>RN;AY)64`WR};vp986{cIYpof&&yK|=5n8uc%2Gwmuh-l^#i;~n!vOufoa<# zFs&|u!?|a(<kK#vQUbn`ZS_f}x9lX9eczxA)D|z%paynU6U5QK7qcUEF=M^-8 zDcd73B}!mQT>^fm>koIje%?QS_h@6vwx0rN0C8#dBXC6O#z_KZi`{Y|_4l0I8V_~81iN+5i2Usk*E zg|VtD1^|Sv7%Wtq;ziYXi=ucG{ueRPR#_ZlMaH9Ifg)q0a1X;9Gzyp<$5-Sg+Qt{t z6iZ+TG{~XF9M46>93*=@NXt2NLUMHuUwb@?-#@j)`Z-!zayBVTZh*4n&R`KXBE&lu z%92-#%F!{_j>MN92MKFOeokpeB2Z~Z!l^<(Z%{o~mM9YVZdbu_NkC#rK!Ox3W$g~f z6p!*L&9_oJ^g{W4bYO4o>xFNS>z=NAjSlp(FE=`nWmnheKm)rvNBNLipD%WktYuk@ z7#(cuU3w-B{hnKCE@vcAJ6%T0_CM!tNYJtGh~J+B-QuOH7vW1Up4HPW-Yc5Y`ADgc0E|F$zfwYo zx1vV3xQE(&sVd9TP+9ykETuB+9i{v^P@YDV5#k-ky2X32Zt>EX(k(8lOyf)Y`*7Dk zN_G8m(Dlnf*I$CrlOt_+EN1?dzTpbA@l@=Ms@wS3m{uv@#iaZkOZl10!z6rfi2X{{ zmZma|l&eC@)kDfxA?52KbygvD)eQk-+d=KEMeU8E&SH2-o146KskPKnYuQf1^J`J(M^Wdhr6Dv% z*sp4GQ5Y##g_Ns@)LDhpSqG`BD~i2LycDN zqN?hRB;8w;bZ;1G76U^qx+v755jyj$=*+L1uUKuqV$poKCo8->))u`D%|t2G7boL9lm`m%@}*aF;1rg zh=GiPJf|T=h(S_xF%GBaq~>ph)cl{pO}y_U=tdm+t`P322~t3%Q}r5rzNmM4OmULr zkbpBZ;0y&A(*SbJ6BQhoLm`Wnoi*&2Jd`NEESVHKPG=aet1+WXetU_pd4>3zGe=o- z+-6OiqJ^xaAef}354uhMy(rjWO3{9ztk&c*t;wRicbwRhGA(6>KGWNY()ng0IK%jX zFXwNq3Ws_Z-?5XW^mHjb#cK$995HgQYI~Q$_%>s`TW_hXl6f6z&?AExMTG7;I(*lW zcq%2DhZq#nYA9HCS|LHYr!kc>E=jYuW{a1pTau#uI(})Pa4o4(ydWY0wF}_UMbS!(le;UfFS`Fos3UBErdNTMjy><-^c_*gB=dc``+yp=!7bUP9PD3CR+lDe zOyh960b@E&7bneuY$1u8F4;LTt%F6U;BjqH50vD>;9sdcPiOkPNTw~TCes0E>DU{T z>GO7+>GSGj`u~*Y^C-^+KhIy#dH#axUzcmZ8oURWxnqMh?U?xKLPznoldQP)4c6B6Fiy zY_i3Cu~X@gz(AzV+4U-`n>1jP0^FbhHz>f38gL^6Sm-91zdNPBlZ|cku#eF0RPpZC z0CHR;DtBSgXcO!373C!kR*F@;QrxBD+=K5b8Rs72e#q}`0Q+}`!ni|Y+`$<5xa)y& zkHWZDr+cpg+@}HeDZu?2aK8fFUiE!YBaovgDqoGUHj;GSqMSYKET-~sKCH_4s4C;5 zRL1k;DC3D-#zz&(V+!RlLirk@oWv*qksJv!KO19w-DU}@>I^ zmEBtjZx*%MDU1RTY`#1ZW045HbjOJ0I1o(2ggh#*FvWY$p_R{PpbUj>n(}Z%}-ZNex{Jz=t-5I zC#&-FB;{wHXnwwk{Pa_P5CU}vpd7n# zIlfNiST8D%tGweIlKQg1cO}F72AUxCdYpO-$$Fm>m8Vrie7&zlJ4hoJIv;5d*d*pMkLKrMbWtUW0fLfo~{SaVgZPex;X8L{@FSO@{*St>4s%}vv-pe}@& zbKi&N`TZu{G(ZZle69Z3r524W$m-ayF5MWn&Vc zWZHk0=}jB^v|~wG?ay)EwXyGmi0@CNn=hb4L)JXZLG_#uztiwVi=<2;SDany=As-{ zpTk&im(tq>-dS;tf3c5$u@!->VeQZAn4k4yUhc=d+={@|<;UunXZta)@?&0QMPQq> z1~46{;69vBWEm4V!zXf`Pvkl)0^7tH-vN;^pU4e9ksGWCY!jDZ2Sm!;K4!TBWwoy& z(oMo#e@L_sUx7aS3F^ZLfv}_m&h8t`lbQ4cl}mGEH5*pJOjG%!oPQdW`_qOIZ-jLW z_`G?hMsmi1#qQ)du);i>*4s}S2Or6N8q&r6_+9@`>F%?GblV~+`;dh}+IWPu zSTAk!j9*KPOYqaLJZ*`sOShM$L_CzGw)plkWoF`iZPt09ma!zga1Il}nP}4R&gML> zQnPzAe=7@3X3n#6OBg^fYm}cz$#y?nlxJCV7ikwv8@K6s8qY44=*-O{wOqUbQpS?i zC%h*(!Zb)mv1Cbi(c-sRVeERqcI7H(m2Bz13c6MgF^&t7-zPb4KjLCp>vQKr$qL(w zzMOYBLVM@SO7@Pl=pN@Fmivsw4!2b^_NF)8Vha}J7~ev$A;4NKc37S#yZQKI6tcSx z*_}exBIHpDK`A;1`^w*tS#GeLaqL?x+Pw((c8hP=S&lV6Kqf~px6*Vw_Mu~(o-IEI z?ddlSToK(W=;a7+Uu;bp1wGI~p8kx;@`I;cBi{Gqr^OKbSjtaWaUJ!IdoBIcudsOY ztEx(|B3GW3rsu^32YR!mH|O4^M!j+wyk9;}@fWzWU?)R&7O=4M@-EyhDA#Ujyd5jr zDMYUQV;w->T|&>*Y*v@3+$;lgGc(+G%G*eL`L6~|ANevw4fK`_-+`CIz!*RoI!&(^ z%cGeq#X58Dz1);dAUWG2;{tn;Uv9l+8_eh70=Y!BZOpZ^8X(WgBm=#WqeCL~#VH4bo|1=NfTO}bU z=oe#ZvrZ1SX!VkYkwf3=fdsOPC6EN4t5{eSRnx-#B%$IrDw$amzBloAfK0K%<;wmC z@m!@H!TiY$7dK0Oy%~zLl@6gKr^-etp!IE(A_S)0p0%`%(q^3pa@;N|ErMq{d_&u> zP$IMuyNEIR2J+a5wN&MUwq#?Xk`dZkX(;e$6+aWi&s4?t?Uo_{QXte&E;s@tuR5}8 z458$sDET@lT~U;-Iw(C+l%6okT!w{@OW7YrI*5T)XP`c)E^2QrYHt*E33L8g(|ysR z!@DNVP#9XgUs>Fwo?#~3-!f{Ww)f?5&&-nfM1jt^Ki?Q^1q3$;4+!}e%0(UyO3I9n zQxBxQ9NrTq+gr5=Z0_qoQ=9t&OxfM~yg_!i>XRk9LxykDivl~Cq%!8EiH_7ED#uTo z?#yj!K((uHhYsjafUE|PDL}sl^ee!C1`MdKSc>-fQmD_DR9D2eJ9NCyes#PbLCRMlaK$nK8k05IO9th*bCufl@>}A9;O_PB(@Vt>?o4Cok-@6BE`28DZZmfiS0y6L?i8| zYG=BfP6&Ou2q5(ldutGT>t}mnDBjId%ipZ%@)y-Poh5w5J2*vj(L_IVR zbLCMkfHfzKHAiES<6%+RQ)LI=&?7F44WR#si(weicU<;V3G5k8APUs)xWK1$9}f0q zX+ggIilhTsmGvpAA_41fS04WYU5>%ogP~)|z@$I0t)S|XTQMdb~4eASb^QOl_dMJBiCxx?GWpugF z>s=Znqs$>i6szDeRJbli$R~t1&*rVc04Qoaf)A4UoewCD2_zOPDfp-zw-^F(El2)}%%W%=~(9fd_+ zyjw)GiHx;463eKHx41gqV!_JBI#ZN5)tNq59?|(4QQ2Qba|>RJhIpj@*S;aIDFZ#LpHRyjd0Bz#f#g~(Q2c>-1u;GJtSzBpfctXp?KSbu~g>i zNh4_-A>KOd*j2H1*k||k`|K8c&sVotTFmDe61v8+MIqj* zoA6c!u%+qnrJ9(3**CaUBj{3So3aTwMC;ofV1FiN%Guyf5q*86S+es8m7hDQf|Zj0 zurBt|RP0+(>`zm%5rVm`loA$>ic%ck!ckF*iF}_^%t2;Fe90O{G+(!EFJF65zV21|y0>1w?xlP!kLK%cX+euRR(-vY_V<`j*F&rUr>hQ>X%_QmEnF>hWqQ4;eIN^$|&XgL3s&L zMu_)$RfYyG!~H^CGrbyts z-Rn-T1teYzNYHhsxxC(l9}8r^Vt2MEo@h%I`INS#$ko%N8qs*t+s zAx)}6np6*|y9%kh9@6A0q{(5Vc?^s^7N`Jq(R!-UdctV?X=wPdKncmeiZdk z4UfJn7{J2SwKNpa8+}(W3g1B_v7Jc5sMj#jcLjY=-NHJxg>|-5FOhczeNY(neC9Cw zv-~B4A!A#x1G~^rdR8XgvEVryIBdVB4mNZl1Mqzs+}|#$5cxK6&VOwOaujXD9Y#u; z$qFSsuA+3$>V(t1;a-P#^KzTt>V&uXZR&}5y1xCb$o1`K@zxfxtMUt;5b6tf21M>x zP$#s_7NKqSp*Xm6amp&1;_e#T(Dqhv@AqlCdoq=j$Z<@4Nws#XG00>tX zOu(THy`?S*Jt7ouN{;^)l}FXY{%B-vs63?Wot>ejLfb8KXrDxQ&7!=Pxraw-)naPu zU<#UWKB*l3ZU8^UUfV&1WKy@njZvheQ5Z zrl`O%{?Nbj?QFKQ<6Pm6FonmFVEL4!T&$O3tMLSP;<&pk6dq@UV|)bkh^;msk=1d$ z!c9tVjN?3I4()@Fg%GXOEc@GX=}HTm@T7MXhwE>%dB;D6%scw_9lNJ!`;Nhz53C8( z->EcWD#++ydh9=v+MuJ!FnVc5yI-cpLJ`82=tv#S^j1Ld_pq!YiqXC!WbZgKV4>ei z*b{nJtww9i{ScknvRzW!qWt1c*<#iK1|`;gYc;%;CO`Gwj;qqDZ#+qZhqMaDzb*{_ zogKV)HWzZW2cR<`2gciy{P-%#R!R4}aGwab`)ivNBILI5B=!?L&7sB-r=y2qSALRZ9VRq-${y~*R>G!M0g z7puKNMTURu-*qd=shMi6@)SnkH4;`hW@eLMe{OgjA4}mdFl{TaP3TJWNI{~4THh^S zL(_c+HG8!ZDIPlZ`y^flglb<0i*UD=s?z*d1XrQY|3J-qlVzDcl4WX7l^Rjilh6%1TNLkpIQxv!bIU%f=nx6MGMv0J}uj}ZS(E6oFl)Vpn3@740hD^ zr)7g6R9MDThbbQgY{1r}CB!?j$R3uzUMGZ|Hj*PtmbhRf*;;EHe9$jZ;!fg7wMr>ozI3 zb9)>N%`1=udoUliGDbTr80FmbIuQq)$(V z3zX~>_FVR(JvYz7YEiLllOJ_%aOg=0$Nk8kog0%hJNFBxh)S4B2_-Y}O=dg41MSdd z*anWHYXc9D{M4blcE~T=&BO{9OuVv%It0DDCCano;g?e^$#Dg?TK1>9!*ar%sX=(l zaYVBhm_`+VYh7~9S1&@qwkPvixN~p-bgbGJ$gc8tTPvJX@ja+5v&~~OvJe&ILeyc| zAuZ-?F`4q$qc`K$f?V1&-m=qnno8 zssGdV?@ZI&4Ly_t(O%$B`z&5mWL49Oku(d(@B(8x{8daVmiVC;w44PtgAbxJCs-Qp zQ@78d+L%pHf@Yzl)+ypdWG&D;i7mG2{)2)CIhYL%5-d)PGugUqP_{1JZDb4GH5_7` z#-<4U0;(z830ohhak=)9c{-T##8!`$!Q+0*&JQ+~c2>rXQGLpkap;KY3+GOf<=(lF!Sf3DX|MSTABVv3l%*3-Zl74h;?;e(y zsjlP)Qv@*vedq!zZYE*ovecXas${B61Gx!kAp(H`_?LO(@m#o`h`K5> z-=d^b^Wxp1Vs62mgn746>kr+q0nM1Zs2+Gzog2XuvGA77H0=dAE4G+%n>LI;^esqTbBL zvV3DIu+^Z%1M~`L6YtB43n3P0in~~{L{nm1b+7hu&Nx|efSvFa;RYuH0K|MhFK=Zp4sE{i$-x-RXc=^tHto zWa5qCn*~XKKiy7fy|`cVxIC2J>O3rl zrvac_OjTlePoN6U6_sBLNLbn-VS!Uw|8?g$EQ)_q_@a0?*{-r5`kNpWPPVb^?x{lG z3PRyzd&_?4+d(LtYm=T-wT4_RJNV{;P-=IIF+4eKlo2UFr3Po zvmgBDAQ(<%+1U^NAP9z2S&ZhEl))bc!Eh?;(Hz^Co6txfPn#rIYcK=BnhZJxf{sR$ zKobw4Koogu5e@N|vMK5GBaxW2Ows zb5N%l5es%Pbdt$BhDqZKHqZU*3lh|C(Wh8GiA-Ua<(e^e4Sq-tOx|UZA;@OSPs#D) zttPA=MzMaVv2qcte*&Cr&_CoYG*r`ChOjgJAM##PgVh|D;MW>-igsh&eDyU(Xpy&; z*6b+O?D|*>8Y3w#sGp+eV|^7a^1>Cx`WwKLoAl4$>Zf=@QzT#Ht;MQDu`2bku4#(o z{924P@$KjYP3dtdI4%jIN2t;398r?*9z%POb9iF#PRkUI_4|{!gVo z)_(&0GJZPRb0MEV4IYg4>1igjUqtpAAS>p$w}>*vvY{k(p@Uh9bT3G&vq|Sp+45-QLM}BVr`^#cfF|WEWZOSqS9-sS45S`TEOL2y?2{jtE+y>r(zehld13Z z$Ys7)t?#C>St1<9=PmsB(*e*i7T$f351eM_W)2B=m?SU#O+r}ZBOp0hMte_s-lxIo zZ*bgEZ2sc;RH-$WDmB^pnJM9p04BOpR@Y$M%FWzOc(>SOXNBAHW?4@6OyG1_g_ae5 zw51fSGX+~Ek@R@qjeYW`WPaVnB$Hr4p?9*W9tN+RVaxh4CzWE|X%%`R%- zX+AJv7kXC|wcWw8r2lD>5rJhZ>@u3;cU(>*$+FBVS!l;~z04G2XVaoyF&imi8IiLv61iNl(6es;hid-b8ZNO_w~V_ zr{fa_Z~J)Lw$U61h)}j%ND)bROfOTG7O4n@iBZx5Q8C75=I|;#34@>p&dAg1BA1#2 zFacy28SQV?8Qf@SM61v{+TX0;8dI;L@+svGWuZPW*IBe_|Y z)j3!wtyFqz-a&Fkp*hqWgWM2;tI~m?`t(labNGs9tIC&d3|cSlP*3xz*p<@(_Q}YG zPV&@1V|SkX9vO?awc~JG15dVZi*8@(#@>pPuqxPF5lIk(JYtp{Ukhkn%*u)6ZajqQ z(4@F0O6~A870;$hXFB{UHr%Tnn&bKth3To%F-|a{=4Unt?_^xt0os1Kv_lh0W3qo% zk{Y2c-Wm^DVP(_ri& zS(@FNbl1R{%A{&Zr)IWiQmu}A3bLHcwOJXbKe4qt*JjIT9%j*RZf$B!PGmpu6(A&r zl|#yn85t#G4PIvU&9)~uU`#1+#mP%2Z?3%$n_$t;Nw0#Zsk{`B(VcwDB^Be zj@U%@8owNtFAG|FlGfvh8`o+*4(h|$DEH+?`_p3VX-v5E(r%t-9&EH}R$k#9fQNRw zM*G`k=Opl7I**1#Yl21tUa{mU zFU^iggH~y8D_xpv(Q9_ZPSCLs9T3TSf>K(cb!OI%5@I58-14*Cl@1-y((K0X8MelG zwJ6xsu`}@y>ygHzD`V2TFxO~1v`Qq4=W`u4P#uOlqO7_%}A+ ziVVGC&o>P(TRrrS>a*ZGhW)feWhbA!dz9mA(QRrl9q)A0Kai9Jev9&1c<<5}k@0Ea zpv>WYF)Kv^lfa**El=QYpiM;JZ=~%);BSi)Zyf?8g!eMU-v=i%aw&h)z#G?=_Z#`m z@W-;9Ok#ZxW`;J01Dw7#n_YGla_K-K^Ohp>Hix|JlbNi@yzP^D+b0u3?!FYqntfSo zb6?Kh+?RJY_jM*W_jP6BoBJkZ5}S)OpF-z;DfNLfNT;nwj)^goUef%j5k8#jkJ}Af zr^?VWX82#Sira_&%sBR<>|*7$IQ($}yFa#38VcSs-c7Y<(0q9`pF=5`icxWjelxya zKGWoLSJSv!#$Cob7;7Cq(N77|=}hyWAn_p6DDtQo`$XQ)yX2|b6?D{xVq-CovstkC z#k|@}kX4wxoR@Yny&*YkWWBG+&e_;%y0ZUSw;dtNCVQM!UWB>gEJw{lSeK5Wdc?a_ z4Xwf-*8=>I=?$3v{1Fc2Cq2~*!Zo49OR0SS&@W%cuH~iBmUv6$Sjxi%wptler2*Mw z{>rG{M^#ftE7MUmAI~*xog|TI<@-LjZ?N)Zi;i0R8jQII1#6$2dyVBj{|1?FV=`pq z7Voh)slQSy7$N-T(xrwRewCp$5vpinHG-P9`W>hDYv9!z6jlwg+=yDvCBVkpNtSmO z)IGgf(mD269@~XEfRYx+JWQ#VEYqlXmd5fVi-!H|jfSD#yMd14D4in##&?(DlJg>A z)yW7pbI6BPf%Lm>X1wnSm|>de%F10iw$mFif%IHD3KMrf`q+{a`n`Z+cvFd0NX*tD zm_K05VhS*}ZQEvy`aX%iZIn));f2|ytc!EXBJ3TmU|`7E!_jKK^Gy1(Zz5Ja*E~}) z4Whr@yba%IAf0Q&ZEDD&Q9r*Y5U0nacam%L*z;%(>fD!nAA3T2p-k=_#@@l;`>d=g z_iSuWhq7e(ZR1ofuy+pjg>vVaT3wvWK9lV(`GI7piPSIe0(d`-mGjOe^;Qj7lT`ry zZW`%z=0;j#!u=92Xy&lFYSbEWFG2MkD*1MZJLtFkEr4W_l}LUnq5L2R>r8fddR&%v=un3Y4Y+-)S?<;tPjjicqtLDH8sD+dGkd6UaqiIkV-Th#k+ zg7STtc9g1kxRRb0S@$YO>%I=X57Xx)+*!W`(jKHzJY36rs5dg~+Q^&hKCTdyvCCGE zA548o`e824944!AN++yS)j8uTloU+cz+qh>tH9kX^K_!pk;Qx2xaZ61r&KhGWo1ow zn;cWobjVz6fOJLJlN-LGXXT3LRfN3Cm`w3Dnc_**R~P$w3Ol3`hUAB@D6~XDof4Fn zAog{sgnEQ~hh8r_)RHzb7?~!!iBQy1AK}kYpF5u-;%5=8q0Y z)^mfL4MuxbGQx_Y)w>S>G7Ai$?2)TSJ60%u4(tDMF~2>yyfQoYNSwahXVSS*(r@ei zCX$q#d$UuRKbUeT3xjs4(Jss%DcW@XhQ5Z;GE)4*`Y(Vg#Qjnbx5w{dhSoLVKE~z>xmV7#Mb3SO7|FU_&%9CNqx;TiPzch&DIf&+v}LiqaijhS0W}Y49WFCF zBq#seO7{uMMB$q=jdK3?^XGP6FG6XU-0vbQ$-khNFuW)|LJWvD z2!?R(dCd+NL4}4_FsAS?6UX||t=C2OLhRdk(zGm^EoF^;U9U3%-bFjWOBnqUZ>7Hu z^vRZxoPw2KiaUZST6@!3JFBYQW8yx-rl^3tdm}dW4L3POeV^(C-qZeo z7WM(Fyf5vCOw0W~T4p~pUfF;?5wA$DGCsm>51wchwbde%Z2YQybftpa*4an5a~;pB zi8qDCCq#U9t8zG%^+BHZqI{zK zZTUNXJdIHNn&XH0?)W%t+!xQ~9ft~MX8u3HYve(hWkr=++We}i}d>vEzclgJMK?G{nLKQljBGF?o50fX8)n+3c|&e zf?o#4F{POwOqhk_Op(W{PTY2op_5FOi<}mQF%e58*tKZQmV{}+;Bjv5pYc#~41m+?9k-UFP){C<-P4$pa!?M>RB!YUN%Za&MrTXdzrV z&u&&%yYA=evc?zbwNB9aFO4lxp;~$YmDdxg!&QFcEAmHI1C9y+9A#-WV3}T59+GLD zg8m>XtNir1pYONm(ESFZ4WwuY?<&X;s2cD{g~*5cw(k4uK##}c4|w83NT&&fnu;}adN(%%~AQjgzY8FAlpqw-t>&sW2q zo5E-}hdo~ldu|DPHd`3ba)AMK0829M`pf?&v%k4Ci$y1m!l?j}rzEEWa@4Kc5+t`~ z?5&PSx)(}}m-O1Q&yd`!svZ}r5JSt5-!*n=jX8$mLFF1^oJQ-2-;5@&jodqim8>R> ztIJz)l7bHYbL21S9+8IhJ`?X9xcz%m_b5om&O5)~vDcRjJowT3_T5KL9z05g4$dn| z*Pq*;UA#w|bi{xEy#<4l6=d*J2s`JaTaO#uT{`Wid6Z;AAE`o5*o*XR3|OW%O+TUq2va>{4O@ji}DC#>-ksq?6SQxR}X7_ti> z$A%$G0T~TL%782nLyiUHI8*EQ%#ro8CRnG`vaLESMho*O-0{Yd zRrZjm&gFlgSS`ewGV)Mq7M@Wv1`$1#%}lczFZ(}9)5{+XhN znzwWAtHI2Gdbaan2-?E#Vu<^OL)K+*_-MvQvwN8NQmkwIXC{kziE;40%Q8ph`<~wa zADu9a)1z&28dv8?b$yPcLiwwJdODQ70hwq^$WI6jq1=WMj@1Z_p?1WGq6%tDWZSGc zPsHVDvR-JjGx3Z~6}ab30NDqkA3>)Gb_Q_vhmsCUF=8Y-*@ES zFXZ3*2HCMR+G6zP7i_5Een0d8AiFZk^6w(~cfI_(P5ymD{=F#w-jILq#&BL}7+HaP z8!}z_w}<@ug#0^5{v9p@0$p1Nt+7-e$LqfV$s_-9&?C1hZ{{mE}{2mg@ zT%p|$9s*eTrFV*;iU?&t6ONbjcc|zkb%`#M$XGO2XPogNIWPHsYkWEuj*R0&Xji{i$%(+{9Jy@Ujyf8*@bowLhA8ffO)Y!$neL1$?m)1{uSJX zxtI1q?(ib>l|9Z2jaHJ^q$Z13AC7vHUVdKYvw849W3<;UKaX9t_hb1>c}Z<;OAFqQ z;xQ1rd>t5Atuuvx9UVs7BI%tp-6lID<$z9#W72-}v@{dU(RQLQOM8jFEbR>XY}zbH z-#Ye<%g<)o6j)iC4#SA&w>)eOnNGvjw#HD#lAJNMU&p^yt2ke%-&^&bqKS9+?v)N* zKRn4KvCXOYBq}2?d3>_Tw<}K}*!XJsX-f2C-SiH#46FBe+4}~&l?Nx!gUveRZtNsW zvE2BXCS7VGD4ubhh>f2`JCC<%F@A@Bo0B94Jc|}SC;~h`ey*wR*W#>XE%gVaUm3=c zFs`Iq-aeAC96ybC8D!qujHhI#Di2<>aj!7g{*$Nx&Arl45qSS=87Io`nM9l7(8DV* zG7BHSi!{vL4|{>Mot?F}2nAZi2;1w|YQu$PGF3$=`yA;n8tug7sCO^b# z#RwNJ#GGv%JSwrG?l>CYzSY`lX;wj@KhK00gL>b;-}6!J3sjc5+e}C#RriYv^#K z*wpz7EnZKO4*uD8>mD+SoXlEdnm%^}j(}_qwCng1KA%HM4eUAD{Yq67?gQlP;sRvr zeX7GKg8L_j42@8qw5$81F8yaUpI_CaAL=I6edCCrZ*V~dk?9scqb)(6>p)A>8SWQR z2Kes!aFrFg|K{R+z?q?1Z}JMV*4<5x9=vk8R1LK*)U*T`*MO2H68^1i|8+a)8$KncPZXk%oq6pfn_DW?Q-rUy%?zOM?sBeR0a3Wmwi_SoTCHIQ33l= z0PQ*Pw&1xkFRZhaGU>blhcwNWV>@Im=7k&83kGBr=50ACTu*CysNT&``RuDgcp*4=bsVAG}J{0@uIEt^7BKjD7NOz{93QT9|971MBnG_3CU& zXYsGJ8m>2$h0;BGR5_?xXaWyo7PBcr<3qGkFXLJxJhZNd+*jCHhZK1vBb%~LW{fp6 ze;OgfZF*rW(x&b|sMToM>(X7gnG5$ZR~mf^pX92{M`nbBp|CvzH=VNnbPEdI;W6M& zIKg zXXUp->or8zTt_*s?_6ZUuYl!sO%sc>;>C3?j~n1|`Qp-+P9jOxiW4}*clx%{AIZnzWYFvVH2-ULt* zNs^{KTqaerokU}z4 zTMCp4)szCIL$#zp4WSw$P;pJX-{Cr>Ef9A{?&Ugfa&v2}Bl%#UtXRFA4WpPFLQqo1 z{(1_s{A2~^3GQ{EoUGg!a^p0?y@uU4h1@rXaK09D-{QM1`dE(lH05BJ?XN|0wa=Pu z+qS_n)szr86W`R9fCW6nqgK|YrXq2NexUlzEy22{cnu7Tf;(Jqaf!^Cg{I*!G#i=+ z3+?WWHTWv1nOndgqAA@Qm4c-h^Du=#?v2ukqftZKF6qaq;BausTC44&n4LysLWUVf@NR=tS+iLZyqR25^kIPs(5Y-mY_6u=snScRo{M8 z_U%2d2>kx&ZL_RG+S@6K3m?ODi7(rhEG-I;o8%_C!G{sumTpZ;Cyl)Rc*d6VES>RX zQkk^(6p$Sqyn49J$=Df363ry#I7?=d(Q$TTMq&@AtwN)%OHC`~UJ^nXYHN@qDbtWG zH{gceWR$khT;*?x_=`GfgHxD}Q*g$S8+%>vpQf<(zg7LESakSB`g>xgY33LsB3qRK zd~f1Vg?c$q2|@EJI14nD?i^6803`wdt>G#Fa0!s<_Ioyr?beqiGos%HPhh5I;U8|Try1KQ@M+ZG$fq?C0DKCmYbn|!5| z3T5zStGFcIHPg`=<-Sh*LfP$VfOxp&Mnt|wRIURTvm1AAQ&heZ^M%EsUS;K0yr4r*h=ih7 zS@|IJ#7HQ*pw%Tqb-vqWT3?{?fbm4qnUs~=L*$Bi;>kD2@C(Sk`egTV3=OODZCuur zd%!OD%M#%IA%<-=v`EsdG2S4o%27B#gD2Zq8sdvaZTeP%T2MqLZVs!?NN}6A(AgR| zr84xKaP)ntta~$t*K(z#ZeF(9eUwCatWWME%+&}CpUdj(axH`&1 zjij<>vS#9e{~v4b9UoPdzmMOUJ9DR`w@C<)5bBUdLLdZCDN09rNkFO!g2-S(Q9>w+ zpa?2hC<0OhK|zrwA|m#+m$erxti7zOYh8uk`+3f}GdI!Q@8^$SUavfJ-p_fT-p@Vv z+<;z>lt=dhU}dHnkxi!h>V#qd5auZ8s64+y_qH2lpv{B6^=TA|QpUN;*T*~#OeHK|furh55!m&w;%&G2p>sZ%+dX8BTN zet0*cQlgbY>Z=TcG2Lon;YoLRrj(zyjoiZkt2P%T(r&X9eE?uUpTA^?=xX~o333nK z5mGB`FngR?RwvUiG` z;hT}QZk_*j#x^X5nn#7LxsL}E|DqTgl*1jm9QH-afv?#}1sK5!aEB^~`&kad?3Xbf zQ1$d7d!75g%2oTv>}go8aEtHjUdw%9?hIv($*iRRe9iehQ{SKN_H!_@GK-7+xy{;p z{kaQETL_di@n^R8_;X6r{ke&tb4!E%+&0BxDk^hlsxDFa-2Q-DjRly`4M3BSK^v`% z&75MX|X}#b2Dxi-t|4=}iN1S6X!>cBZ(AI|#Lpn8C5)*VvvVf=XO9srFCrH?53 zK}8?MPok&pAy{t^>to9LVP$<>TR*~IZ`}!~9Tl}lmD*!U?QyO4gjRc!zgFE-rhT`4 zZ+px&>z-Cl|E8Qiqn$phoj#|XKF?oY-3$En*S*N!K;295avlWx7)5$c6$+YhK0U|vuP($J zbA08e;A{3E%ED(wdbn6SIg?a_iHW`hM-a{J7|~_oXHQ{4Iw~#>j@GNVsMRw9_P(jb z8~Inb)cnpdC!d*ndisRR;(VDMbh><57x3(Uyp_Q1N`H!{74{^RtH5ggtKT@@6v&c+ zbh&o>S z1dH^Q_1wn$#jU?lam#{I6%X;DZYXmCQck2ih`H|~ETuEt8OrBy9Yp)1$0~pNWAZ4q z-Xrr^nG+*3YcCM7C{qbO^%E(q&I&Ibsi!uvf$*U0xn`oEnrN5P znpS0;jw!QD8gACunt@U-trF@+2oZ=c=vJ?`yTgkE>MVXuZjcutdBS7F(6~4$1zY{$ zB}nA}QT3;IBX6SbrE_2VBQl;Yi`BJ4JwLbWOEVmQEK6CqlNkIx!onShmog*0 zvOX|wKs#U1ADN1^gm9l;Y7|KhC0a%JN!RmsBd~;O53u#u4 z!%LCjZdJvj0&T8#+Grts1JTjyML~u1FOZ02r^km^^aVpp4PEu znc+(er!-AVs#-5|>G==Nj^D_!_FXmBzK47d#aH0UJ94H(!3+i4}Ccs9W*= zK)JlIlR*0zN774chszqITz+;iAR>Z)oCAO<%Lsl_~9{RKsHu$O@l; zXf&Nr^G$%8XG&&KL_Wk$t=kv*078c3wwIQb%JyU0I`u!*`k(xz{^uC#eBo8mAu)0e zo|@tkJWf_Dvs(nktNY=;^1B9gG4d6sK!sQY6 z+kE-$9V3W6hTG5L9b;AP7nT~ZZe~1V{Fj#AOQ}zVZ;k1V!&n!uRl+yL`dPeNdo$Y= zRItElF9}~Pvy?flrB99b7y6`QUV{Ni(=CNg2nZbrua54QM^?MBm7w1H$K6r4un&F* z(Rg0+GNZJK>2}D>g_;*JD*-318a6}m-K-v=U_m=Y;P4QCBe&?gnCiQYd>Abt>P2ov zEFPE6!Qopxd;{Tk>)-$7n|>Ajy_j$Lyz>*M;BRF|>%80R>uQvF7+9Gu5&+veOP5ucZ0|Dss12_BI){BN2lIYJbnj(k%h|{tCR4yUrDx6W46^^Zsk~YH*_o2?3eG1{xK& zE~xPNBUr~LdKThtt0lNp%j?g&aD?0E?e7V%L-(6)ca1)NLTIg;$f~acscE)PpIMQG z2;O;fYcDBBKhtwWcY3KT*X= zP?23og{7@htn4w`_5`;l_`Hu@JSRvrB< zrLI>~vkp^ic239kpIhNJy-=_qz(~uQjC&(6ySA zNM+^Ln@m&U#FZ};-e|kScR;UbI1hnyG!u&x5<1CLPB@-pvawM;6Iqyu*9uy0q$QOVE$UhllS)yo>0JW^2?LO5m}8ltK|nqLJIsCHd8D zI;$H^XoT+);>xQh`2g&33|2*PZhxv7-hmBpOiCVNz2r*YElVopIbPo3{J)j5vg*F( z`~qfQ-8X#UT}hGdakx@f&tGvZ(q=VoArtDdS%&v9^m~yZ?dnBF7HT^w+{HN-v?FI@ ziFTPg{2;3L#kO9Sw(TUgS(ELHn&?g(q6n+v)t0osDj~q#+cbT*nLou73WO`MSDT_< zO_Lb`l8-r=zD+2a=r~_tca^Zh3iay<*pUf}<(31p!{^8i-5y#+_s&s&qI>aPk2L~c zC?)9`z#aJLGiL1b+`%%2_rXSSR-^*?Vfk{CC%!5YbI0q;5kaQf>H%np`n77YyK+f* zzY?%7!RJnv73mg4VRKL|zzbR3F~DQ^Qade{+B$h6HlM{xeM>YRT!^(&OGbOeSkM^D zMOhGXy|@eI7YOeTM6XNyDE~!Srw$L|&g(=xUm6+IPi*rcjj*NqRu~(l2^w2DM}*h7 zJ0C+>oUd^iW{OxV#`}vBeTC8^CKc-|QhglVu=8}6i?=r8)+L%B(f@UNj{wr5Y&>)7DDjxZ6|LhJjCkXEmJ^Si2;WlGtv)92n)Kq1vujb$e zfx{rFs*dH@V@YuPcVK@-#ajflNIL+vf1o3^16wKK!&<<8OZb=;u;CJZm;%Rj3Gxz9 z_t?X_3fHaLuYdMsSSDhCP<-^ewCWzNZM=uKROj0WZ?qA^$ZDNg75N9Z$+$^iMe>k; zQs*G$k2lpxD|QuAxS5RU1qPP^_>|$Z+P6VyF!y`)2UbZ97AWI2$DiPpf=X@BZ4G0} z_E?*@*wy5AZ`WM4{i1B$ep6NJFA|N8@|$zoZQl>%;kxQh{Tx1;Ce>o&n6&s1_R`Yv zWHi>x`rR^)?vq4>(yW34Uy8K>`!ZG?Q!mperazeCOZD>Bqy4DW`b}Ve`40fpc%PFlglli?giUq_R#@?A#7R zTa_+Y?d_34Pr}>YOrL*)vWkAm`fEFk0(eW(oyeb(ld@7`ARc1%i42{rvf*00zHPp*0o3G?n>6oGV=EV@VbxR@oWDlIn1sGe8Yb{v&mPH#ZQ*{X@noivsc}@>FO)h z&afK(=j)Wfz5GPm^={;|p7A)EfvUf`8SRp-@KH>}a31d%D~c6}x z?N7K6;C7ua@)0`Thd9g3%vXDIzQ||wNwl!cvJ4*^lhTRWs>4aDC2bE$|5c<1Q|ah3 z^VJ~YCRXvf%aTMT*#}fI^}Muuv`qBnm@0AcW3nstG%YL4b&QGo1krVWskT6$w$0(= z_PXOjd;c@H2c2ravc#{T+p2d5r>sKi%el$*2?U2R#ttrOR>848-4M&)I#cJbM`c^& zD?G1u?2VG}x^>3i%?yoNR@v&G{7L<@nEEI6)nx|vNNoQHDeX2-ZIIgcasFw4G`qka z?###+@GUmnNyeYD{nvwQNd2n16unbfJKyEzi&Wvq9Q7?nevdnJb~|+9WbN75jP0*< zHuN`+YP0nGc8ps+>Q2Q8(3mH8A&PZ;x zbu87scGR3QK^d!9pBz{I#_k`^ao2Y6>W`Jv(B56!5q-(#ARmaB;X5#q2L;`Zwr)qQ zTMpeVw(eHwmTTQ|Ten>6c7pCUTX#EjJ89icwr(e_TLIlWZQUKvtEf1}^c^~vREX!evGen<2J#OL zx`BKqDzi*_+w;4kxatQQ z8MA5zU;y)o^kh_$K7-xR*PPmClxfXx%&47|-M6thW8eRO{LHM>zRooN(kY(W=kNcY zfk=8&*wVx4Nb$D6_UNB@xS=f=0W`CIb~Eg!+g*Q~=&y+ZHZedG18riUCeF7B8e(6t zhL^ZExIWuovGk4kh&xN~j?FW%7!5k+%yDYXp6&P#>EG7+Kjg4;JIp!yzq$U;c9;uV zTA7a7_6^f2v&U5CTRHNdE&o}SnD^w{=OsTE7xzdUYYt*UZMnlOg4hu45?SRkf~~FG zX4;_RJq+Wz%*}(XRS-q85?O>pI#JDf3Cs@K#V3rRH1fMJrrdW;z0z)jA z=!h~t{gfRDl?JTbLLIz6uz`BfZ$N!mP;BKkwhmg|YuwfEOFhwP zFc+XG)#pXN!`>_D{JBYnK5Y_L{RwK-3RbuDnr5hlCs7N3h}J@_n;TyovW;=|-I>ZA ztNI^KcWR*^%D(J|%I`qg>uV55_WvskI!noJ;4Jh16t$)eok^+vmGWb@b#if*TkUvE z#$vj@E)SP9bWoPyc5IO}a4;e2V1;&&)gXKxOsTKZsG-V*QI#9)U{f0ET>K|*nl@CK z5>A&Y_+dt)K@Gq5FqdNadIW<;n3IE;QfIqoQi@8huOLx+>4bolQ z5W9;TqKTpUcbIK4OcTRxf(H9}?jG)MaI>W-qqSRkTr)sIX%*zrE{t2XBT?qJO5cQo z-0XK6*=s}EwJJ(#?XLM3PMQSkM%u2Tj|b?=h`LMS)Ou9ZT`v{dD7w>nL+v#gBZPCM z+?K*eHjC`1rLmnV^$jQNQWa&n7Yycp4lKhxgSdI>V)a?N!QR+AX}FVeFP|&HOIgn* z;5=TrRg;b{bzyhd7fHZ(@gj+S?BBeI$1`OveK0_=k(cmn{7s*@_WH2~wj#Ok#b?#@ z;irJzHE&y-=h#DxF14C}s(rWc_ojZA><1c5Pu;(*SRC8h~iA0(NolDs#1-YMol)QhrXj^q8>v0pj1IGD%z3KMb0qyYgJAIsBfh!PtuiZxWyXvKJL}S1}76NGv+`UB^vQQGv=j~*HCQiDBsL< zXIyZH+&;zy8K%x&ScOtEn#b|RH+8B46|9-h&yyHDhM~4-%W%!k&!`IemK`3xcr(9z z;hhMUfdepcYAbB^pM>y?JtPbZDfu__cH1>QI73p)NNKoR+PAd6D?cXLMi5cD`kiKZHkDw z-_G_OO<`Fk&k?9pxi81DfjiZi(4ButOS>DT=ijRC+>i2~13PSxn>%0%ssJovS(5U_ zBJzpmLS=8(vp4_m_ABbyr`ESee~D7%bWMHh5_gg8$M-W%ThUA9ezLzQ7i{*fSg*pP zg~g~TA=Iy~mcNzMqSZXc&U2_KffSD>H`&Kf@lfY;Rxe+G$JW&)@npp6A$wn?B1M&Z zGdxyWg&bOpOwY|#=AF7Qyv@8`Bdunf#C!2wi|hn&~zJdp+*w_n+{fh3KFi6SB6rT& zPVOJ%x}D?XJ|Wk=o0I#LT#xQf?lW>ddpNnz$(`HN$$dfYymOu0m*je#Cus}XY5R&? z?_Q{Xrmo{(lk3yl$$dkvZyzW3ExCSuo!mdk_3!88z9ToFzmxkHxq$=7>2~xzx$_4) z^?o2X=zMazZT*|v;6dbc+xn5*kiq11-}Do?p+mrVb$Wj$H*Bbr`-R-_VNUK>awCR2 zx!=f*90AVK+<(Z88VSy?x!=i+9tAF-xj)ENjt1w}{qAXURh3Te47o8?PR_8vjUD6U zT;who>*UIv%*&kqrIU-ybT>1jeQ^f4SrKnDGv2N*A##_`0%z*9Ws$qgp=;BIH# z9YXHt-A-;OxySBdJ=Jc9k$ZfPvo9G=?y0@dv-_|SOA@8qh;y?(&SjUo5OLFbqf|mVXFlfSrjheJ?&PME^FHC^E+uC@>BU+@b2G^Ko&sn0 zO_z}iJS|+J-QUk77yKJJtrsB|_Y63@zn?`e{#oG?Y`2$_OL&f)c3Vv@@p*8z+Zu97 zFF5Cfv&p5ri1M)Kv2)0!zT|1d_yU8@p!|Z;-FE@r9mThA>0&q?NUp>bL+0X#x|aI;q-;xjlRm_1JA4Z z!;|=Ra3i58$2B3`n*_J{*)>-M^*J2%{f7hGZ#X^_t8XcZ_htL-yGi`Kn?(7nKHr6JuY{uZsir>+jX-z@ z&+3Ho-QkG%nTh)qR=Z98`F7L(XuGLD)t*0B#Z%>lGDjXm`i{BmcO!7#y(#trYr=8r z)X?QY-hEK5ernXu>>y6aPd1fTX6@(jYCpWf)^0L;wxCpRZKlwMh&lG z;sN#apt=c|xe|HVzT2jg#P^`fu1}`=5XsGk{?aV3MyQ!4PEoDoCp=YPwqF*RHS<}R zc%Knx-wyFP2#Ts^feZKj@EfmuW2QB+W-T@uLzy*oE*#&pA`9jBWYAY=`Rd;tRA2-; z7(wh4W~*m3c6A)Deocwjh3ZLG-7;0LZV9UQydj#A%j!w9f_y8MQe;lhJ~Pq!zqg}b zo$V;R1Wu;^RSQy9`Z)`pz8^+Dx@*ScxR@!*U*Q!$%k;sYfjEDXTWV7>!h*^CEGRyw{BYm#D9}OHgJ*Rl|D~vw2M80+8)4|Im zLcN`|CHg8;rg|fgDd%m|?0w?>;pLM4BA-9}8xBMJc!!Ihw?HX(A-<~RT9cJid8wgnbVzcr{#ZDL!>% z-&+sw`(uMJ5p7v5)7kp-Q)PYuvLp62@jf5SSmxMWrc5y=C_OQ&+fxB%J5By zLU?sBn*8KI)OaSADOQZ#z}^eST71h0FMsg+!s!41CjLGci~BTwU&xW~xCShm?RFaQ zO&9fEm?C1A@#|t)Vdn#H!;1?|kH=nrb6git7y_y*`QrSU(^EXWjW0fW2L-^VQ&ER;_Z+kKD}PA^P_`{o9kj z?pj2FU*eh;SsNun)A`{{U#99&6BHZJ-74NEP~B>(;ZtteKC<|I*j6DO?dv7lys511F_9t8UnN|B6+SeJ0YgM0Iu3Vatm9S<%tK_S7KTCg?2JL5KE%mo3YW^dY za`7t62!4m@1~FAnz_Epu65+)+Lfjn{Z-V$kR9p@5?8dgZ2IBIlc(aI^)vwrcc#{O4 zRo%FWQ*Km!aXmS^`o4N{W6{0hWm6M7B`GK zUM)F;NA#Gtsd2V3&Qinv25oP6#NKhs98N$lyt#hjjM!b5(fHh4KkWAI1-NB^FZ<)^ z@@jQYi(k!Cf3=+I!&y%2^!`rKbn2}&(j8;wcf_z6uNxYD*CtD`ZR1)Jp>Lb z_REbOR;+m`s4qZ}PUC+nzSvOl9Cz(qNYYw;+9gNH_Pob!wkon(^PA9hD^PRHfp`5q8F-xIxtp@F*-ba!vmom;uP*LHUw+^zewyGQBnzNkA>xx0_< z#_L1lI2YdDaW4EZcla3$3{pg6|5QZC1KfAwQ6h6dg*Q>3jq#)pRZ+zeqv(|oXau2P zL3>46yjg;mN|=0At}Me-&*p8h8EU_e;<#Ai1lp#H?-@MCwC%Ha{R)5inuAOz@3+)6 z;a=RImlTsXyK#3~?0X679`~3(xEq_~6T`3>XmGTHG z$>eAyvFk`K<98%lN7|?}XGd5^>=}S`Fu3R={IYIK589qTs6#ty6Eu`7A~QS=cTNp+ zYtamk$5$MW>W%=l4;{f&XDxd*s4o@4jhB`_Qxv_6l5Xnf$)9|9rGXEu;AQn+d^l!D z_n0Ogwuy%|aoi?o_%ar-X@;c#0xg@ zf+n7^2^wMt;GWT?`x1(0y)Iq5Y#(RYz7#E6k81xf>9VbT(f0I3-L*zLgpT!7@Rsf> z^;;%y*$M4bU+rz%KN^A|+;STJ9d0~|5}kK!op)k=2jcpKI&T(@>wFjE%3F$@eVWpH zuc6+14fPD_y&u&}Q+n@HFPNP_*}d>2@{G~bBNe06z~aTfw#aa}=vjSvu08)csgwDE zoy-q3@u5x7u+T0*51XJN*f@W>d*LUs+@hWo_CHj% zBs8-<{6xF|)OJrpu!$^77k=h&|EY2~HtO&*?eKG5&#@yE-q4_)Kh1Q05l!a}DxF{0 z_54da)GxJfU)cl=%&#tnes?X}(qo6sMe%dH%9omvk35EjjvAK%@uhRs092XT?~1s? zJfMh+=Yj?KDt4CRd?H7yvIM7vJ>JExiTYbQ*SRl=pMS$U30@C&W9T!6S8i+#<#Amr z-{G#t^58~>go5rq#Rg&lM|_xbw)nF}J;E-IYFMGWOW;9{Dpa&NV{8>VBp%E6yD*z@6H~xL>BAjXzR^&9PK7@*MUfGOZ#j zGZ=^~Nc085S7W&KO3Y6-@<-ZW$K{oiL4TpF+POsZ_=Z~fDIUH5mT8prS8F{SDo*g| z)5TNOG2_f|d0f5Y$lt1ZfH>|JH_!4MEH-i@FX0@sR0dOh>Nwl6xmcLMm9*&z&qX`b z8*j(48(XY}wMuQ8Qk%jBWhmS=4q~Jfd#fkUX?+qOgN!;&YgFGpN9^6Th+tt#^=@fj zp77PU#Jx;x=cn`a7sG`Kkx^wNPczKUe2w`^Bl$XIMw+sOdG5caDaVv~ReB2Y2Mu0UuKlxV{O)Iuo^L^EyNQA?<5Scdu#cSP6p2BP@6>T*& zQkY%ASBr6Te?qjv-7u~Fdx66AXoj_q!RA=T%WNyc%XObtDgDKv8m4Angl&9_d``AeNL7B1dI96<5&}%sLVzoPbHcIE^ z65OwG4jxkY@v)xoup?5FjN#fB`IiXQy2$=^+{7w zpPnDk=_@fpy$$mmrcccM46{mqpB(cv+794JV)Z-7|DH!EeuMtFh58B?QY(wos)t}_y zQ{IsHo=^BqEDY3b+OfNQ@eL(+VVh=8ZfddwmuaNyZ!lVun%(R&Tw{XHPcfe2aM%c0 zwagvP_F!wZv0$hqdh;_ZR}R9;Vy63a#!xXx%$j)kiPj-l7dQ3j@V$H&L5+0|uiEiW zl*T0BuC}|lYS-4SrJhKuvd0aRbud`l5nvsH&dirwp+D$W>1~K|{!hw-qQ>sa5v!Ge z@B&o)I`m^X9!9@uEL_C4Sf@*JKb@(_FRrPK!?`0LOG1Bq$YVy<;X+&(Hra;FwqdSq zm}eVy*oK|9VV7;#4MT7Ba4@$;I7a`ad&R}yqk+#q-u9*tER!+NN*i{s_ z9uGT5c6;=nhT@t_;UZiw5oY9Kw^UDEH?Xh&66>~PtCbs%tg?b0rxa)T%9@xFX>nG( zhd&AaK(XH+C~;@xW9!NCb)?A-qPS)jg3WgZTaH8a*mT~el2QYW!iKqfiL#sv%i@NX zm3H2ZP+Ie$RoYN%fvr`iv=&0EQ$ww3w$@VHFxxgPwhc>^2iL%Zvl|ph8`#Njq5dt> zzs35uO#j}if5Z44I+DBx5 zW);rR+L8Gpg%{%UbNTRSDD-mwpgvw5gB%GPyf;<(oTYs}ImXu0TAZW3pb{;um_DVe zm@%daZkeev6-rjAh-?vO-P+>os6k}e&B!tt<9akvUjWBnqD%ezv^+DKAOunvrz6ms zb;DhYXvVsIC9#h$zcua^i)+}?||iqhHY=8TVi;RU9U{VH4Si z3l&jLGEXsHWjWEeX_oz>BgN^Kx{j)y!>axS z8wMU&hL2#8^A5~8`kkfUEd9<>Et-GARR$VosR$Oxo6}P5A9p{+GYZ~=_(L9OO-zDxzE`EY3nB-QUVp88s z$*hX^X+uH*)^(T;`2zfDC*xUtrqrF8?-wTl(e{T<>hkhtOuW`^SFK=KIhMU_~ZY(4}Z;NyZfJg_#D-T&v*3USFi?vi8M!yYE>VO zpSroK51&)752qirk31gKeK@5jaLA?5URT#G(0%wE-G@WwLK}VfT-ArqarEKJ-v!P- z{BhNXFHn7WZ8WB;51${ERVpGaJoWnUNB@s~cr0M_;R~F7_}uz^_}qGZ`0LR;SAF=r zdVTnuXdiw;_u<%)sJp`M!=F}t__L_ObLD{)@7xZ>CBHondiZsc&oU*k5UY8oy2 zjO>TGWR}QBQn|Ur=2rKHKa2(UJDq;jqpnf z?J}v$_v-2_`4PP@4d3c(Cw5PZ4!&cbE@XnX!$s^8E#BFWZKf)m2PMCT{TpE*xGiyWxUl6 z_)b^g?g;R+@omQkjnCs>$+C=ZySE*mXgqPCWO|~}u{ZF&S@35x{TvyD&MkYcTWc8) z(e0s`z@F2=9NY)<^X*`M@hV_T>K`ILPQ2(M=p2ayj-S7CuVr)#wjG~p1jc=kW*PCF zz>k>Nc6`X#a=`~_sfJ1Zv3T%L_CZ>%Pk^~m5V*Nt+ws}Py73A7E#ul8Fwao)(?Hwt zImVG8JNGs>j$W|gBFngyp`T)$|JED0eH-w>(ZK6(1}>Y4u>MY;SBqwA!`1)5GRYsw znM7k}IdY?V7H|RatIJEK=NtcAi=63HhPZWSd5!Pec6_n1we1IK#l{V{1Jiqckk;CG zp)Y(hHX^#eGx>wG_Qp+%zSU_8b|oXG5UwaGU)hZe%v`Kz1?nHb!Qo?T!vqy_Q7%0Jw!5T_goNm zUITaJCL1qD##Q%{T({UXi`$N??k8p+HK*SS%|;@*MDyC<*IAv7Y$M5ViQQt6LPk^L zENTWX+%u-Lkz@3iIZ?84xkx>Xw#H^^9__wo%=Vf_o>{$TOh2R4 zc!APQ;~`a0N;cMp_l())K1)j-X6zX=&^X(8m2o-K3cj3eylyNOY4==6eT<*@xrZ$x z4UzfK8A?}B>Sv_5AXSLe!R%*bP&!O$u+IaKX=83YGK?rMTdpF_(z+ zJ*95~kcJySQu;%rxyDH8FyUvYXwR61BAuqRL8Pm2r>Gm!LXnn<sWlzta?w}}*_beHxsp3*y_xk02vO4Gz{vq&k*PNZ!jr7OF3d&cY( zDU(vMNOy~rO{r-+rP-9y)8g)4k(yDuv{;4SoYGGs?H8#fr7N{vYf81^%VCkilx`Ng zqax)~`dY`jh|={sgm#qn7b>Zg(s*%qT%PjhI zq-RAso6=~JUKFVtrBmX|t0MKFw5u3?jxx@rlqAv{BK4-Utq>_1W%Q-wYNw?Bls*^D zcSIUUsdcfk8$_vG!aFI_5K6y_FCU9EjMD2`a|ET{MM@e)={X%nkfx!L%IcBA`1T5AMMwA5F2prx)eno+u((gvf2xmEgx-F^3r!T8+Tgu93P!rexr z$VB^VFMf7#-Dz~A-6Xcu9mcsPV)h{0^lqa+?OIEFzreLuB*djd8|e#N2aJid`?NFs zJZMazyDc}u-7(`H+FgC=o-s3AFF_J_M_R$%8^$SgX@=`2XufHDP0cI1p?`TtOK;~% z%-ru99uK5-U10Z~5l`u8-JUVOxZgK2JZv4)_l)_{IAxsWLFg5X^*@YrJxKc-S0e4- zXzBcUO6o(YZ!0DBqcrylB@Li2BfG(uZ;Txlr)^u$r(x-MR(a< z;qE(Q0_}<_VE1n=&6%g9$&`NYsicc2g|Adngwm!(N}5G!fwr4X={s#V$Ab~!hrKB2 ze;ZeNkh`UeQ4T*ES5bOv5u~4uEzGk!Shl|ydl}D1Sw_DZ2dMej<8=DXQnZgLYVYbn z>AlM!^{13<{733w*gZ_!jbg1E@4DZM5T0g@oC!%ZZ#^4+&UQUV&8u0L=DALJkp}O@ z@MV!mh;{HB#CoyoC%PMa4(jJ(*DsX1P+H=0Tkz$0TljL7E8c?L)C~yX8Z8x4TJ360 z=?Y5gT@{parDn}=Z*ujZFH@Sqm*cL(l+L5{xRze+1?g!mB{O|5YU#RVkY0l%Y50QU z?Yr8p*;%lA-*uc)H>TEfA7|*_N$88+2_hk{k4YQ*$w+m-Zy_i0Sej|>Q`CI7Gg6!B z{)WE1$8yMY|BH4n%z|ctmKL*x7rR3~XeO+IX0f}8kA0n#*hY5;kr2YG>|eUN&!XKP zw*Ir+J?ZX57q~mi-ItnAg%Lt`kzn`DRM_=&5A&gn_OQhb6A8Wy@6VZldjzGbsgOpx z$5Dzu8zGE!Po*z6c7iWs-Irp*WW04Jq={M@K9ld!{U+`5>Y#bV{W1L< z+8KU6`ZGYbj-$!zo?37E%*)gdd~RPZQCKTbNfe^s~-J z=&j6a{YcS|bGxVYaP`(w=A!Oty+pc+(zElsr*$@Zo15w9_X{BPGavDzXSm?7xD)9y z+6~Ev-2n3mN;AaILh~Z?6-u`*?4DL)USfVm$ukX_wPtpJ3)(xor}Z-yn~ehup&E8; zwA8)kSjI~8X0r_?SM9NkOGL`2bl?1A86C_`W;aTAYN1Blf_872;{wRDkK&JI^f2BtCs10G0O_PTk{qI6FZq)*Jr zl)5KF`qI3R(ykOp-o>#X+JbyDIbhrFsxGV8Q=BTlX1S*(fEu!~?K-I;<(@gTn>2Ubm_jqvtE3eR*U4Necsgji)#t#jtM>!iU9w;u`WG!ty$Vtv@3)lB zxfD`AZ$=Q(lKUYI@^%O!X3M6p8mrv(Gy2_eDY4BVn zO{a8{cFU}}l={q7(tJwmu7I@MS`@^*=U;svdx}%X*Mf$`q8* z-PXhO<-}I_vd?;+zI=NleA#ckOuMP~!S0Yq=l-{viaggR$AcPOBI7(jHePpFjdiG*Sr>qQ0`Lz4gYC>rr)9|^K7l*h! zH5YOD)+(lCT%n{=YHpmlPSy|KT4j_z7ip5~TdPAH#)rNvzi+LMacG;DGY$W=I>%uJ zJ%u&o-y*@!Q>+F5w$7on{|Y7bpfA5&p)}8B2=O!4jd{)UZ>x74a^lTa%B~+ncr*q3 z8b4Ws^jwx&h{;3co;A`8~uH2 z9CpKew>zW}zReD4v~OFSDf#kkcSsld?xQbf#^GVa4BtLVx#N{|NGgS_>MlnvUFJLL z@TJE05PgZ;18I)$INepoDd|L9nnbHZ0^HU4o}n}<$tiV>b4o*!ozivnBz(0aCY3~` zSX>~DTD-ITCTrBG8lLalkf-Kp*k-_Vj_cqzV|{33zP8qa8|(z12^4 zFpalw33yE7{XwH;9kJ%3(Vi4z&XEs2A*1C*FNtR60>mmPm}aaU@LGp7V^ovZgzu1v zwA|MTm`ZbYOQ7d&=nuXdzBS8xvxCb>C-%Da13_P>&m_cO%f1qG!K&{B&t3DY;7_-? zJ0b`6`;b3z9mSvaz zxJFXpGRCjj?{gXM{h4BW|776K@z8%_WM)Uxcw%y6F`tssX=$8h+?uWV-E3iu%5T=O z1(_Dc)KDwY%*oFe%(%B*$2_C?ybglB1zQ-;-?QJ>!gzVqexGUFfA24*X)ND@TzzfS zXu-QK8||_EIdf%&=yzIlwqT>#Jq5ohM|~JKd%rKw_^zgp`1wjrrQjblKUyhYXlF~tPs4t=0?GNHMa<^u30a*qh_<F0vimVP7XD*0aUpY47Y^k)7pc{OAH?_$2J)K#8m z{9IxQjwy)~>{XI1SXr7OIHM$6Fux>MFjU%7@B`*d{Oq=3o*IG=D1C*c#^mbXrG0&Q zeOY;#@zC{M%3a2FJ^P5}t-S^cCiNUD_`THUJl2*xF2@u@fJ$R7d&H};RT|%(niw6(7xXYp+Z{7d*Pj^k9o|&$it~otDHT}%s z+3M`I74Mc6FQyiy)x0xY#9uPPYrg1k)w)vJ9we?DY;BFs$KNms%w7uoYhL!nly%Nj zD_@K9rFskJpB7+EFIJnsbU1gn0%wIbuWS|Itz!PA71$TQ9jrnDS3-$&OM7Kc%vp+G zcaO)(iQ;XQy!M@^?l*ELsoUnR)=n$DQF-T4F|ttb@{2WE{evsq<-d{JH$PSnsD*w| zh&fKnPIi&-k0KoBSvHBG0CvHmKFu2|G8f7Is6kedk!nATrx&ggz4Y|e(FQWz-#PRZ zp7fbm<7mT^oFD)}_RWv&uAQaNEssV06b={GDMGV{7N$Kkdz0RJ{k{&@N4pg&ANfwn z0@bsXZpqn;0{$wcld~yM3B=ForU16~oKz|^f4YdX68>xP;A)|ce8^d6K>cOdrH=^*ZWagO zG0}$~Gh-Ib+mEPj{{7}5ZJ*^=;x+75=_dfzQvjy3k?fa9%;4EuxX$DQ52TDPzH)?% zKT#z4t;LvE?kwjkTz!n@A=ObYKl;QQW>}9q^ck(mrjG42X<@yzt^GnX1#w_^TMPpX zC&LYG_l30$<2oY`reBQ?uhHZK(37x4NN-Ypk@i?flzGJ~N z#uZnV^z|ws8}q&M4guSUwiNV!>**Q(@(b7TlgXVB7blOAJ=a#oC;c&eGpeS#m@FyE z0R5W#MjtL`=6VAFrw>A1uwavwqfFj?@IrT3_g|b7#N}m??%`Nv@E`Asc9|D%bmZnm z-XZpO)$xM2OP;jJUPb%lVvf`{BR#-gSSwA0#wUcM1%x0V(&`fGy>p{ap=axfz%D7YVI0t0*RFfF*}@?xCv( z43RvBZKrbUUoYZQ-klUDt+#aGn9pm=H=&(b4)H_sgH}&jC!s6pCj`_ry=cw5Xnu&} z@QT~1h<<~&r)%#qhX6e$?kH?PifZv(ZBfmT_Sx-opTVopa)BOp@5wkOkBJ`;pKCkH zWB)+ganV2fc@}*#2Ej~&_A4#&%WR6aX!mwQdmlI0eWE$f7~wW(da_ZvvYur7m$GC~ zTQLcHvD;qo&b`gQv~ade{w?qPX0t-xMuUC-K)iX2+}EGi$)Y($Og^~D(!I6fIvyAz zh1h2o#j_RCil5GaAWr*|gC#0}e2bLg-PN5_NuXFnH?^^7sDI6?nHS4P1)%S8bZup zMPzfrU?W5HZ^dYHBtLh}(#X!45&LeNeT!Ckh%)q7bfWT!E!Ab%JSQri#IucjC5XKz zzy#es2icIHEF%%OtDQ{nnB|KNQ5}N=>oA-+1I~NQt|afQ7bG%75I_#;GdWvplS#OKZJ! zPYaA_r_5%kfc?yp+B<-SWf{Bx=V$-&eyTxtZ!yn1G^TOs;fH(5*kd~jjnR#jlM!VN zsc8&Zyg}|+gTHs$8g=Z;d=Bn)f)6xGT^8DtD&fSvMX5Q%^uM@NjC3G0O}lZFZ0&Ol z2%fTpKRZNHBwHCM$d_FaMV-w8HhFR)_jj#QE%jn$Y~Xqa<%dqzw`)Xms#v8?3v6PT z%>w(Vap0_uQCrASk3sfII?s0q*@Pr`95qPnU2g!P7U;7Gt6A9p{Vp7E&*RiLx0L%5 zpcPC;y97*xk@kq5rIp6A!Q^}C?k!f^QhEz7{qgGYq@nEF%OE49{Jos&yJo9cp|hd9 z&{AC;sWH?j*!UiPD35mhkztT_;#^~4bT=8c+kmE<(YX&d;*41Or= z3n2Fh5N8OXde@1cI~EF%W+;xwqqfiyGa#@=oi(H8$@&K{pVM!R(FarG#@_%Ah{T<- z9zu$ya4GBpH+2#H87bRZ?{FzJf-z-Z`tqpn_jEVOSAq-l`WUpto!#lB*ovq2Ayf2o z{t|V~7hU7*`sDfRe>>dl=*^Wr@4rtb<6~-}qi;tACTD#ns*b~SJk-LUb&?De@VFev zX?Ah3%D@y(cWwPS*XH6{QU$JL;Snhrq1els^mLrsG?o|9(-?WMy9_jG=W6Y6aTnNo zY#@i+q9Xnt_-?ofA@0-O4vr>)!-d@b>*)(1fv-J777ZeCKEdBaIDE=M_uqm$$L5y7 z+MS*3+cy1z6Y!FiRSK2*hx6dibuNMI>?N`pbJB%|?EXeFV_E@KjoiQ2UnE10HZ2%Sej7P6OS!e6rohEhZ&!Y)y zsP3)X{ji;TLyxm0Rms7v8iR8jS2br}o(vm&m0+HNceKYeY(;2eMQpn<+$?VDZbQ+P z?MhloSjyD}tp>ior>*zFKd&ASk|T4o41)a4Lwrsuo_{y^^% zLp_MuEw%Y3@WQxPnwEQd%w@T8e3oRD)5h2yOZjRP*4X)7zspMG+}h+VsOsyY@2eLH zVHgW;Rcln@Kd&h7>!|75ChB8bR?bLT8$4~DWwjM4x~s7`Ga6eb7vzQOiV&oy@+NoD zqdO%eRd#YTn$r(zZ5ps@}!PrYz+OyF4%4r{K7MwV_32U?0Ce3lESsbsPwa=@>%v1NDA87daxFgvp44gyCZ%o=l3G0Pwhkp=J^?@^5A6JgBQx&yp{%cS0-SWga!oRK!Lte1QF<>=1cRmd$GuP=WL_Tp;s`M%Q0_9LFR zl{QeZBx7&lx)gB@hklZ7T|zWnFuEty3i7~Dmn847S?62~`8Sl8SwvX7cEaj$gh+Fa!CDn&Ma4;a*k*j=M zq|e|&um)7{kLYPG6{pnoBz%OknvERJD4ch1&UjfJ)~%)m_NBB~!UCsOKbF97v)rs- zzVGd!hFC2TS3qr%1H8ZQVYB`ET_qFP5>-+qG;7Tc{wsp{URKd8_CCpx$GXNA$v;k! za-uOBk))nc0L7EteC-R_+1K`7C182d3!WSF)p#LaaY%eR`Nq(-C_Iqt=1EMKyrkI> za71zp7&ELF$WyBj`sX9Cg}&W#l-&8zpwsI_+aQKw#bBACWu2L1@AktNdAOwy?Oh6r zy>=wWF^B?_D2}wgPs^B-_R*hHoUm5vp;V=g~ujrLTOimM} zL%o~`rj|aD%aESR;6rA`DQ8RfDd(*b?2zT>dIv6dTxpchY-pkK4?eUaAd3Qu|C z>NU-{*HDHlu~eNP1Ch4a@_Z}4Keg|!(%WnQ*t%b)y_f;(TYGoh$nL-ofT{}4I0M*E zOIof-zYznN`zKg(n`6#q0&A)JpCVR~mVi&6I=-+Wwoqaof40;{YxCeZA6Dy|{ekB9 zU5+&n$IUOc9ngyS zy))=x+TXs7PwXi(HstB}`BwJ?!9uXU{2>I98#sPO_Dt+2_phJ)GhHARm7OW1jmzvL zh97ku6?2W4y}$6Ddx)QZh4bd6^7cSD|9r`j)SK;(4I>%p1qF)3^e>ZVLVN~n2K>#4 z>&0BgbT`pDlr9m@3Vg(#NtJ_uDoBnB2%hpNlXSPr1*{LV>B5gACbCyfyc=Wg^Z40> zE8Nn_%qJ~G-b?{dB?`$^#be1;rDNr;1aH0z*Dd)i|E=nQBCOq+^*$36PL+|A9YnE} z4Ds;3SeqATgmW!3Yr1oXEQ6UY+Yg-CKHSkuKZG=tD8^HO^8UdG-7MJNgrp=_rC&K` zCGA1flLagChdJQN8(!3Mr>}@6qhH$%;p}}m#$qp+-=kj7uCkKcb86h36Kn#^gUPLx z3zZjX6%W?>La+i@q)htpdcQy;Z5)43i~odCWUcuHAL**wMQyMnpBDHWoUoZ3Qdq<* zt)X_s)=!wPu3JRA|7^#;Fy|iRbt)03gnGVrA-+J_Y9IJKATyveAU41hMZ!IR|9!qO zIpnqQl}PcxaLc*GOXz~T

}BNb!*|ZIPebM)Agntvq+fZzj^kT_i!6dU~EJD_cE? z^G22eL77IGiFoG3-HdvkB{~^;tGC5-T`l%}(ASW?gesT~6dih3T~axCy$>9E+r;2Y zn)t@<{PsR^O$1HnNL^X+3W%eL{%%o~(P4%DHs^Kvf=*=#xNMZ+wV25KD)1u$B`+8`dr$o^f#n;YN=SF&jGV9GW_Uv%^IrTa+L+bUe;pHp$OGsYT zeiFIu)aZJ?nu_wuQL<*`fT!R-)97uEjNMoFJUJ95+rFw3bzA$9jgM_CR_U9`ezCLi zac>@dh7^+HG?P|T2C4+NYpJo-67(&qXwRC_UU!Q(>q zT!1;k#mechMSw6r;?vDQ9BENe=}pY3SiD*%{`twYOLWla=rBXo8ICx;<*`QwH=)SK zq98D7-CZ6D@>JD>$Ufp3I{VsvwDoOoQ}3pL!NxJ3ANy_fz0cr)Q+QC<8g6Lu?*aV5od7*_A7(i>Fc_ zvXm*{V>Y_;mt|Ja7du12iw-cs-_g0;UcaYmsH11D4d>*5`qa*Fp8ptZVfsbJ!cZs2 zu>VPEcd8mQkw+<=$%`+py)u}Cy|-HQYgM%jy0F{Xc*Q3phn_X|w&%m!jfwYe$rjo3 ztH+%pSzd#)-w=LL`?SbUOmhm1@ld^g?6etv5-%VaNWSO4_zZf49keIqThxGTC_B^I zElcBXQ`&)dUifZm>H@!hMF{kc^U)B!PlxLfJ`nxY&1+Qx-%9q3RLhBi?kG>mE|lnZ zpabq+}E?(1G&5w^!(x`|(2$@zd$*G?sN zgJx3mnP$2!*>E)+q;d35@CA0|FKrnnd}?E6u2zR5-P$o|Ja$^OE6(upeKJ*Y5u{D|Z!QZq(a(;(}} zKFBehDY6H7y1w6)_4&Cnm;c(T7Us*%Ju>RneWL|^{i#_DxzS4So2h;UT`Ko6j81up z9@L9o|Kx+|!}4o)_Pq;MlNWS7YK1?(7of?X`tWe2iD`A|qkB%5pSmk|*$xSPdHqn6 zKq4mmaD^l~6uZ7y%;(0C6L<;$Z_lXg;`j@=%CHnXgkJ|yO}0ti@^Cn%rGKkAEu#OO zirBm?0`~WN_yA44BrOsp((gzJ^u%T+p_pDOL%db zDbbf0-e*JB-G$}WV~*d+iX^8?J%kDY4Fy39=tM5!4joZSssYoHlt$8ib9g(QHL=iO zvM^$@j;MG!%m=xa({IN_xx@=+{n7#NEWnSSzUQdb6b`SNlMBotq=q;q`U4>3swaba z(i;-BagJp~m)1k>4v~bmaSal`v3=)Ia*-!!Z)S*%kVzv@3O%8YS^STAZno$bs3@XWHZDw#CpQ7 z0Fh>yMcDm2CE}sJ^+~m?)kMS1t&Eq%UEJh)Ae0$x{%Dgj*jB)*Vnz0hQd)aau~{J8 z7qy5G3?bj@lKSy0y4+T|p%q^V{_p-zA6alCIFpd4s|er5UdC^E>NXxE2J%bixP2?B z2fi9x^kxF1f^B}|_;|_8>vQhnh#ah8!-BQ<4R21PLqQ_0j($uA(5`E`Qytm3o4yLK z)#N#flA%AWYgT3l-?EN^9NPgN$q<9a<)ae1BW*^XgOVcVYF%LIXZQ|MC>vDu2yIRA z8h$79uS|MeV2C95Bh-?uLR zw1T0G(#bS{3<}*uIf|Dd7JB}9}q>m&P?cKczm*IrFcQPD#IuL!Ee(JUo{cSN9 zhF-|EBHq9kOa>iXssTs-oEx`dKI8ZD7JC(NNuof(4+gD$Ync^rJqq ztp?J{{(?a@RjAh5RpEh^5#=tHi=ngn8$av|^ZhDTDdhIOT$DXoyPfs#l3{m|n~>52~M@)fL03e9-gOA6ePi6lpHVg>FE zK^q`!Lc?jIuS6pQ7S_?}<-w7m^nhV^Cu#p_>Rrq8enz7#ySeT;* z`AMuHTAIuwO;#|V&W~!nNB^1ve8r#RML>aRZ&kiULTOT(j__>jxWfHZS3ly%RcRP_ zLQEkFgQl4Gu44+YgE#Kpz9v`pHeg zAZ>byDseH1`h%w)#N9%>Gw!r5!?oI*oDa(s@a$7t)*ELyQBl(yX&Lf#yD%#*tuWCr zFD{uqZd=14<2PYj6!cyBTiyC$>!Q@_J0q=>=rkn#0`BWly}$=6D0QRYHOa#wTi6SS zCiC3Sn@dd1#VYG(g&n+#+w{dUqF6n_larF5IN@O7QzgbrOJ+d4hccuW^q{I?hr`I7 z!KeR5 z=f7w}3579*S39Mir=S>6#j``@d%3`f-z<6TJIj zK{#{}p`#Y^DoqJOUlSlWpwne;(h4k~nLb>i;tMJmLA#-lGBo?<8&AtFBu-pF8&(@T__-J zbmW+@&88ry^(?GXOrMO4Dv;NBQY24}i;nrO>Z#rkaReN?-CiihyIr!8J0E~CeSFfe z+odk5fHnZWEk_A^DM##$p&SQ<+0fOY9(_kFYmSZ8#rQFK)r4;5R!)$ZC#s`LsD24z zEAHjqZ>Z=I@#pGxEz9ux zmc7YP<+EkRPUn1yWh49^_8fDPlAuCz`5Hqc>$y{h2G(?hj=!9L7E=x2V%BmMoA5Q4 zc;;Khys&me-P@c{PqX#R14LXqYO0EjX5t^*x41zT@EQRkE{~lJDJl&@bD2k(17@fV zRxr;!{!rq?zlA(^C~x&)S##T~9NA3L>{?{39L1sP#F48)4qj=l8VhtLUXzGTV`>U! z2Vh8}cCzji63$j+6@HSn$_wlG39;>iQERn@1By zAxpD96qkEdzMxz{@$yn^E-ocG1p~9nwHa)3LS(mcdp(44Qe^+=_l=?@%rja2dX-^% zeZ-*0w?;HGwSnO>q?X!hW5wO`?P1goRq&qg(?0ot-i@j64jT;FEj(a}*m!60lE=9w zK(FdRA1B-;`#};AzVZ<6@(7Zh>A5FspGtJaP!qKJn-ER!@a|XpjXAR$W!9sNvmI^P z(ew~U3@f}%RAD>vbEa=cJ8aOoSwpwS_b)K8-cS-F*5hC$!Wt18vc5?&yelQ&TBXr* zu}XxOPqdrfccW;*OrD&kyrUdiBjb6aursQzH@cEp9%$7515x+by9g5ac~xUNTM@@& zzXJEG>*4B9t;nJo&769iO`up?Ffw?La!r{8~#BkjBQ1fp1x zcZq?Q+57Qh8$L6+D#_OCE-2zCZJ9~fHJ`pD3m!of z=XH=CRQ^STp5iNQV}M8)KRsAEdkk@E-6&m8?NAKYRXdR`kBP^QMJ~Np=lGi=D;!Iy z3+xlmRzQ>iQ16Myb|y`#D?8`yh-YI`jq$n&MeeyA&`kYpeBO7_-d^Ie_gIGZ1}nTD zmPglfTMEKYN3Lkx`xe9=In?M6Sai1LB0+74?t%7ZC{RzS2j+Op1~Io1xtlE@zFHWD zp|kBi>rv=W0+5A18C{!9QfBq3zp!{8^d^ZQHlRIj_QrI=V_-d<_GVRz{V2D_p-vpO z2*&W!!qNR*tYVhMUFX@S@3{S;C7e3W7PV@dO5%8>?*aZuDE1HALVrzQABr-nFQoKy z-zP_S>&zaXKE@g}&1${QV1QvNvmz?RGP3p7s^$2CrTGp_qC)$8^*la1ee z={9(yy&A0l`xYr@Gf-l*ih)A-Pjki}vq6P;q@0~3i3jiLcE0LPi*Z6Z3z} z>YKkFSqU0UTlAvB53V+_r8R(FOW}i@7yhy>1g;+iyX6eB5ob$%g1W7$Ca#{k_4(9b z@g~eYAv^xEPjgz!%7-UuQvvT~v!JFq-@56JuC`NjjI3q+HZyhPL*#G`bkoZn?3~B# zl2&F*bImol>SN6r^Dj}V?nbC}b(6>>e?qKvDaOpmOX99|vvSkTWcJWNtZ{2~)wL&v zV82b(Q$u^sXw{rpzS5D=x3W4Sqlh?S?H1WtAC-Ff^RxOUCC+ZcQc$drdwO>An3?(G z4R+TUz+lwu&bfX{tOjo9k6JDw_GY>kJpD*+lr=kJ z>-y`>pKi4#BuZNn;_JA^jq&(^&tG(>dvhEyXQhJaRAz zVDs{9v;8&UX@QGevHuuC4nP&QJIV8;`L#dCRTsQ7Hfo{m$N=Q4$P7FMpZg&7yr=vW z27AAcK8u3*SIw;r<|Zny{kTr5npG)u7em#y%mn#eT5F*L38q|MYsC!}xX((v16>o5 z^Yv)+8N_i%f69LS^IAXe4s?rw(@p?xk9@=G~_Q5;VCyTLL&8r{S&WD z^*nUjzRnYM4gM{U&bgGh`?$Rn+%U4M@V7z!Q?i9sbk0``{A=!f@!k={&9vc0&necy2pPno&ZRLE2G#`zD%i%V$&|YoYg`^x?Ut%#doGdyO1T`zSwjl|BL-; z0)u(wvY1G{Wmn`x!>*N*xJT>iu(W6Mr^&-=?5vopR;mF#h@gWSeqD%MbkF z@GM`1`AZ5W88wlcZYA`+wP)b^TNNbo3T2u)t_C?_^A#na#s%R0VFSuNyY^)FtH@hi zbxE03*y}V@OxkshR zuO10P$@dB?FUQ9Cvr`+4VqZp+P&?b^mik zQ7Rp+=L+@=p6JesWZT>b8#=KiPx`&GVJf^2#?%|RgOBc}lX8Xaf{Ow=zOn61g?#T+ zmrT2K0(CORVdxD7Are7{37dNqQlr^nmfzU+#Xve<7Liq(*fcI)jwA9ttk9d9RNBh> zrp~H&POmq#l`tuq>W$Mx(HA;sY7ggE>{o=jUw2){m+v^0W|stboW!KI`Q^nd*tc1j+iCO$v(Aj@SPvR@S=d|HQp=ST$PC# z)U@Y8gYh-6TPoqQ#S$C)IZg%9$d#PhH_405oUF@HAIcnf#luL>%}8=FoL3)EuaZaT z8=>MoX@=@g5=nf;k=N*}#|7ZH#szM15U=!>XhVfw8tC34CJeEu*FWFLpqEk{=NuA? zMb)b4PLH9V6|_A_V7g#icq^{AgBxXa#Fkm{2g(I^9w)<%KFTLB0ng01U+<3RP z%d$SOCsL~RB6XuKqv$ny`lyR_xG39W_H{=#i2v=Q-iY>P^_U)FcNwUis!979_ zuO`@WGF~7m^gcXQNIGA72R`f5w{X*#FKZvGp8Df&cY4-QK7Z8I9LMJTNy_%E(K3!x zlK{))pMQo}zpCEI!>H}u@OgAZh2*$E1>I@?FGafHv$sMk_XJ_7c<{C}j?D!T&MNqR z>m~-?u-x4-tZBS%OXk##<7u=kYWY$5SQ48bpR5t|Tjiv75QLS@JdjkT83-!rzlCC; zIB?Gq5l9S%dE(t5R_hkLRh2NRx|vd}L%O*7+F9j*jM&l|?#?_Z~` z0v-^0k^ke20=l%~D+k9f3#1&P2L(_5H7M}yXHb>wj0E0HE$sFssA{N~BmQW>~%}QhxM2RUlejE??Kh14H<$p&U79(Y- zCS}?zWTIy+WxCOOh|fnHAKJyA%g0NsoULI@Cpp@?RS|u)QI z0Np%Gm`dXh7S=4#jOqFg8Fe1hVmjAibDATYe{3Jg48HLZt_EgZ{@`oGyGU++1BuDT z9DB>&j|cGe=X^tb%aV(^wuY0Y^o@l>bfK3e)Eui9+$F4IaD#D3dPy^XNq<8u3wQ^?2=6^ zTu^3^c#8&bNkBjZdH9ZgMZoycY--s58_Q^|{WS3r{vN$1$&#_vQ48t=ng>Y10|o?! z0u;(~W_^EY;8P|)MjV9e%E**`a8S+2KRE7dQWP&BPmvrZ5ij6~isuOI|AHqL`y39T z5oU*BCL?P+#-U;2Sz?sjk}EX9Ny`>W&{BWh=VxG36~w(f&mblKV2DU6wnwl=q6>g< zvFdtb6q;+-oujD7Q=WxNep3NgU1UJTr>X1!7(^9OicHmf(n=BvpT}vM;2l12h2f!* zeKIqZr1%&%(Ep7$5wA?yy=y!sw(B+f4LhAyt5vS6K5xD*j#PlCR$P#tG zb0W;e4w!{wOZ>(H|PL zr8ITSvUF5p3BvclsW-gRzIb8@9cWxMzEmFgC?Wbgc4|7N++`X)5!R$oZ*qVhiGUj2Jg%Om^*f7B@pP%)_i^Z34XszuzhiKe^@6xS}+mEd2JG;%bHyJ6u`qxL3ybBl$vlDN|) z4`hXEG*+%XxJ29%xg#*3rY^j&)Z~h3KmW9p>pBi$AgTk+{)zKH0&5N-r$|f-nkJLj zPiWL2tvkCY7A;eG8rUa{1u*T04Y>j>B9C!025)V(;VLyr-m-=`;yB_Y&;mbMp?l&4 zJb;XT97%|38m}59KzXjvotFB8``e-+OwcWgnTL~uyHLmqdn?PXHU$6a5P7_iGwJGt zLl{5D4q+;TwLg>5ZB%e>L(X6%W}s`sOd70+6rK?wezgpQQHK2`X;U99{sc(7OHv)i zB}C6Xscu4(F;j*K-LEohGL_ymIb4>FT1aH_n-U?FROY;}6K)P;7w?JHzJI<=Kk5>K z*meo#d?lAsewoZHGOEn6zIVr_) zfVux`5xptwp`FhEh0Kr!#N#0q@;p$`Qb^Y#?P0jk_%d+nKv4>HDz3i4(+KxY5i$lt zpMWYEIPzIlGFRc_hqfn^B(9Z}eBvhehHIMn6wx--iYHcB*&It@9Z9UYFi9R(Pb?B0 zi2AC;ki1=J0tNWLo`qxjJ!B;pS3XOU|E#fR?_m*TZ+NC7$N&O)iPKzQ1c1OXI9~B1gD)Ie!zTsx zj`^=i3#)YXT72^m_aDv;CBj+k1TR(PEhlsZE`VkS5_FvAIrAx^<$3i4F&(HO=8$lw zPQ;+(7eI3_8?o<#y5E|asTZI*A3%(=p#J#R?4LKF86_RfO2X#nWEz^4T{&NybQ>JT z(Y2U;v@>N(puJd}7`)L3`cZ;^O4#>xzPO`s#W-J2d%T7T=CK>{Zx)vG0*>!mY?s=uXNM-+^pV8kQ zX?Y`G8d+Jbviqy^5)CRh@$6w@AJ#2NhUL1X`yearA0RYBMXO^bXZ^+tubNnv({Hn6 z9y3{dwaW{wQY&`HScjk#;FwzmEvm8HxQb=JAgssN%l2e9MXidKLMUGti|+(D#+aw9 zFu*Hc&wW5s#_uSw5vo`oGnrBWwfF906DF@HbXx`SF=TFQLRztKo~L>!9`Xa!WEPdf zEg{XxEW*^3{IQd=6;OZo0XAXk^1>^KS|il|XUwGR@S9CP-W1+s|1nB|TA5hJR)LC3 zhdqm@>d>dSULDn+7hjP*c=GrwUs5!;GcoG_4Q*kNSv?hnTE3ssQjNa|ovy_B-n4`9 zQkbYME2hDL(U>v)yyW`KU@C6CC5K}~Toat9VrbFDCb(#U;kjnr#UdTtleolZYG>rB ze3sSm+gs|R##_E9uVceo1Fu?XWu>;4VM({q&8_vc?V{z2(}Lc%(Z8lbx|+F@w2Khu z`K;8x-Lv%DQvVpNf8KIz=ObACzOL73Uo!Dh9P+t?mr>Su{M$-ke}Wqd+F?tHQH zXXh;&cCQs9c}d69#J%JbbM&Wu2Vw&|wJ);%!!I+Kb*)|OXPSn~<==@@tpsYJuy`c@ zekDFWYGnPe%<_sxf7Hm`D^N}RqWuv;%gLVd#rWK=PyREdHT8=c8geR*J?YEmD4Ra@ z(^fa^SGIS&U+cxwkAC-}Pk|O6-uDNg?PBYVngkT~zY^{7n$@d>b%eh%u{nKRPInnH z>4$H$d@pp-r6=?W4b`^S$D3>^IrJ?q?4kw zzk84iTvKipT@nnX^vP{QX_2VqbKe5tb>~e-M}n>&G?dIJG}SK9jSL(=+)UHV~V5x&4lvPP)q`{*QG2QlP8*QNh+< z;wrwYu1cBr(g|sbvNIJj?+3r9m85v}(+`*f^f(g97GtB{z2&y&mT2kpd7HS4{VAwe zCv67Rahi_s@R`z@%-psmL;|EkGd8kzJC|u$3S*-TGejeAqvZ%n+cM0;=sRLJCgc;K z%-S~QGbvGDAq!P{_yGfdEO$R$6Ov@4lKh|(ZsDVR1Z=<;8W<2iI{gc%<#jO^X|WQc z$h!X-y$eq3sKyT)xUFHc09%?2;BgJ5Hj6yxC7W&y-zx4Z#nMGY^NDamTB{>s9VB9B zF4<(GKr|1Z=H=?e%QB^Urarn5MD_gU(l^A8A@>G&e{Z9f-uNd+QX3|Z(sND9+JgYO z;~k1l73R)$^CkfrHz9XN3sZA}j*$q8oMaUV!XyL=FWE|?x+TVnsALt1hC?ul9AU~N zji7D0QPM5n>7XCAblihQ;AOR5x`u%(@cs{OZwR;Ke9Vs7;YuFP0 zoHz^6HTgZ9Yl81Vqs%dUp_7_DQE70?6eW4P(kg;5zkq;iq&MF6G(g<7)Em{k;!n?r z(H4iQN&-g@vRU(_Vo~&MR7?-Rdv}zI_b)Y?Fsp2WP?Y*?@Kg2Ekw3))O zr^X+sgBsvDSb9`mup#m4chL_$2r%|Gm9Gbr?{cp`G^k=BV2}HN-W@oSg>QVKBJS+W z{`7B3npqKgfQ3VepU~D=pVM;^B>hAvy>Tl}_kvnzH%f0th|AcqE=qSOx^xQ_JES+m zv!0~Nas@ygK|VY9^({=Z$q2y1C_#dzDyQPIqOHI;FdBd`OCItBg?{cpmJb(zvVztX zu{&30LBfpP`m72?ZFs=R_$^fsbDOa=ogH1HpAdbzZeL5zQBaRGeLINr!6Z%K*du_< z0Hg4(EFoG1bWL^Ra`8TDy$Hx|j0o|Y>y1wMPv*3xgV!zl-1+g~i};;Q6j|__d4z>L z|LM^_{MSe}L;A15eEVOg(g8IZ--L%0L2~IcwR~co{}g7;;6I9}#l{S5fMN;xqy<2H z9o7)idaSv&*a#@9wf{F_qF62e3`<$-sH{-+RyzoFA-VOjC$`$VkJ$s0G39UJj;D4G zddGH|%>KYGSS6mUu$$%~=cr2;sc@=&G8Q*LHx`omf_wpps=4NfBKA#7S|{YdKMH}0 zT@ch$eq_t9;*_CQJ@dy_%gIZXJi{|2(2%&s`NiPE^7H3Z8hdQ4#P#193odH+nlxe~ z{Djb&`58PTWYaKWBO(P5-`jD91H2ip@2)h^qj*8dCw&8g+%!Quph$;CDpEfYJwDWv zn+cBO4>(2zfQoR^H~5_LC6rw1ebt;U`+)Vyoeo zDdPfIh&V#Bl61?xNq)}SLCi0hKWf&}J`5+^;Q1~>qwhJQ*7)qZ)Abm#m%-{$I z>HHKF4f{_P{A$jIVR8kodz!B;Ut|Hsl*$F=c1?Y3BPT8evdFJ3gIxNC7M7Ti4q3beSpLy_X{ zUfc=p5GVw93!azn@ALli%OfoT6_p31K^hS3JLA>ui-RRozPk`D7>$Fehe~4I|XV+823isg@LaW)zx6Os; zk%d+UtVg^ScjBKAkOt%BiI)>x{@ z3VaRnlrRs0HziKr=Xk3^N@1a*pM1Mm{U*{=~{MdI~2Pamp&SOFfG*HNbkjyY?v zB(>|i`WC2L?xk}^z0)?BTebz| zmY%L_#<5w@6DnYRcb{Kng@*JF)7WI4dufLHc$|G!c=zDPOj#8`{FKZ>S%o&`Sn}_j zUzMAL043A-dlibo2UDAxO0_r1U+2Kx&3eVHoWu**-{4X`%D)dfWfyrg*ND&uf0jOc z+`LtFH>O*q_#l5HHPG>59p~)xV$Ch~MjyJ~?x;!ci{Vyq_azTAHw3MI=)Eyohfpq! z&#OGvy^&@tbFOa;_hfEXBWJ}dw>-t>@4_uk~guwf)G($&8hUs(Y!`wSnnfi{xXhIb%UCH2!jr$joky+2#x?+%c38njjj2m z+RI9P%antpbA)w+Ymqh)OIuvIj2&e1O6TU2yX#uT%tj8H`eU!FcuLuKel(FOU8a6m z!#d?l->G4dlo9XXwv`h8HK6j~4u00D_c2dMW_@X6Y@(6J z(0<6p7kgKEBgFXlMzTxghaFAezBd0_D;g6gD7gyX2;C=5%8Wi2MK?mWT#9bYzs`z{ zD3RNiFAN-MPRpJJ&2p+>Vi4*|@Ks}jJ$UmbBggN!(}BQPiMf62KaO@faGZLAtr+e* z{FJ>gL;b39@Hs*)^>fP%fd+5#Uhq+Dnb*~s&XUS(8o%RZfveCbOMlEqc{PUge@;_* zD9@J3DsBqpVHP9KZzCO|j>p489fHh0D1Ga!7$Q&!B7VZj!)eBo?6NLEdPbA%g5)DL z#+Z#DZsW&!5M7^yoGqROC+#Pf^}Rg<&vnEZhUor=56am?J8OdZETfX$M{Zzjq%CJ-jU z<1AcF#tfvGbrgzL{zm zBX2Kj6H*@Q?_Ya~41y^ot?&yh3rfGmHC}z<{GCnUno^w<))ast?%TZYBMO~hYwlgM z8g8R#t4~@ClDOM7H`QR!-hstyWt6G8(KjOPAwuap8{b4{r+Cp2IC*6$;RcC_r5+f46aA5OE_I{!L z+F-?%jg|hclx75lg3h**-V13DOV^dXJ4A_jnADNE^HrX0dtoz{ zC~etFZ_H)2KBXk;0<2}KUANO$-XjXCAtW<-8?F}w%DAM!F$fCDXyCPE&;AoC7GZ#2 zN6CoV4QY!rd>&uTK!3tNq4 zPr{X5=;w@hZ9=dWrPZSoJ4;`gxNC@Q=uN=tAM2^_z8L12e`s2fN+laTk-Jd%KCTD{ zmfd{6ILMQdsS#x=jR=;-6;d%BboyAF*cZLYm8)ggu=hC|?c((1RG`tvEjr%vS|Nu$ z1ycn*mlR2LZQ)Y??hGEP<`V16BeW<9!*O-|l@C#a6=@O5Ya##TXx=_OodQwro>luD=y+0c?iWS7@1Fa~rdh!g_gIR% z))ewUxoUJCul-S!7;7+zuYq}|7D*;Vcwo*lWL!RLl&Gu|$je3jHFG!YX=yB}DIgz}4O)Qcu`eYh)7AaF11k@fa-=z81>9c<7Z#a-F0 zRJf3|Q7=G!mg|DFGHFD8TDWeZhCOsWts^?4sMahOZtA!}SYl(l{#UBx5C1*u4yxbF zzgRR6vLf71QK?j>4qN9)CW+Jbxb0CzK@JBOV26y;vq`J=-Ip z&}*LimyJv=S^ND3uN~@!LgOv(+;ej~aF8o%$sionk;2?&{M~o|tw8ZV^W+L{1hav& zCxBayV*HXd|FZ;fn<`L*aex)BcSHqhooN0kZ%3~yT5tPT%XrUQ=f$LlM5~-cR-#>z4S#^2*|7v`p0=D+~{pI`u+?h&+s{Ro-KYn=ai1Z|u zFhKcZIYI3J>4s!L5;TM+@?JB3DJ}8t)sliwi{m(tj?x zyx3oKy3z3eT)=M0|1+TK#LRP)dk%sAZznE+^spBt{>qQNnJwc*l9w7kqQ~!LU%L2z zU#{5Y=&(sDCS)>s-Rp&@oTo8l<)HD~g}!)Th4_?-|C|Q8k-hZiLxCstz2R-%%kzbK z&|jSL*Wy>$@@x%nrUaO3J|O2gs>-Y5;(>$I;~4_?$P#N4UwWWAGHvvtn*Pf2pA~yS zh?xmL-JrId4`!aL4gK)Ptil477WP6P>ifhMbsIDv#d(>e!c;f+#8Nhbg0g%~ixRwT zlgT`mX^NN56og+9NCKfO(=l$1?m{ZsaoaW3K=bU%kGfG7W@XwoU+un?&=lL+czz72 z`4d;=XvfFAUfx~9SHSyHyjDiTu`ckHI;y~qs?R8_-<$Uaf2wZC9ulhk-j8@e(-Tq_kiT8@Xg$Jz~KjI5gP zGx3o)vREV(CTxqW*Z)#VW~W;?|HCby+ZgXgeGkg#m<~L*oArztuXBqN3p5B@mTkme z9FscjX-IOjER=3axMxl;UB$QJwD|Pf3BJ0BGmR-FSnRVovKSq|BAHOz;Ghmr^@iEm z1Fe~4nGC27Y1mVT z^@ULGR67i7g!VD|!hz(`a|)geJQRA@WNHv*#eE7=`OawyDTN`f4}J1hlYh@(4X-S+cCwDWs_Q*D448qLwAxcOBaqFwubc zbI5)-Zela1O|>ACo`~+k*LR(8!Lzg^yZijX8W1}1#H>!DL4O~uQ+kCe34N!KL^@`k z2SmIYrj&#{zmCUDxIlK#ody5dXNwLaW5Uj~7K&(ldFivyZ-rWk6e+LEK9(U0X$s0O zo50XRxR;sE!2W7VkWWbnHLuGsgCQw!Z^gwrUYl@C2D{!W_Csd>O{5r{f=()M&lM^@ zjf~f^Ovz>lES0P(MpJ0|;zl8$(~6n5U=mb_Mtz?GMpf|t&p}WjBlSHQR!||3`u@nZ z`sz($`5s^BdJr+&6Oz1oBb-uFW~Tf7h-F^>zR9reyQkC$$K++7t%p&aeYeJC z;{o|y@%paF1cx9ie-cK~H>ioE@nDA$aJ;2zg(-aTy1{fTb>V5C0!}{5YFCLmIU; zFipDCH(mu|IZ4}G!$z~*d-dn6WPfjdcm`WxU1D+CZfbLh zI>YO%5=(imTx_)BX>qT$o4;w(>aoTWrAWETq9v6<&lGakl)Q95 zOYh15c!%o+W@{H=pb#+2qdXa<*)TADo3d1Gu+ap5aV%9&3gB-je80oJ#ANekWFq(C zwUXv6{uOV!4Y!qsMrnJ?pKLx_hd*wM<#*0Y>Lt3PTb2q9J8AVa4wWBF<|mr()H&;L z`eCyB;Vx|H?4l%1vZeKs)@TugOZ1ZCDXHow3!L%qldGMpVXd~#E%E*8{Mku%?PN_l z@~_?5n(^8t?=e4Yc++^5m^VbiX0W{8Hz~U4Pq=-$R$9ei2Dg-qF^I7i0+Q=|#mE4I z74dxpiaderzFG>XlXWMAV&3W}7#eASt$EoSRwWC)zN&=aO5P-0TE7m>`fwPlo(V;l zxV(=2NKq7&DXEGd<{AxULxH7TvT#AoBkr)VN-My?Ps@K8>1O%lnD5QRUe%qRCq6yI*QaU)jc=wvWvKsy(9bFEMCv4%G_NJekek-6l*6)Kw1T z#Qz*;Sc~F}FXj53{>?zOMib4g`hvej$EH3lij*Q_CN(H;H&g#)>(;acsc+Rqbc#y7 zJdd7`6SpH2z&l>XajT7n3N@ z>9x;Y-WBfA?!g~o!+5`d%n-{Z!{qYDPiu+;d*QS1X3sW4Zp+k%2;D*2g+JL3ZYt%U znu_(C8L)r(+DZ&88>S2do_xzO_moISy;lRbt|?jbTY+F~ZTjjQvXy~T_SSr%Rs0Jl z(e)&}rr%@IJqy=z=h3?Qp$QWKeq?ag=guoxwO|)t+yYO6=)K>wZe`X0!7Eu89!z|a zu>-YB73*8AhGh9dtjX!vk(-!8``j9u8FEU62k{b2d$}XNJr{R#gk)(~)V|^Mmye)H z*=dPvS(04WB*RI3Yn(mXZ_Jxv_4ww7$3L$mS&)^qF6P!J+zf{W-fB+r&%AtuZ4Tv6 z*ap=Y+J`X4!*TxX(bjy5T4cYW=J|x)rYn4(iqz(brqERHheRZy%SDL z*IZ%lO2iOvp@Xu@HAU=KjSzPvCm*Y?oJRfh$oM%0RsX5m^$!sz|3zj+OT~*7{HDP{ zUwAWXHuu#)m?3dTiYbO7FiEKg&6=Rt%(d;O%5>D5hC+Y>ZYo!#FLeDh7(Blp%KZbccES^t6Q}Ha; z#Ab}(%6PEv4?4^f5?%cY7jI(A@I%Z6!GIaLm!w&(hy{QQ09wJ3i-mo|J8ZR6{7SFu z`C}jC7A!>|h^Z;a(3@9kfLvPZ7H`P6v_-9P#)R`NQDvtIcV=U{PIVD?N~6GoC8w zMQ^Nqp%9MC%2e-DUyikXg{CXgJIhi?*DXHrxi@;#^5XdCjtfrTzhS~mm|?DGer!jb z@5{nmVTFVeY_RWvb?vWs%}Jsvga-=%vJF&jC1mU{3ML7;5@E=8+(lxd%XNE+iuqDQ zV$P3xz8r@7_!dlt4rQmf!=Tdnv07W&wgA#1MI|d%qJW!t*S4%ouef0jhm2Ka<*uQ7 zV3!&%p<7r#sh!Nt@%9@$$|suNS&ujG%TmOhVdxawIn)ot95wj{Fzy7jxQx|T^`E4b zkLY9!EcLyVe3D-lgyWta4Ydh7xgb-eEFn_4>nHg05Kd@p;gf7Y=RE=xUpSoB8MjrO zu`ky9;lsqzJkYocll)a#x0usgV&_=9=q)whq*E?hg07;AmQK->UsBZmE>YIfnDcIn zJ=yV9npB7R3I9w|wS8@hoh#Y0$2{lzI<#L6&jhFJi~+T{PvHy0cezw({{1h!NRDM@ z$wtp877mmSS;Z-bYh1(pQz{M?T92hpd{a48h;}`sT;-b9v>$ts zt`zE6;EOiMzR%u0qK%?L42(mVI*NDmkCJyHOcRUj zH4z3jTBm(#C|yKVJEV0zL}5GB2CRHFDMy~h6d<3`eLRq+ ztBxs^Am(gBr0CPOK;s)B2=`j->z!k>OF-AFH06qBcIB3#8ST_07z(lw37 zxKz^d!>Fw|2e?>S#QaX$s`lu9^mokcvQnH`s%oMceB*;)#aFg(lqfax=_lPKE~p6? z+BT>||Ky^bOj+_b{W=z~Bi(Wio40nyEiyWgJ;b$zZ3JgVrC)DZQoqF}I_V z*N58{7UfYM6-wAToW|@L4@;;mA9%Y~;C z`gCU^F20)C;&Rz3+3`J5e@U}yJN*m z8j#C&1pH|(3%q znp3DNEPuAmId_@|%vyGb2Xy>d_S-&UH*qX334E&k!*Qtea!9ou@0WxRWCG_7hr|$5 z6rve29r@CTzLoe^p#OZ^L4D5c-g@h9OF4X2Dv%(!E74uD;w}udkCA*@wvX5z!(Bu> zXy(aOTD#Pn53y-6=@yVXDz*_GUFt-OwZPE&0C$*Ib5Apo5vCZwm$ko>y0Y2|E038g z_Lw;NDSDVHl$+I5XtkiNn^PPlwO(Tg1%gW_h{_L@;*Oe^sdZ3RA<<=9elWYKy*k~& zxu-4{&N^w3MUH9)3Ym})(}OGDy}(2zDMijxVe42gs=0p!keeraL19Gxk@}che!Rt(wH}DgPGla%aYxl$G2BH0Ctt?pon$I z&4MNReEZ%D1^!zPf?41KA-V^}i%7-{?s6acT|tP2sBMt|$yT2&N^=%9%2iX=+$k4n z4Zb`?yE`rR&KrJmD<3oh!q*n+ahYoU z-v+US)Qe6-nDad-ZKM~04IB=rViNTVC>gI`gjgUr^?$1kI}sQxW@uJ98M&F`&acQU8fVe%`;2WDxT zKCrZn(&6ITK;GT{G1?Mldx^ptbCRT=Yfo6tvSp?9`$h=p=ATyD!Aktxxl^({7>FHA zCK-40%fxKMmuXrV^Txc0j$cWb_J#QY^>u>VyGyT`%2!ZVyRViIp>$bQy$m6yN!cmVcaNB6%(#Hb0`e~rL`SBe~TUW;^7ZE#+ z6Z>Th+?6y?TjNS^_K;z5$MJVGS0Zb~Rki>2`fv9$_c~9P)7b&kl$|+@#;QD| zZ9a5M-A|7r^6cF?5S__DtD&+R&r{u^X)SBv&t_5)oa6cx$Jd@R0exDwDxg#X9a^qO z9NE)$P(yDZxGUdt9h^Qlv9uA@aY;FO6j(8_m(`?2X6XqMOuC8XAMQon{$|T_mgbRbrZKjM0O;nC;76f_`j} z(WlJP-Q}hYJFUuuGm0FwyvgLZbN)r64HEK$2uP&5JFsIO!D5n+Og0N3T14))Oj1Ni zW?y8*k0TIV>oBxfDs^`~cmJ7#VZRWM+zSb4v~>;Ld`Z={%hb!8-j+;ewo@!Sbo(JU zYJgTO$_EVfFu9&fCOOy{|Bl(TI_2c7x!JCB9EXM^?H*4}cx=+%E-58>gZL`Sgc;}> zRqF8d3v`7f-$a}qob(Q~gZ2EhPw4lOAyunY<9J8cWS-l{3){q$z^Yr3WOxA~Nv~~l zrGN;)s)TFxqGFQqGJAd}ygiD{AfL1z78s@M5#=MjLZ@R7Tqp)MpmrOzLii2@kC8S} zpn+7A%7esD!nySQ7t27HNDjPRi^TTo2IV+FC*PmbhRk$L^j>B?Vi~_iI>u-^JBrWe zDt`WhZT-E)aga{_jl{BC_v|l67{#7RRNaBvdj|BR-$T_`QAU%#jj<KvL1GunI7IwKE~9efzGnPkiW%`W_npBTO4vj2ua)b zN6YP_7l65CQSX#ps)hIXg8Fy>HpEYUj;SmG4g}A!Ww)QcoBQ*w-Y>?gPYBEkj<{14 zujQQC><>q4okKVn9(h#+i)DfIic021^-ahMX*MV~zfB-tTR0oG0y{8ZowIr*9_&EPUV}%(O$Znj`@x6wwGNCMntdzFy9@(>h$8C7XjA)0cN|H zK;`vmur~G@IUaMIY43IF;` z!md_5)T;gC8vlrj_2ZH*yF@h#E6#4t+zv)C@Ibf1pc+g-^<~|o+o5=%9ksi%SnRcT z&Xr3{F0wZe)bcRN3NKHd%pe}!zf^kWTuxt?R(vd_z_(N1l{L|eZ(E%zH*RpCw6y55 zF3FtgvU@OWn@NB}9-$5P3<`e$5|REzn$yM~u(~u@_Ny>o#)MG6Tx)*U(; zd2ikkWO79&aWxUR39mEn$S~1m^&i!~S`QpIux3`h`q1q{gUWs{+r2}8{ALtByQ^U` zmtwec5|saC4)AHN=rAY!VCK3C8FUve6YPBmcoA~Yw1u;ev4X0$8`d96ACjNs;V{ohR}?bc?coSkG9Pnj|ZxsQ)krqp{$U*`(rWH6O%Mk&!){ za~h}72vv>E<;1sx{hSU|xGq8Z4D#=HF;NJsc;i7;&4(1((a>QCX%>@VOH?@+#K{Y%Nq4sHUM!B7{5JbG5 zf)xy>588~f3k_@7#-52W?A8zVro9@{6tEp8D;)eo`b1X2=pu~>^sX11Owdl@*Q1ih zLOk{AqnKU2>!~e7(Dn}OZJ|80`Wr42i?YsrmK!+uRdV88r9gIQP2xjR1R)YTAGXXi zk~lKDS?r^Y_5At55pI8IV$tpwxyX1wsGqRtWvJ}>;M>b>6eGJOs@KF5Z&<=fSniRJ zY)4Qdb#(Z9XdTa6A(TRnN9%9WeHgD9UFEF4H};XINBxHUlT3FW41&ph4Mlckh7u}H z&xvOm{=3%iHecgdB;<6LPo`v9%(t0LB=4v*;b~CTxVUmSaY?>qM)8R^f$I3EFwdf4 z%7BesG)hQf5-JcJK*g>~%rEy!WN8DTOtG^4%;1b(;rRB?HCJ+gyf|eYa zGq`0=&1y4?aJh9SW@Io%wcPI#z3-6|EW)xKYuToXFh^JBKt+jruE>`+t)3%F_w0XM zF0X}^U^|DbKVbw$a~eB`aLk+VR_~FDdsK}Ub#O?DK}n~!PUp!tK%u51Ub&8s<;a^S zsc!P+-^>>Ghk@(~>)EwB{wmcfNy*HxdoB%Zg{v2~bA>DZ?=P%ed=_Er9E*(8OU$Eg z3PM1VWO0q;L;h}~YMWmKK0izVBi+B?dz*nt-tHXbv-v1(iif(*dMbE!<(cX_g+&PaGPODi##Nz#rFMmDvOtaS~S! zVEe4#bv|=kcZ)ozc7|))Q}Fl%QTC*{?Mjaw^3LjPl3nS<2|Ps8|02864HR`9Bpzz} zUd$CpcJ)gl>fLHCC&kE0OJ6I-$hUMhfrB}Q(I}saYJ(y%on|$E#p+=_`%Q)?YmJui z`_Vrx8P@_oVIM4jo0dpHaFew<>}Sjd^-HR<2Tgba2V6bvg@WykF+M2eP!N(D~gMUehysFoNm7MuyD! zXN7g4whj9Zi^O+9j)#LXBwV+R>nsbSk^e%%W5pbCr@Z8(X zrrKjgy@VzrI>!|>xDv)xhtI{mh`{5Ow<)AD{HY!}0I0BbS8_qgm=BTT-QL%lfP%;$=*{C;Sck6jmt)lxGVo5C*Q4?Bn} z1`vL?8Z%n~T~JlQJHVgd*K|kwJnwdGZ*RNytc%!q2e4ZCe91ZL+fzlWC&ReEfER-)J_N;uPpY)Q7;Vgi~Q*_L>0pYTxhLeMx7U{Byo$e z`Vbjcju`*C;3kZxp`-AOs5BUN)u>g)%5%jl2?$?%787eZ&;H%P4(Jvv@!9le7ir{! zG-QqYi03Zm<>sFqESmDpqH$NP7huc@ahH7b*}7|c4ILbN^09g2BU@OP@Be1x-fW<< z=gDdGvry1u({~Q&>*nk#Oo!p~UGsX8_1%~&hcx)r>8Vp3UOr8v3BT zC0Y=cLZtwxEWfs^3Sit7bJb6=^ce-~Yl~g}7!`vmxU!_wSr^ ze^hnz6IU{-+4y2(#x~|ooSjxw$h_MyS&Ug9^>LPO7kIOc=syQvHQBmzI8o#$g@tje#LIh zzjMs~nZsyr(_i`0Q~%<$;Ra9zgOZ6}uELTxRyVQqbfLebD~Y7I0l&p2Bv-w{gd5jx zrON|cmUH@7egTnVVliFs^zdv8CSy6-`n5%&=-$GJb|b&e)G1$;X1u{k<->3(1QTl> zp%EwNDC9$D@$2?+v9dT;Izqfm$xDO)aCc(gcN+jT6$f0Yc@gGww8t}l6zac zCRoI)mIgNin8{!{UUkI=sKb|cciTZ+%2c}T7Ef)bG~*Zk zo@3s^cN4t}F4S3IujCes=MRLpdtGLZejHmq$XZo_=5>jn`^T`xY3e{wY%K=@V> zzgl)d&1ah2E140#GA^ezUhC(cNjuN!5ODtKiN{5qJMpXgqeyM-4yXF5q<4$kq zI1+boHA@@uEywb%Y7uewP-E1AP39-|++^zRSwem2(0&w?0Ri%jk(^<(5H+a2HHkvxQsjY^n>EN9(NwAh92<=pGiVM1SVsw z4BkNMk=?GgTiP`E>?7rm(I5xjc2WMx3GBDUfFq)CQS{{v(0h2>pQ_~SoKaYrP^BkitLT*_Hlm#^N{sQMW9-aq)o(4w(@EjdZ{lf#gfYj}|KYOj=lS~9 zzjS~YoKwV`(}V2Jalyh*e-ttZ{|ZSt$CrC1Y5K_P%YLTvZ^D0o*Pj6e;(7Ia)1$K5 z9GN4*Yc<2Mc8&4H$=Tp~mmsyg00UB*e?ts4Ha9ou?5T~py` zByvU=TtW>`{ZVRSxL2yzyejWl**CW)`7WyFO(`J|PA}A#QP*zN8>3%m^Mj^IWzfKv zbMr*u!A$}JRd{raxj3FE^$%spw{L>u>o-;CA z&wz-nr9$=t{NL`s)3|3HM+-)dP}a+P?oLcM2lmG&I`{yT5z2Gpi|v0QWN3S}_ciVG ztHDkYT?%a}_FW9*-gU5Iv;i@)6T=2U9Q9_6^6k`R9JUNR8HB~T=7mgYIP|(ca0pbZ zRMT8eZJnk^s<^{k*Yh&Eg!`b~E|8wivq#D_!0(+4y!&n2g>Rt&Zm0i9>&Ad-ITH%j zkj+zXF*XqZyh@T9{ulc560+7D4B7&{TX0R=@~;KDAS@v}2G8IgOn{t-tjf&e1Is{@ z>T2<^$4WE%7LcUQa&N6=XN9P1vmH7}9HMl^tRtU|#r-jJO2KJRRUSfx_KZzpw6H)H zMaaMU!^POgaR!(iNC_EaZ0DvI5~M1S2IVNZ+`Obrk`T&v99QH3T%09ba^+uHxp|=iXg7x@MM3UL?)O7q zgsj>3V?Uw={Uz6D1j|B1R4sy!EQ$Tq?4mE4nb6ANXMgw0juTF6MOu?*{&a8hG5*Jv zu$;F$o?GO10uj>cnU`5hM`^Y=q8mmi2Fbt1x&~|S(C>d{S>F6s@8v;6ruy5AL50s< zGjlXjIQvo!KB1b$H@#jM?Z3vfVmI!5`8oEU7HYp9*H@#qVqX}n_wa!xsIVnY*RgxH zqRuymw$4z51nvZ|h19N23NqfO$V|A5o{#Wf&^Y-(BFFy{bZO&H*?Qbe*0Xg1^R2u}FC2 zkgo3Z@TY<=^qHCj{I{%-t`~eAH`PX9=$BaD674iAM2NY$?yl25PY{PNOXT@xvKON# zA|n*@DHV<&^4X|}fojV5I8>kT96|uF-JHqu+DGi;{&lAdVSYazr8^?<_HE?8G0?8% z*x+u}&mx7?t41u{qE0Esz8G=v+m+A1{_EY)Sw@(5-?RJ?tdFdj?*YQ*U3CZVyltbc zljgI27UAYB6#&OreClY}faY&OKkh)WH*635^`5yQvEzsf(=`!^fyNe#PDDPeCFfm6 zR|DVo44O+gG115)sDNn17x4%;cYQ$UUu4T5vcajt&ts~RkBvq8JfM53(MR?XM5XWM zN@K+EqvpNqLnU3vq;MhCe#Mq8=-mEqeVj*IikH7dbXf?|?{@n*E{Bu2rs{yRBN!UM z=xhrc(9{c2ylr`xO7ysa`2TG-R(gOIE}+c{a2+T5%Z?y@1+jGqlq3ZEGQG#MQjMg#Q4>P<}Gtz zj`f)<_T$*k99x=GJ=uuOU7=g%?;!ViFVGa|hQxph)$GQpf1MI<(pt#on^os;)0H!-Y!8+;+<1*d|xIX>8c#Cx> zvC~xi?B(?nSws47rFB-*{I>xuZ@-5`-DEZvjYYoCTeU40?}WPH|VMngM4x z>Lib|3h&PFaa&I|@)-*{x+|-;&B29IXFRdkiDE#Bg44}ikJ~#`Kf-R@v7&9psHE0j z$gv%p7cu62%_3niB7V914C)aQPmaDf?!*09!S?iahWME<`5j#hV|%(2#-?IV&`P2~Wy8^)__MXmg`WFTxL z-11%>g*U=NJ1nDbQLfRCo>(Y&^*wdPDciX)w{Zt^+qpe4hCnVw8pl>)W}j2G&oQW6 zXBSO;E0Gi)AC%CKnpCf6oA-49imE{mZAK7NJ0`V>zAuZ%95et5%HG?M zJls-T!Sodh+z!x(NtvXAj6zZ%}eXrwXd_GnaS7cI)oI-X78g~8IZZFqGVn1~BM$6U^)$uG_J zv+QtaRiPqS=XjZcH?OOtxS#1;UZAj^*LvqD>%ah(z2;aVC-2+?vF?oAd_yt2?myKomS?9hX_2M%t%p~Ulgok~LRJ+{ zK}w^)mshM5m#uiy50CoOp&1>v zB`>7S8Y+vq8-CNW*ZlEK4AZ=ZMJqUuz^Eus)78|2pN_`yDuH9uBWe1QBgR55+@cj zdI6=am|#0|EYKs}ywW`~26iVDPXq$BXz$7ybFQ~5)-PtVgMRQDZ_h|y+UBd-Q;(wB zsL&2a(Fv&8X2{M+zK~FYnWdDOlPdE0c@r!mP!Mk>&};4JNAYl-zTf%Ix%c0D&i-aHv-9k3cK6wx zJV|yU?R%LgnUmu>9J|ldU=E{#4%0c2uc^<(M(sHds|=i8w|`(Y!}^N8rPH>$`u!!R zk~-GZCu{FS)`LKUMVqVfUmXVRArRjg`lDpUcwp8rKhU3YDfHQmzg{@lKM1Bf!1SCf!}|Sei)~bi(%NSQG*ppkgqfve=`qL zzqiBtCJ@<@D#)VW96pqB?31EN=!!Wfn5ro-CwP{Tq{%;*rc3qgS6Q+XlBCVQl6Pif z81`taem?yEKa%y)qmh^8PS=IkimNm!7;CQlKQdljicIw;2QnSHv$zQ>06OnM;O0i* zhxvR(+LS>BB7apze6eWH zz0OIom3lLsY772n_Ma_xT`qFsGyRb*eO95*l>Vhy*IWNf!b_nPO(r_eS(YL27kiPa z=WU zjEC4SV2LZe%qp{?-ke8cWznDVnE5}7mlK^lDY0ri3~f;x$|>rVPG~c!l9@Fk+RY+?Woo=;m4;fXa!*BGLdl(J*0I{ z34LcO$v={Ue~WaHm?+Vv&qhf}Rn=nj#~Rt9b@;v~@LhOvLDfRtnX_o3qP+dRzeIYb zGM<6%;Pa0MRF$~#f1A-#s8r24A27Dp*-xKn3TTbB%Z<875jYnHIh6sNqw{jDoBa{p zMPGf?v7|6WU`F*NCgG&}?@KZyD@*W#c?*))oSEXbzZGgXW-@I@99jLuJX5gaxFhq$ z{#>cA_0f)+rR_a~{dDM}YPnA;X?|sPjh~&Lg_Y1pb3cP4ya&b4QqQMimh&*23;)yu zkJHCVVz!CzgP1iM)^-=|<(!bKv0l~uFGvTetK#7_X;q+4y`PntFmE*{4Es=^#;?py z*P^#;+(gg{WJSavjR;yS{G8XT+bKG^i%?oW_&C8dkEJlZ z9|1#&X3MlBtccIAX`3St^SUIta&Oa*KI$;P$@rcc5;1c$xp9mVaF)6%WQjZtLM=;_ zK+tcXs^E%&^u_Xtc_Gy(CyCN$xSg3_0(tGe#%ad7l3f+~l0wC%lDVG>$8)DLDoY_L z3w=&ei>dQ89c>S)-G%VDTl@A+AczL7tCw5PmV*2p5;TgOZ>QFB?( zQ){k}Y(KE+@M%n@E?7HL7lq$zIhIQB&dsuG-ndOV8b5o;TQo4PsUeB1`C9zE!p~LX z6@LJ+e%uE0=^t6&36hjQm;xBtyKQx!^MC?ssR~AlMjA%)MlX$OPg(8Hr2F>(voufZ+zazk-+ThFri8 zgPKY9vPpsDdKqAFoq^$2NSVPzsuK529m~_9*)` zQ-^x&UPWNLI@OI6Q@(Q%Pf)~rL;m*p*Ks_t5sgagFP2T5N*a>;p9}guVbTW!cEPH2 z^yhxOSmlduL%9DD@-{!mnCIF5ZAbq@tipUp?Qsz~6VH~#xL~T~qW!tamW|h9#9g5%alEG_w&DFA zbMm=x6~oS6G-dZ(i^*&~swqj~V#~hO+@s=>@zeliIS=jWI>HAhKcai!2w zzg%yQWG>!~C>lAecn*7SB@34g&GBpEf-T-iRlo2lYvkTFue0VbkvGzK;AY?|6HX&& zp46JuvM&stR5p59IwTZuSGbC4qGdZ=sn7mv*URzC_)ZN|F5ybU{?!vfB>#O%x z6>*R^jQSz&Um!shL4j7?o)V6jhtxeZqYu~Ds@NI5qS|o-dac?)9}jwP^RVCEbFYz} zhUOmsrT5KB2L%LW)2LiZaaSqaEqt-Zp?SHHlYTNKIR8y>KIC_=%g)w-U~_eLfA42s z-*_cH2+W=gKrt*2B%Wn~Mss2DMgIgnZ&C;98S%pOr^)$pO96Ox4p2%bHn^xT7GG*S zIOq3s&{jPc43vRyG!z3Ep8b6k;?~oRSD(U-Qf)m2b)4l)G8st#PD9aiX+9Y2y0u)O zN&c1wJH4|2(ORv5dLN!0qip8AwF8>Wxh}nK)-(vH;M+EbcG%L?Yc>P(7=k+v@CQj) z3zRTX{-zPgW)q>=8}a~gUNHg{((GYwENFc4(dcmo<95{^?3N!set3BQ&9X|llx`?6|j5`CaACWOl%O^EaI@4KJU^EHO>Peu(h3zs4LI9hhY73aZhrET~_1kShmv zkS7S}>DcJ#6jxF_`H)@!OYj+j!^MF^%2laAn<-xR_=+}q)-NBSYI|NVl16QoJ1I|&nDjk7T`li|Fe=q1o zzGMUND;EISe{-RcQv-nPDONyY1um3(PY!0Yrw(QP3jyTm+z&tXzagkx z^mmN7HhyUSY-Np}6;7DD+m00YrJ^*|8bAElX80m99kA><1miYdj$m(aXrh}cc)xa} zP#4O=75t`;Ku(m<_hPcN&ngcXhMXtwi3`i0_4iZaZnv8uV-x*p_~=7pLRw(M9Jw>w z>_%f~5uU&uH|_qde{c2=$`Yo~^Sw~0S^$P+BQ4seA`8%`FDjt2{fSpI)HM4X6AiUD z;>t>uS~_yKw&J5UsGA15E~J~a6a4SKc*lKyMq^WEFc9pQose9gJv6OX`Jn$L6zMoV z66|KHLO$IK?o&9Z3@Tvzi^^rN{yG)><;>iY`n%IX$p6p#Q{^#Xgu3Mn)^R@#S09z{ zpquOB0Ar`ST`U?^?#~p>556SGBi^_yiRM@X2blM`KE5msxB_Whje@9;q{uH9a3&L( z#QsPCxmW|&)sokPsgC-WZJ|obQgSjssI=p)5z_Qyg}N-uVA(u`8IEx2awUDHKR%G_ ziWal=cc4>IdhTVvRLuz0)mMS#*79$G>v{b_ZrV-PZ$HFu31E(I2~dt7rJ_>6Q^6E# zspu3(dH{-5Jq(INJrs(4Ph86nV}6SQ!SA3s8=l;jjoSQ{F=O7)N@-8PpWrPZ-W5CW z_i-DhTh3SzOe5a}$aOQxlZ5Ui2f+2W-R}SzP$i{ zLg7W^Nwuwkee*uOsL};im4GKRPOn{m>`jOW2K*e{G&p8H&SP5FH$FX9>2JK1i$z; zj!xMd`35l(@ zN&DmF+u4Tl^@G_z8h7;L8qGEk&x6?&ki=!nV8TPL)xaa!LPO6#6;Yr#Jm~HfO!v+W z_To+z<`IYne{n|v!@3iNy}V0@zP{9e30@GeKf*(a`D00|!nWg1V*zi+51ytBZ? zqg$|wCJDY~Fg3*j176&r8+yM_IQS~b9{q@+0dG-(h}zFa%?s|#{44ZMtr6_X#GXJ= zui*{PWnK#POG=4IYTYfYf#0f1xZSe#^vv>k1&nF0LcIz5+99K+QzjQ)F@A-&g@BRp? z5PQQ*0VyXPKRQRlak~Xah=Kt>a_wM{Z~>AH`)w9z!zddJ#g5Ce=u8*JY{v_GYi9u? zvBR?bB7n=cBu3)a>Pcc5;Yke_-ByHY*pb2C+DTg`G-1@k#E9z${b}Gh+qlr5qc_N~ zf-T?-(US~`l{ShE-ECdi3p-THHcwLci|q#}>1ZT?Ggk=udUOQpn3D)Fknjagi|zv* zbG1P(p3>Mx+d;^+;*7wu>r4ptFxmp3%0U2W-I@Wy;xa(VjeF|)UpJ(1t8E9^yX{1% zN{$S;S(KQ5IYA79eiQy@lB$2D65K5Q0MM2&gF25AzywAUpogQQ(BGtBdv_MV``SFH zupymnhahf-~Np6dpi23oh+ZgQ2$6p+kvJ-8-TB&m_SD$F?bsM9MuV=fj5ixiKw2KPYBKr zJBP9Ywo%4&B>}#Jx+%k|JovCBk2ip$jP#N^#)oH}0FH{#L2l$yipyDp3l1p@s?rL13%~4i==bbUin>J!E<8aE{VB4) zbLpalGSIB!Z9|Q0{OPBS6-vKU>f@%*D+_zSZOV4q`}Ix+`G9T&c)F;X zho8J%CVMcvDtn;rNq@PiN`G0(LZBUP6Y9s9gV9I4`j$QqqvoH0*GF8)jm+`+l8HL; zN0C5E6XhS9cEs-u0Dq`oPNJ_Ck;K@K$LI|x4y#|DMT!g<`X&=N&l5vx-yYk%eI%%AN&4zb4nai=DW zRLCO*BHDU?LzVJ&S^#Ze?*;4#hqm++#8<19S!_xm+$=3@GO0G#Xl`+?y@Co5%|nG)u=)~fB&=S=pW!lR;KqRb8bMf zOJl8)aS|h0Sx!7Q_fsy1U#Mz%%vX&PAx0^@O7&Aj-WTk^ zwV2vk5`~w*;j=1&;6~^J9Ra&1mJG5X4xy^U$Ot-mY;>zc7j25cAMnXKWshGZyAa)e z2TCq&Xo3By6;a)#UzZFlIjGR)R}0h`?sDC?`;)W;7IJRu@JrHgO;$2?DU|R=owur{ z8|i43=qUw6s)|IPqbAdmR}!(FDg`X&_Mhn^u=llfYdKZ7I{)h$A=)!=9p@nV4WksF zS&1vGn||{*j|9%$2d}XMFyl`MN2o(MvTeppx|bP)_`XsdrXLCaiZ&UY^tknNmYE%vV%_%Z z6l$Bf$)WzqyYYf&U%Kju^ni3XeNSk9pQCQqe7I}cPipTX+%Pt??pf*cs?4gn_uT>6 z?HXp~(q+=M(v`IO_?0qM=2<;t6{U{EU%3vEPmK0yofDfa9RDUbvVNlzRBPG&9#AB$ zKQ>Xm=XsHRff~>j(qdleI!^cJYCrPa=GGy&;Oh1A&2m$h>#_Mp*PlD+l@5Zp6LO4q zMhQ>d66m$7)-D_~%{K|oxH~wznH?A)v&U{=ndfPVZ_#YroXwc~;$-6FIw#%y@z&>* zX4B-TWAX~P0`9iB2|?Ud)h)R~SL}O&dTv6h9;R=mZl(5S;8&e13_T+E%O`i^h_n^o zkl&C`Pbg26k5@N!XOLM)`IGb$)1$>TWFKLR-&DRZFzb29a{2L6;&9-gFyS$Qalku) zB>|nrgl0wD#Un!u;Uf(X>c5FOD>=(Y{#0!T%k#nq*GJP!)7Kw0h<5xL0og38n-}~8 zOajz`E=@U0;U`+pa_nbm0v`+Is!)G5R$wJ(h&F=L&TX&uN@={kpuHgT!!nLIkr&5~ zR}#qqP6EaeWsv`I5}g0L|MwZR6_QRizciwR$s!hM8hPH@sRpYm44yI6g$qVfW8d&Iiwa5#a(cblxg6gbw<+YOsoi_^ceNc4 z->2g6*gLWrug9xC+&}UHM;()j$j8~pcJ{$)zt`vE0~r~Sv}lmmb;?gv-`Z`WwDp>sVZ;mSvHequj`HuJ6NWX+#XT6*H#dtR>PHMu@M0o{M7a-|QM zmCoZn(KJY|)kIk^7BP7;x<=*Dwb7q;4`vOTC0`_KD|M6jGoSixWG2ffHLGysI_ENp z`ywRk&!R>ReMWaBYtFoL)y3-&omFRla`X4^wYKpkAPYAdb}JPX73MmbD)9+J3C1+u z5PgNeXF7GtU6dE*f6I03inu1ePnZ>Vs3gXW#^q5=$xPKpcl<3Arf7pLilfA zo$pT|6d@E3w&%M$0uv!-pbkZ^-TBQ)p5XQpug`xs<9QHXlz+X0X4K5i+Lsr-{bw}I z@(%(k_V>+Xj&79<5uf0n`aXs5huL`8VA;4Nwn=O~e)8sDurZHui1Fv#(vKtBC#ND< z;BO8*ux$vlVeQ-MAC1c;HzDg_z6_n6pH;EG>KE?ord^;8lx!B7CM2hx;pbtf)m|KL zb$7pU7g%?R>R>slZ4F$<8wjSpdXpn$9*ZBNok&NTPYF@KpS=EZt+KwquCiVlu_VN1 zFe!H$@zCFYzY6ntAu|oc>$gv8?{(&k_*gGpu#4^3Lx*kmu=-pGYFket9D)1RW=>TY zZ`RM!urZn|m9$>X39BP!(N+9%ozJvJ$$LDfNQIP>V;j2fp=r5C;lN6lMbwe)IT;}P1VBirl}j%J1S#KRO? zYsAa_xjS842^QzK7V6ovExO#P8{EG+Ty4Lf3X^fj^okF8S2uO0Dh($#x}5S%D=d!% z3~4uhK5cSpzNa?fptI!MRB%eY$6DZe3Uf}+p7puGy^Ol2U0{H~_BQb6iaoFwSmTOm-E%K+LdNzs1rFSA?0jS&KX!4oG%1|c9SF@a(j*J*wjOZiCecjVc|iYi zpub!hl$&%AGZN>FeAzQdQ{p40achQ`NwP`wOMRF5hK(>KfAUQur%sAqbOtDmN4H|~ zHI|-rNy5u&lEOZ<+;nDk8R`AVZmITs|N;(GR34rHqDkJl_JW z_3}xfzrw{j2s{Z0O6xx z%wyRn2tZooL{po)P=PQuW*HU7bP4459zP=`kU@H$*j>(|Z(7ReOEp2m52&^z_nXwK zj{~f(uQNLhU`wg>7W|lhBwq}S@bgmo@osf1U60MJfNLQHn`ZcVz##hq)4thY@QKKW zlj&P;x%<4^JO4(D7C9G;3i z?e-prU*#!XTfP+Ec;BQG5*3im8C>WFuvw3_AX zLtHYN-%+gL^>V5T1hHD9tk#5=;xm|&$6tHmu0`Pekvya}ik#JGNPd|?gNcnXAn9~& zI~dX@)S`9vJ9$hpO=dCb(3H=U=xb*_@#bpra!JT0w9JM0C#-CLG6hwx6My<^k1{EH;iEB?82;O7{1fX8{4xsX_0m=rUeeY8Y548j+*ckl z=)DvBp6jfv#AF2Jwo-va#&|gkmLbr!sg1m|R;-1}J04+(m*G0u>RtTiE_!3qISL(9 z!c|3ZjJ+;-#^q>Y-7)@T``c5ykJt{Yc>}D8v0Lq@xg_aF`vml}Jpa}AYj>|x9k%cH z&qTAWKOtN*FU?oqtP`@oPLg0HJ^5xPI@)GKuu>w_dXR#yvx0xPWLu`Mp>nK^; zDy8Cicf)n;lQCLC_+>RIggSe4Rt z9`+UmoUbxN}sb(y$U^elwwfKb)7w978l`SFxj#EUqMC2<*Qet-1CRVQ0Ri&6OTqBU91K{)SqDg~ zLSCIN>-z%RG--RYWs;YdQBB@-eDdn-d;<0NYi( z?&G~y>G&SDg*jGMU1niWz+5ie@%VO94rHv%;i#j?e+C?O^YxbMy88}Iw$w#k?u6ahtB}xX2cnv99m)*d@)Lu_X)0w=3iC>ywR}D@ zw4~+sGMJ`asm7yYf4b;pRDJ)xnpYdDE1D~BFjMl4<0SvHt8lCKwIzq1TF&w5oqW3F z%FAoCL!wG6<8x? zknsju1-|Q}IK(l1SQNaf?7Mp1eU)|Pe@1iNOXbAdzPa3t=h`Nt1tIKwNDa6;`vTGM zRN<=gwIZWK?}Xq{TUOhK)a}dM($qiM3Xa;m__+aSg~oZ)(Y*Vug~O1zur za72>`IXjHKTkSac@Oe+@X-{MIDztmGlV`nlkSTINAYb#*>lecNesT4VZ>8mCZ@tC9 zllOYm)rFxB`Cq6YyRFMiG#i)o^(Y!)>$z1LLUb~EaaToCVIp^dRm5Wy9WmN0!POmo z|24yxaKt$yemLh4AvvM&TSgbe2hl5_1x3|jhdiLmEE7d6L8h>WxQ=;ZJ;&o5%zA3a6>j`Y2eS*Kz4T#t;P8}?eVaS$n%-9?DY^X# z<((qW?J#xplIx8MPyg(?>#RB3aaWllMR|{mK;PNlbeHOvIpI6Q48h#kU^9jqKfDYtwr(QcbB-ltTAu zga~a7R{EI^-@i<+_R2suiOyZUel4)#+#Y8*f`1R8I8qjsSfEcoMWq`I+9=|lmG|Vv zUy2auW?!SyPHdGdBMIE-`HFkoP8uclRpHdsvkqc(vLNIV{9E|^nEg=3Wdtknx7`y{ zz}ns0Fku?Q3gTmeu2}f~t;D>)-^!*lL(=|iOmL7t_K}upUdvDR^JjNT8J}~%4WIkw zf9g$oL;0A;%Q>i3wuV4ONqYnM0|bA@wT z*ol5)@W5mI*8$cvp_|k`N~thls5(OF#l4wfGQG_2B7jH}57fj6=W*G9EV5@H!Q1BA z^+iYMJw^wK8~Q%bXdnP|^tKD=+cbRKvIrbH;GZUU_mBP$k7lx;y9WBhf>2() zLo{L1LjY_|_;ZR$CIDNXG&9sw73hn*PiDBM{IZ{edmH5*NnX7hc*8Tu3b4JT97ezK zM5@1+L4$~1y|ZYnyrz**uVrL-C-=8z9eJ)H*LBvJ4?fK38OoNfk{N|%Cm zrFB8O(g%R4X{-QVy*!kIVoBUtLw_{BH~x5T^&SLnC8r=iDpa;6oK2-974VQ#-06!! z8=$SQmjB09SDrxB4bF53K{lo1ly&!ikGz&agiv=J}a&m*s-t*$#trGYobo1%kF09%9VpopGBWFOD4 zTR?-P3Vv^~mCNQ~vo-k-8PcyHM~rCG@m{JJ`l3VahHN7n*%pf%yp4ZDSak{>Yyl2c z>)#M=EC6krWp9wD76NSz%5qTs2@8IcarQui&Xnw8^f%2 zz$5#a+mPPM7d%ug-|(Rm^y=Le8^<6g^6JVR`a0y>dH)lABM>Q;UVjLpEBJk6crO2AI7hPx1x#E*JFyj$W_H>fvJq#!ljH1Vigv*fKwK(h*#e zm7))71CbWzC{C{ez|zI0XxG(~i|OsQ%{NCM1XPY6{r1<%AO8y=Q3z)a;}+0qlpi8q*d46dd;O8Wfc8r z!}wue#-b^i^;skFEw*$9^#(rI+fbHOJT4W>H-jK-uD3Vxy^V_~su;sv;hV-8wxOtG z@)-9J#MH!;6w@5ct_||ATvc54rOLcZyuHi;OP>ZGlVa2y}>W9>{cQWgTFAhU3K z85V+pAvNuVy2A_nv6fuMKW>2*@v}!bKI{>TkE?rL(Q(xR9Px7|+n(m03RZvpj<_Zi zf=xm8H0?!tyr4NFd&))-P`xWYz5&$4BJP!}rXemXEBBk|J>tOGD8GEUaP<&`>rb*t{BmF+KGRj0G$33$E{McSg5Z|#lz%)|cIU_7fSfNFnVFBWgdL6- z7xe6$kB>{4F&|Y53nx|~89g+T$pTQugb(CR48rtN+8Bm0CD#E47%jlG@j+lw+8Z)A z##3i_dNKmQ%Cv&2rPPg|lWAQwl*yb;===Hog|9*~ug-I*L*FW3$pFHL5ZC5IxJ3?NZO zzTP(`xs1&e z@hgy(x?(f*k&oa|s*&_O7*^jZ(};TxM$Q-e4X*Jg9GuuhC7yg8QMA2TVmO- zCxf)(`N*ke$7C0|tJvHmCqprZeS0SRb$_s}fDTmTtb7^zNJii+-~l{dNPb9?#0u{s zY$G`D0Z(W#(ZCQ&?esU&1c!o?;CrhQ{A;>oAUu(g90(z8L%HrrRu4^7(uL`JVHBc; zRtQWa^X0k=BSV}AV4SlNct6iV3#Nz?C+-5BZ_577*r9Oa633H#)q4K{>EElLi^Da}1K^QS(GygkE?^<}D}juL7bS|9=Ic?0^Wqv9yD3MUm{5`V05JJWsjI&>jEc zF>o*wft2g{yK$a>%wSwy_PldqK{g*yv>o3KILG>@RVv5_D~?eG^Y3hfCeD;y(H|t~ z1D1ExwVc3Jfw9O_PP2$Ygd#9 zkALcH*&a|-p2#iPxbMHR5oiw_|I`a|J!t>bc;j{8e=Q+CH~ZJHK-nI`e`=R;SI|E- z`MJrzIuPJsk$+W#3s&&LztKI=@Av|&4pk7S4_frMn>&$}&dLaIw@84@#uGrXDlR0= zn1vwN{oJPDi7={L^w#}-_JlSF5g(E@|L(jA`KtiBl4i;W&~f*U0xVInC;ZhFc!FG| z2j>MIt6kg;?SGaQ}Cxe`S zyh;#^TSEGNya_tslhCaV+^|R{^u9_qj;2Tk^}+jJMt<1ia{`;l9bVZdDgtM*TTXcK zgoVN>4ZX4ZIsf~g69bi`Dh@bTVLQYH5DZ1mgh$|cB9uZxQ9+a8#D@NMjV+Gvgc!-~ zNzS!HcVdg(;bX-ku&3x|0EEyP_0iP}d^|HD40kQcUVY+6E^fl@sMmg8oX5Ts&M?*@ zyYClQvgbV$G_r&Xs5k?c$c;+Tf?9%#BK{Dy-+CLg-Vp4j378-s-~l|hxeML5CYN8v zLR#ztx`4>On?`NN{l~xo0t7ZmMsz#evT<_O;DQ#=1k(Tys0%lWR?G);rwO`~Y=eB{ z3{*^{Ru5f9MKUT-7dkRi7HP(jB0sk))Il?oKR}LT;cI9E?f8v@?5Az>6x6 zKkx$f-H0rO!O{q4z@tC~YQ_J|6B=oKmPCz)%)~0-MK3}m(4YsSU^r8opahd38E04? zK%Q#A1x2gh6t3@tdFnv_)%^hF*vJXh@AZKgtjcB#)toqx_IQ4F1h#M80?H@s!1W70 zK!w@$o1^^hGsg)sIPkF)zSM;~9c;o(4@hA_2U-QhfuwFcm(Soq2i~xcvt}^)gLoK~ zwJV4=u?uyV9rVMR-$$gLBv9fQx4{>%LLJC@OlNZi8$%Br2Q>JC5%FE*DG*Rm*T6FR zZ3r?b%mEmd*e{K7zdhTP1i^{Aq`l+YNd#L34jh3)Uiioy>op{TWN7XvOl82~T2aB& z=iAVoT$_B92Y-4m`GY?NJsAJgWamF*cfx1G3h03HtbN^pTZ_#b4Rp; z09vUJbmQF19dIVy6a3RX+o1#U_a_E}&mrI+Yvm2DI-Ci?R4GruBGQ3w@NK5-`Bnqs z!=nYgvDd*}0R*{l(B3iZtbitpY-B(W693c#e~UuxCmQm{Re&e?P`sZIEOF$mQg%Hi zrvkN~IkA8y04HkKdy0H;6+051o_P^bka3?3$ku^-Clh4w0;Kr3g!}RVU4$6w5|8NP z+0gp0>xHVSIY6Yf2(YEU7{)rVp5zKHG8@PaU0CN%IsgDdNC};yLkN2JV4QAzY0|EL;<$z_w1CC-q__H z3;z0qA3k;B4i`G%44wH|4jqdc1Jos2pgxVE6pi%P0i`)ZX!xjlXhrG9VBWwe1IjT_ z;(%uoNvM6IJGvJp1=;4caNXtAj!ktgZ!B0Kc zhcNO!3#=fk`%M`6Pm9p)M;1OVbLt)e`R&Xl%-hTBD%pRomiaRX?oKAs!`nQW34L_5 zH0opwA>WZe`U!UT@dXx0Kf&lqY1Kfrbp><2s%!zZ@&!S z)=YL*=>-47V<0j^B7}G63Shd$YMU>9w($1R9jmpu#vS->GOp~_xUn7p!LeD z2GPx?Tr;?tt*OAK`w~OH9mYFcddLz#s^wws7vKX5`H4(I52Kx734L#1qkVYrKg1nSa+XT~uT~CjCvyY2AD=tV z@noMg+%_5;TGt0F_jyZcJRh~lMKDuN z1|wW)DTrx@7r@`^>?0?Gf)g8=ohb`J&iO>ae87V(J=fkA>9_^bzc!B7G6QS4U|1^8{q{!fa&{xBHR2xCmR== zZGm$ugRFjiYeDXboS@n3Og+>jg*S3TP4;iq2B)kHWmG_VC-M2`e`1xaD|(SRiv>7< zm0;TP)Ekz!VU~0bns8)Z!8p+F#!LYs9kNsI0$xy2Gc%%WJ|#$EDq};UqM3O`?Hh|f zK2qoiP5pHRDo;Tai{#w{x=uFGLkCi>Ky@!eJ}v8?O2dVI-G$CPm%-}fx#5Qkq|l)+ zC*3n2H*b`Ox~hkeU0-g5ss3026~?Am03Lj0cZxO?3RY0Vd0vKKp09xasnNPwZ%9>_ zk+<3vYY*DJ>?sv2Fm>g_eLi$t_?Igfp&o*sk_afYOIbmE01yN`zX?Wq(&2e(j|A7e zzvzH6dH4Ls#J}Qd0my z=^Ny1LpnO46#gs=vQH>TqeYzCa@n}f6cgDeY79s2Hqz_i4Pkg)ik;kJ&p*8cG?B#@ z2+3Xq2TA%1A4hMPU*AX(kQtwvT2|Q7F_f+M zxTOkaz=hlD;BI87{~O$_MGtnjKy|DX8d>|F84U2e3_`e`F&=Qt zMGc%k?}2)MfZE&ro)R3)L(pDiOZ~~EjVNU}bX<#D4;Gz42~X!X1X|2_;2uwL&j6oF zHv{0T#xEM)x#!I?Wc|FcCO>wt#y^INQqA&Qf+T*n!CV^fXE}KQqcIP#&Q=0ZR&gkH z5w>604v7tFP#JuY9~efFl<6RrZ{%GrKp?( zzE{_AW~lzwN!q%28qp`UMmM9~e?&-U4Dmi-T8oQ!)e2ISbXYeD)n2}iP;|6k&zQ}a z9xvmL=BAQgDi8?|kh}W0d|#4AftlOnjpMgG?GFFbY>p{e?~OIvoo*`8G79KuF=y;o zXn}3}?c5xT(FUwe??WM&`Rj$5|5SC&=J-LBL3!+D$p|8kb5r*Yzc9a!YxEPV6U-B( zlh-F^Cjuv}Q6Ggr`b3Q4Uxe!xaw?2rj6{AZ%$DcH=@LBuGHxP|zvT>C>GT~Xw zG%>e>J0Vfz8ZAxm;ByWsy0ghoc%Z*rX=qxDT>p73vi3y!q!47dw$}F}`Ya1ySX%`0 z?dER8`4@JIO3Ikp^5-DP>7QQ^%}43E$;P%#TyDhsww}!%laQrG&!rRZZ{EH&cd+)v z>bs@(>1jt3&l*-^gv*1hW6(qQ1=If7{*%YUA7RtRRTir5`qe8cVb@N-bs8$f+;v}n zb8|xTZnNFj2k(WRufe5{N5r! zJ#A;vxf5o=9kuhX7cUyk^5-v_%(y#z5#9Dz-#V6-d=Elaj$Drtj>PKioW^hi+w(oP z^+v_-2J9?u|F%ebdm*lu_m;^IgEyD84<4qM>5d+LE{}^jZ|4M$DsA77h&{QDg15s* zA9mV$q^=gvXk~bt5f67qD_51lGkK7i8&?U)YA;*=N9-=0IBZVXN}m>pE_Mm!-ud7o zY`}&W{K#|p9!}hF1%S{Y&#S<1K!-9uvhk7hRPx5STZKz!DOMFCYIg#5?tRVFdyH87 zDCHkJp6{6`P43b(DA&4>uqnyUeJ6O z;koa$MsN__ixdB`VDB(Hjm0;-flG?PK`Y&1N5O^fCg|Q1f?M-wjd^*noJq+eo1@j` zBY%D$FKHF@(l8}!Hz<)GBMK|bqQL5Ug%f!c&eN(F7qR>t@8hF6HD0i4iNceiDQ$qP zY3RP{j-EBwdA;bf+vkGcyT=tP$ZI-81fw0XW&~>~O$Xe}NZTb9*&T`KM8l4BytR*W zPw5fae;;tV|Fn4Q_LK+qw9Dio;ok&+)uT=-B9Kkn0aL%uZXGQa+7eYu9X%IdnNm8LV;-mXnOQvq>H{MlZ_z zW==`t^dQsPLv6w_ki{Vu&cd6Es^tBJoGcgd? zj_M2B?2asRB7geE)i`uUJGeOUjEm_uJm6Wamgz$)-rBQ%Z?RfT72SOuWV~a73_u5Qq%nJR{WVved$KvJjm4jcg46&TRFkCsx@s=ns}feL_t8!w z)9bu;cV1+iCt$ts0{z}a*Of3nd zJ=>+Cp`dX<92_3)QXU)}AwN<(kdxC<55B#f7dXr*o%o>lTkjTYj#1Z_%f!?JZ}dI> z#<$|I3bg@l^32>qk6$&m>O!ZCG=u7Pkuir~o-g|5cMtuJ_IO z8()WhYKVBdrbbGZ@B7c+JwiTGOSRCh`-tu*@JdX*XW(TzHdW5Z)g4K3M+^8YsmnuW z@kJvuQGzAJzV3w2@T56k?vYRs5nYGjuMa9Pmsbal!K*}^_M9RD;E8 zJa%b+gT?YJmj?^3LJFO!#cZ*NOlRdi-s}dXYUQaNs4GzyrpIzsv)19&$=fwUC=Yb{8EaLsk1;Pm@^5 zo;;S4dc=GGjl=g^ublN~HCs?hN=KN@2VY31_t5q}quowc%GH{ax0+<1@z$r((Kr#t zUuU0rq_YT3UdTy3Z9H`KS?N9Mxc2k9jIVCvi+d2+pp0uDQ)y(k>KrM|Rvi4PLhU1C`tekovJ~)m_LI)1|qx=R^+;zJ`92`TkXFS(owD zZQ_|omzL3?=m&K7doOLkytGoSx-wBNs7_Nlu%CfIBai}CbN+OjAYCTb;EOR{x(BS+ z=XHlHK9Vn%bGT2{=@|n?d%!o z9UAEA?Ck669~~O$8SU&4Q-@O>VkX^zND8HV2Ef}6IBxS7XKwW4dSAoV-MNgL%p?Ve-Q=>Q=Mk$3*rLJSS>$v5;hTLQd9=Rmx znRKUa8lAdnbXrZL(=?4v(=?Pj?$bK(j1^|agwax#aBW9P77q5H1XbPcRCT*k)$LAM zw>x#^>l9ZwD{SpgWD8ZWsM5gnaDm;Su%AWGD0b58?^Lh9Q^+dD?Ox(2)ZhI@Kb9RuARqZpQSc66=r;=9Cjmri+?xY(r%K&b~!WhhCRkuH^y zE|rlknUO9|a2F-9i;{?t2m3Oa6V+^`OY{$S4)?crbf&u6aU1R(Nwtr54fl);^|Yrt zx;onjQyrZnogLjGo$Botsj*?g$uVHX0q80SQddEcrd}x@o(IcalDbN0a!JxN>28&2 zT{F6M&FHpjMz^UM-KJ(JcNM{;j$l$pFlho!nn05(5bo1Dz>M{v852fJXLR~9-CVpR zE_PG#cC%WjcAG{nN!9kXWF)tk?ds|g-KoLh-qGRq?vasHe{XkRcjsW|Xcq>w-5s3+ z9UYy09lf1{9lbqk)Q}$0-`U>LKQhuY+}$9?C+Gd9NM4=DmV6?-jIqugZhvE=m1fHMt~dbcLNg zy+)A|o$l)I71O;sQN5g~UP?X;@?=t&cLQiaBS+IrB8qG$Sb zuKKw)75YtWlB8Xm3KXc=PdS&qtDf&_oo`5B{D|oRF6RLXIzT}O#Kmd^EH0j?7M8Pk zlZzFk6=o5SXok_#7mDsdE;v~9{NCB3B_@^kXjoH*<|-k5>!E-cD=$0KWunldsoPQK zB$I~=^9y7KmMbgZ`nr4DhdTS(`v!VC`r11OMuxfv&`R2Shr3e4ot-^hsOEjW-GidD z9cmTrrFSqj*x51EGuShXdrxmycUN~e)a^iL-{9~-_mF_X?d|Ou>W9|t?(H4z>rcU6 z!?k{L}8i?Qr+baZ(PropIgPjTd=<_N}Vc#1Kk# z(z$V1jC6PQ4vhA8Qi?{02Zwu*ype&v!I9KxUn@fr$~( z(J?X#Wzg5&-#Iec-!s@gJOC}-)jlxLGeB8xAL>Z;wD*pp7S=|^(el*DVO^DVO|~ks zsmG=ot6D6k7GSxlnk>dArqf4c6L&$lnn1e}Q!6m17Z0Sz?I4rF8k~$z84jeX$WyYD z$})l8DXS&8%Wi8*49+`*MMjKli>{<<)g>a1IN4=Khv#7OPQhkMDx@SznwYO?Crvmv za-7Ohx=e{_s}ZU;D2A>P%hc^>GAix3%@y->bJd+PqRKSOM1)3Da*vkD zPWFk604;~_)E3l;oB8SL3Pfm%i!gDQrHqu<_#Bhe`VKqU3NxdHlS>uL$7J?|j+?AA zPr!pKr;6661Qi{BhOBtI?rF=OpJW){{F$ufhEr2cSE16CPq;>$c7qb@DMPr@+F@#C zakgCKNUH~?Xx2srsN`oei<((vHRbW-OOPSDRC7rE4Le0ofI5;p?vp?tNlD&)S!l#7|YLc#wSq4X)H1UeguP#JleM{OS?9AG)qNER7FWMNV;&j$z&>0t!8o< z>K6;MLJqI1L@vUvV}hPZ<8xWGOtJCppCmGJ>cFNTEX^BHfSoB7a!^V^PxUia?51W1 z1cYc*vqVlUsl-rot1VTgY7ks}Fem1-IUxuAQ*`nacdkT8wK24it>P6PE!SA+HWDs! z=!{D=rE274&Z$sZ4rfdGqEjVLg}FjbK7UnL`9L|$pIDkL7WCtMBI(QL?sGw+{DBRx zG@dt}bPuSRBUO_dI1FZ86SK5JRJ4jg%hZ!fM32`NkRdG?rpc&9jBQ=wrWSK-$V(-p zdKQOBm{FN3Q%9hkibSv~Res!RPE-lFqAgXc=*m?aonEMt)t1MLEM_tVIf-M0>_1zg zS0ctMjwHwp&jB7(W9iENc*at!bBGKfl_DlE-Ox0%wS z&(-63CKMSz4qA6TM+&9mCg_xtEt+tOkuJz|`NVjM;;K}r#Zny|DG{apujxg`GKiWs zTB!NM1%zunZ@A!|@`1*W?}>qsL8)qs(0m2780vef^wzZZ1`bdZ<>@1X`4R*( zrEF1BW-8D`JW(hSgQhZmf`~F>-f;_6+=pqNvdU2`x%8G?C|*?UyqYBvg+)0@>ubTH zByUot%tn5Oq3P9EH3O+rC1S9A(tF?N2J>FSoo9AQiv_IUUKC=9kd$j2E9kuY?&_ z!?0R1elSc}NEPSH5H2hl&-K#ja@~WEIWQ=yb&t2iN1YRVFDj?ZyyU8yyj=Urrt#h6q7EY+kv`}oSeCG zs#z6j*9b&f{Ks{wY12#n{n|84tbUz^Rfh0 z&uVwd8q*a-tzFPTFa;awgGG)(e zXVi1WxjqhMEUiPwlW;V;DcFzTwH+%OpMY!~SUt{IHn)Igqm#^S$ckjrSu8Kxk@y74 zqA2CZ=PZdG?-hmI@$tDiD}vQsrJ=l;~@bDQ$HjmViC@7?+Zvi>M0>!PR1EGj0S*JOcT zs^+Tvb~JZf7J+8zk&9kh6j^d=RCO?F){2&PkYMCPvGL7JIicgv!-&Y$cx6E@bL$BS z!@B{#V5mu_QlvZHBri!^wLk-y3W+cr^%#syC#T8SaVz=(9_RWvsu8ScJke0G>M^i( zvP;F9Cy-_8@ws9(Q!?C%LJ8`|yje^Za?Z}MvNCx5F=b>}KKxsNRI}0cH)Y&&qu1@**+N>uFOW(0%ecGoi|CbB z%Q?q&&D@CJ1N!T_5W#&l>S6x$1vZHY)`fnNr#l^Ja4y!!01@|{{a zpf@$>E&S^-KtNKrK|reXI;r)Rf~90_L$DI8Y(q~%^%g@<&1O|>mPjh38<$iv6v3)U zjS8oDu1i`sevzZtjGPXm7on%dh}OQ1tbV%_d6NS`PvRRF8Zl2+Q!Q3JA}Y*b1Y!hL zP3Ufd-t?}0MY8;#t`nvnB7c}Fd$<~iZ?YBf!^FVoTzW773VX@@bX%rK_M zOU~em;igZNiE|ZOmN(s*Fhltr(~qG@sh`r%viYh->y=)ZQzopMTk_BNXrbFkSgz!( zh%<}C49?4}r5EuA)fy6$YLFnA0wc7gtDUsf?;8SOv|z~La&C$G5+fkPKchzkT&qAk zjV9Q%19fq$I5nI^v%{UjIk@>qx*<{C&Mez|P^zbggMKkg3+`$%G0QzJcC5BU#%N2@ zE{qRJ((JT(0!{WvPVJx=Ihk8vUX3}K=E07u7-<1$PK|!a7MEi(sZeq-r*tzZA1}x^ ztH_+Z!2p!Dr8J`yT`4G8QFmjE#8ci2cw>&8jX?7lP`QBx`jD zChw(us#q@3M37Z7YR8pbl4P~1RBH>&6WP^KrQ0)xgCjLNV~yP?;<0Q+mB}(sX(~>4 zQ$|3Rfc?VtE4^pQU%FTHyuk?Id zpkIW_6Dw}LF2ojbxvJbqv1ldZF9G$s%WV5fzbj~Ag`BRPvKia;Rn9#rT2Cn1`?P4o zi{7Rs@*ZhT;%9itgJ+;DHjiYwhLh7+l6I+iWfo=oQiBBL6qwkug}enuNz|y_7Uj6| zWU{(hSc%HyojIGW8g`KzgC&sT6sr9hw=l1tMm0NwXBL$}s=Jz94tc7znSxhs{mEL* zSx&?)W-B^oJsszX0@HV@a8)JrMH7fZvU)zX#xo!?ll3A!T`uQFEnhy7o@C9#@*w1H zpjNPaH*(^Ead}BsKSgqfujuKrBIMgrewWZ_7v*f5obS>i(q~GdEUD3Ic~MF9GI7TSaNB97=d{q z+|;yGb*_c^Qnt2K_2ja&4OeusRVxfH{%LlqQY_RAH>U|!uPQXpv?v=@RUA?wQv1nw zK%JdE`=Aa`RU>J0%RS*qNLpDW`dlmUR?Vp=5BTJYB@BHT5qAtelymS!C_UHP;=~P&7hg+&7jUp3Qe0B){OA<(|v+vn~{~j z?nTN`ot6$}T`w-f%xZ#Fg7NH)_H+opBseA{S=PtNB?qaGcvm}1uPBvIlss0}Cy#dn z{Ibud-1cNVS}eU`i)9T{=2kT+^m+arxK<5C zM_V#!uvl+NFyN<7SoO&1vUyj5>cizcUZr8B_x?`d$J^@zA z1r~3uGnxQ44^1pL^7&=960n`r^sg=Q)-A2R(3Y4v8Izu6Uuq2JEc+vo{S195;ME8{ znPMu0EvVSclI|rlHI7{MjgnI{9z?1Q6Ou9Aly;-3aY=jg9=a=#lr^bgw6G+NGLvkM z)RIaJw3?)3lb5t^K$6oNIBLFHrJ^zu4jh{-Y{e`a(wl5xhnlQnbJ@}glQgcHTF6#W zkc?{HSWNRiN7!Dpg{zu6K{DC*j25c8+hJ1eM;t3xsatjNtU+gv7+RoKJHtk^g(5~E zdTBZ!_15laBxJ@bUe8e{rg!TX%DDo|3u`}5k`4@p?1vhe-ZkwLda3Y*4HzwfNLF=i zu$<{R`nUL*$J>J`&p~e9@MeNN|Bb}j>I|gQFAC@le`wPN15q@PH|VhZ4_U*_6i$8G zxepG!^7^G5e^H#m-TF#7SPfJ=^m*3?r5nhrDzt_r=@V*A}zU~;RT0=)`Ju6$R^Tp#> zIJl~;rptCpcz=;pT%Oox;n^?Amo1MOEoSH4;Cq&f(@rsaQXXDXpKfTB{8Fw~?=V!Z ztW*p03$^+(qb69)u2^Z6b4+?kpg`Z?+d1(RttXXJ@^xZk3CUR{+VUVHU`hsJl1JFu z)pKNuOq0y4pgYBcGk@Jwm{Nq6<#NQUiD^_`ylN>6J*9_nk=Cz+DG z8PzAt$M+=3^gJso;*Yy0G&b>B-F z4{|E-q$hBLf@6hhZ3$+%O8Q}Bg=`ec6>Z>fz1-6BwTZ*y$S7j(v~>1tWvS$8GiTm8 zsU^Hj?MbGbn#aiI>hY@8GVL`VF|}0TZApBD1_{_saEYqO(v-|%_9XSqx#P;s$t-Z5 zBXYRtFOn=dCnSLi$Is^thU0T<)E-JVJRE`fplJ?M)ss|ndZ&i|TpX18UYup} zGjSFgQdKwk$rK6Ppuns+>b)MU+1N!tm%mfiqZ`8;d)V4*Xzwz#_lHPrNszCC<4?}% z&L5iBeQ(amEY9(lspUEPoRGeI5y)XHp8|sD;(B%6_33Z2rjwWjK9aefyPTIMts&lkllLm==)O17ln)KkF z%7gqa?DF)qvbCnGvcgIWeSV&I+bug>9y-DXVxE94`+Qlff8FVTvN*_vcDH6L6-7$B zR0}5Zv-I_hcmqGWc1mi+8XJPG$@sE2BlN=A{ks6`rfp!Kb}>c zr`B+jF|QV7!?@~&$gsEGqjm-PAF!&ke9o%QQ){^K@KkQU<(WY(=SIvEHMGZsMP?Ey z@NKa=_`~DnVxaM9ktzADpe4E1sg~6=Pt7JAB zB4m%e;##qK2{I#QE7pKaekbNiM%spwhW1jF+yN!qaqdWY-aZW>Rh_5p9N8)nd`N&i zt3bEL;X)PzTl%=yJ;25?eenyuB4B3G4XMdzWM3}^3v|K|_qtOKjk*OdIY`}PQ@Es~{fi0e;VsV1#3IRoT#3{{7H@z0-Nv!Y7Jt3P2wjVup<;faVr26Mb z6ULJ(YRXVNG%iY-N64C?{a=b4DdjQvrC^j+Ny>7bSSZMoT3|O61dY`TdRsJTn#9MT zIa?{{ZP9)q9oJ%aoZe|Kb%(upPLfp*k=v|O7?S!oUbEy#zC3$_7^)CX)dJ6P^S@*a;eS&HF zzK;pHph0~O7`=+iOv7)i*@f+Nxr<*$EJxg)KvuC)9>>dwWmz+=zQC3q<&GO$CsUeu zr=8sLDTAxZAYEzX&m&`I7YQb^F5ZT2#P%*+-JX52VLWwF`AVw>`BST$*8_@i>3!c17`9o@8(%!JmQT1=Kh3cZx9IE+x2`9@0x%f_=Vk|FAn z0&Pahd*;%J3#%FJ!F9~#Dz33`xbtifz)WJ^sCFm^5_#yFBCYW7{$QA3a4Wu_gwu$jM(p+B5B~;h^-vwDNBQN0wc6R ziEhfcJzAF5sp?P)bD2_Ebt`BvglbW6uuPtK#)K%|*HJ8=P)7&Aen;q>V!UnP{vF}k zh*xKUlEkf(ke`{VbfNnaE{qa<=g^=DI@v{@>h_LbQ9@;rD0jV^!;|n@l;rgG3&mnI zM3cITQ&YRfqbw&SaO(s%1C>#(uJ~NYf{+RD7IMkzQ`^u-vx}*t!#v3HB;%7(u=+3) zVlmCQ_8i5UK3wgiK;Uf-CGXtnF3l>&oc(lw3sDMrBt+91lBF-mY}S0$XWSPTQ4uNz31ok3YK50N3MP;A3>M(qN)}awU!&h&}ngLvElSrX=zba zVv9_dOj}nH8rx{0r1caX4{)@TVXbpuGcy)D<7d;Iepf%6?)JO-*>u0()z794H|h6A zoIGGl9j~Ph*U|%dBGp))NHv@%a*~cqgujKVjHAX8%bPro3%xksh6~Gd;$%yL zdyiTX1)hiU5!1ZKHLHu!KP#^aGaxi`0h%$}=xBY^;vo$t_`?T(3iV>!*^HBLt6Ev3l{;FUtBn(&s&13iTI2EU`}gm$th4 zJj5$6zeFZQo@s4M)Ird;$U1`AJl$;7V1ak^vzGvQ{L&T9ikE_bi1fc-GF2zBtj0`@ zCFa`_#aB2$=D4$>1V{4v4!fUM&jgQa1)qc?pdYwrkwZ}08?P!GlVtRcvsDF;CzTtj zG4$@zVoC3*Rh$}PRcn^3&C`zBoO0qlwK*@`q_bS0!LQu5GK{3~f)rV!7%Z9vD!B*N zV)Pz&8oj^-_1t*LLk_6rqKBe+?v_p`(*l0FZvbv@V%DOnpXKgUGc;ziqUTW_oo1(H z{E==|b7R>X${tfFd5k78^Nnm{r`6vsGO37VR^&y=|i+RVtMgsan9HVtJN7<}wxIXqm=#i(2H?i+EN# zXIvF&R%Ruel{aHUN<&jG?J_-4b!h9CW~F_oIbCpGDCDh^fBk zOqc9vN3%6wq!w>JNb*G1Q7l@-v#OG$HJ-ZkC|-5BatGE#wS0r43&^)O%W|P&_J6@) zIl5~(%06gS=SJ(+mb3ZFTnp45YkkDNFY#(AsoqJgDb+hb&G9Az%~w29FHvCdr6ksI zYO7UhpAQVJmU029r=044Bp{GX%falgZRi@@gzIw(Za1SYHlM1_vyo%@%z30*b`*1J z=PrL;;^l@=yD4IH1{aa8=l)m_~ zdHZXu)za;MX;!KO4%&Y9XCokK^z%;EqG%wmmLwhg?TJQp#tc)8KrY}|0^W*jCsCDv z9kJTQ7l?PF>=ukRFbpdsIqzj;;fv@ueCaqRe)6eO!7;w>}(2>q+_aGC3>c3Dc!zI`WafcOromiCJ>jpQL$i zvfCUjR~?K(B=_@UZ9aLwl$QkSUMAoHc2t8Wkyo^`*CsC|I;JI+Qox9+2i=iz? zbjD$ga2cI2QR$h|ar(pvZ%c3fo-V7C;Q2O~%^e4+m(8d)fjz}po3tkezSN$oxw4*k zB$Ato_oG9ywOBlF*|K;#dBtMY{F5zG>cNCIW}n(nWA^x}{WKoWQwtW)YwsQ_=NT-4 zfBn*Sk)4b!Q3h?)x)qZL>x2?n|MIgm z>NN)kFhd7$GeKK0nBX2w50TZ3ke_7=ud1rnaEYZu(-(-KW4tBB2Ou#e4<~1G$)zn% z98L=C6FnBmFHg{F&UfU7ai%rOMGk8Y(je9xPr)APaCIUsU##$q-Y`$LXTk9tG9)f@ zu8*T;XPBCyj+QHpR;VEjE=@y3E7Q1*4OQ@#=tGo>7?ro-r3(EffEdCxSQX<{F$T}} zYCf~8&7JdS?P9zn@7$FlTAIErpO{*zR?D<;oJCwrIii+vP0LoKCMKCQGjggB<^1!J zv|PDX=VXje*{pwYTUDbG>iU#KukuUIC@sZ%UpFd&YO}UTowa9+*pTs9`I7^BY0yrJ z?CNX@Mo=a#W|*ZUIx~}!ZE)KDq|Q{{nY41CXnowY-UBE7TIXPxFlraSPim%1wJ+Jd zPkII86CBdtaw=ZVFvtx1M2eAGPVO)CPM)pWj*3ysMT!gVQP&>~D(l0rY2W;_CvH6F z;kh@MQ?TOn`T-+c^|e@WS_NaI!4fnM?rIKd!+S$FUfALttc@j)p~OwoQAZBxNLF=&JmY;Wy6Cycd3SWtRL;;Mk}(JPD~ZpRRq5c( zZEC~1_kq0@#2d96OgI7<2 zzbr}n-|J*#bMiN7RsWagq$6fZd@y+MQDUZ&_l~ge#J&j$TXx=y1} zUtt$C+UYw#R{V}hl=h|TwRvA@&BZT?}%L`3ZAa3#M5O(m|xyl zmORE^W=y6gOm5H=E$PZ`NKWLrw5BqG(UaZCMLenbsT%C_d8s~36_H3@5f=T2); z^sy-OeH!su@dP~6 zqTe!82XYemCR^Px$1rjO>{70#-lxs0DH}_YvuLEdK=-2#47aMB=$ojS-ltZTQ&2>V zmIx_2`h`+WE0S#i_O51Nh)x}yN)JLIi)qFq6B4K8?JBwr(hvUd1viCw8OiiNBz^#oJ=S{(C>0k)9dn&hQ&yn5059Rk|OVY}Jk zbR%f^fON_4oMoixB3B+eMLP;y-9<9(GRpN_b(*ey#)Xjue;3~GJ4K7NT5ve)dJHdP zXlBZ0Ttn$umTV51oPQ%t7Gh8)`}v?WUo7%8j4iAGE`z7a@?^3vjOLQ(d$^E%BaSe^7P(E08hp@WK`# zwT)z&t@0Dq;k>RKml#g|YKN;^np~)r8L(LU^D#SFmQX#^k`z2L@C_S#Dp%;pm_h?* zeR6?u=c4tW#OhkdrdmQO?4Zml#h{Zesnvt{mjB(llM7`OYM+8X9rZ%FKwmGnU$bvh zf$Q7jXFsv-#~)nZBCJ0p4W!;98#t;`Y2b3G!Ou>(Vp-cILd&>S-%)zQsfCvP(+!k&x8J!P{!nO)>n#l#yy#CLqvUP zf}`{@dC^Csk}z-4^SrOIW@tLOOR|AT5 zgnJozj-O<`{pU)+Em5DlZ2Z%~fehHs#U<-7usuNnfi{*in7H>Xn z*3N+seC@p0QuQ!fBp3deq&|iYq4D{ZjMDL{FltQt&Vw`WP%_>RFng!Dxq;*7<FYPfygl=<${%QZp6aFEqGmBLC8I;8AicT4Cb#xnkymY{vDdX1fLu}xvb9i8=x>Bi?=d0Pu z!iw$B?zfEa5TBq@p?P#yc&CuKd{_x>h{!u9l|&ybrjLdy<@vxSJ|4rhzkql7M|3sq zs(Yg;@Kkl)(@_frSAR&wH2=O*rC7)nYRoIm>ANrY!Pc|E#Qy8 z)yMSe>u=4;>8s45%b&-cq9&N{%Uu1X4lT#JYwRCTv-EOzzW#=TOe;eM#y94B4XH>i zHccO2(g0m<6*F?R2_X1EfUQ1*(@eG&t#?~>bAG)}t@q*6l#QJmSi5@8p@9SclzIcX zH9BtO9MD-lH>tH(b809z3M$_q(UM^U!f?tOzQN{sm-K2oxK)S0wwH=U*H=2d<5)LR zv%OfU7N4YGGyXBH*DJcBZr>-VHIH`mDxGhn>TN7g1~c#Ta_voD-aL=1HpHl*nQxf5LtO^_<4-=K})I@aFSE_@`E`wf3KLF zCb;+Kb2z!<(?3Wj1={vdY)#$Omc#PgoJ%YjZiSkDn%ryR>raeK563-;?o*5)*B}DD z?&GUudULZHcGpS$ZN`&(O~aE(6}r}EAPom60UwP{dJK38G!oCjK59M?#Q|%H<@5ps zR&LhJLqmU!a`H!~Lci8OHsz~@(``I!Bs7Xyy93ENp3pn^ z#izqL<{o&Tkc5}$}|D4#_2pgx%~nS4_H-;h> zhxE2W&`5tSTNCo5332pld1@^kd%&NQYt>BWff4KaS)Nkn4_Wk1S7=uy;Pu0@q?PR^ z7avho#q^|86XPX}%aanT%*eWX_=lGQIKUy+s( zs3bI}#nCF>+dQtcHd+f~bgd_t*Xz}I&&xhfe%W;SNcjYP7_l4(7!0I&6wc*^+M%lUt2;B_?{4@G zurr!KI&iP<^XTg(gPo)<6T|0x&uDn;Z{uT#m7Dr$2ti*%OgZyRyXwwAoyMmpD6!na z<4HzJ%Y|xL(qxLrle2uQWo7~{`1P#k(C8ai&o%H>q#fTXQ+>SZq!2AkLRam zC?3NrD?|Qpk!IvfJ4`>QN+Uev?L{#kO2}cL>WfZkEu7j|XcUF|`e%(O{5}GXrxA5E zyK*}5+ur=WupSrbf>fk=@rtj=+i7fqfzmt8{Wa?6@&1HJgF9>1h{@K)fBFO0$c3ER z`G1v@Q^aQH#`b#g!Ol!3rx>NvYWkIGI;ZZ&)-t9RpIpKO+f?2mRVDAJ2Xh`lsYAi>vNLSF`pi571FZ%ovsn z)?=LjDb2Q1e`&dNYESYNlSekkB&jCk4I_8J8aD8m{F2rflXSEkao(}vlILx$w3}S@ zsFTi;>r55Px<~bR)tNgdELY8)A}3R19+Xe*kF9I%cWA6kvs2>osa&;yyFA*3GKh*& zlLJhqDg+#q&h+sP{jm;xuj<;Qk8ZE(s$&VrhukRad9e9I>QGfVJg3da+LvMUFF*0= zLPG8}Rt(h*Nv(0rIc>>?xvB_SexPh*i$&Vj0b_Y?u5gkTD)cH}StUS`@)g-~%@k}8 z=2s}?;;)%W@k_mBcD;hBPjnNUT>6r^NO$XJlSJC3c~145@g*HMQD(=N9Fdr9Uy9X> z2!>??OmQ+k*-UAmqr`4wu{X`*^JfXHk&*JP7iD}Q0z&e66y}&b&xMFFKF0c_d8cHo zseKYeQGgN=@`!h$0>4oz=ive}-<+V&qh@mIK3rI4jZiGl9xFH}xOFo@COq9K1v9nW z(eeolg#hXUK69KB$!K?vaZ)y-?N=EIB+{Q5dOKqvJXEFF>AXw&T%GS@*^_Ec9EwJ+ zEFy`LJES&6=%sF-i~UPheh2k?JwBm#hPF@aF`l;LDW;`D-b<19a|v?5BU9tK%ZR;a zna_@l$Y%NVNRm~N{gICp*M0kA;t5EyWXVaAzcuCsO?z=O_^FWcAT0yM9d(?1-RU*- ztJ*Z&ryHk|6^a-vpA__^%t`A@cJK3bjJ>GGk+ii}O}WXtYH~8w1wV)1%W!4lyWj9169mFYrh#S)|a z)9DPBL|G(E&k{^u;Yg{zo73|A=j+kj(}Kt8nRB0KpFl5U673zRx8`c8Z!eRn~n)k4+F{XaFX6k>yo)(sLhUR@(imZP1d zx-fO(NoO8io#P4U=b`*j1)?zQA#a~1|E_s<^|Uugu`ivz)CoR*8h8GxNs{R!<0ahm zhb_#kHD2+A^qB=&d)fSIf%FggtmS8wh_z{Xs>lQWYQAw3i}-ZG8k5S{DJj+U?ai$#X58hM$`u}YET9qQ4J9?T+BHW>o+Ui4G#pEnW}!)R?OUa>Y5bJ-YL|5UA@fBRFSD(1zKSQL&ZiJI6AToOh6?G|OY?S_0& zRN#UDEd|_(cZF!W7}wKq9mI8>5X}b!{gGs!5LZmWXBB?4@Vy(?62egIvykl;C*VeL zWx*F&lEriLxVzvSaoo5ZIAvVYC4YKxZC(}~xVPi#5`DP$7#UsNkaprvY*_|Me?7oH zaD6Q8Hlf>bb%+7v7xA`HndG>{ipbfl5Id$&Vy-H$17Z@Xrt&RtNsIk{*9k6HmCfWbY7sT z-FOC-4b|VWRXeQOyJL*gHOFO3Ve;%-#k67BmqW23=gXhiQL%D!oO4q%xe+0;<0@5R zWz=pr_`c&qc$bsNK}HONFLM4U1)|Si6Q*#_@iPmYYN{I!r?agisMb; zs&Ndn{66UUSBo*EK(yLV6B~y4X_Q8OV{OB#22SgAH&4TVg{bSVQfZ=G&T~5~h?AU$ z{X*6u+4k&uR^a!xo73pM85gOl;E&#eEQQdPqw3A-cm6E2EpgKe##B@etD5G7U+d5(!*rmi#vt~6HihDH&lz@hWTZ)>p*SeJKvbXE|-+rZ4#4c#6wnh~FQ{P6DaTou02?yX;n)ter3N5p1XaR!TnB zZl|-X>E@sZ=b!`U5PJs-fwW>4@+@l6A+B|@?tt%`MophV`lrPRq#4A21nHj^qhcH` zW00iaItAA;F$lLbs43QAd8r9NIb63y>jAVTDz-(|MHz$@+r~Jr<$A5UrOGLxoR);C zxoyE0BbuPmnl40qyT$o<#v+GW;3^`bPsfWBO?yD?5x}+zVk_en7r3%jg}BgPDXA27 zAGE@Jjmsg&l@BrQJ)O!UQ=wxOdxB}6^!bO6=40R}O=80!s4~Y-6M9UP) zcSUM|W<#~4xy(95FP=IhEKa#lALzL-r(AkbzdRSoO(~5~Om0#Sk-ONT z-$joAi(CWf?Q2ab)lj{H z5NB05wCsUu{1j7bn@}^G&cS;dVT%mfdh;=^YfG%3m9GmlbsF`s^#ZhZvI@=@h&MCA z^;(yyuA4fxYTX<1`byo`o@@29Ij(ah?z!`5nW4g;9=|IpobJZwpFHd)zU?`k7L6SeY3`E&;Y@_Is|R0q5C> zsRd#(Hsy6|mqS`v0#&ZvQ%o&$AMS8Y*L*u?AL3^?>e=+BCV;N8@Hm%;)_zY1j5ShK zno^Hr7F8_EoD#9+5KHsu=^btfqz}b5EuDdk{F^e|a9H(r(ryu(M_>z3t}0&I&Q7Ce zE2#G4b6)SPnCXu35vb`@|LZmsPurbySI|HQc@#k>uI~{Q*=y)mAzD&M{_Rc zD2>>QT;3);;vHu9ieKKA=9DaQzrrK33r;6r6>jBXpFdB*ke1It?(P0|Oj-9uPGzv1 zxn^H-dOB;BGVM8?l0P84I!m=&oYnYEaC-1Iq$TV1nGn9vtv!yEonhx#R}YM z1am@4FGzE}BuzGs=TZ+o%qh`nBrU!o{kG~Dm^&-Iy3dX@MzdvhnS-oR-iLgBh`8kR zN^6Q+6OHb&Y}-FuhTiXg-h`_C4i9!#g3sD_s=8*Z{tN0;B?nO@rSYs9C(c+$q*&_J`1W*K#%ear2bY9%Az}k7{WCtHeDt z&B^JuG{shXi6t_mnWc-*@Y@#~?3&RT;JX4mYRUMt8qrWmxwvMHy+pn|9pm+vL;OZu z_FZT3Zf+nudra9G1-9NPemz4suS!<5TrA}L9ma|qE>^whBuWVUfIp4)T#B^N<-9_J zCttF5?oJVUgKaIy`AglG@hnMpOz4?GJzwXap>8||lhbFZ2D1-yJkqh|()al1o*Ja_ z++nU?Rer0oEF0!!e~Mcm=_&7RRQNd!e4n+tZ?W|{HR1Mj;7QOOps(k-X4I$X+2Su4 z_lr>5*}|TkKuvBr8*PB%on`tE>tE>B_}M(0C7RF1+vPd-wh71wQ673Vf#x9etQ^r) zDpj&kS`TpUDOPY>y?5Yn8LIiNtr<1rKf<$KV{D6*Ecr0|GxAn@mRxKtaF0)US+ezH zoccc0gjUikIo11$=9+2O(%L7=xVFr3k6Wa^zs0LjVuSreYW2%%1Z?co&GmB`BHaVN zU-XIr#Mcg=`$6~e4B~z@kJtrj7WYp0+z&tUZw{f_adjgkxrWl+;Cs2XPz>!HQ#W!o z2a4|fh=F42g`}Njoe0+rc?YlFWPt64jpDOd#&MBch%|a@l-@&<~nEE;IeZ1o2fa^i1K5plficp$T z)(t=1aLEDp!xyD)z?2i^Za~e%%5uu#>IRqPwJ6GA2V&~wIoWo8Y6r(O2cKP>6MszI zocGmZ>f(E+dUF&$2dj0-VT4aXyZ0d05j?q* zDbjKskW=c1*vEeO9pDfh+@j@L^eEEsToFQSy@)9VA1N-&5%%AYuzegGX#uL+gK+8P z_tOj6AV0U4OJW%Q`?!~+*xKQ*A93}tY>@pA@cZ7+wW*h%FbFz@ko(#1psHz9@}mej z3O_QoA^df4ntS+p`{BDC@pW))!(8f=QwlKzipqfEqug|{#-LoKC^jB1&|I!JGw+{` zm#eyTmn$u__$Dm?XF!<00nstW)>xG-r80cfcvb8|To>SPH~Q5nq+vJme1PkU=&662 z8+e|ylVq*61*jK+BFXLQ zPCVj%DsCILwB7o*&2ju|ySN$uHZtFKnUN$Qcy&{}xjD&1+pW*nvSuT@H#e^X`8UzFTfW)s1-d!!k(K7=77ib8yZMEhZo35}({GJ6H(Mc}|E#$3 z(%g14qTC?8wB7R5wp*TTrK;T{YjH!~(cIk10aS9DsYLDy?W7W^r~>*9?k!t36+&QuGx=k@&4C{?E=W4U@;HAm(LWyZnEJY5dTF5Khb%y2KOD5ot3f%LDmlLJ zKl2WM_;xBa$?AeWL*>`^_H|b5Dq=sSLN!LR=KXF^0`K)`UcTK{&)xE^-?0@tz2^kK zjZHV-6sP)%JGGHbS5iw@A5L&x-gL{Ok=Ep0bn6JAdR3#syJF`RPA@Vk-GKL3mIe(TRvw9ntDlJ)$nRf?W} zb!*^=1)f4$V47bU4gy@eBweu^pQQ=WKl>9%|c;;A7!USAy70zBXy6NTkAKx9plM@M5w8N2jczZY|!lCUO z!)OXO-Pg3~=9g@G#&$~K_9w@ZVX)gH0@_czzHHMo!YqGTxH%q@b>^_DJBQmmPfD_m zy(%Ud56hbJ8+O5lzJ5 z4>!6e=#F~Rg#M-plBUF_o8G%4ijYZE#vM_W(_7x7a(c^qOex*+AyuLuYV$lP$vXC` z7+nT8FC=iO7q?(a=24W)qcQRSxA*<=aU9ouyL&%&7e9`73sNMdJ8BivGHg-I0XUFH zo3iPMvLOeONC}c52e$Cz4g{nl00SUJIZSkWw{+-~sp*(bAV+qjnrRq^N$8Ym5LZs< zgh`l2YG_AF>4yG%;FfM^M~Ru1ZIP6Y`o8bY>>WrtO+TOXkM?5_c=P7X?>94V-n^Mv z#!@NN&xF8K&Fpt{@dLW}0gEb|YO`ZrIFO^iOxTyeOiMUCs%bDMZOfqm;wI%s9<;ul z#$YNF+?@%!GC?nmz!obBnNxj{8tP)HC4x&ilSquYnR=&73E8!28fEIIiKzyb;!N-* zm#Xv|7HE`32hV{_^~<)i^2Bz65#t8Z(yXH9*FY<^t*CIt z)q$w92b@@onMk7Ra)~xO?p6ONvx7h`LEY{JUuO9GR2zi52!D=x73xOH0Z6smG|F-* zCzT_XpxU`qE=Kb$MICNf3F6Ejfl+;45u>FxfH7DzXmEMqNiRGBeI(UFRsM>_J;A{P z5L3mdj+dOMm#fsv)hJ-m(P+@;r0uv+ed=@Ht8G$k^`pVCKmiMix)5bKNLdc5fiuV* zTx-lM&I=Ws#%4Gkkim~Qm)Ud8iGzZSRqrC7vYTvD&YxQAWZtRT$+NA=p9N1x?X(~ z^=FIa<`OA8k&|ihIvU!7CBsE}8l4u0v`e*?@JEUQRlRo6mNvQE0JlRpP04~~J;xmF z;jvF^C$vi> zZB}DYWAVufopfyFzumT-=J00RwYfE@8%ZK!_%i#JJv#{)oFcZS1WVcR966Yza3Q&f z8_Vu0skyA~6um=+N#yrxm!0+%6gR>gVuZ_)B9=#CB+(iXQ{X^a*cnW?j>g(~lDJC3 zVV+Q^%^D1b0Sj4L|G^7VI+>+Q zjC4{V6qs)GsD!sR;gEzIjJsBh0SUR@??R)!j@LCms-(Z7l0H|`Z)?yt7%e0TDFGU6 z+pMCKAheXSd|1>}DN+$y8tB_>$GI-_I*P5Z9AJ2jBBNI*!8M9Z63H8; zC?vCJJR6jRX5%$icQ7i#T}q4k^?s^v2o9!i2#By&+l=reF_?4}EOynek>-+uZ#{`h z9v!m2u)0bJ{bH9a%41DmNAxCW7Qefb) z8jGhj&ri4MMesEJN^b@`e7jASieT8m?kdG=MKDZ4j38L5LLn1auX776 zHaV}pgg@e9^_5(LK#F?UrS4qfSw^ejQp$!{#{^&@y{=iP@jh1QjlH(^`$@Gnb;LU2 z9SKiFUvreKEHBqlu|1-{j++E2?SC*s3AsDMLHe~aA!`%ZRw*hCFM^a6t+(L}EtN6) zi_>31WueyKa0Y@k98M91R(EvZa+athQ5`=4HP}kDQh!o~4tm3muD}73V_ts>i%2G% z&(f%MW$4kguD;^Bxd!U#so5a4G|;vdv*CHbUegpyN;>R#!-5_2!Ud|wFn2q(xXFPQ z6dpzWC_yeky0=&Tx~l47?4c+_`c;%;wn~aUS}xH-Is~b(ncy{x2q|7gXbRJyS%`G5 zszXbFtL4UNz-!OJN% zwzcdEcC^x9%uxij@mh_@EK*L>;+Cn+c)=wvc-;%Gc)`_FJV|Y&<%zXrSN3PIjI9{C z6McyaBX`qZ zsys>7>SYJgmLpznC+X0r8!7mrRziKLUWzs=q!za}wykb!W3!>Qh8xo~OX}$+e)IBp zih0uJ*>;Y1Le;BY^%^!r!ddD5s|>G2nJ&9dwDGv)I@nEdj1$o`o@i{Hmb~f}X!9K7 z3Kz${Q@z0OWYhxR;lR~t=s^dXtPmKMwIizgtFJ~IDPq7mDfk@27ow~d999H;H>%K} zL_ACMEKMBfnXJB&$bb=Rx2`U&u2_%j*{GC7s=^{O&uL;_o82@lQCP5%r%ymDUMF|b z#)K9^+%EECho5C(bxk@DIu5XKNLc|Y;>@IJ0}OFS>YAH?$;39yoRbMY)1lZ7X&oNU zgrOH6S!>%~c$^|Dq3hs}^2E-YYDJi^j*v80Ov!DC?gTdBDH3r?iILrew1w6i%u1WW zgN-rTj?-oUqAeMtoUw2dna5RVE`y0w8b-?vB9l6? zQTndQ;wF_8XO*pxR4xmXMv`*aoq{>X3)ZBPzLm}9vW^j>7@6Q(p6%pPY`UfR6g%Y= zlWf36cA&C>=s8E$9FlJ)W!B1CyObhAl)P*qpg8FGV0*OCZD;?EHnrOHc|*B`jm4&q z)@L!9fXK~(&64u;irB-rKsX!Nm5UAzb;@RkDW^PM(N+O%Ad3~7JTPNmw83l_nUj1Q zJu{HCbb*83khV}xcr+JKp9!9@Bx-c3Wrv$i(@V##YHMcI$}~tSHrqd|%7dww%_>E8 zK@2jT;&8S!*J_md%ef_7MG`uUve6DotCl9O3Waw%9t z(saEVzmzE#2Mc+yem%|BU=2q)u%d`g&Ug*MOpxQcoJ42$V`b2mDy<_uXs_d;@70ca zwHLe^NwSwP(=gd+p6sBIf=oAon2W(dRhDwVEXoS=4|U>-M_SWCRFL$hwGbEw=yzpW zs7SP{#c=^7y8#P4Ydf-mQ5;=fhqj)ghD5ePYzJUZgot0#y9)Y~**hU!;`6GX(mN@u z6=wlTGl=$DRtnPgR3lPj>t(S5M>AU7@L(&c&5py{{sK*>!sE?>wIeF9cBHjI7E7<+Ff?~&8i9(!24-a-@8m7S;mAzRdX-w{F!EUM+{80o zG>tl&3j$u{f-|B_)>!1!SPiNh>4x1|l$BOCJ}aZ4u2&^xVV zh$py)ueUcM!Su%w2#HQ5hOf^h7;efX7+#Uy*XeyprOv((gt@G}wPop4VpMbHeCW2^ zu5uTjL=3Lo5HYyc95J}2BKF-Fv2R7hKAd*PXs3`%DGQ~v088c&>=7*%ub#A_j%P8R zUvPP_Z7{qcT1JJm!IY5$;s(?4Ez;{qyQ9@ihvT2M!E9$CsdfrQJ}`NON91A(Ci540 z0e?|hzpF2@w0}`H6PBlyuSku8xtpYCw4|z8u%N8tr=zYvt(Jz`qFx$mi_y{mBFA5J z)pScbx|5fPYeL~pUQ(XcMzGA2C5uPT<@QDZY@8fKNK}!f=8T1+GX5UHesi!NjlzlR zBL)*q5n=CC5eILGIM^I?*(Rkdp`25H_MEYZl zmVKO>Ks~ThX+ABB!Gh$(K*m8=jv_i1xPNFP>}fG(9W#m4zNo}hR<)KX1 z&Sq*uvYHZwyx7~IY+^)=cj$UHB)<8x_y}~jOQ#%v#JxeK#iwSz{`=b zthUT0o|lv{+qBlG1#FqJm*=3-zhPNkLfqmf84lj6s zsXJZqu)I6V`u=veEjoCjG_W6&LuJ@JtkP63E7{5?4ufoZ#eT)gCES!4)o}94=d6e^ zjAK*Uix01{+r9b#td6LiiU!jy?NSn?72lp|*cmcx4{f%ItmP{> zH(E*L7>;H+Y4{j3Z0n1WgyQj%@WK-g?9{S7tY1-1CZry_LgFbC@{SO<$>Q|aw#J67 z_zH#!MZ#VYJ}c+Y3aLU6gkouzBm3t1Wp)4MGM|cG(wlkSB`TL1hVd63mo4EHoZ}JXc-WqMA=|FP3MK|I8k-tS2?&Apb}I~b)UX6MigwLK z(gi34(mH`*NL6!fp|RR_g)=*k(@`i6)NwT0TVR_H&td@b@$l6IG!D&@wRQ`YK>24Q z68~`wp7a8*-eNnNT{0>pvSv;FGT25Hib7jpo|Yth?ZaRb0BuPY^}<)bOiT|xC`_lg z?R<2v6GgGORrSlV0MJ^*8*%0$qM=DZppS&dwZ)W6Ow&xlAqkBlTr#TuN{TyU0CG($ zKLflAgz19UD^k<@GPGWWeZ;*KMGN~>%peXcd!4p%6Roh;Ix1mUfFP&%)h{sodW)L0 znfe7m>lY*o1?w01)(Xtp++72a-X3WLAshZ+;aC0{oJX^Hg992jVl;+vhb9k2A#6$w zcSio5z8DU`t#BtWhh63{B-PHAMzEv9l^`BW(Grx>SHM!NafK(^?PLp|;UemZBnh_M z27|PVY!a5KT$c1R>RB4M?Q+@V6VMfQlh=Dxu68|2I8ASFcZyb?thbvWC9~Bv&Lqxr zc+KGZ4!i^%T782yztpVFN4Fwm8)!pap)4TdR7T+-o4$Vv4Y6TcAeVFA&WoG6DRAmt zPduA>t>x{`Z+>LxvGs+ek5ykVHX25}Y8b~1!$?{L$p7#o@9r|<_(GFu+%@#`&&CUt z?)P==U;fj-uD#=T?jHWmpa0$yAN}rU%in%yI-Nm+wwpy!TU|`SXwd)?B{jy`QeV`?FU+_Ip3@#O;^f`isu4AAN02efRJ;TL19g zueN>e?Z5T@w(m~7`pmT}FFo^-{qK1FgK6W+n$Q0C^?%`hZOzYq=qG;rFMn~zL#%E z_b@K6CAv6niT*|n`JPY@*S*Yl#=H2v4PN))t&F^l8RPdlqx@#4$mzTJ?th8D*)Xo| z<#($W4<%01L*@7KOPvzG8`;9|5Vmse@?xRD?}J9TO$Gk0TbbYe6bTzsUxn-CmqU0l zSKxO)BmADHsJ;+4%C9E6xK=&ty^FlL$a5RFay?4iZ)4of9&X1rzHOi9w@f9zpI=h7 z8E2YKEiZ<)^1c009zDJ4wUWG&$aC3J?=7kYTY2=9_|Cn&IqKzp+sZkVnTz9?9W-xD z08E;A3;@J<0w4)s12_OKKnp-CKpQ|iKnh?LKpMaU`1?2Bcq2}KZ=|n(ewh7-zHYJU z|K#&{x7_^ec=5NR0yOIhSO7Z!s%Reowt zz}*152v|#hVi~qICW<*9Oc>y2+&u3@zpRx52gXv;whgkh~R;_D0%s#Ia0TM`p- zN+3S z0lEOX0eS!m0KEWP0JZ|m#1~Kx1A_;Z%$awXJIr0?Zu3!dt$C~Y1Lm8|jpm!pJI%M4 zo#tE3x0!dDo6Nk~WpU;yAzfX4vd4=@PuIKT%0egt3$;DZ1k0>GP-_%Of-z$m~NKnb7>um@lQU=rX- zfTsW|0DA$Z0Hy(E06q*b3or*T53mnlKfu!f2LSMO)A&aKeiYy!z>fj^IKZ<20YD9) z4iEwy0{AGvPXHVS_!z)X0{k<8BLF`I@XrB04saCU697LA@JRsZAn{KD{0zX)0z3!s zX@H*tcpl(00G|c;d4LxHUIh3T0G|Um4)6;A{}SLA0Zst?62RvHei`5-z^?%OD!{J+ zoC5d)z^?=RD}d7gzX9;C0e%x;5#YA~z6kJd0A2$462NZ*{0_hwfG-35F2L^roCWxO zfIk5ELx6Jte+2Mv0sa`^Wq?-z{vE)d0GtQ-3cyzZ{uJOtCTDYw)ILDG+AC4>r9Cbpkk)Tgg7AdFg^tXfJ_Q#UB zL_CQt9Bn0bAmwUc=LiHZP=p~uLiob7pbw;z*WGDQmsD|6H@WgEgD$v=gf9b>0EPi( z04e|n0OkQuRQ({8c@T|5s%i*u7~lxNQGjCr3jogp90xcBa2j9{;3a@F0OtXg(HI{9 zr#V3!zyW9jNCTkJ!8!oNV_c?4asyIr$)+<;MCk;Z7*NicU_0uamDa)I42y|4R(Yll_@!w3YUf+b)xItCYo76%K!4g;LjEM90yMyGcOxERM_ zF#44ndktmb;fvRwNaEr&!zG5xfWZXgKI7L~lTG)V)g9!H1}(aC+n!u;Q#h%wPVnWpUI!f869s4JeRUwvu)in=u4X+wB;up`R9aRW>SXXC^T z3|a?}O(bs*?qGi&Y&xPDjt;J0#mGOdNFkVB!%V4Rh}JfNw-|7>0|?j&jQNf67ht}G zClN3Ra0UQlKRn?i)%g}mVBjNg2%rQoL6e|}Ja`(OQI~D{b`PN=X(s=;P zm|6wcF*WqKea8Xxn5mtH?<~MMfR_Qz1H1}w0f2{5+Dayo-({U}NtZgIkwG1_&?EzR z^NS3wVjS|YyhqQiLwV3T6(g!If-SqabNj)LeuVP0!jz~F0$@7V(XcwWTR%#I%fYBu zFF!ylAQ`g3&D|uduo&{h%$y#aG!oQh1x0~H3aP4Uoa5qK9h|9yGj;Hz4t~_Zk2?5K zzl5T$s210+5GhP+pXO1BgrNZt2XFw|s3IxUD}=}iG3D!!)nTDk*N)0jIGbpYilrj> z81mc=2Y_<2gSs%y{!kB$5K}+o!NwKApbF=8AO>p~DlvtNIr>(OLNJa)jMPsF( zIAlb1$5jtd;t{3V+}g%f4seoVw&~1pu&&Ejr}itnwIgj!-Ub&M=kdrcooQl)2odjk zO09Au=|rlDM3Uu(7{Tz$7`}?pe5T#8B9WX}-$)Ct-GtVsa@Xh1ZZdjuY%qVB$dG&?z(|?s0QAwX0qPyB-=3Ad7LepId3;xF)h62HSi?W zFw{d)oMLnsHf3bxHW)2%QA0*S!JXXJ2qh0J)_6bKf|sP>@ifV$R=n{Gj-<2Hd;GwZ zrg&{&t)WbwedO0q0f?SNJ%VE{9_|Ilyy|n3WT81pmHcUq>P(Llw#uL>vqX3rP7Tiq zNiRtn&_gY9EZk`~__Z?(8kTJn(Y9?4vu%Wt4^dHxMXAIhRU(Pg$Jzijg|BDyr@elg z((_p(HQz$pLBLTdrNZr@`c(&5cwS+cucSY;fE$dV6bH%y<(=XJsxQLmlEq_F+T?R3 zm?0?&;kw|y!;9#~+8Lxsk&FIINH`vEHnE9@cI{L;LI=<{I38Z&3gQ$Vc|g0S=cX?*VGG@L`z;OFzQH0a}$A*+sv&7|0Y_i8vE(k(*1T!2v#xuDXPg zW?02;z_1*`q6He)>3FBY5BwNg8%kI7*n;3Zww=A#WmK|JQ?c*2eeYiVDiaEaE zK#Hcs$5@~k3i^`R*MaixL>NW=LrXv(v35|SUacQj42vm;npeaFLmUGXsc|hJ@ck1- zstw51$=WU{VwdYnx7Bu`hW%Va+?XRxi(}$Cv>#)ahLl{p`~*eKZ0AoxPDz2EJ${z z#CNnE+*i^qJmJdALujXxo(jZc1{6m)r9p4TebaULq};{rZa0nIPvdJCq^(dK7d`Ep zG8iPyX`Jek;}V^#JfON6PdyENElXo3+WqLG2PxeBryhNsM{?~V<%hA|=10}0EeuuG zb=RjYo)#O-=C_eFZ%y1HrAfhMFLC0SJo7qDziqz0;RB@>QI_R?tV|SN?t$YP>nXmx zZ|GGFCq%=N>1CYopc0K|iN3y;12N4(;srn0!Gmv?1w?H*iaoe8_F&Y^g%ts{1@O0) zrxDIKb&(8@)(lHx;;se>EyV*pStv|;y^*a?k#EnN2~&8Xo=_oO|jVg|7 zom{504Wc&+>%^AY$KkNl!%_aA2zvwqmKDNB)O>W85r&uU5K9h^DU6I` zkfQ~j^vilahQbxJ5$tW}xPAJTpKr>w`PDSO?6fkxXt#snUQf#y=5-WX@+fdOVs2CE zr}?Jx63g-#UUTA29IP*;d7&RryH_j)N+1XRDkF|pPql%R7oO8=MSX}^=5!bx##(Y4 zZ<`ueho-xV3hSECU`|s`BQ+jDHLxhPt*G{jxcMk9Ve5siUq>~eDL;Wm@cS)lgR2&T za1;0BfRi^_qMXJmkYZ^sLLb*e$jK$x6I>8ymn;M_3i(a)GUcccE#~n=k#!K4XJl3M z2do}x9aqPbQBw7)*F=R;tJ;M44&dpX4c)AIL;{Y>P&usxmq?&I5wsMeeJU5t&t#Uf zG$DcQ*44h&T*u&=s!woD({!r}Tu!Z^x=1f7Xc!OWK;#W#f^j5HlrRm?3!{qc@KO*x zaXGKkEGs0aXk<|%*L0i(o>IiLFssA*bXXMoIIHj9lw@*=m-!SPXJ&-Q@c|ts45}pI zjQFb(q3VST5q31fo{z8>z+%P@-D$!aj*JUS-g(>n=B+ADTRNN2i9hdZRgmX(!x%) zCUlBc*GZa(2vCn-ta?SQpvv1-R#i#$m5;MrbPqJ_v<5EjfYDtw+()ms>L2koFHIkqOPIy=n z9%j$;T#KtxvtR*f9iqyf3Gdy5=WSVk9C52ow0>53e4fEZ&F8zat-ih@94r72D*Veh zU+6_PNOO*N3rG{Rw@9MhO=&V*6HfCup-Sb%o2L}|N;Y$pm4Wv2=1r>$2-6Q-P)@MbQd=VB zH%tpL9UWR=-_cJijKtvc8CUD(uA|8A>Zb5$SCY~3B8uqHP(W3IwR9_wiiLD8!jCra z+9}3UOs}TZSx&S!&^wKw$}wubj&W;~_d2a|ZBwOg&^8aM7Wrwn)qnwwKdoc&bY3Sy zh2=y|%mKBH?8%EK&x2*P43^dGxhkHk@Px;CG>E29I}%BePK||!Me5YndHi`YQ_J5) zPI!RJnwPTX)k-8nNNvQ);h1qr9OuL@35Q-{&sp)D<@%hIrS>FeFen)evgeF=&S?9I z8`)1>4j-2AVLYFyo#D*RNoMCbd`QBFm^PdOL(WL_sdJHbPK97(~>}>B;*v&W5^*UkXVrofS%zM zJ;OWo#_Y7SDsNhP$BM^BUf!}c2tmI-T9db88_e`|RBr1oHkA#)7^E;|3+j{gJUqec zL3jeTJXVW!tUl=Y)fXF|FJpl{KqO_OVWUynh&8qdNTr8Ku&Bn?ytZ+XPA96%0XC)7 zWC5!k<`Gnp5maem1@>?X$G3=dOd=hl-J23W{KQPMKBjjvvLebN99-mtCne#@sB2G4 z)+b#y&R}DCGM9)#FGb7YM1&1Sp$j~&+GK9EvB;+4FUrbJNRy%_A_q_Dm5GYq_#WCQ z7TH4^@dZLW3?lU|)}lXOxB>Uba#-j1br8&U7!(63t4*WGqSep~Gex4!St?EcQWE3P zM$s_XUUEtjv@2upp^fQ=4U~K&t)W@)1-X=0eXiArbDve8vn<);(Ngl9ErQwNwx^}- z={DLuX=TR3h`_gZ24uNLAt~(hWHrjvURCxsJR?%Iyc6#f{hT#h{vM#X7)*To0H0{#k1BEO?Gk&tbW$Pa8?AVJ z6bEPnXlGTZUcieR7>wAl#BPa?_w=*1q(3DNFHQAL?rN4RZbPczsZlH2vt_>15Fx>0 z+t9DmHvUNs`q}(PyGK|M>POrJO<%9RBN7v83r?FLMY22^#q~ZhE+`r-QdA|>E@9x@ zg9jp;m{lFA$-B5{TIqM;Lz7O5pHkuV9UczJZfciTpAh!#axit-RYCYj7c7lw5V2p| zPKcOzcZp?pmo^XtKAU0r!^y6tY;&iTTgCi!S7QZeyatjZcsv0_x8Ycx^b>t;KsmHe zb`%-~Muw0mkZm8<^_G)X32yAu7pX!R4`G_kJoPJ3wUq^sq%JEQ=bgx8&fz%a=ibpT zdYm*i5ArHUz0Ki1y)5g+QE?WcT*AQ&?Hy@oVOG7Ic3{w4MS_t>oAUEExn7`gCzGCn z0>4#73Vg>BDVKg>* zuw4Qhd`x7XzvpEzpJ&gj;(3)l7sPXcJ+i>nFY-jV!lX+=y2NH*yvBkqFVC_>=NCLE zHqkqq=oMGvsR)ZlSR%rl2y2P3wg_u)qcx4Ij<00Mmo=wSDPrWGUY-O7rqDj2OfpV(3Pk!3pq z0#`j{i#A5#pr;uH9jgh4q4fo}(dyo(Ia(<16(SC-{_ zSB~u3y`hw^Kk>_6p)WMitLzo}ac>C596oJQG+d|Barwka(+9kvc1<6^g(`;?8d885 z!SyN5%jauT)a#D2a3GWok79uwWW|S3H5)3y&d>tYO5pw-z6(Y(>Fb79|Qh-=&>olAMt`s?hS@BLY3nWY0f!s85I@Q$=Abi1tf>ZHM-0JAW z5w+VHUF7IAH1suQa3xRWVd zTJRFXv&_jCIlq$}XOQ6;-FYs1xxwK%#)r5HKI0{Z6C8R1omAvp&oMls`rYe~s#uAz z6A>1%j@b(H2P#=%{1`LvBI75c6sKt%B_rRZDE&l)4Mw30T-!E==@zH4m+r(~nlj=B z(mt|NZx`S_&+t`-7Z`HKlZpxa5+E(`osm+ZvCB~xoTsc49Q!QC<_-}72r=?^k zFN;j#c@Z*$X{FOyMU4p~_JurpLS`5(TAIpz9fo>5(^{oNjzt)cfpCyIi)N^adx7+` z0q=$ftXtkcJ2La&^wfO^#>zAElhacJ6SLD#&zTg@;&`h}qve6=sp-x4md7S5hH_6gcy(#CQ)&6lUG%#-Zy3R_ zX#^i=WVU%%X>^mnYu{*Pa_oo8&)k#GcNg;bDHPe+Ccb=rOTJqW3GeOh?J0EibRi~_ zyX3EXw0CUV_}1}!p{KBAtf#v$($lqd%XqQWQ!W>~dqzjcyGvX0FMn$_x5)6^o$ip#(KvJVFuI=bmd3KwibFy-TASRo}Q7>ZM|FbW8FL?0c23UCR7Re8ki15hX>4j1FVm%cmGaK=_~g_i7LU8OzqdR;@XSnk z?wzG4p6Kc!p}*cVIv$-X`}gminVy}0xIA8-El-W%mFzoAV@p$B_aeXY{KRx=XL)qr zp8Kc9r)T$$M7cgPHm$Pl?luh9G~)Nqm-iaRYSUQtqwk)dpPd}tH(y5CKV}#i(`ZAX z@0qNWx!xQNlzXRV%l(t1vm>*3No)Mvw@(gkdh=iZuzPpz62ssuuY1HA(lWnFnYHa<%M)A9W`^HUw?)|~$YCb{C-C3zT00m(0+!%4Xyt!1V zNZ=c9rcBbYsp*--=xll9DZ4^t@7bJJZkKYqmD@vZWqORm;dUvvTe&^<+`NQ~+ojxY z<@Tt2<{WlMHqTK26I2EWAXfsIkgSxZ_Ejowr8KsAvaoq?m!q(}Mj}eLMtU?-&`7UF zwrFIlMv59iQ9#5gvNJ2b*ZEM@V9{{9(X7jPIETtT0}gN3^N(=6zE@_C(0MLMob45sEcBYpVj1l6{Oa zk5Nkcn~za^`kPNmmPyGlDcL0@v!rB|oO^n5er$r8JULa`JlUm?eHxkU))b9Q7Bod8 zlSNx0iZH7~W{a*u%H!_byuuv8s4#_eYowr&qC#dhg&00kD#hmZjmGxwtHer^`;+uX z4IqZ^P0}Awnkd%vZ0rF2%}rG3Z#GGP2$?GHp)oygk4;bQr-GH+t=xigi{j2I|E%)w zQ~rHL2YtMMa&|s3HbYZ3Q7H+Wo1aZikrW<%(j6O_n;)x;%*`by=O(A-=3U8(Dv{VX zH9CDDF%Qk1(u`M1Nroedxq0!-kzt*Ml!sOBWK_KvvXQdKp!FTy6fBU*$_ z79v`NO=1!Xrb)9=;B2u)V?3BtJdJckSa*aKBCM#f*@#B@X{wP4uEmb)aJQk5rtor+C3GJA0oJB5`rs zQYn@SnB7yEoSTo0kpvpsGoKt|ITITr0W`)!2BUp`inPkrfce_7^j9G;Au_|MLa)Y{dVTW|B{`-U;p%1w{+ZL9c`W6{WPp3cr2lmqsz4dZ;>ZiY*c>U7lJI?&V zcP{@;X{f*LlVASj=Q=+)y6N-fO}W4OvwP-0IDPjw|K`U(^lPim{>(jhW`EMVx4h2Z zd*+jc2R`uCPd@O0qXvJS37WzihOwwriXAuCJ68Nqvy9a3UrZUN-B<2dH2Ytk#uWc=&iL8LsRk$%Uyquj@DctF6~5FaKd0jF zvyjIl{J%Zpe{9}!lbr74IL+U18wC%HcN(ok*YS7K-yHvM)RV@{igIrDZ8-dN8*Wqj z$N2w)o@+{%rxaZZZsrnE<|;~aKYvjR@$vtUSBQ`5e<8nVS(}X#K`C?GxP#L7Q`jC( zi4Shg7|(F6_ZSoSKh1AK^NnAkKlv_Qk+8d!uZw-}BYybQxA=_Lq^kRSxSkKGJSJ5= zbz7(Y(e>TJJeL1+yJYO681qf7{ocIY!n|FX?s^X2jK6Q^bnm8EbNq?2QOfTbYTZ93 z?f=t1e!{>9-%9WL-^Tp@&;N%%{|it{0|XQR000O8*7ytkO zVs&Y3WG_u`Zf`C_Wn*bh7|eZ|5bhfSm@DB7Ng#n>_yU2Dfa5>{Niaz` za*}UizpCn<*;!eTvZ_Nga#l0L)i3xc{9s57~O(haqJFr5fN$Bn-jZa1cQm{(GLue8yE_H$dhI zpfLYXQo(-BIFCf>zs%El@J}A(tCyM*Oj6_y;Q8PN~V&{AZ>eIcJ%6Oxf%FhRWjacH49tGX4ZB6339V~n>qWS zc+TT09@w!Cpkpb3ub15K9unjI?|ufUF?6rLe6p(Pu@GXhFp(pOj1V?N)nWxUQfMPl zLa=TTJtNf`R05A=NVSTQW%Wbg7r3^?>W>fA8o-cP26M{)sHO(uvm5K_YN~`#mC-?j zYJ`^7cKhfVE2YY*F&JOn9%PhnP`gN0v&yJ|aceLs#R82BhHwGl)=(-KuXZV1FihC& zhf%`qA+-xfL9aAY!?ENn?71hX2R%U}=na}dUkcr5_*H}aWEkad_LA<=(!_O}pHbC^u17TI6Of*nYEJ&|48fkCQD(h?%!DqlL<#1u~*S;&2Wz;9S z2eMio`Wj^9ROE)$SS=gTiaL#V0b zT5N({M>`hvy6UhkxTN?adPOj-$0kvHY1X+^OOH*aS|4LA{aDm=)#`1u;B=ActGi3M z11IzghhL9IJQe*!qahEwMzhYrrb3>gRS{3f(4)To>+#ZRWv=`^G!#(^1|!G^7(5jA5o?Km)xMg9MNL`Sl5 z*9NazF#dZAAJ*e;Q3?PP)h+4Qs_(y!zRMVoxLZF=1=drZj zJq-PS3_;+v??dQ+%*OjE1I8*6|GnDZ&=^nlT9ovZPHJPtVmZR~!UL1BV;)*h{>$ZD zOBuAD=dj5Ht=YV0Gg>EB5C;!9i&0fR<_gdeLr{^z7L2ou(%PzFNu0PH#h2hJtqhME z`*A`lw+$~UtreIM^j3~f;s)N)zqgoIBE`1+@P1KuMb!|7d%MZCs<5jx-nkkL-q~?)uF8igP&>-z**bpZ5vf8gGbt>)0 zCG6=4`kD4vgZvyDKwFY#bWx+R(@?6iFj=8MN0IE8D$O= zCQfn_G@(!tZx-|n%cn<}&N1*bKE1SO6x9Ybm--qbHDByzu;YAoyuC$mh7qQ(hSAWj_V5aS1wtdQy>ZcvW1cES zs?=_@Afk&#LVDMk{Ge0}Yvu`pQbiQa^{KHkviEx~^(O0d`-ssIcw{U3(GV=}r?5^{UR)v*68u4J3kRSXf%F>>53 znwkETLuq}cOGjRG=F)h>1h4{?-`gXcPR5D#n zt)z$`0tb1B>XVa^hBqXJ(n8Wld%GOa%o0`mx)37Aucl4kQyB3a$ukkSCxEBiwlUF_ zv5^kJ`6t>Kh~{`P{}eWI&JmFSZ$Oa0`Ft3xH8i?L?vWi?hlbv9J2Dfum~jr1Gq-^c zBdp5knoE#R7$MB!BiK#Xie3Av`vid=H!BVA39)p=?V>L$dUb#)Jn9u$wX}VlrB(Kq znLt>YdODd}z`J+(Hnp(3l6o)G3m@#lhq&;eE_|2^AMV0OxbTx)c+7>5bm8SLywZh_a^Y1jyh84sHAL7D?y6|Bxe7FlA;lfXH;V~CJ(uJ41@Jbgx z%7s_C@Cq9*mwU*~vj555n8K9$?Hq=kVJB$99d?!`9Aal`qPvpnFFGu#0iw&28Yns~ zsS?p`NevPmmsF`w^j(mAF;YHW+zdqNPfvF(KaK9O{PcE@qp%>K#BHDaFZyJlQr?lL1#c)=v=DPZZWqlGaZa!Ao}uEoftib5d6g-SUb%lhWyp zqLSbUJrbYn!l%$eRyw1xa)55FrDR{Mgu{7H_ikAw?u&+?dXg;vAx06YwLFyGs9h6X z_+%G8#l}VcywdjRBo#UaI6j?_<EtY*PU+>vHE7;c;jd}JUni5X z*V>&FWqb`L1SDTb;nF?THWzUcu-2g{;wL-ZxGT96O&6s?o(&KpMXQ;Jonad@T^KV% z7&B8CqX`41i?xXH83J!4Tu7nsrrQP}KEs8R09}>%%P&eEWMfzr%ZSqbxDctrij&cb zS;C6hqRGO#n{78)o=kqq&CJU5mI`A{b^~>yfjLn!IeBw=mDl1p+aH5UvcYT+@;ZsAT^dOJ#V}Fg~p}6m3HDRBX%8V=1X&TLnqOcb01iE$&>!N>J>{4-6yN%SnFRp3} zGQ%szb~y~*W{>TyFziKv(=tGVWG5r1+Iaa5y#`j~Y4t9gWa*_xi*xs-K@R4%#m+cX zW{pGEL4|sRN7-MJJz|uq=@4#a&aR1EQ|ABFkVySap865GS)w|4j-g`>$DAzkggnuj ziLOYZyVfCMG(;sK$Q3!f>`T{>r}k%3iQx*?XvC~25%$XZsY|FT1y2Z2v zGsM}C?j1*OfqY7cXnrhq&5tF{{Gc(>`L*XjcfPmOH9;1;aH{CKm`V8U!|f6$xK)`A z4G-|hc-gtCeXT0|<50_mZc0*$jw#(M9rcD#MuS3HI7@7hqqI^kzAM~oWD!?ZyU212 zS;lZak`%4C4`no_IK!ZX=QR&Zs>>M{F(?7rvAyOM!rA5(ReCh{$Uxq)OY>`gQ3DYoAM=F9;P`ThLlPTq4CXOfU5*+~d?XEiu^_cB@E$tb8JeEjNO zBT^q`&>5`zbQgmTVsCb@B~ICKUW*7{t#*;n>D}w71x%`FX*F=haEmnVohkqxJaGZa zggCBmMLE&jq6odMnz(^p$q>6aZle!N%r#lurMDH`!r#H0e>4H19H&pM;ExjLfNwtGXEK1O^Y zpRKd@P*AVzj79<#EwXaphDc5*hfkA*Rs9jGWh@^tQYedRa`m#~$BzRmtr%jnrO;~O z3t3q-9KePHp@7ry<=XJBBA(Nk_%c?n>Ly?G0nc`DhU*`#L=|gKG%K1jv5*wX)AlOtc+Nx(IX=nAMfy(^ zBQjAy^21|PLBzYL@FsGSAAe;BY;#w?iB8gq;&lS+`b0q6taYna<@RagR%}2u=%v1& zR}&{Vc{S@5oFTtF6IXMY3{IAm!P!i~xl~rB;FP_~4drqKjtPfy3cE${74r2;#h_4* z9j&>mWRYy9mbJ)Gw41rD{HTo=)s$)ikKV9E7noDF`i3P%<=WYFW3ogSk0`CuDY^Ni z?cFF1_FbO_FN6F}#@;`>L|&10ZJlSj@HQ82WpAm@j@p*lQDwijK<0X(-G#Th@D3Ng z)rBWrcq+5Y3jOE}(oI*&Mt7&HUlj^}|J18rL9_cTnLlj8maAM0&d7Ut{ed_yEL(?n=ub1JovaY;WtXls^>%l z6;p#A?`1i(-_hMk4yM4l6=gw>FT*oqyV3GWZ_rn?KHpc)2WzADFu$%cYM(Es?||?S z67)no^wq?~kSAo^PPK85zy)30*z9quaM-vToI~q?{HP*?hM_{fFTgV~U=AB9^cM!y zQA#I6@?AG7T`dOIUL{t=F60rhNEcYz2+mu3#yuI(Ak+gWo!xA$wE?nt(CVsV3R z&7k#Mz8dk?{w7-&2YuI$jIJH5D+douLKlC5L(GupGCbX@I-PHvFL2D-U#VRb-Iar~ z_0j~=MUhPWDN3zQK4{VDY&3>|_XavgiG6hp?htZc4XR@O=)ayPhI3S-E%N2;W-KB3VsPFKd~;d6udH|c}RuD9R&>F|Ag4(q!Q6xfxy;u-P$;s9saf6Wp_|m)a$KgrhgASp6TCH z_#EDM|F+BiZ5RE!g8S3q^l#69(7%p8`xl`8ZI}HklG7MFVx~?;ncH0b`gL}{wts!U z?)X;beeE;&9MN~bcF2D15dFG}`?1yO*SY^ezqa<-FIqczzms3v@sfhQT0|q3mpx)1 zWcO@GUp=$?b=O0geqkO9C-vPgUZZ^CnR8@{n8Bm;f}A6xRab}P%rsQuor&VC;=M$debB{r7K`}+=VGew@4VymKnxwPANv2(MxbERVoxucMmw{=cV?0EBQi3)D>CJ z*)E)vIIpu<5o^JWBCK{1<`oKVlX=2X`5vGF^~dPEtaf$V8v){HyB5#gF1&}g9(noM zBSx?y&+y(ryAjnD>TwtNr2M92LZ_<&Hkmcb3xnM@Dqg;DKNs2e1gX8$%?rSJ36VOF z7<-5zE)UOPlt0!xm(g5uz+OVNqRAnI}6^Rsqp{sQ)(clPB=`qiyQ}c{fXa$9#xlGeqx1 z?&lHg;{J05>jH9u(S1I1_GI`MQnp)usw#x7ebndkIdEuP>6BK^^Nh_*Z5DdTcj9)H z&!#%v9l7Puf0B!$&t=IWEO~}rsd+G4yNHr4U88Tt8>y!or5n_!^h1$m zJxIw*`I_DivL5cspT$D{tHdV@s-Kh^-&bM(J`2ao-dJHC5n7{geW7m{L&DwG#dLd9Kp-aS1CW-N1H&Ncv@GI@Tv-> zDE1IpO!2xN?XBXmxfsN&sjH~x7jp~yB?-Y91Sw2CSR|<9X zaT2RNz`o3p)D6^PL3z8{b)i(6Ba{+peFMa;Dh)LI0J9A7dl5n$JA5N`_(E5QquCu6 zlA3O$X3>?$H%TM5c9Co?Pqap)brbMACQ*i}Zzk0jv3oCK9jS$+;uaEHNat*dE(`57 zVoy42njij-&uTtrAEXd6E}cYQpy9@lx)p2YMCk&oBI?6b;s!P`b{pj<_8EvakYCfm zW-Fg!@GOIz(f#<6aRO&0V{%NQc(5ww;Aw?k2MsYorX!GN62$^Vc$mqx-wBcKcS7D# z`DVx{ERJ#dRmCz@kXcoy@_flK;f%9JdH1vE8?Jw5-z#pqq1zfxypuDhxtoDvl3(B?B zw`gcgE%rUyP#>h-+>E`5c&>`b4-oPCVtAl1%<@N6>mjo4Y_vxoKB{QM+1L^Nm~n*q zf$OS&cn_6Wm~K_@cXg+u4YmAxS9I>8tfAiU^0h>c$sdTAd;^hsgws_1PJ{v>T01DD zYdH2r8b%6@PGxS$V?D~L=VR`C<6yb-ozEEVD;@LbBrh&*Q;(D5o&f$;p2>oXS&KJX zQzVI^)#3u%WLOo}yGU9!V?Uw*`L@%RR9O2oe{(Pe+Z)U6Sz@WAvB8{{HVA*E>Mb`? zPm(({>r7Jflvw|-6bt0jq_mvZ;X|lr9Q%h3q{A;w6s@`h_aMcu8PU`;q#;W2;kTY+ zZCx}vg7IBq1a9+oKQAU$MYrj@fqcgw1r=5KC00CUJu4z7B8$Ee%4lTP6o*ARacc5Z zDq0ot+@^JrcI$gA8v7xwG2twp^?i^Zd6<_brk{2E_;K-_1^r6lc<$E^cpGiUxO;(j z3+qMlP}s`~G}c+E7v&t;q**@%{yc&_@Aqa=wN;w+QdX&(s?L|%*c#L|09$*Rw&;Cg ziyrE1(a~~Ko=?1hxlRydF1FmshiH;$;tdbIlJ;vH7pg(#8>t_QVW5jE>lK019f@^F z;QZ#|Re|%%gx6>~*2=kB1N>p0g`2j)hkl#jV}E9G;I)INvz~g5>hw?j4<%Oi8gZ?& zMqI^fMCx*yxL5N+@jAu(HDaN7#@_Eee2+JQlZXbKIDagI8GU za>%sar`*P%o!f}`q7i>ZZOG>f`LC8m)){=GM+}32hkzGB)S~1oglP@EPcUm=7PAP? z^8(RgKXIC&o!=sH_}jHJmz20r3$#{m%Bbu~pSoW2(p0&@aG%2U-!%!}V+^ z<}Q!nb83IY8`8-{`=%60d^Q8%VI6tP8{n2X;&3pjQd$3>hT?T#UM}4B-38DK3;PDf8dHf`G z_8UilU;0Il3`lzK$v5B~hRaQY{k3u&f{!rg0K=1@KzW*5?+@QBB+jR(!GPlid8QTC1^UA& zL8|qgJmR12BdgkSsi%KtYacBp&I*(q1Ov3EVG!sA#J?70hQOfwx#*?s=${eL5+M6e zMt&F$=uhK_DSpy_oUM9IJ%sv4U@48$T|8O}|1Tew=U$UHiE)~uzspuH65dssLwq_&4N>zdXvlQU?FSy5o?(XOPTryQ}wWh zsc$p27~_Db4z^`AbTYM%%eKHS)_D!L-VOV??1y<&wg)a}s*I@%;XY7M@`2#{FcV9j zVrqq?o`oKy_C|=h3SQ>2-vkBq3R4&73F8dRe0hhJeIHswEPDDYPP69{7k z&moM2e~9qvqW?j7P4Q%1fp&&H2uHyD9D=J68t~f)@$U@&1SOyFy@T+m?|p=?6_L)L z`94PYBi|PY|E~PQ(7-C1tYfy%@VH5Eh>u`@ge!VT^NOC;4F3ej3_l|(2 zF8l+X;B+;Da1pmFI06^7z60dpZ$*l|3TWXnuiz{2cmYE_hWrAp65-V$8o{&ks}aA< z=jl^&9=1zkF%jY4d=sUl0^e3V-oY>pTi4;Qk*Qes6}DlaM(}21CUSN}X_oT(6e)fPPElsI3V7{tkqp$WDZR4(~zubYvgGQvVg`w?{)aAeD3gp^R|$J z5mg`kk;A{caZ~G$%_v8_LGaPYhSp{{-X;%oIfp9$B2CsOd zIM-jtc4N_cgn|B*Ub3^rvzU@XIKMcQPiy@uhdM&Oai|!s8(SS}H0C5{2@2OK5AFl! zy2`w;UzS~r*_sJgOKPj{Bd`5eaDJG(yWdf-&qaOeqJE~I1{vymfpJJ3a@pwvbFk3) zh5Bc#H&{~d7yiTRhslzvSHTRxJV~ur4KoM!Fm*1J8Xn9!pODlYTB#X@_aya+XQbJm zKSUsEX7M;Efig+uGBra|WlXJSY7cyARGTHxF+#MrQJ-j*!sSfuVZRK9-rme^C&S$i^@KScKCH=TnG4HniMpb=DF1urT!`1&k}o2) zzt*ry)Av`k1*77TJ3H;2dchqcv zW3GD3AvV^o_l3C}rjNDj{ja$S;$t)It%i%oX6mhh2c3F*^fmCDtKM4pnXBG9_`+51 z49FX2*He6FKpsC+W?(TJr7bhy6QDUzwx5p<=Pi!3sjF6@$zN9 z*S87Q%CdJod-P4vA7V(MD+QZwS)0%tSzfo~D6Hd|oN z1lyJ(EPFywkfWFSTHzx>nPvJ>ZyV?nMcG5@a9-^*bSFY$=JCY)=$mY*#o<#X6)Pp{ilg~f5dh7To@v$|JC!6 zs*uz<${Vm3#s~_oRurUKB(*m{Wj~vi@%&!+hphLb$V%T{(CPID?8WxhA=PrS-Fma{ zJV>8xTh{8k0RA$AsHN=ac!*>7<%^~UvSfxGZyB$uRn~9}6VAovRgGbFf z;re-*(Yza;msFefqVI0lTQ4YYS=-+ANna$1@i?}%?CkSn5p+LR4%mZ!F0k25vh43EzNqApUv{OC} zpGoSFrud!%bCL8?^sm0>AttGdRq($EnWq4gu;b?#V zA^4l59#RMUUxmEIf+{p_@w@>eC3W26fj41>q~`fO@Do@isY;~Y0!vaaV@$jaXG`iy zq<#wfC3R|^2i}2iNNOxnKZAQEMLEOI;X9Jru2=Zqh4o8pU)T8GgR>lJg8wjFu_WV( zU&0*@HN*cQ)GifNw|~C>6IkX@4gNpC^O9;tt3QLc1ZBR1vGh6QH3+KJf4cv37%QoN zhJTD@izQX2ug9`gf`VK8d-TuYHd&U3G59BVPL@55BlaiwNK)(7b-usAKOHLW|10p- zI>u*vu+{%}D0Qf9{(r!v<#uls_$SPCs6GCF!UicB%)7{c3=)zW9=sf>3njH&xz2wa zez{!Czw69f{GjBl5Y)WT-F`($Gqnfai5&E6%7>D=C;F7%qg1XGlCOlm?>7{Em7w16 zyyiER$5si+kE6fv`<24gqCLtW0?H7ku7&q8l5t5iI1_mgno-WGf z8WREomCcg!BQ;1lEUAw}GXrG`ZpTaw2`vr`QTDDCS|$cp28JpZug&ytsB(*>(#AS0 z`(SOx>fy@AOo@zTxbl}QN?GTY^f7fV_#qw`u7sKTjgNBnla&5K(mYo9DN;k6dRE{h zWula%41T0CPg0b@k5o20l4EqbSyW({Mt6nZ4QKERatR+FAb6pf!4DM@EYSEasecAe zj#8~Z2Ix-snFxT6CqlY0eJVsZi=Tz*??x^4(5>W?Vfq_MKjd~zx&Vcr@E-?l^-$f( z^p{Pb&c!Dg!B^ndMa20#*Zn(}-Wbl49$t`Y!!L5tYuQuK`%nD<#QV6<&yv zq(xV%@Wa9kpKQi+aG`Cj%@_W>(4T2bND5p?wz97#v!w93kP)TJ4ZE~2zVM-&Z@M&` zsM)Pe$O}tEED>(kstHrA7or(Sx4gR-Vgv;~O{ZEE6*^q$^6+rBfl75Q^~ln%(k!A~ z*dzE9!*0K6@Fo4tF?c;U!w&_C|1tBQJb}N4XT+p@75P6XQjtGK&2CGyu1T*7&SV~O ziddcJl!xb(!S;B0PMJKXd_1T8a!&m%(z{;*H~bk7Q!5(#S(kqPstDQa$&RQKXX{sU z+_-xdyW@xAT;&#V*6`e?xsW|a4l7i84}0vm--cox(Bx=}C=$J!9_`&bF<-RVWE(a5I?E@8*z<$~Gw6uk2mmt6Dcy!u5WHKgRxCOdkS-80-VOtJ()GQ4bto`~WP8jzbs>OhapP za%YjvxpR@T70(+5tY;v@VGQ?3&Kji!p@QeJVT=!Bynyj1*@j9GaE-DZ;k3YRZ1+oJ zE<+DI33nFX&-lX#sr3SQxrpAZP76GNkhBd1E&mx93$H{EA$+&!4Y(C34;se&sm!0s z`~v3GF{h3>16j{7hLx5fJR2T;@D`WbX zAZL0wraXzgco^1lUs@Rc9O22xFX_Kf`Ivk9x$>{PCS@(`GB+cn{(i31MYp0Sh||KH zR<7GBapD)iBe~yI(#%gYKh69~h6lK(2Pj8W$V>S=ntvcW&A%|`ONBVclwGW0FT-8z z|Gf-%aj$oAD|;E=%lIz#)qeKXe)hm#=3LF3tC>TZPf>4Voj0l5HAUARsPJiMk@bO`r!#Xgpo5+eI+nTUyU(14(b)kn(LJs z-(-EH`jkFR|0l{X#yontvO-TNbbr^Re3E~Gt}E1TjzaC$D~$yY=sC>!GsjGgLNmQa zxz+bDa>%Pq9G`nwzDc>Y=ylW+QD4WlmK*ON{(R`LUced(6fIx%3{=RUP0C+FZy>y` zsL-=VxvyXx;sLb~OL@MawgH}f%3XLS->2+nSd&9Ag0O~1XBf9zqx{W(8sfsX>wWhl zPFCe8G&=iOGir!VM{U=82=8GyIESDIVU9v0Qm@dvjCy5SK?3dBsp5QR4Fz1;iask5q%07gbD;FcYTDb(_^;~+Rav8!~ z7~Y{=ff_zju0pt0y&mCu^_vJ=8Sh{`t=>j$sdrN=>I2k@%B`puApdffyqYDiN0}-J z!1V|t@Yg^U?k&d=4uwHERZsyZAshn}5Ke(J5YC1cgr_lVfF#1xncocO=hVTOsAslD z+HTiU2#4wfXX{-E%lZ+22E$3P1o_p)J(bYFo6e+9leR+I8BE+N0V_ z+E2Bk+8}+a{tf*J{aO7pz0xzzGslzmoaK1{Ba6O5pj}(T(eXe&?UmT?Fz&7qT;U6# z1foz1MNozw7>=twy>#*P-yR^i3*k7=9)!OOoQLq-B7(IH^BAsSIE!H^!#^qe5bo73 zMR+LxDue?HXun^Re>1`>f_EbPSN?qn-wi#Cu+sMg!hZdzty-PhP31p@@T|~PPU*hD z^9TpBCD$o0B0L&-8R6~W|3SF9nA*Kqe;eV);dc>s_}>rEN1-3F&QB0d3Vjx^`&Asx z?ic+=m4-g@qkk|HL0{4DD)W z5P#PS;V7)9LN(T)zlJmv;YyTJVGT;rm%}3wo`LbELL6o3cacXU+=Q8nicvKNp@r+3 z0v!nH?_*6s*ohg9iu=(NgxxR=OV38AV!kmQ;X%xFRCojr&wf%zae& zCC0D{@52Iwzk)?{lHgp6GKKy~uYh&f;)|GL9fm)GqEsp4l>^F~ibu^+C#f^k1!}wc zp&HP3Xg%89+V`~Aw8Pr3wS0ZHex-i9{#!lAGt_gXNAICK3_mEG=K;Lnc^`nkilOhl z=;sm7Ru4#?-{CzCC-QEH*gVDIEehB?aCo&5f%zS|r#*-KC)QmSKCz9tz7zGO`;gnh zZIobC3_@-x#zh%M#bE5!5FGiTIFl$Fy%<;LW@U>|H}&L6jg1o;t6}QWcvH)4t0mr$ zI4geg2ElAdH#MKRz6NGnt*!Cqbi!&!qJFm3*3p!VClQ~YNTu=7S_4$QzCAsr7M5A! zS(o4%P05|>YoWCk=61F>uODLzjvosP>c-hr&3MM<$2Zi}PK1@oL^>{UG!UjPuv$7> z<0r$yrnY#hqp3MwUk434Q|WkHRsAB^*3{Y=Z){`@bxr9eQJ=8|R=ZU-JKmgVty<8s z0hKkwf~HN0X1jK#W2vfB;_dMy7Ku826x6M3oWHQ4u^D;k#-^5*#tw(q)UvIqy*bVt zi|l}zEiEvo9s9Ns-O=3I*%EIdH+HtQr?PmP;_1ejooS03X-XrfA)d}=kiQeH@nnY6 zgyoH!9J1YZOJkx1Qq5KeBkd`Ir2mvoM4D2mc-w~7olI=%ltl}+A=0)@QfM%wx~+$#~0Y2_()WfZbgXPj9x+e5*6r9G660d}E^B zCT6!QmUxqK%TXs3YDk(Np4Si8Xg7lkxU+W1Cx@69qzJhFpLhj3<}IH^#9N z(y|L^abqgJwUc>hsIU;`qTLd$Pt8nq?2tstE^duu+{FR4r{%=0%~Ek=yDcIx>}spP+Jr)K(C5vUjvMrkIx>&$Go+IO~DohiXYFZAMY-KCb5 z79_7gu!2_QWjhg@)oL}L$yl0z+&)g2Pm4O5ak|ZFN@XULi`Ccc%aU~%+$j)&ZO0xg zwmLdn38{;>#?#W|6Ia%m>2xx&p_An{bZ**2O=Wl}z9NxIWbtOoWp!C1?Pf1)O5zyK zP2!kuw~}XO3g*}=>4_>RT2{o9eHYTEk!)+?9kulYskyC9n^IYZV!v2;X}q;*2Vm}wkDd|UEIaEkhINACYyFSx+1Kha?h^>G}ooTTGW$5f+%<$#lE^kkyGt6aHx``JV zp^Cr0XOz-~2C?Ha&Etd{bSCbYP4U>6BCKB6h2dvU>SdcT)>=?uuUTFthl@&hW#m@T z6p6HOs1nvp!Ab~uVqQ~fGf#a+s5j_7!DJ8cI@q|`#h?{NFvNb@n6}Q0w+l|Q@J3@N zx;1hAq8z+Qt-Re$cpqrmiG-UY#&wcyjZS@fAh5qzQ!jG+VSH7`&tj zl-q&D@i=k`%#ZI#;GRXR7;j#^RxiPGC3mwEZj!w`v$eHX`d8J0tc9Hj$du*DR_Mfk z91Ll6d>gZA36Ui40umQnkxgX8>v5cUkQi}t(kj-<6wr{(Y~5txinF;5-O(v(vi4M` zY{sFQZKOUmFVWHxZ_i4^+T)whvyF*V<7QDvnwHThiw!ZJZfe0m791yynzd6fI2_o) zi*Rx$+F?OrN21-{ghX~~Z$pxDHX>K4o2JdES)dD=wpd9S>ZrLrL$pyz<2IY3B8ReP z5w5nbB@XOt<%9yB}auW-!bUm(o z@iq+Ic*~p}&G8Pw$5?W*%?vv`o5}F&+i{sowBTGxvelWAL_1EI3^_Bosgv5uaO9r3 z%mP}O@j)w%JYG9OeJ|mb&ek-=q3{caF2uyNvLnbY?nPe4=cr!fV)I9 z=D=Pkm6RpG}2d8NWtt2HGO=+C6NwJvq!KbB)hR{AV_gcw#|HOpE zWu$!o6{~4OJh?4_?yquNoNd1=;3UIwv@Ib0D#`8QF{fS1(wZa;hpJ`)`GI;9^pvx! zF4459-Abhs%_$5RKEG15rCbY*)k(Bmija}w!IPUx%1O)lxR%PCTT{Jv%z84->aaWC zySTS=T<4UO+zeAPgTvjFPH{rSUR4Cu`$#3#xDQY%S6-aqk$bZ_e0kwMWu@#bJj2+Q zRU|I}XoX0*H+09fl3IzURBL<6K8&R7t(~%cm%+jWiMl%{S($D)mPyJv$fN|_WT#U$ zV>zWJvs;@wQ%H0Y(bz00JD0P)i%V{*&rPsuaWc_{i|MvZIVM}3Xw=TC*~y(9Y5M;c z?%2H3Ew|AfNSxsEUM;YV3^B=0^_o!h|5q#)7D_32tSFO|6sK<+1WrOcW-KJJ##Zs1 zv$c~Raoz}VfaI3)E=`OE~7t8DKGc8&olxijHpOzw1XPrRVYj1)!^S}HDj80W4y ziK+}o7mZIh$-&duE-7;A%w}5Q!Q!h389n`ZyY#~dWpvuydeMoggvkxMYZC@q0dL<7al2hM~iDsvp!<&r6 zDf1HJC0u6{^{(dl7QjXFWXO=2VdgE0d2%-O;x=b!4g+X(A_7lJq8gpTIr1jVO5m14 zQ;n{6#nRJ@x1ebUnwG?v!*wvpi4|K@Cxc6x;gFPX*ti{lboQi2hj_S-7pOjYW>#eK z$l!r1i`Qz`!d)xvT5B@2vsYzUBC0ZUc7$a3bl)K;4lap0@sSa94TxY`=}gw0$+y4q zK9&a`gB^jhHKfo5*0%UU`adM!u$^WJPAra?BtFskatmsS?+}L<#?Z-BLpULemAQ8p zRj8|30@Pc<;5i{sSI-2awJGHsFcTS$>-svwq^lxHFSBTm;Y$X@#nY99&9Yi{W~X1w z!Br&PlxR<#7T@``i?(wyp1I%e*!dsiU{&skR>jNre_czQytrm&6Ue;f5M)YctRiC2c&Z6X;whpA|XIum9gf`d! z7PLYcY=i_p3Ka`m1VfMwt}L#vzGV0wvm!?t*IQ#^(m; zWPNei0UZdNk&2^6lBhumNc`W^TqWy&eG9cxatyUJdNyiocY2sasV0_7^=Sb#e3fPE zr41(`-h!p^EYG!}R$P10{xa?XZkDX26}2f{i%`!-=A~g7mT! z#M%vLgT;~3yPlBGl>fVSP=4g;Fq22VonytqR#JVmfRbYxxHO4nahNM(X%5y)BX1{4 z#(HTV2{2_jmY>P`w{z@Mj8k;C^EgoKQajCZTtsV=Q3j*EzIWXe)@#>fhc@@8222A*=f*+9}R$8uv7mLR{@u;Ip5zxI@;4KWVR?YAXFRF_`L@~;g2qLJ= zEc5#OW?`ra>oKfjxY#t2nV>q@T8W2rF^qs|mI28`z!23?AVU371zjf|i~T4Tj;qw1 zmk?A%EL193j&>x%CE)0AMS=MSNt zN5UQpH0y3jhm*Ap&N!}I*;15lNL`Kno_VsrTsMF&M0Xn56<@H|tB)%np@;?$Ww z=J-v=Q;U6Gon#gx$Ez_GU`|PRG5$w>EJ0WJy$15o=6R+;6@#pM2FcGbbuX5nUkoqk z!QjAw0}=Poka-Nyh{59&8Y>~$Lsfl6IwpL=snRcbK9G5oK{8{~kCsl@kq{DN(YFpPOHesILSSQa$dNulbJP_-GV zM(fdhujJuS<4}3o3*i|0NgWvU`b0}5tWl0zzCS!a*XtFiNvd2_xYA99rkVy1Ul1Q9 zL6aKm*{6ip3ftDQ|AG`lYYEIFQ0Mom?7+3*HWA8eDR@wW8jj(_L_e4m`=p?fd>*cp zS}WO^m0~!m#bav3>qB06v5=?Es3taxPXo1vd#*v{LFt%q&jFkdp>;v89_slP24Bye zCE=cf=s_e6S_69SRSjG+aFnje!A4)zkQ45C16dgE#gS@N9i$8bE*XSEZwyilzlt(u zp4Sjg5BEH7vQF$qkmqR6lL|3ygyMZZjh|$^=re2#T|hR5Q5UMf|H$3gxt@b$T&U-J zx`B8`=|Nk^!4O4q&$EiCrlP2i)&k_X(Gd2) zfkECtxaV@)IJ3n0A4#t@$(VaH#=MB5gX(i>bh*99@js_;kK0x}j^m-yQj7ysMuyzW z^}c03JiT#u=xzUGbMb569r)Ulub0MSbuX4U|I|F1yB+M9Rl zV_R!at=abXpZxKhDc>En{?qq<(0Km8Zi*j0x%G_!ufB5o?F}C-8S~NuYvE z{N&1(02~xlbO_Ywb_B%!0di|7+-o z-_6mFXE8*xOqE-jFn5n87jete`=L&ZulM0cr1P&Yz7Jzlvc%I8EZFT;Pb#n3X% zDDmhReKFPWP=&o%Sf^8H6StDEsmPj-azSb3TBO&K89ec&qH0-KDe0-UfMk$W;bQzZ zkfP`spJC5WWUX?j{YdQ~feUjD_iW@{yJR2+QP8B#nzl&ZkI^#>d2bFcE-v%oB(I}& z3VVRP!Y<$%yVvxU;h+Q&?J;nx!-bP3MK~w4j-H`);WiK8wim>G4`FDXK@=|7*vc@} zjP9pJm)k<^j8luat24fsqB}^88Ejs@7aIvLFin2Wp(i#^D-<`58@`7hs=v&uhy_`t z-&!(REVPUJYlic=Q#o7-_YJbRjCAue$D}=*dc;!sy#BB`xY-e$h#Kum^H^pcnqvlW z)n;lAOD!{40v9fw9wnXyN@Ry8+V$@o=Go?TL2mpKZgoFu?T5XxSL@7b zo{xoM^Sjf>Rv)A$5z91rrzk(j`fkN2GHI*!(UWH+#}#^2kAVPnS`32t&qN}$jyS_S zF`hCpo-8q*Cdkew6hkz|A!>rj*fK0C@nC(GC1VINE=azN8I^=qvS>A-#f(lh6%c>E zXb|lV%hc$~WK+jN*UQ*to0Hb|6t2he4Yy!!2;(aB6_RX+O(5DKf|B+^N(-;a#O=k&%0^KDC5%?X5agbrn4WNKYP&? zc~jPJIA_pvs}>!8efd=jJ+EzUxpvW|A6B>g^5{3eEV=ZQ3txVA+j9rIFZ>|mk#<%QpQe$a1rAG++!Epu`X%$oK};>TNG9=i6Yp^p0-->+HvR}O{%^UH#5a!DN zCy{6MPmhrvztm?xr%OGQkutYZmrOJd(>)I&RL>Iu)nLIM#3s?nc9wEoqE2%A^CQ`*RpRszP`;WgsmXLaw7~z zJ@Zj!6Kj~ww=z4q7n@)+YKJ~}WpFS4t7UIYl=pl@)i8A`wo!&-P4~A6*@uN}?;@!q zA?>yM-2PwNJ)Zxr=wj4IcS4ze6(-+Dwn-wE}4d%Q1yPv&|vd)=p&{YQ2GKk@Uh z_@6aWAK2ms`KHBEKK&|v+V000110RR{P003fjX>4RK zO>b^*E<2Y~WMVF4Y;5ek2Y3|6wk}%J-P1D~#hKB}2muNR!7$1aL5K_@M}fcs zY!e;8HiIQ>41)k;<4AD8iR}yyILGaXBhC?=wgVVvwsYLZ3EuiwRrj<2pY3zcJ@>xv zz2k55cm1nYRjpbTR&`Ie_Sk9X30(+b(7*lrg}7hH{|1VG|KCdbmy!QqhPWr?rNaAN zV_qt3Ja%47!NTVFG0n41D3~*A!Gidrg4stEG@rDfVBUfhT?J5^O%pEALXj4C`zY@2 zR*Jhrad&rz;>C-*ySuwQyCR_O+ZR(X{8|5eaG$FOou_sNo7eE*WW`VsG^k8p=Uy0g6> z70YLauBS*^`OK-X=JykueKJ!g<4`HXP82jZhgieq4R;){50E4#r5@%mV_#YF{I|6Y z2Ox6nS`4(yaE#KyK~jFHM59GG@)H0JLu=K%S1uF)e?4+^W4DY<&tc#dHE_tw{zTK0 zB&Rd$Ku3+IQo9u`J5r%U!LDfaD`tWon&5cVmJKPYE)%mE7fDD4pVQ#aP+ldA0X%(V ziY7_~uD^@T!)iB?>j_>9{631PDGh`EK^xzo>G3qB@?*~#{IE&-M)w)l_O6Wi$6|12 z>>KzJx8n2Dj+xgO7-9z7UYbaH--`e3S|t)VUN=R^FQlZ3G-l;3VlUiUhH4|!nG|i? z_0eK~EhL@9a1?tTW+GPz zFAMHiemi;V-BZ8)VzXxVY7fGzL^@#Q+0kqMF3k*0-cAoHYHrM2 z1-j_a=?z4Gq2COW`4c8MzH&(;j!h-S2=4 z$Jq__OAiFWoxIkf*~@DmZg|zE&l_Mx=`Pc4j8d2A8ATiVqdT9s#rBidJ^RZ>j~A&a zhmk%1OZ3LW@wXnq>Oh&88Kgbo=s3k?xxv+V#wb*iQuEQT`0Yqgj8Ienz`_J9?Qx) zJt*vZFs9%f70)#-0me*^V}~Hc)}xx5;Yg`dz*eETx5Eg-j;SxQ`XU>#U9pt(u3u0d zGm#u4{{F+0DmVOspH%PQs!T)$TJBqV0{?lnbLwYcUYpFC@6zOu zU7KXzZ`D%wh$S}dBrk5pZb~AREqPhG3AG|g&k`$C3dV4}+G{tJpbLN3hy#llT(~0_ zwlU0`wTndf9R%Z*g6my1eo!mC$V$(GxiRAke`qfjd-*H+!ceJ%&BJ_Jm`mu zrRNaeW<)&cI_)Ymz^zef?^@dBn{|M??YI7N^@@-*>hmi(}~kA5LtzJBvq6jN7R-}ke~GL+6K~ub&F#XmR*+nYWxlnVbuEh zG9lgdF`_8p0)xsdo~>z7jxN3K7ENMM#TBf|0<&Is;w;!xBwv%LZeG6T>8-4HUfx{n zxC(S;pK8(6=Q(J87#O0b zU{{~L&3uCM5<5=Rd+gzJ~BX)BMC_9y}q5$(3@5u0SHCQ~I}wVH69}siS$7RQrY) zzpfable{g|Tl*kMVO6^5TU{#CoLXN8LEf$O#J%+yzy?-SU{#i6=3`v@{7?m#Uc;yF zmcr$7@P^LEmlQ3VhBv%blJT0AYv0A|jZ#S5J4P-b=vF)Z z9mT4n@D3j_&35FtWTEtI;4LKg<-W215Iw6~F7om4TJ3&lDh0B`EqIMQ)$_@xKUC$4 z{xji!ZBj`0zZ_XVr+)3h-|rB(maUg+7sU1b4|W`aS`C;qoU*&`pAN@Np39gx?1^!7 zA)x*UGwl$#a~t%MeJ)0M-+5Mf>chB{_bP|Ur&Lnjbx!Jl&AxBal}=5m6uTh_+aPaf zztlu_V+j>m>GKryXI%E>&yGVfb7fi!v56!BMbmGhItAx=b|do(zY=iPrkAXfR?D?WhEibDzRL= zR?>|YOBP95Nu~0nHfiPY+kfKUF?!K4dXKTN`yAWb9mtOSsO~?FJHT$Ba3{%?CO$JJ z$v{RNhM6+w<$^ov(iH-c3tRg!VJLY42}u&&PLbg~j<4UhN?|XKvXgisBqoNDr)}o7 zp=l7hbDc`V`%SE!_n|K5F@}XJ3 zHlsb9cSXToc*E*R{FpD@!Ghr?j|>oneJD<(t=$4-t|9ZE}2jbhe}}zhYVqCG+nuoA_&f z<74kUz8Ong^QmbPyNGhK9&P*59XXNBls<+d;qjY#t~u-7*N!TR)2~}_*DP#-n}bp{ zpFDgCpO<*cqj=B)BD1w$=(y;}pE)|?FEDb@*{qvS`a9Qjk?ihri4 z_#2-~xaxG=+BuhlvVUep2t`GPo0K!Dw)2}Y6=+gC>*{1v6+>W7hjL4!4-|=-yA5qp zNPj`1f~{NbpuH#mc68;2&#&T6H-_K*_kcI9$NG-(*pRA>?>@?r9XF)R%++;a)Imn~ z4}&kW2UggNvvp9~@~9klgm?!kjN zf1WE+vch%g*xBRvB!4}{ZBP8Wd{;{Q5I#$lJ;j(_cvU#7u3qg{E;jaeKBQhFyA3!` z&3`@v#k++eZXdf~pIdj18Y8}n6Z6+^{r%D83DoaY+80u0 zp51kx6?C4NEPc^hDy1+tw}wE$@fHi+N|AN`x&Q1=ud}}rU+W#^kpz&wh_7ZF4V~_> zqdmznrJ8(!{VOKeL#X%h>55F_cb|Hn3zrPFK(0DuRF@sVI&pv=`=IPYl~c`O3^1D4RX*Zf}rU~KY9ezNQdu~x650p7?1R}x^!QY zo;8K<-%M><&iJhkA2QaQN!r>#z{0@LqJi(>>DK{H7>Rl5a@sVK!uT7;OENd?+WeAn z7om4^26zFXss3=YMD$ipA^|PMHwY#f+40mCx^kP`3L0GeHjChw`d`j>JlT}K%5(?x z@(y!H1%%4kOsq>KBF7D`LTf4tnrfik6luE)m zRFkZXuQaX-vWyjdE}RCmddCM#npMqNQKba&kA`Jsl1&;hs4eBJ+A;hOw<#PzcfPd) zi$<{trDw~v7+qi3gHvf_%a_Tm($RtNla;_FGrr17M?Rq^Sp$BebV$=@gQXsI`ITQ& zP8!Zwb1C2IsdwE7(-uP{Zz(s#zMb`gHDx6IK@wpi;0D{YS`hOUaMBT7G2 z?O~W4X`8O2D}q5(@zL|!PaT$st3;@6SGJVd9XLaBV1^&Sv>&;X!8#&0+f-ov__1^9 zIJ2b+XVI}Q0~DA=rEGNeNL&1JbIG^-)NcvpW+&-wch2?DGnk>_Wm=8J2=J$-l|eZ} z(QXiwR#!;@LhSD?&spcO2y0EH%|_mYDP)U6VW7FF#Fl^9_R&fz?6PG(;@s=XU6l5(C9W9@+0y{I}|0-?iPrquNpQR@zUwchF z_8z^TBXoT1iYBi+&Hnc~gZCQBs$>!P-P)kQ=WB0C=4t)7q{Zs!s~e=^1D`)>>(>#0 zS7`>TthI7+az)7D@~-}b$Dhn~I#)TmJs{Zd#(~$h=l1Z1 zI7*SdP_n-*>zjG!H*?cq{4KOC3p5q^m*MEwDqeo=n>sIJ6y+Aed!{vIi|eN!q%l0& zoYzYaqB^9x#v<;T-cJiN!kaM`Wa4P5m|0h#w1)670EpbT^?=h$L0_}9aA zo;o_gPMG_Wh{W=mv>U`QtwO>~E#IX@^|qp>Y5}q?@J;i^%?WrRVr0$bE;mzJ+X$d(9vv&b%_@DxH)a1 zT0CeFo$0zTamFDkiP77?-&LSeBG8(VC^6$e+`B0>$s**q3NOm?>5Jsv;Y=EFl=SeG zP^uqR*Lds*{WqhwL3Q4Y%tPDL@<(+U*=-ErNX5>fJgnU583fuhg?zE!NQI?kFLbS* zv9|R6USxxt6zr9J+_lA`Kc}^YK|O@N?wu_>2|Fp}I1`+y6(=^j^(fq%71To1Y=Y{P zu~Lu}uE`<~Ywt*{;`HN=rs>9h!d^HNDTJb=$Lyp68`Tt}61lq_gwO;&t?!D;0J=>S z0{8wpy;+B{1b;a3w=f2qF#6n|RpCa<4oH>fg6=>%Xc3vXACn3$MT#Cpn*8$?Jo6TO z^A^1G7X0&vJoATq^EOpYW(ywDnac#$B+A~|pft108l);Xa!Lj8jo#eB%?C8nI9SYRD$JI_)p{|`!m^F&vpGeluQeS zlTYL6?e~NmrCSb;i;}V96{sTrK4mP?X5gn!U^LGx=ta_m`h9_RqcC6{v`CA&_{-Yy zwjq@Wt!{6sS}09eZZB3~p>1ONwX0Mq>Imt0s8 zsGCIL9~{T1L&yZJ6wyDcrXQ^_QV!opXtd!2u;XrS=H6hAGZ2atiDDz0?Uq^byO6ET zkL_H%^rM|p-R*>ajk0&bLH4YVBbRp5;_a&K*ZJJ)N z82sO_@DD$ZMo@iu2&^f9u`&1Pbb;KAFLNSmon*SwmEV8#w(e7?bhc1{cC#**p9b{y zxN4h00~{5tHx5{-@ro6RLUSpC=8~0v{zAqDw|6T`r)tw}9_x|ypDVJ1R{kJq%p0N* z#ZcRd9-l?5gkRA_ImloAEem}&%Fq@0&}DkM{4OI5-kuKVl(Ii)J#7rHX%_xLh0ydE zfAz-$fYEvE!7FlIyRkzJncsi)$qi~O8>R2#@6tEH81B3{tVqPl!k^FlR%!$MUU;vDXfz-_;(@rLL$ z8Hg=hR}K+u_=oII=BvW#2Us_yQxuao{miJK-vnAy#bgUtOLM07$IiZ{Pss;JbY(s7 zD8^}S?-n9v`)V$#`o(|_xhJDCE2H<`{(&qu(dHf}2!FIlZ7S}7D=w~Pkc1Zg1sw3a z6$Amv|G!v_SJNPA2sn^eSZ1y3mAKc&`5mdWs z^y6 z-Q8K5^xNgbPB)l?mM;RMc4D`z_<&}2J#lGC?!I(qb7@Sirtzje!FzGGi8bv)(LuE? zsjblvA%G9pbjIedH#ThwF>0mQCKGNB?Uho=>;^OM)K^mm8yWBaOn_?C>E`GG60rDQ zi+Eia>4BP_y6y4{LFp2#D~B^ljlUH9f$--?nsY^0)o-7ib{S(a%RQfRB&}&|5lwkB zXPmimlWn)aGct8+R$@4Qu-q2)B8;v1^!`hN0oJUwydTZ}!o5s*C}q>|`<#l{nafyH z-w{NcJ?6x|irt6iNNztMKwk5$8gM24>#~)YPr7PIZ=oJQEOO$(WDnxSDUQ^b8k6<$WtbU1S@iP30UpodwUzvxU)Yqu4nA6^zf z7GT+PG8zQ)HvWAQ2xngihf88D*Le8)isI7$r`8|TYfwX7+xEAn+fvZ%rKwJP*!lEs zFXfP{S6)YIXzN!NzhsTtGG?38G)sY|F=9rsNs^f2HkG#fA_vD4vVJCmV4%)v$x&z# zx&pnlN9I<{wRNg@6jp73zu6m3x(H@riY>})wjZn>5O+-^+o9ZPXCLDtHN8*uZ%I>v z9AL8nh5L6-lBb7&8Q9k0jwG2Tj%&eddJDIBam{PpHa5o-m5#LL=9uL5`M`!|?(Ph} z`ggNO#HO&0>v4a<a21D!V20+V8fU(sR$ z@Q_Q&=fjQ_b-0=R1t7Ci&szo_F);QO4iP%~<<>}^q-%sZ)3Cok z%NoBk^ahx)Y@-?;=II9f5td6>pAcu)d7`HjPTw#6Xc((XeJdYFJ5o&U_3#lV1BCPS zq-s`bU0HLX>H-ePG+fS2yG|room0qf)-B-Jy||RtlLE))^A-7$Z+wtYf`csSR<`x- ztC^}AGdzGE9nG5Fm}9@+1WZry zVA}>7G(^*p7n3dQ;O%2U;+A2w4Dw%K~L%>&<-X73_S82Qf{bl(eWYF_zd1ZJO(m9GMy7LPAwAGgg|8W~6 z`-XnJGT5jC8<9PIY z%B1aK{aTvB(0b3%TnQwX3ODhIna}2Su(8it;ZIt5?*786eWOY)=sjoObcVH=(?vU( zvO1KTU>HRA7+&%zd*&Q*hu82ILjfXqM^nVCFsGUS+LAL%zY>B0;jKC=h`#0gvQYO1 zNVp!bS?7Gj-=bN_E-B`hBX3xg#!zUOlGe^PZBMLnOi1qF%MZ$`SU=_V1Jcot(f~dS z%eVT2q*{+*-8Bgw)-!)myF}J$PjWH|VBTosOKbXx+Kf*2LN1H#?`304(e0=50_;0x zd)F+0h#4-P-+WY^*KJfno3XO&k&wm$l7UIHw8}ZP6#I9S)T#~a35B%EVPYoZwrfu* zn@P99Hb4N5Q>UbO2ElQNTO;Qendf}%!v>YV~;IDqv)K4eVlUT$5bf4U$nUVwg zm~u<-8M$|(gHaQY(HP_Wu|&n!O%%+b&jXRste=hsNAMdo2tnifFwTvM8@m*(eB*Za zIU;-RHsN&)^NXWLZNc1oUtehJ&&*Jc1@TmNW8GSnV!J>wu=a)f`sF|9>CG6>z;+Q6jTyo$>jHWlu=-0o zSiIvZeE;Sh?2`8&J)Ac%%?7DHId6Xm4TRtE_eOV|*|x9Qv(AZ6aBiXs z)cPHAcP9nA%$Q~Pth{f%T`P$xYea(zoLn2Tq`h4+t@8(aH^RNG`4q>NJy2dA+R1`G znBqwlcfEW#bR>4w4SlZ-=Cw3uXpQg=Zwz3sJOx#Cs4#{RK7ms%@i$ecZ#+JuHC`U0-hO^H7B+tkin$09~*8@Q^-cM>=I zZ%YM0+lWv6MAZChLde;To!f3LLEq!Bv{C)oq&~@_Exc3NiJjXtaTb*)DNyL+G5`PSfhTZ+BkwAUv`5or41EbcHl212q_lD z_mQUdj(2x-_y@kQJ=XYRps2z*f+t@(Ew>(b=y#umFYQ2Sd#41Q?4d1Jku&)fJBJPf z>IbFGTXLV;dx5@J*JBM2Pr{gyf!m?^*tI`h3*Hq%g>5CMd`s~wYmHAxA z{wyP2U5Y}mo%nuvS9eSFh+wqNd6oU>bjAdKO` z&V_QE1+WP%^R6fNl^J8;Ov~eGo|G?9?}R0C)90T31dxAhY1Mg^VXECShLDaMzR-@0 zzuoEMr>`IkaQ1%wYmJc5)^0Dd=(l2>V!-2Pfyc+dUVocD7f=Eiu7>6dy04z#`2M3l z_a>o3(<2xbl*|A5mD08%rH|X_m6u@}$DN+`B$!TToBM~VmV}-Bh)a^o{^7D7>NQbu z=5OcfSCXL7=&wtZqv#R)V}kV!vjEA+ zg*MH>o?!FW>+`AB^(X1r*E;Z)2qyA}&Kk>;NO8FG0kxM7A-p01=V~Z5`>*%x!Nkr~ z&6E|jWwpDoA;ws00ryZe@ySrn?3(owCGYuy125#*euvxLdG1i2EzySY#E^Q~cjB>v zokYoHu$X9<3&L)2+^E4y{3Xo%EYbZ@Gn~qm@?C8W0s29&FwNB~j__0H(QmOpy$!P~ zP%0V+f$^V_OTTMSmZNMyeYJ?2^#JVzB`6$Rc?ZoBsF`m!)ARt!s`{#X?k3VlQx zq+SG>nYd8T?;!jyX(l!S+N219Y zBV7eNG-!Sap;~rs{VUDLL)5JC@aH1jSOoX9zc}2$P&+);!X7KW=5$$(4HsHs zJ@FT z1O#}Ik5QSi6?gc10$3t~b*)5t=P2&GNi_U==5f?h1kKNoq0QmGg;i?3NZfk>8s%9l z!ANs-+tH01x&MYgbNxvZEo?YL`|;{o=qO60F!+uo{G$uz{!gXV^>kA|W9cf&Bp_P#BW&j*K!xe2Q%l!#=hRbnUHAnj$VYV-1e02n%A92PlBK53O zDLB$xDZmD%1m(pd9J-EgRU|UDKUVOGbtK(z{*E&-@5c}rq^`^@NoS2sQTOphCAI}z znlCDUOkfi(;8%4T9}f3<)2C>|af#I{ZW@|kXHI)zV)>L1*hU)XM;I{*@hcS zO7?FlpNZqH`b6qg2cD}i^rdvyuF`WFb~5HVZ6TzXbFPj?F5N@ZRqE}hgftl@w%&d{ z?N@U=?h__+&&PC;V!tGJ-!>Y%QLWZS`mNxep$_Ndd~PwQmqqH+%`kP)2t1CoGm~#M z)?{bLe(Aj!8=GssrEed}Cz6E_RxhERV1s!_(3`e!uD! zQRa=?l}*(EJmlc1Az~V2vc6wCysMmFc6RT_%9bELcTp@vbmFykQX5 zt&duTuygQwSX}vYsn(wh)!|~8qaIp{?pvOqc%Zs!+@MN`5J7WA1j4 zTzHdnz}Kt7FyZ!Iw2Gj6s6QFph51&p>X{QCK(m~hK1)dmm{Ma%UP)7|-^ohNPYZ|q ziu4=vBF6HG)ao%_x#q#5<4T0^9nVjTZ1hgk)rLW2)buG2)yo8eAtzXqrW&=YSmuLR zoh9EobAexnOK#*y%6}st#wgp;9?GkoiBD%%t!hn`(BoJD@F%7(S65sZCV3okjCrRN zl+Lua5*3xtPL&Ny>A7M#xy$%8KPw+%(=n&&^lI0)S9x_Ci>7TB{dO?-pwXB@mj;F^&-oZv_|3-^Y3 z--w5*VnbJFfi8Z9So-9Hm#)?twiLF`oQKV3i6BlrzkIKl`e?}K(cblFjp>&*_L~d# z6m}n9wpH>G-l?thPxoa`OpSuu80l=s_`Bh^`&Y$#qn(d%j5!*2fe8`HMxSZA_edvp4>6w+v) z^kT<2f3ElGDnXlf^Nmpwfvs?A#f}&MRDCIn7y*{TZ|s|>?XFeAxM?eIUmNeId@n}R z)Y)WRg!^r28s#3iH2Lbi60N%1UN1`Z%Ks{W`-6ryOl2?YXHn?gU75#o+;;pPLvSKrqL^=SBe_TP720eT??P~6ItQ6$ zu_G%Hgs0l$(6_d(h?3>UeKs93m|Z>Bh0Vt!T&Rvp6#KUi7BH1E-8m;rSM=(U?W=Vo0lF85j4n(6Q zY@osV6T;Zb!_}Pjjos`=>kRZsN{`a{C{X-Nm;=J-U`(PU7Eyx@M~yqTok z)B9v#&N32g4!5$iB@+S(t}ql*ouBEruXIOh1^Ybk_+S2LMO%0U0z$sgcRo#8CcUs| zu#=GXx7C^oq}N;IP1UV2&d>yfi}v}UZ#P=?rSkX@gZ0<|H`vh@tT{7}+#~dSpDt11 zxa-~*ZMVsz&+(%0Qdy>rbo+Qh>Z9vZoG`)V(KdLJHa}xnW9m~_r+$yM2_f(#Il-FH zgIz~V@En}sELcfKJrTju(e(Je6R;PiT@lylBRG4WgNf;OS z>O$&q!HQH@RwKmGgI`#}>)F9STPU(wQ?JRHUSPpG(cd;eThXHUin|SxEYl{s<7RQ@ zwniLyy{7B;Z1+YC##M$JV|TU2x}$gp&kyy@LNYq+yyWDO-nxCzA7l>Er?7oXB6+=n zR}i9YwG`BuFF3BBBGFi4uCPE z7yIvJFoQP&%o=O)T;>De+QQTn6n7f9*?Ist3Z~Hhg|`6R6O?-iWH7ZZp)s4D^WOK0wMUIX?USw9zHlcqilIT z#|#8dv9hTeBat!!lMKW~xV{Rt?V=`Yox}Y|eTsB-6yMD2Bm%>4;2$ZzfVMEoLB#5Y zPQF{p@g>eaB_T&eGDmTP6gk)&Q7hSxe*a*p8xAmKbDtstoD1YnDPbQnUK|acX{t9r zPc(%UaPT)<#(XDrOt5BDU|^6_%LYwa$Oc)TumsFX{T|9lXmcNg3dTeI6GHrkb+NZC zrnJHtLRTRw__N`J=g7D`jGkOIu{=)^Y+IW_v5^ry*ebd_*^Dda;vZ2}J2$+Ses@!E zw5=zt`{!oPX7(#OxJPH!D~NPo5bSo3lcdt=gA*_pPt>b-9?{xn1=BTq+PThd5^Ebh zbZk@YlWpv~kG#bNNsU$s>T+s(L(bPMM&@kuC`J(Gjp$M?YPM5o#AB&$mJzdUdfj}Npcty1%h0*Kc+cXL58jKYUt zf}iRSJ}h#sBTRr*$n-nX(PdiFt)dsFz>^KJqo}Y{iUwrt{?GKhwN%mTUlN)ZEyXd1 zYF?&K&`lr%{k^xjB>Gw`h2e+q$d}hlcf;r9jNxcmd>zy=zhZ*+O?q4xZ`#sS=Z@rs zzRt@0_T>6J3_O!08-T%g{%pV0t$)Y+nEy_bUTwb4>UbH_T4=|P_1_UOq+)1kJOk55 zy5l%CJ>>XY0nSBP&OmYtK!EvDu5_3h#bxrwaq0Y&E$OF|^FXJOLi|j;xbZI}bKl#9 z5gr9i2xR%#CGa?jd2$xu@GJ3NoCNoy@5=k07=$ygy+>s6bhIqKflX|e+*5jI9*dD5 zqhNIHV7Yz%C^}zsN0&Aj*--K`X1fq40x6 zG@H;loY0VGeQvecdWWoh%OOdM$M)LyLw~`Ux9-$y<&g(`1Ba;rZ|Y8L==ad_K@b_G`3_VM3FIPSYo zs*E~|*Z5pt5a1sd6XNFs^S})o#|%TF`6+8`wbY+H*)POnQ`mEVYnIn*#>Zw&y@;I~ znTPt502O9i*1{xDwg{g_6tx>LdhW6r7`sg>-ull}bP%V)3+dAE@B!}rA_Qkt;|HT= zeG-Z((Uuj*!&lF`>4b=*`UOU)eUOHTrd) zZ-aNA+f>w%rRW;%L;tw(+v(^zT)p7kKlvj*Tfxuk#FAF#FmlQ}qi2qbJFsm%WFd&=t}MQx_Mx zZ;(7G+nRng!b^UZq_3EG!%C_1g{&7%a~{m^y{l*jgK;Xtr?BkKjZ4V(MoI|yX>Ft z4p{!BPd4z~qR*6^2$%oT!h2(7w@CAQm#w>d2Vd0gC;q!)88Ml9fU~o>Ecsnbb{N6g zBa9$K1qkBUK3I&CJ_Pt~yZDm&(Z9fWSfsoc;(t&8*a!Mve)VMMYd44IK}T_?|S*J5$Jr>$!6EDM1LL{7*(~`Cra)`49wm0T5Gs6 zn`d}1`$*TMwmu250!RI{0Dk)XzM~KURL43Xk)#%{S1C{4n{dSScmY(P*@eRo>i;`IR3(be`lhlAaaHP@T zD#k!z*scJ(#c%9lFxc@xm!k@|*kyEJKsNkak*m|D)IgL^e%K7pKr9h=EQN!kH}WL^ zRph@@W5jhwRCys!>GoGlp-0*YDi+N`z@lvELgDqm(l#EFl(vxP{^Y83lFT^qK;FFuioJzx6k zRvEQ<{0NFKaV@^cv)b*2hJ-)7O_&wuTJy}?Mb^*Bo^6Enq^=)#*B9Trbaivc2hbuf0TU+h-nDHU4EZUYSyHkFcw9Uf%e-Q&kW-=y4W_bGu!YNa4^ z;bdVFxrXPS83a+TNx}#7x@>@cq4O86)3vbl;H;{;Z|fKD3~8qJbSnV!!YR^V>E!@d zoPgy2v_LnYATzF)f=>F*A6hlO!JQN4CUgS8C9cd(M)uB9!1A|=@e7m2M1Hra3!BEs zi@7s0uFeJ<@q3m`V$#!i!2$C)HIyk5i^iNcNmIopAosTzplYI!O;)<#qq* zBd8({Ahc%wQKsNB)2Oxo=y~s(SzN?4t#8;koLmh=wrgqHZ8|g0)LW_J=^Qo>n6v>1 zjhnA1x|=b#0B@17MrfO|3?4q~w8g=D z)3}G@;n$4B-; zIZ}r=^iYx0x#)@b_>-&~FFS~ECYpeoca5Szu61!QUM@(?1hQKbaEJWnS16Z{*`8Cr zaVCJElLxC&OZ!7TA1RY~&Pu&(#9R+aGt?V+78|LaFT_QU=Vx#E2XH~$&B`%g?x0LM z0<^tc1?ER^5waeP%wlB%%4d)PEx_I9QBlcthQ{mk*?Q<##9Q*{bEZ|fpQux&8y>{{ zNG$V2TOx`qQUbFV?VxQ}!N(f8asPRsnG)x0{7Sod( zuCaa=Zj?XE%S9-@zr0oj8dEwFFi)$F<9w%gHJWeOi4w(Kw|zeH%kKrAWkn`ksdK%U zxtc!`Wa1ZghB`C@H(22Y9)PxoN92Qw>s7@zE|1uqcjetFVIHeqTdaf|wd-ecYnxkj zK=~#50f%-ftUuZDkT|l^@Q*HwFjue)TS3oolv;*agT`N zRGfVPy{0%gB_D5BMv}1zD)W~`pkzO)rJ&N7u>^|XR?9%gWg3;xu^eF@RF-qeK@n%W zDkv?sb|F-9uDK4QX?j~VVvFh?*8-ppo7J@_L5+;ojG+n%t4XK=zq(ojs_1GNIpH5p zj#vxTaG z8tYJhC%n(?pw!bV?*F$EdHKIf-_}+%;%I7gi{7A1nHXNXgsxb(;#fQZ8WDL2EtER> zKoc4yZAM9`H9)%u%E@i145hK3Wiof~dGsAy+Rw!!uT>7E*_LAoMH;HF`cB{T~3NKwG~khL|%%U!WLb&M^HX z#Sn8w>dO>E%o(GfW?4otXS{xnVu(47`uU0><}~S-Du$RdO}|Pp#GIq`>lH)HS*YKt z7-G%}{T{^-bI#HqQVcQYTz#8jh&gNY-xNd4S*vSZBty(uuct6OjbhI2;q&y~D({T} z4~Eaz2P$@Y|Hp_u-9@g4XN_mV7wCJKohn`&wOVY@S9X<}H|D<_-k`tOP3E0D^3Cu? zx;JLA&%&4J@0G|}&W-*MzD!?JD)UxMaz*~8e_1N?R!s6muFx+pmwBn6S&jvf)YO<&Vfvb=HgBX{cAy(Igi^GT7r^m@fUovBFvxJf!zk?8zZFN4Dw8*-=(?8vOOuyP@MdlOw19g@yrr4%$b7*eUi~A%s zpVp`KNoqc;&sKT4gUifk^;Lc3`2BOxLy_n8>+HNb^F{p@N4b~vdmQCn)<06^9vJy# zC-N4f2Kb>C#U*YrA@Jr{XRA1RsmHvg5#>pIda#rXv<7rjob(NXSgeS^}h@B3lo zZT&^Xw!1%%yrX}w81COc)I0Q(49_P%(N9+lPe(q{&sPjjBtFrvR18l?KGAPcth!-u zX$G(KWEpFt~tN5C+Pf{e){+&BFT!XoowRJ5{G8j`W_B;ZWkw8 zGI@`qTz!d?T~_uavHQ4ntj5LJzv?eB`!ofu|E|BG7+U{b-)U>QhT>?ja|THEV_{v+e!W#P@9w%i!ey*h?5jE#v2{wboNk9S<2J?S*1CjlJg?Z@ z-oZJBp$(L5xNk&`+vu#=v&Og_(^#X}8J@-*k1=wPWS4uV<#>%#73=4lnUiANsMw9h z(K$XNYp`Sq&+$2_#;b#^I-7ISjJ<;`%~NvHje;SP?HoSGm0?U#?9p+{b25#^id7Y_ zB6g`_;hHmuy{=eE)f!@1^%k3@XBoAM^`bn#ak*kchy{#2ioI8GK~B&(eyC*QtDY3u z#tTEOakwle+t{n}>c?M|6EeE;gQN4s>Is{3!bbHl>FeXBtQHZY-!QA3No=Uiw&X;N zg~L>D^Y6^bH8$An!JH1pyy3EzqUt@O&{#A)*?OVj9g$?64DU#bJ)Kizd^|FlS8U82 zB`tft>q|LZjO#}wZRu*lf! zzKRFm}IlM zob!x%l8J@Y<=O?tY4fesQJlNM*r3=cbKSmE~S)?6FzD+$)Ue2}#SYF&?nl z$lPmJgaZSt;AdDA%W!8Uo@RNgh5w;}G#yF4!Q&fvUl%szGf5j!#WcB5cn zQu9tDx-gk{r?J_QcemjxaEbBVDH@1pJ5v-8<0#q~Vq#1yaEoiJ@d@GMy^=U95sK`3pM9= zatXJ%S;Mb45fi`KTt(<5%UvRcY_@EpQWIn;^y03rz&nf4m#ar0J*j&#U0M!YSOLkc zBhb_B_2}s{WB*+47Pk#TTPIaRXK@j9?q)AtFakPf7W%K0TXGuZYUKW-8*-oTW=Smh zpgPD0^+u_#y&*rX5c1!BNMBQl^yJFq7!?kIMAqQU&FqM@w+(EpY7;XOBd?_m8D@dBO4eB$xJ z_`6@Sr_zU)_CpPKvE^TmKn+=31Il_-TaOe#b2ax7xd!LDRqkgzg1;Uz*W`9R+^#jd z7CL(RC0m}wmhWVJS*P^db7P?M=omrk4s-iZbN+0e^9lA6eC6Sp?-kcgK(A-vZ@PEU4`Fys~UL zX-;%#%3VbpYt4L3yxax*e!2^VI^4ELjpw+V*%2Y`b<$8{4E@)?LPEBDuvubm3pN9KPrXXwxv$U zgN30{2bQ9}i{!_RI8ZLVJ!LX#yR+uN+OY0)v1Sxo*gKhPudjl(yXgNe`3ZT}80lg< z{tvCio=zII{(UE2kM)?DtMf237v^DRe&ejC~5k^NDsQ-72yB{W&z(QDHA^q>)u za(!G<-qe`11bera%!tw6Dt_;&ktOb48m$p`i6}@FSw;B!fd`My zgnr5TNka1ae$pFg>-ci$+&Et9pskJLX!rG>;$r`lb z$yTJKss2Do{m7)m+C|ZqoE`_xL)!Ui9^N=SIS(iE=uE7Jz8S+xKQHgVQ-O0X9XuNTEA8qXz-=MqNn{Sg}N?V04sH1S^9f%S|lL_K{AQP0rAL)U|{K2^54U$QKs48@}< zD0{&al>KD{%3fWGvePS*WnJa4;oCCU@cdvpbBMvF< zf6s{#x&L!w{GSu!|C|{A51$yt|B(};_zNdS@h2xnanOlT{O>z4?qv`Ac@6%~>Bd3q zfpU&GWB&T7Qpi)KIOtR<{=-wH_+L6zivOikrTCLmrTCLmrTCLmrQlPg_zzE&;!jSM z;!jSA|3&%#2TqmZPfnHMFPtjHfAgtQ{Do7c_%EL-#X+Y^anPw!{3lP9;{W%jO7Y)t zs{FU-$%l)9`}+fb8_wqqjxzE*dG9btj_b?2Yqw-t$_I9n=TD^N$y4gc^!0T~{W*?$ zrbm$;D|aoHbm(lIU1_ckMq0{K@~pHbo@z+SElbcxDW5S8=;yQUFpgrUOn}Eu;M3!N z#<8q}6Qi|LJcF1;fknp-)B?%AFPuDGvY2pr^+ZaJZRE$FX(}tn`&U_wteK2$$;9Y1zAtaCY zO5#>tr?c4qUAiW1kR!W%0@CF?KkKFd-Ml9_(@Q4u$d)H{+Baw{`Rj;MX(N*O+wi1( zYVCpgh1`q#`4sU>V-nvjhduYRH>6eR11yP^{*}+nSVso;&dt9#ShXcl6ICOVk~8ey zX<`wN?3t61?pT2t{(e4ozjyj2<`0g&M@+z^jPddm&Rbpm7QV9(L<8*O`RckdhAw?N-uFVOsz~xe8a334UsYgp82Ga z|9=<;V3yuAA?X>cah>%IaS5Mn;VY9%dAO99OIbE(!(hXH-v6an@5+ZcNpwkKMp(m zQGBORpP#J%ucKU9OL!+dtrnK!&0)G9DYW){t<4-B#53yX&X(nEdm%Nu@l2aK)>^ap z77I0R*Mj`*D7Ig-r@bfFR z&{@lVD6U6(9D6m3=lmU0oN0VpWQuGW!IS9U5}GM*(?49dQ`B8TF?T0L+?^C}*HW}y zD?*}Pd@FjpzN3FB0`IZ-1%7pGN9YsX2(v^LV{gKc7{uw3j17!aSw4%?^B9*9=8Cgj zsOK8j9~}z_2XryTAPtg{8kgeq+1yr|__(ZsYzC&WB%5)I_;}b@(Lr1@WQOQ0UTcVp zCED;_i>N1$8cT3)$Zr*=YGsY9#diYlggqeMt-n~5lK%CgJL_k&PIm#Fv$@6dwXNQ* zVxDVB!D_0lUDqcGS9N)k%4QFLhVcAuFNtfklls0!IAqG3q`$*>Pi)cfrpFfTj4@ww z4c{^D6_1Ngx|y!Wscb6YPTwAqOd0NXJ;3t5+>3g~F^q+-XNRs9k82&L^mlc0-934@ z>oRd}Yz(Ep@6h0STf2Pn6xXSwImgvVd)x*}kDqd>tDbvN&;F?*uRiN~TsvaQ%dXz+ z;S*gLwcf5R6W=4ry2AHdRjz^EK5{M5GP~>{$=Q>>BAhqud)MJqkD(3XQgg{m0quD9 z(jdz1tob#(YqE%Sj%SbkQ)?L2S6jxCsocs`*VFamw9}O&GHe{-AMA5Twus8wnOc?W z`A*MLThL!4q;201yo0dVSO0_j#V@{66P7&-roB%xGhS4;u?e=exiy>ou{U zz1&6UXZkqkhdKOqF1e|Z=9|V1>wavQ+WvJf8m4hg+rUCW$vrRRI%$DWr^s!fB`chgti1o}a= zDrw6geE+_F4sCK-;*ck#%@05i#n*Qd{?X2P&y(DePjgEi*Y3wCIIeHJ_>-RF+D`}W z#R%B4`Kz99X?JY+E6>y1o-c4uU0{5D=v$uaIqoYQ_lMlh&jY>Q=e4hR>b-lka=62| zQKW}o5;t->d$h}^>)3-dn@O1E9ZWc>7z{VWqL2u z4>P@>oqN@F-UZg21#SI$!XI`K{{DQzuXIsJ3ZK%*Vx+W{I~Tku?P&5PXlds=zat*d zKArrC_W^C$g-5+q{yV&{amd%W-Arv~=i}&2sR=K({+ZX*f@=x?74$K2#pd^+f4hgD z)SuTrw&C+=J-YK}>eSB9Yjji4)PKB=+LrDKKCk_Q2V=*$tMj{F4U(t5+l=}SpV0Vr z>~VekydQdx>kppyQ{Y|az2FTS_nq~!_bTJk)>k3|1MgEsp09h zPJf-I^&JUZq@iU3ooJb3Kx!G&FxLJQ;jbP2SwPc@9lr=XpvRHU1Nv6js0`cB47Z-? zq4M9Mt-CO1eh*`$Y(B4jHgL#%kTtffkXn8_w|qz^I~mf+LT=~0ZZm$f^KQiY+0L}) z6+1*a=*6640sF)xuwP_>`+xyx@qXZAq6mCK%m7b_L%=7+`+-lh?=viUR@?}DPTT@~ ziRG_wtXDbKN%2wO>m2e;jw>_@@6jlHK>J_7MvY>v)F@W7MzLBniq)!7taTd2TFeKYJk#lA(Bml+ST@AZuH9Ogz2b2F!K zE0^I2m*FUv;dU;=o!VVNQ{1inKfwF6&jRn~8a>Fq4{_Xwk-jM&(H^Asdx2%W06eIdf!FJEzzo0z9JsG4QDV3E=JeoxnTwdw_TA ze+Ily|2*)1{UP9k`d5Ju>0bvvtbYUei2eldnEox`WBPZ2Pw4*$JfS}Wd{X~0@G1SD zfluo{13sg_0(@3~4fve?ufP}d-veLLMLpVI_X1zlgTRyea^UOwO5mINYM?OA1bU2f zfB|DYu-@1JY&1H6D~+wdW@9_B#Rvmijb7k7V;69}F$BEG7y-5!?*eujW56yW1Ke(8 zfjf*mu*a~0ea1mxzwtickZ}VrX?zg4+qf0D*SHP1&-fEy#`qL)%D5YtGyW7|JZk*Ez&nj+fp;6v1Mf5b5Ac42 zb>1M|d&r>Hd)W8|$yl(F}aaSOa{;I2-t?aX#>*aS`x!qaFCBu>~kRmjXSW9l(Gm3as~B32gMl zfh#>pV6$fru*LHpV5=t$T<4hruJ=p>FY=UtZJqF@PubG@JY`lz^6P{0H0=j#?u3Q))NCh z=NSaP;7I^q^6Un_;<*O+s%IQ{(lZHs-ID{p>A4mtyt6=$_c~y}I}fb)-UMv)eh9eI z`!Qg%_b9N%dk3)9`)S}h@4dkF-p`V4_udb>&HDvlr}xXiF7ICgw|kEPcX*Ejd%S-G z?DKvb*zbJ`IOP34FzNj#;BN0vfqT6#0QY%c24=j!0_MDI?Y(3(%U-hN2fbv;ulJJu zocEILz0rFYS$i+(_N`vh?IYgbBJS;8ve1W^}g2|{Nf_t?}2T;KLEQ}vYjP6SkmLumitAY&jalD`GG^e zATa4$2HfpyT#lCH95cQZpr?E^o8)|C*^0hqNXou7%Q3t8&ITUyoezABB~SP+0-o@- z1E2J50Y2s98PIV87N%r9(lkCI8CfSEaOtKHhOtKG;nPeZHFv&igFv&hVX_9?- z%DfVJJ#EH;&zMQzv*sS)bLM-1FPLfIOXd{t6>}Q+s#yY_G!Fn@H?If2X)XXo@B=_k z@Wa4B@CdLz_;Fxk@RPum!OsAjgZBYjf)4;&gMSWO7yJrveeeJA;1< z>Cxi3Ar-C;D zpALQq_)PF)z-NO;fzJi+0KO3XH1MV1y}(z3_XA%IegSwg_+{Yh!M_B)89W9Qb;p68 zy1xMi>b?!EuX_sESoeM4%DR67HrM?W*i!cbu(j@G;JUhB0oOC#R!17xSx2L+tByw5 z4wm$=q>m*-EJ?CtHzZgm*U`#3Q}^3Oub8T%m2sJ7utG|MBsc!~-WErh#k1nGeZ(lY8 zymQ$hS_v;B`*yH_%71+W`98Ir@ag3g=9%Rb=Go=91D{*|6W|NWe@SItzP{cRuPkpy zzOOE)@|;{w<#~NMmFLanThKBOH&TrrX{6RW)<~`QSR=LG6OGh*CmQ`UP8%uTR~xC_ zPBv1zz25jyq~92#(yk0qNt#1clD5zq)S@$VKWfw!`T}r!=*z$zp}z$7gpMKo{?O~7 zi=nd-vK%@eco4C?;z)@0O-Dl(t@b(12RY4$LTtT5G>g3&qFL-@h-R_ZLo|!Mi8LET zV8unDjiOH6efmbRLOcLGL!1DfBfbZ`P&^OZBm!q_6qkwyV1#j(XaOcz{%+BBMnt5= zByhjD?Tj?&PXdWPtS~K}IOATX?*;vkBKE9mLXk=f;!;D4~VTAGV z6)b-T;k~D^?`ozQA3yzniRPAnX|YMZhVUH52xFS@Fyp<9_kHkFz!w+|aZRXBjD^mE zyB5zmA{9CpZo5c_HbK4>?lwG^;<*gZ6?nq%Pv995lc56${~0Y6I*#W%S~m23Z94QL zxQ0F!GWF@u3jNy9xp=nXxdQx7JaN!h;dwWnH2D2^Y&_TDIj+xyz6JODcz&m6LzG}Bf8jmm z{igSXH|iVmjr#WcioUY%Q@%g<9rJzH_Y0r!d;BZ>XZknzFY{mNe~xmSa!fD1IVB;-?5H#Kh2n(}g&{gK#u@9q{s=n}8oXkMMmX9|HDWNEqDs(bH?g z4}||1_}V4pTNwQW%ZZL`{uJ>0XHxhmhkrayXoA+om6{=Ru}kv;`!zqkOV>=`pjHQr zYs-K`+H!iQt%ZOIZ3Qr?tpbi}rvdk9t5MH)0d?%~&!Bff+8W?t?JT-wqpbx#pq&H! zyml_|LG64I5bxB_60`?iEBSx2aT1U7SD$~f9&~!=Nq24JePQ5zKrjn|0Imky8?Fxz8tvS6k0+5?m3#s ze}`Ld?9%plvf58PyR>odE^P`=-us63ruQv8@76yc zzwWQUcWfx!)7~a}`{UsxTsu3twM`_)HgyaQN5lPHL~rSI=*Z~UaAZs|i0cNah$8WU zq5kOZE|o}RsDHPUh)XM?-%3pkTdABPBh$s)LD2E&z}P@ytT#TK91ag|Yg2_(sdvZw z+r;+Ew~dXpw~vA9u_m&4D>7r33)2HuIh9G3Q9Mh%tX<5d<|4V2ZErc1aOj7pq;wqWPI=6nZ>o?Sl}FQ?L~iDdcii zx|}WK_f^87a^U*2b{P)p)J}D3uhgksq%xV3TbT~jW@k@08Qw%xze^2`bhEp2XgD5` zelE2$*#|A{k;S(jD>(jQ6=j}1n{!;(u5j158}b5ozj!3T2KnjE%>7@8SR%uN$fDx@WqoGQ`4VS2QfDo;uB>a0U`=L+fl zPS}~eBD;%7QIh?safc-3uqBzu70QxAl}3|^vAmTkRk#Uevi3wSRpt_=G9$4(k#Yb@ zI$2Nz`B!;6zS4DVi)=FJPe;{YAi5{o3rn*zN;I`-te?q&@F4#0L9Z!Jk|<(gC>n`{ z`#C+BE18ERddHG`hGg2q9q#bzaEDh%Wq5T|hF3?`@aj;*tD`c!I^^(@EjZR8dS~+K zec-Y@j#8yLFc>wEur*}+HkvABX~=OhcF{^_Q#lSWoXSsHXnSh533kKfa%muypMxSW zPh+h^#6XYar&IaVq?O@zg|L_zpCy+noSZ9K39H1sGQ)+uT~6i8$g_QuGgvoK0V47E zu2__sW^8wScx>49-c;2Wn`Heq$@*>La=6KKI^#MP-qPueY^L3z$+Q}ppesWYj2fC8 z#3j_&bK<$QA}XUzCZI-}6O{&*6V;^^p@uCeHI`y2N<$4gkd8_#Qc|v}%KT96&Z_3= zbk(WTRj1C1I(1gmsk2I*I+Z$gR@A9es#B+IZYQhu&5GD82Jo=o=1L>AZ>cmA(=MTA zkS&!dWJ}c?vZZPg*-|}=Y;mTMEmiZ#7B!JOz0;*Sr>oL8U9xMsWP^6O9n|IYNf)iRRFSsHP}{`zfkI{`XI(C~ z50$dBDfAd>W=&gps#PK1gC$!QYcU=$1HG8m#s)_R!ZmCnEPA5dBRj{iC>#zCL}|Jw zV*rb+$bN?;OVisw#x%9b@F={ka&OkkWr!}$EOsfbQq)>)&udLD3uREg(?(TBULCx_B$lE^;IL`9@*52qV}%{9nx{x zDaLwwD9fH$A`%|%iS~>Q#!2ORqr=g`NVJEhF2}1T92FV4hj&W(P;Y;DC&h)fM*5^| zWH1riIVkB0wKFuio%qabm6R0~763OA%;7(q-RyRx{xu>6^#JjJg%&R*;HrO8< zBtPt`28QCy3>5N(jS(yjavO)Dto_MEUl?R!&j8KUs*Ta}#3Wr}&k(ybFrta16O#J9 zJDiA)xq{)?Kr9I*aV5MKcDY_Gv{2<}WLIKjKuX>EjdUlVX|edAlv9_YLk1EMB;viv ztHZ;Uz);`#Fc*i$TeN3nIO?c%I5{GH&|o8xr1DXwWt2+Ge9u6IC)Exo*^TnJCkBCH zgJbR8dtADsitenU+qYCPT@LMZP%IMe75z~_wQv~x=I%&OM|)&bXM1;aOHWU4S8s1` zINBcW*c9##cXakdy1TcucXaoX*1){M3OI`(Nmi(2d{=Z(lHoygS(utp@-PZ$PNHka zX|HSg;=R2!eTflYQ&!R@G0~rl?5tTKQ(j3*&t)B|Dz0Ly(%$LldhgJ#ojj5-VM*QQ z5`~8q!-k$i`B{@l1!iz;*oGa&y!KOWpLZ@pK{1m2x&90=#qVvp7OwF{0?fqc6c9I5zTUGcrzNefF(M=V`hQdj(x zmm{ejTH&6aS{Vy?27r2ZM~CI??ot@uSO+jYgh?_9(ivj0gyft-=I}0AQG@8HOro;+ zcgi4_QlM&wn&dIL_M(unNW$d@T^`AW`(xpR@(6b)P-Q|#(`gQ8-{@|#{#25LoOi1j zweYBTVtDKsaM^y?Sjo6+>#-`Hl0tALQimf|0(M*$<%ka_tGq|KjMcNb^l-;_q`y)f z#Osb%@w7aM^zBLvI4z*8Lqe`ZB&o7UjP-@F&WObOM+P8OM+F11p@cI_GL3v=qur7I zaDwS7vO-BhZs>Yq7>h}%rg0{qq;W?w;))cd9KwV=VIAoql8~m5L|?3zsf0@n_?iXARrq7NM}OXrZ(KviNzlkIk-6_F#6ZemO-5)ZWqTR-#( z2jnGte@rrRjn15!s3|;;dM60xd52`zJvSa>roWou(_=}h17sDbnsJYjm0vCEobXCc z9r8-XIarij)!CvesN&p%uBsALSZC*}JZm^-16uKOxXPYTaqfO+thza6#LC`9c{&Sy z#k$LB#k(uz#nr2+oeC`1U#^d{v~dNp6{}KKq`M?gJTC$ittL&kc+$eVHFKC6)9&_} z%hgzLC14v|)h%R5s=CEt9n0bLwjBJbH66kki7LJ`z?A+uW6Uk6!&J3@bhp!pSXT}Y zhxa(8tfFOgd1l*F35~q_M-&aC4_X7G7DW$jC6AZtS7y-60p%Y0=6k5+B+_?~7)vu`yo5hjY0? zI>i<@Ih)F7bGei_5ItBfrTB<|PNu}Poz2nvLT1wA>=c!gW~aB5nzoplkm4dcyL+<- zXC!GCW=d&w1TF>np^S8Qvn$WOoY#_qj_}klO9iGC%bb6kQJ&pTOrxmetDV>=8}c| zR-TSB`N*?qrNu-npJSp7iOrH+AyqD7nXiy{HFS)`Q4ehGd=*!lQ$sz`-TxLmS8Gzy&Q zO{L3)(vVe3I}M$&>@?bSD3y^Z!!1m(6E9kM(giU^KyTwX#K=`Miee(1$u}$a7tN%bk2rDZMJhJEA#44Wq`YV#MDI*4CrL;p zQJj`}NAuKO(jBl$lNJ#fD_2hSBS&I#%FT>Vl9Mjv$bphThi9hq#K6E!7rRTTe0nNo z=TeYZ2aDveN>7xssF(;Bi{wzIyRziRrlZFipW!PBrD;BwXD@pH#)LdJNTyJ(G7B*N zvQF+)@JVvg1(__Y%2Yu%n_v=M+H$Op&GOOuRg0l@wbh1LTzD>M0b|y}5x_%w;V*Sx8Q0 zZ52FOn%l`Xl?!yp$wxZbY04c2ZE% zO$p~_Q>8J|%drxRc&u>9)XbzM=j=$Kus>^Iww*=)!6{=&FqNdK2-yv#O18!HDc+T1 z6`_dA{S^_bTwh_M(o>j`NhxAyqz_|^JZJLd?6fowO2lW)yhy>i8hu(L>UBhz7$kvi z=*`M7vKN@MtH?v_U^*QmlgH+IwvfY+1(UU1vO3>^nOr$rT$HmbnZc(|^huj%9T~~2Ma$GK!(b%ZSs5E4)WnKC#1Ze5P!5&#?!YOB%3HOC^yCss^!=*@xWf=Q-bTR(Wo$5|qzb@hDy7 z;}Il6n#C?DFcWIhVcM>uE#)EtufN>Du&$-D8@$5ht%FKT=67sb+FzcosG)$oc1$Lw zQbi0fo1J1Y#+TXH@GyY|j3i>N7D!&Uf~2c0yp*uvlw=YX0kdA&!fKN5C$SXkj(+Q4 z7K2Ad}I}s-DW0J%^>0Eti#BbP%8-%kXlf~ zFmpgQ&gfWKrBYUWnvFSg=(ijbR?eDs{EHQ;Tw=0}8Ciy>m%U8QFqUT7$z~3gRZkRC zC5x6|z1fn~KvXId&OvFRL-|yBrX)v zEP%Q0&ecbFsjCraqnrhY?W#DyNTtMJFY)e#*3PaT2wI_5IPT9$nx!f-L>|rB*&12c zwqfjYbIEMET3n-)6|r3Nv5h%UDDAI!q{kPTv6|g!MOs`ez_t^U$kOtVX&;3R#%NpW zS+z37Y`r)Xa!z4BlSaHE?#-np?V83wOL7{+RxWjrDSK&N*wtlb(&eQdkwS5Nm{+|)E**r~{rL1v{ZXUDU-Y`MxeLAP~ezcWQj#ey9p*gT)2&=wtLhL;XJ8+Ih%)YB9WTK7_uhWohY(H zOFO!ZM5dGkOk;A&<|mk(EMk7nGFi+V7{XSQ=^@%Lve6}OI-6$~8~AiVl2~}4#~ms5 z&POK$03Uq(mv!+Y7fM-4`z3F z_9vRBompq%7j!cdv=ho*#=H9{hp(*fMo_p3F>xSMg5w_DU_XR@Bh2Q@Sl;7d0nTe|M>w%FF<8K4fIVc14j>?+X`ox)u9H)Oq7(bG#YmN0kvxmh3|!naYkOcbK_Xneo-9B?-$UD{RqWZ#_1SA5*X`cNg*99DB%vX z?ZVjGnJbKgV3ou+Hz!q+DJZ@pk%XK_dF?-dMbs2TJJl^fhfgfxBkm<>xyb`L4SE6! zfcDGLzMb9bot2!Eb2S^QDj7zZHAytDqhk4VN#1*`O=L7%D$guRq)IlBoK*~JC)CLV zE$2jeKRYxp$Q%4p73jLXC{5-TZQ-g|QOH@FIyPotlEIYgeDj_N!EbPnZgK571sYrWn8U|P~v{9r1s92izt9)qjuUKa-T;+>> zrQ%qnD#@dCPAnU&qKj2D%}yBRl7Y>n*+4~C<>kup)GdnA!IDk!rNSh+*$f&(uDxMh zc;U~4dog4qSBE*wI*2&UFC=35T-cuGi!<<-WuKXr3q)E5y6ZtvoMML#JIhQ(3NT?z z(Tk3mWT!Eq=efeYd|uj{&dYwbl1#b;s~k7YXq2aD}1r9V3!Bz-34*|*o@66+D2PTie9$m#^_*SIwuTL-xcZ0JDE%2fl+tX63n`a?{qipKh+igRpp?Mb?D4i}er zEIG|s65`Zn^TOGVF7Z&;`xcA&^`b0YcOf&k#Gejf5Mru?71ALVRr}iiu@@GM;j}E0 zJZDlv*Ij;D6YBMv;0;FQbsJChDsN|S$QLaRGf|-&!f9X_>Z}y-`ngJ=me&qTYA{r= zvnt0brsxo{c=TY}DmrDUFoT7%`%wieQ<1~8@d-zK25V@xqBRL{<1P(7IFrj&q%qoP zVKOPwmL7tNkDXr{w<0Op)=Z|r3zVvlmWsunHRZW7S-r4jDX+lXvt$;z2er)6^4sPQ z)qtVlJ3i?~bl-f4+K;f3#c&l$WQZE0y_?9gE=n3xA-lBP5bv@|1#yUgmp51?Ib?CB zWJ%V}bMc3HosOM`Wzm+AXf;h|`EXwf$koH12&sp^wFC8D=oOsEt4K4=WM%0Z(N(11j1SBq%jg4wTH zXB~i{q^J&^Llz5)w*8`i$1?hCxo;ji5~3BRlh^uCITO25qRH8LkJ8Usi%Pu;Z zj6y_Vo1uWmZa;8<<7H2J4YFdO~kPus{qMZv4Horo))$4Ox z-Xal2dWBrwGUyn7Z)`g+kZt!3vdybZb+b$g(&O=*BGqeTn|FFLMfvR|mHR4+KgBnk zh-@vZs;4+xI{$e)Qp1rF+Rnb$mUjlZZQR#*XqzgUPQ&fmcdfSCb5seOS*J==^U6%7 zKwF0;sVoxmOi=r7N0x7iu(U*?nq-MQRU!GrnmzBuurn{S+!h+vZ;$&zx@l&)PlRI$~m$&#VRCYMe?s#SXNA;Th- zUFz)|CD^C9wCmn3s&LBiRD?r?;taiKsz@eW3j3*oU3E%2kS*GxFq4WXQ z7Lc4fQMsOrSsn&%VD3PdTQoRbxl&^{ks98;lQLW-QG=?gP--l>lA3OIrQDNlK2@BX zhRez;D*XPm65T!9qS$USOQp0-ady5Ori$As17ZG|t0Yk)V5PzQFINH8mcun0w)6hH z&&m~vrK35K#?YeXB{S|&`~s_+>me`VO0t}(s-WB^OZk4erlva^EGSCHnSmsSMQ1oo zyHt^q&MA*{D@VC}bCz5lR@Ln#Yb$S6xI@BW^VWgxne=`l$CWGBIPr-Io4A5<$FpS` zjdH_+K;`}JQI+jp!Lch>bxJd|5_Ha!WU;u5Y;|Oz?2oz*%1c7qxp`G9bmrn(>7p}2 zN2&si6(v8z%}g&eZ24Y8&gigsbZ~F;k+Q80j!?*hSPODbC(3l>nNF2OFWU+DSoLb$?AL5s*AZnW&g6lQe-h*)$ui2Kn7V+ysB~l zn?Pj0Ti#Mqdx>PyxjR(7?~LWDQi)W(Ur^%oQc+AbQAI*=cb+PBrz~{lUMcrjp-Sv9 zv?R%vi_V;w7Sy5?M#7FToHs}TeyZpj}DZW3a#*|9SW$C2Kp`CFj7TJAg*pVW@1QV6b zD1txZ!Bly_A|~WJFPpC_lR#Q-j#fER9V-{ciZxQj$r-pLlTwr95Pf9AEj$l+I@ps$ z(IM95#VZ0Sm#<^Wr8&ta?C$y)h|Oj-u(s zyGWpIrFltAIi#f2GM`9ScNJgGIK+NMNPTt~<FX+{{B9JzEooRyqD6T~hpNmH5kLPOQTIZtr?sky=om#3Od)UpGGS!>Wb zSgyWs!?%C2bi-1XOb9W>^sKOE>D5@x4bSL7kse4Lq&pwgH-e-nQQptQG=Q6xE?04J zsxF$+N5iDY^hDYXAs6)pwJVom=OTgR@-9W?kyMs(f_B$1U&tB6BoVx1;H!I8rvZ|e z&FoM;S$V?`rboJkbb6+k%BSa?OB(d54GO?c)j%lbKHI~znnu+kkW7(F7prLdP(|zz7~yvI zkVxBy1h!d+=sRq^L*f!4u1E;P5ST8+wAd(y#f-><%Yw56ecyKhR1tg*d`To2XThgI z*+N_zhB5H=4k3>oYbxN+n`{$g_&Da^q){ojdoR?3Yv0KSZ{ z1(6XkNG3oDgMNNBi6@LYwu%u(@cseOBRYhLwIQu-Vk`c2h%HEA12_v*22>}~XcL=R zmSTUBb>L|Ob^y1DO~^Tge_E^^d>5qK5H2m+5w-(-JEz%>e;I_`fZQ@1cLPGpe-j8r zF*^~He6^V#u6>Hzp@jG;w0bM&lNaYh)~ci#PzA)FfNR0e;aj;6otPWJuSc&HAiYdn zhrHe=E&`nuhnQ~%e}T|8gb`y>jEO$9PXsZG-1b?dG$-QdW$M=n^n5`a5F(Ub6hee$ z{2A62(waE;Q5SP})?hUQSnP&=BXF79#OqOFzbb zeS-923N=ZgO-Wn(Pm#80U!3Nc*aZrPg!S1*{3%ZRU0e$2)3Q8TB83!ZNc+xR9G_~E z!@n^xS_!pzX)a-uB*R)g2|b)aOXheKNv$8lKM|pt$h@)$8%G#tWM#SS#@t#`NSl4j zTt7KJGeYbcVINAr$TcprycMn5Bf8;cz~^|}NclMTrp=O8&^9oSm}S;58vE4O8->_L zwm@2kR>&#jG?$G=tJFBDX{}-{w5-+DGco-im1&T*)dE$k_fqq0Rco0xag$1$FA)bZ zdPt|8uobNq+iF{}RmIG6S!Xzxr73dEtD^8NaS1EqP4-wTw_a?~IHUY)M_Fy%#j=Z0 z$1vjANxL+SkrncQsNg zLFV*Bk$D;SvYJ>Hw4z+8(dt2!PKq&s(Gx{)^aydr0Ox7DX;%3qNLTlB84du+2G4LG z6<9N;d7O}5NPFGNqsKah)?VV)Nr>yd_RhXfeB#CK4_{4J*6Xqx}{8t)o!K%j9x-ZXz3RcXNE3oTfn z)_CiMS8H0hHb75+8gh;IY=3Z7=zR#jpi;cOArK0$LCQKo0FPe&6&a*)KFCFyU_gC zJU&FD8jcWki>can{w}|ADK2tc)inR7NS6F51Cq#$oEQtH7abM|_!Z}-^s-9nWhFtT ze&wPJO$&2@kl&*+LxFEafp0z2AC%k?a7UWvzXWn0{h$A83rfi~IHJ=1QoyGOE*&0Eu z!Ab0{MwFOzjavLJooggnQjqzt)jd1KPsG5!TIB-`~6MpWy3ws|EXO<^Djb+ zd9YTr@p-@N%HRQEAoH&_G`LFjqEf0Cp|C3i4e1sXasDj?ds$!EsOe`)^TYl87C4;? z@p7|YrTH=jOw;@?o915&WzmNLM=WcyKxWVME0fdeUls@i5K4x56#vnK0a8ZNxlmR` zew6j$cd#`L4GkEz)c3kycpB)>@WDt0S#b&9V7v>hi8PLL1Kh;+W|`Non`q`%&6G-E zvTY14++ljqvD?YKgsFI5>gU7vGd{@p5aYwJase_mLe(Sa6{yn)R1oG|XblZMn5u<8 zZKy*JQ8%9{R2MB!kQR=38}e+Lfo{?dDZ>X2ns&jIQc$q|P4hoQ0QB`tP%&h%{921_ zHt3-qfL$bALhA&Oc%a3nXcRPnproszg^($9U`uG>QFLUpzty04fgtQMtR@*w50Zkp z*6SgMvkVTBSQ7}edSQeDx)*8ry+SlCd<(G~DE2aco$2>`)n7wvomRzy3Iw>3bZ!r$ zp`oP(X_yUuziDC=9Ww)f0F5|u>GAta)1)})*p?QWO3VNXPDKnYJYVlOImI;u_5PsO z>+$&mX0Q&aLmk$%toAqZSPH1W(B9Bqa@ov~+}EfH*lSpxmgWAsro+2U6|#XxG^QP4 z&@9r@w6JZn|8!V^-IUDX9ihX`G-ZHcGgJ;8Zh^Q3R)Wm|g;^ImydI^OrA7PzTM~*Q zEj=RnJ)y(>iW>^h<1kQ&H7mrW{uNETn+_M74&U5#crRiPg%0`K+`JyYdUi888Q@6(35Wq5pyE*XC6=UxYeLr|fVCcKwX!-8fo_f#x-C~^( z^rJ~fvApx?0Pw?!a6A1bk%oU4?)}XBJ)OCZE8AyZ|Hoh5aOpQT?ECeP9v}O_Tc5Um zetGVDXME?|_uiX$@v2QH9^Bjixv%d&1oU%89)n;xL4d&IUsi&T z=T)W}$-_h7qre)0PGAs_he00uC~%6Pk%2rK$)lCnR$^O;EfQNKwn*%?#9mA6wZu*l zJ4Ngiu~}lX#Ab;N5gQ^lL@fQznP)ArYl$rpTOzhZtWB&32oh9}Fu?L7fKrH=OmS-ig zD~Vl4>^frC5qpr>gTx*rc8=INV&{n6LF^7{Y~GMeJ3?4ih^}>@cwjViUwBh^1fB^0X1#Mr=E=?Zmbd+d*sxu^q(H&wY6| z5xa?4`av#FJwXG(JD4SX(MXYW0)v3m#N#FK5%^in2uy+?K^;Lo!7_pdg5?B_1R(pc5Db)YTp@fsepX5FjuKf&}yvW*&_|Col-8r#xN)AAz4BKwuIC3F-*y36>Ew z5G*GUt0+AJoxmXQ5O@iE1b%`5fk_Y~s3WK+SVqu5u$-WgAVknau!3ME!72hVPq`83 z1O@>aBafHBN8l$25SRo(f_j2w1Puhs2^tAbBWNaAO>jEF83eCU=lzD@w*)5%en;@H z1ph|xI>8$R|4#6Gf;S1?BKQNr+XTx1x`tUv=pLa51QbEX4s?e=6?CC_S}4#w8yvDQ zXA$)rv!pv@Ry~4#Rr?5xk|&X*8uJJyC0IeQl3*3VI|xoAXeL-qa5}*m1T6$>2+kxp zi=dTYEy39Y=MbzTIG5l&g7XR16I{T07osj8&%Ha4Erd`dLcs zk+epwRokJ>>sY8Y3;j9ttX~(HT3V?=cL+Im(hN24dHe0RnRgQpG;Eu%-|N|26L6p;cU_hF{bIfXEN&M`!tuW}B7=sVOxvT1wJ=kC^M zXZd~I=f$FD9nrrecnzTgcIhAj4x_e%t? z5WGrolHhf~4Wzy|1PJO08j%d;al;ORK5z|093-G}-9VY$;PLv_0EwiO4pSnBDUrjC z1S<(z2`(b&B-nwZ0u=4=F<{f-9^Kc1MqAj%+^vj9822&WNX{cj5RXpi5B zUAPB37qdA4x22&erq_XJ3=P0*jkmFt_FCANIRENfP0ihf_~^i+Mec+6NT(UQO^?}Z zQfgjyd3D+nZ1ocjfk|=TAT%VwR-f72Y&NYln<=8%&}`Nrs1kt=K*p>4W-caV9AD-` zEafUwmUj?GZU61eXLotv*e9qcr3! zZw<;qqmE6DR61-vS2ni<;N57hK^zpf(Ug>dEyY#Dp@|T;(QNinV>EIgIPf$nS?VRU zoR@qW5HldtprUwXVh}2SQ~4vH7qu}d9Znj5%h1R&*+#Rmxw*Bz!nyy}s2<_;R9soA z<^Y!kgr5k+tCK-E1=?*B6O=`#V4P0F>e_6Y-K?5dp{?0Q z)6m#V=UvqI0h7-zN3cE9&Bmr{l$&DdHGGC^1~9=jG;@J9=ah<%EI#6Er8A1#V8;2_ zfp%DTG^H9_^{V4Wi0bID;x0)q!_2RI@t@B$ZZVrif`SMNGGanI<(aFbZUj{?3=IPs z#u!Y1^0^74oK9()Mw)hTVSX&nk>IOqd|q2m`b4?h(HP2d(dD@vG=@(#0|6Q14J!9` zJ`4i8Lke%<1NbbLVE!JYA;n*%)I;l<7QB8Gct_JngO`qJMmTDKjz9y;gf{>!Y>}$y zryV2=!!nG7hS0(?X#-#_nzlE{o$_*wi>B=rV?krJr9r2@VQT~B#QsWiPxt#Nmm#kD z`~n|uH~JVoj8YP0^fP)Hxt|;B_&8i1ikn8OsK>L655ZQme*;w$1?T$gCMBUmBr`x` zGth*MKKIDYO}nAbMDVE*m9lBKPNz))6N{WcfOL%yi(8OH3s))7qC?*`KHF(Q0~nmn z;bPNnS;>|LTE6dgZS8Vl$fFL(s6G7x5q3B2Hif~*2Yz$4@M~*$W4@b?N%pGXhi^tx z1vC;3!OJ-$(W^r&mwC~VN@M77pT1gnIi>l9M(5n5v4OKa3z;}cRj1$tJ5Bgxu@?DD zEnH~Y4gEk5`h`3q3kp63LU_GFpx<|!$c6v0V%=~f+L(=}-}G}AA3n-W0A51I>U zCS21%Q;r$B;Z9V9Oo^uSiR~=^@v!@eG7Y6GQ<#4Pc;e z>#;UpkB$pywA9AmnRJwq)ZcM+DODV-`n+{=s#G{&V?{@cbNnsWM6l|MQp9uTKqr@gE7%JJ6dY$}@ho1blGhC#!V<-!%Fv?*3=IQ^S3=-pow+eZSB3`-e~uRNayCZ4V%K9 zJsY~C(a47G&Ip{g_Gnw%76H9czc)=$+Pb%G-P*Awx?x*%OV5VRiMGufwuL*kZ0PLh zZ0qP~+qNkZ4$F|;;Z42KXlG8(h!d&|}h+d8`1+QXgOw)S*(3SnaP%U_IwzmsRHzJrn)f)I$dj|DV4;`7ftE z^7N;7ee>GRzz_T8zV5&0K(T&#dHG+Ydv*^0>VtQdKX>mp&i=dkv4dAWXWoD2%8z{h ziK~C|>Gsd;`p~kQJ~aQ92S1Zlf5HOZLhyWVQFEsb}}fj}O~> zi<$Agh4J_9&0A$#_3xOvb6hP$Pw!pywLA3f=$mqt;tUYoDo*)#MXtKo^b2=Ax!eG0 z;k2DDlq`$C#E1XhJ{O5J(xDigj@99zW2e*btif|Go{RBZif1RDJ$UxxIgICCJb#Vn z*Ax!})Rf3UQfFhz}!^HKq`+1%L$sgxwezWZnKU9TMIA(25k^w%NGs&qzc z?mP%??~S5e;YQAx@?L>B@}8E(w>ju`j&u9xKhJX`knUH}--K9;bo%-J2&F(bl8R!E zYcVON1Rdfom9>fo@N{r%bb;ESxOV2QL>{f^>sh`{r`x1^9<~uHQH-+xQ&7qe6mAL<(_}ixmI$_?o z{eQY3|Nr0r#NYn~P)h>@6aWAK2ms`KHBGuDS^CQ?0001D000^Q003fjX>4RKO>b^* zE<2Z1Z)0n7E@W(M?R zAQ&de03(w*VP*nEU<^{9*GI9oRjU;7ZCk5V>-&LLt5xi!Rd21>%C%lgYkljjR^hI- z_C9A$5^8(z=l93&^ZVU_v-bL~wf5TYwf8=gqy?O=8U~r99cHW@3N( z%Dv>L9A}k2(NMK=g9`ghos^Zp+&#%LXmYM zQB)C^)k#}TFvn9tKGDk3rB>Z1SoJv3sz=3BGHbb&RXwT~q9R#NCa9{E1}6!F3ZQM^y#I!Z4KBC_#HmA_#Bl_H$D^OG|)>&v^CILs=?w@}`WSk?7hY`qP;2a-oU{Vd_tkNEsimw~Rp~hMY zr>{~vrra-!n@4cF4QC&(sugxs<+Q^7bHQ>suQXvlk;X+&PU4{#vSPNDPPW`q9uWU_u_t;Ye&+hxwgw8+`LAzL+zyalP3b*pA^Dcmkqg9 zx+@Kpjx+12F*9*WFf$uRz1}XQqDEMn3n()1JW%0o;E)}l2y><#VUlR4`&6@m$_^^! z3o*^6EdpFqf}EJB`6BA4Ae5gj z28P@15I5NiSN6Ode>7=!=A2~bYyI9g1Lab=qf0wC%!5%^dTNG{>9kDMfCsc@e zf;Fe}LI5i^kxL^ldX{0X;i)mK-R~_4>E2->f8}sbNvB>OqLC{!3eB^rk>!&J${=Rw zCYGt2?e;u$0TxJmdO+4AjWfeFep2y-G)@ZFQGFd%YAy9ZKWR+t-b(CJGfWdSiBuo2 zQ+xFB201{qt%I7dnt07zYsVK{-r(bM&g5nc7xkl~3DPcJYv~A0taa2&epNTj_2lVn zTGQOB3i5-?AF_Duvmeboi@HOjHtE^Axq%w7(qBjMLFYcocLiK!wCmLd(@`#rq&H!Q zD3#gibC3_X80EWz?(&V4Ll5W;xC%HXUW)VZc1$0UJdO>}sydA6C;0eL7L+=AHsLb| zADo~-=eU>fS&4W8K6U3{Mo+*^b6&4oLu-@UpKk<=%Uh@lo}zqTWgy@Q$e!5~z*(N} z3-|&?%@NEQ@KA`->&6I2x*4M`8cU)aOVnwL{ziuZceX1>t*pBqQ-OR_3IwBvs-z^;Sb3gcM})EjQyI#y+(?7yO%+p& zJ&~5?Dj}#Q!AT@&6oM)el#`$?;O!-p?+^GVW|P)06s4%3eEB(n9HGb&F7)IU5wU4C zc;|fb<*{QJx2c10OW!IM{|H=5KXCEAATaop+eckS$ScuPRd=mIvtP1;o=D8hhAH?T5e13z^ zAMyEArPB{UEvC0zoQN}pi ze1(@$P!*-#YD((y_L5q(ho*OGi1R zpMfPE?U24{OAYf9q_^OyL~-b!Wc{UfU);_3Uu?XW@ntstCgaO(+|T$53s)wM^p!SP zXQaPrgEk|*+XhWW`YIdDG1A|%L5-2V+6Lo|^tWwLVx+%g1Kj(+YXJ;5*I+XJg1;R* z_Pd-Q94*4L>j)FCp1wmBFmI%Ig@IcroR0zMdVF%^-DNhOP00gZ8Lp)$XX65avT8Sot=ga;_(R6ScL5 zrsk`3K1ttf<7XM)V&k7OzSYLJsuXhRea6i1vFbMJQm%%W>ldhYT|-pY+qtfPwJnbb8Vc z+hBz!{fG@3J?TenFw>KM%mycW(vRC}#9njZbw!&K5xcE3= zZTXS|mf{RpYWY-gPqyL~E@Sv6Ejuj}w?^O*2rrwEOY6P7&JGvi3|2W|=mCtbDU))H z@>9@uqAv2txH;+Ikf5pLQQ1MLZ4gCLtZPyDl!o^)9@*(MvQO|75tK@zHxRg^_*M>I z+2*5eaOgl9n*P~6a`}T!G`M@(c9L04qncpU-xO^kL$G-OGWf1+AxSw-2E1%~H3zs_&fz2={3dnsO- z?J=&1*8B(8>Rnl@zlfB-Si;G+?LBg7zE5bK{JKfo@c|{}A0plHk*qVV&kRmi26)cW9ehFboySa@RH1whTG*L@-%?)^|~=gTr0==(QAZfe{SzBm4bd>4w6 z)oq_p(Vr4u%%Wo7@47SE&!{g7$mBmsQ2G@sDkrGh2%7@Km);*3VCvfT zl`~6+W*+5U%BOr3h&1{ts}eJxLzxSlnLCo}`L*Ycd|t#GXb~SHMJU-##zg~4(o8%= zajH;SA#l-ArDA@|qWKD)ut0ooyLob`DpXrlTRjc<6h&`Sns5@1!`=5mOg})!<62UQ zXnZ{#q2P90Ika_-TiyaIPZrzqxKo!mF2HmH;s-IDjGG@bJFNJG)8ow2eOX@GUA|Ci zX)!Bu>&B)4h9JO*1l!~p4(rSMMPeTCxyF!nrF0YsJzX_C^2y?ocKJoCbeNbmHmJk- zOd*@-9^Wql`LKw-=Yf4$bvZgb!t^IT4YhNaU(NJcAJJE{ZuIN$H{ZS4I&3c>er;ZD zkq^$x+3NR!H<#$on7@+gFqG)IQM<+(#6OjHNxlyEv9`##BtHiV zvVIZp!Lxc4eeTU6y2(fW|Kuk6In&}il6&%q|H2@?k@?${L+GbdrP^*SiuzxN5Jd`D z&wid`pZ9W|r*RuQxfNr%UB%2FRT<1$`v;QN7> zgES|H!%o!2^MtN~(b9Z@su<--G>y>&iDohSYfzxsjAlyR97bOe)f?iD!Gwb!k~ zNdGyw2s?duxfJ+a;l0S8KmGUTRFLxb8dJ|hFUBgrb zUUl8}Oc=3Q81sjrlK`2fYYRXL=#hrF3Y7 zoh4@nXhb>%f(vSKqjuU7^(QG{nc1!eo?-Jb) z4@&g8cZHq{?^>3=)p)*bJ3*jd=XB@+xJIIH8&N$U#*P>0HX{#DS51tbg+tlfafDVg z`VP!?^jOjf_IwsI}2G-dtmfjpliV8K>B2m20dq%|=Vy6O9>A za-wMa3g1*?7JTDG(f0G*Q;j+B2Z@@BW*hUMsa&8Rx=%Ig;cAJ#sW%%7;9n~RQjAt( zA-q{Bd_J1L#yAb`s}j0{xm`vh{7j-Za!sQNUak_BS7xs<7Q+Wp_i%8Hu>`hP3*C>< z%TkC<5xO?iodJg=n&j^@mch(Z1X@_I#%O`-PZ9Z2?tY^cK9T5bM9ZP9PFSAhxyV=n z3naSEeT8u*EUOcicLl#|w83tP&em@>R>AcWO)dC=aTa_a(bm8N#%h>5O`yL9eqgMD zZ%K5KXO-)0ctE1_ypJ30@T85NG1h`MU7*vw2aFELl4!K&6{8dKCCc}{VRXSriN5f> zW2}R6iFD70#s;`nqIZnH8Rx)_65Zg@JR9K-Mi+8qh`~LKc455hRbudjt#d;+9Ab1> znc>5j0R=Mzswf(R=uJjD;SGg!UkaUfOW`C$u9?DeR{`m=1oGZnSc9lU>R!s5jcC0@ z*@4p#nT#&5>3l>Bib#|OnPKmY#$9p!xy%OCSsP-h_5s7{pn2P9UGc&!Egck>(muHGT%Ti`~lJFLz-6dUt z22U@%@38EJ|CE+LfJW3EbLh4JE-co~S6V$=plnvg%T|~;D`UA8CQC~ntVLb3!?F+B z9F~0$mX@R8Jk&)cYDIJ|Y?A0oM09FY;6oSD&kBiN?j`z+o9JEH8U7tUcUBf;Yy=%& zMEiMljwMlX7aVLu5|wW`B+1KD;UV^Rzrm*lmcN@zG@t$4!{u(#Dc8pZgZTrxMOEm` z{y)z@UXbCJJ9xj5;cv^!@aOt6ylAiBMXw58^dV6d_wujfS8>l=lT8xAui_q#6=g;w znL`rttU<1Opv1Cq(kqKB8;f^pGb5!A825jcs&Kmh`0|O~Gxj>!w|-nNe)thSIzG4Hb0c_x)=2;;z71o33{oFdBhAC} z9MO453!#zuGnlq94YNGTyjP*T(~u5_dCFppkBuA`v*A}50UMQl1tj?uM!W*349tc$ zr4l1tm~#bGqMJahSV2qOi{TRGgZwc_f1BS5BjL-!4J?nLWLN>oU&v2DwMwO53!9BG zFiq_?w!=L2`$hezebjRywvQ|uRkAz*JzoV6!K=nTI72nP7s5#@#m+W$RL*S><~lqN zYYKh@6WMYyT;qQUX2RS0>#%@Je+?+tYj6ZTQ%#P*VW3hDb18>`N;v`>17nb`&3_-y z+T`a$==FG%4}t17P3=Ydhu~#5)$@g-pfXS0mtBnX{p^uQUv!UEHt{L#4&_yUjq*9% z_F3IoDxjvFjzJPo0|mk+M_$cefjM zEBkS=eS@{Tm4|cl)!oYcykTme`e$VWO8&?-e`Z@fdr~-{kNo@88@bMx@p$c5uFwCudNt0m*VXHJ?j2OF)89kSHJ(q9ru8qdtk1JewN1S) z547E?>N3^+3hjowRS)t9m0R=zqq!uh^%0G-&3i0) zStt5T0nvAvf1dgMexmm>eU9nFOn=F=2R&R5v|bJ>ntOzHHMeEA`T&=>+E_PqLtd!Ke#xjJ}{b~DfFgX+~qN3`8=1lRHpAyHJ~x=+fl@=kCa zRDWO4;Mxthqvtl2POwK%8+IM$75XT&xL$`36_R|;R6%*4%ggj3plJ3y+y9I$hpEJm zVfrGk*_U~p9^#wx5jDqkkLwWMoDcEY@(|yj5Aluq5Z|8<@y+=V(5dtgukJ&CWQC03-Sh3Gh@^-ROcMx>q0?__=# z(;J!I#B@K?!%W{|s;NZBF|B9X$#gH%Cz*mqKFhQuZ1;jr{92~{O!qP^Gl{VeUj;$Ou@_cOy@FP%k)X_y=235u8-(iru|I!GJTTin?A02 z7SS@MbD6GX+Rt<^(Hma;;5K>4HcnKD|PuHLJbX*0An zT3p+zU8G&1eM?*K+UdIA^_7~Iv zNFNT|;Zb23+N-$Vxan*Q26|YDRK?SPmriF$Rh$J`KzmOX@@s%fIUA`8?U0N7TBLs1 z1Eom!;z`2~H{%TR!>uqL>FsbL(mUZKq(8(tHy);9zJGxS;OFo%?yq0K5+$r`S1wd; zQl3)2QtniLrM|5`qUE_pxq4iexvqBI;JVHAjO%rmtDjExK7PMT&zCNG+eY6k&`-?L z=TEMO4Z->3J8XcDU0eAro{OcHo%=Ylw^d69w(O(ap>`&{n8q`ZhAq;tzunk=H{{_H z01pK5$(Pn8@QSK%`ab&}23PX$a}9@c_;<)omim*WzFNv_F)e{>FyG_&s7ej&Q67SS z$0th-!5iBBir4j+GS~G4K2`84Rd43(Y3=P*?Nu=I)JSSxEY{lB6G_hQ$jIu=crumf z?M#`8jC^)yd;5ZDvL_bqtB-|~Ng+f})iPI0Dx8XTI`UH1>f>dtwzAg9tj&?s2D6LH zseeWtYLYKyBL(r?u=bG6J|Eiu67Oon(!sF zG?~J*p}Qy5hw04Or?j_kNrZcd?QU;h7>$QxvA$|p772GX##6O5uq56Xk457Vfn-Z+ zWW8%-y=!E>YmPhGYinR(Z@hD@oxN6Oua((rW%gQOS8EkNb+WT~L?XZC#%88i8LFpR zBAYn{a1v~8Z>+Nfbu>$0X0zGV8;i`wD@wB&H$(N2&S)&Ov;kWBlBq~{sBsAfEt#W5 zR5#2F)-!BLFcl4Gf%)qrL}N@7>%y_5;BZD0(-aABj#&An`SQ5TA(*(utWQ}gi-~Mv zUs5SFEf`MQFvy9j$%?`HNU9yzM7S%Q3PaKfaA2&qWhO{6bZR6XNkltkCmcsX9vhQl ziHgERn^{rcn@B|BspfDzygt&^x**|7Nmp#f0qmft_@Y)mXOsoF0H@3IW4|i^i#@9}B8>zGnQm-OHoig$6BTD&P!xl&M>PVh@DPz?fPIYd;nma8QhEom$!F7vdSp-*TXN2ps7=v80htRyP z&EYtv-27#cbrBq0gd%GOTRoPMP(*XucXvb*8EnTJ{!<%-#g1 zGiTSfwv&$g_h3lRYrj z0_?#66^_}Gg}4te;AueJKTv}EMmM845xMY}^~O`t?o6qR&3I%$$RIz^9NrjN8jZ(s zK@)ULe_JhsLnH3kG+%7_{LFYd@=|{@w92)0G_@HlizLn1=7^2$R&bOShUOIZ2gv3nlNg?2eXY@yQ*0fy zXs3%bhbfjiw5_#BurmaWjdBqGX8YK&E*ZDLXgVwX>jA+?FWr(}2Q__M#8RWRPDGO{97e zIZmYYQ73e2mYJO!lcBDd%#4+ib(790M#^)hJY~u=raWQF^X0(!Pw|pROmI!6xv{rL z@XgV!(KzswSb%-WlN-8ht})3gpSG!W(N3P25a#CDgAiFKPnY%qVnJjb9}~@Z=I9BH z@*YTh)WP$iB$Gp)N*scrUO{Z84gpot0Xc3taHBZ7I3#x5cE}nwV@!71$is|7#35gv zMfpr(gT-d5rMIWYOknhC*xDK4-2?k|eJ@4&CB3O7>z0M%>mx&Tboa|h@t_ipMZ0)w zCc#kqjHKDz9BDN=GvLE`nPXLDECF4r}C^qVY|*DDmt_odecv zp?QLkws*1N8K=L_J6^XQPN*WuR}9ptr4w7^C*l`@Fu0=-TV2j&Qt-zBi) zRf}CflSw~9Dw{`BXh=XEc#{#Lq1P879~^+BbWq62xE*52`RAKmeFF1Q*9xdZI@3N; zB#$%s#B|66%S@AbO=FfQZSm{+Bph%e6>#t}v-@eNV$jPm%g`a|$*_Z73-TET&kIY| zt;2Cmf+4Th(L^$pfqeIji1Rlz#5YG1W}JCzE4Qlo&qNZeTqcspw_|Q z*L8j)3j^NI;t5WqVix214L5$GeA;lV6Kke1-$A4$LJeyU$NTU`-`=nZk570iCB88p zu@D{OdhE$X5^Ml&rb`n1B2><2xrsxM#eg>n5s1<6?iJIH*bWV_71J0*p%b5!EpLSG zfpY&WSP08uG1S9!0QXt+v*y}a_+aYqMz7t_fi!^#mjLu4*Ga!#!MYUC&t-K1aFszmWf)0upnoUTX9qSHS&yL<2Kp~oJRWq*j4l!%DuPw&Xc(<{EXIe`>ff#A zL%xDtn@_#R0@4*TXG5F8_KgP2HyIOZ7I(U)<471va3=Tphgm3oLkl(s`wyu3RjN7~ zZCNxLwFgEkZl4-#R=tKRSQqSn-tEC&ck70VyvLu(iqIfKGQqY7n_W6e4YmvH(Dc9# z14jxwV26Pnxw9d#;{+oYb(A&F;|}!SALu{m8RZG~zaqLR*uOv6|BPE7g(~i?gIKW3 zr6cr`C(3X?ihTHFk{l%Vg z{YNajBVHbqw`oRL_FNIJ&d%k`|HT7pur1hs*pu<_5Y2ovqg61{XSlFUM|_AqposEx zoS~k4C^n2>v!f;+Q56qOrDh^+d4@KyrZ|hFRSt3v9Suk$=E7lRl9}qwIatGH$zzY& zipDXSNfT`3xxtA8W%)9EX`ZSw%hT)IVv^7-lR}+rgN?LYx~UTSDC#$M*Q^f9Q`Af@ zM`o2)U~>VghiG){t~J3%T7|(i9$Y@X*z`+0_VU9{MEx4<;9z7FS_Ib^a&hyLp>^WT ztQcAY`RLRDgg|@0L%*G`8=C473!Q@xn$S{Y6PmZrQ>_|v26l$$?m6w}1zzz@_bh$s ziIFco^si_4?}ZZp=-b?@fqvl_3F2if^Qyrme$S$E_4m(nO^($ps^0w9U%z+$j3*|o zegE~R+b{fTPvlRtV+ThZc;Tj-THZdR_PHOfZo2c~l_Ms0AN%OVNjZn=zkS2&7e17% z@|}9!`SbRCa>>(U+e`m&(ruol+g>T$b;jDmSwFA;RrXEOA38Jps|_#refhzoedlhT z@$Q;D_@HplXT#p{zE=3%voCu5&p%dhu?J^)b!%oK%EM=Fjy_=J=IR5RiYBLx)&Jr2 zK(i*VZjCVy)I6pQOvTVObLeem{tPctinJ7^5l8Z>6jc$SSHxUe8o_RjwVRmsl1K~o zv1W~m-g1I{tZ5VL?2>VLY9`|Soj{mBWCD%`nnAQoW$KoxN2WfRX3Nws(;SaTN8wJy z4EC!O1>0=VW0q)*E!uB$&tNR1)tE=oqmCGCmJ+PfQS1rUk+lCIOm&j>ANGMJBgaTD zWfVb#x)m2bkfUZwaP?8nW(ow^pvXbO2#-pPL7!$>GPDrcIO)ZOgV}m%kx_*DoG_+e zVbxK-lUEsYZi|Zq*NhTYJN+^Z1lRC(^1RsgpJ#ADfCE`P>|zR1V9Vq2%fl|>9peD~ zl&G(awhD%5ZdJZgQ&m-0HVKpJ zy0S$bWeuCd(Kw#S_$N2~SXx!68vlo?016ez8*&|lsR|4WEpBMV8+g1coamY;-yzQ0 zTpg;#D&`c}Z-wR8-u$&oodUH(Ue;w^_*MSB@Av8R$_1CNyy~nEJLkOk%Xf>5p2$4d?#h5=yC;@w^GGTkvUv0iV2q5TomYmgV>T z=EOOFxn|LiFaNb?;hkU5p9F&X>8r(ec*)hB)Elc4)EleKj&oMW@#-f#wtX2M<-^H{ zQ-)o$Dsw-9fIF}(XV;_Yu8-VW(=0_SQ4 zaZ601K8!cRC~D)BYY!{A-@bIofu2_SGb{ufAY`rwSw=$Nr#Ur%uy|Ah)bvP3o%b4 z-*?GAj_r$KpN9Ds{Ey2G;hj1LV!5w_G3cua?bfrGdZ3$pAGc;b-oNQ@TMm_#!5#S2 zaIe%MH%X#uMvJhY%5cm#qsORh$1<+-66qr<>uj|<{y(bwRQ^fHrRbC167-@)%FzqQ z_a*XqhvXaF^T+G=>6~vKS|#P1ix~Dw**}%{|JqNF_@ z6aWAK2mlp4RKQ)y>zb!{$GQ%7ZPWpZJ3Z*neV zY;5hl33yw@)i8YSm2|aQmgIen>}*P8JGQfjBxEOs>~=zcfFs*VBCst-l0!^3r_fRg zX-R=nX!s!PlpR9ZAyC>vSw6b(zU3{YP`c2a_Jx*i;Xmih+`1Sw&SeR3rs(Zo`l(g-RN!n) z#b>2_R?#!1Mym0t+V&AyweKUU>e$CbY**B5WBX#iLE9jDWR*v2SQ)7yE|#cqnXJX4 zp*b>+@s*6HG8ra(d8CfPL2^76nLOz5rew|8e4uqkbLJ6q)+|jL z;W>yHb5<^GI)(95^f{xs`EGc_(R;R9CM1%7LZ%oKBKmj2XMxu~+8$T&K)GT2$S1e` zluu@R!+2BWGio*7RAIcRFrIEZ2iwkTwcS*<(bN&Pi!wfHwcWjQeK%WdH#NWQqGQOd9koEDGGo*;Jo{Me6G~+{j#@y)9^OaH;Od6p8@Z zEbkaBxWzHcWMaYRJnqw3w%O~{KA&j4WGYlOJ0PhsI+%_ln@3akO(5H*PeQC$+e1Kd z9a8p`VNIxL%Tm#2OX4P@6}Zzq_!!2d(k>e9r|KS@Yj-qbcbu=UPN34x9 zL|x8}h!U|I`lF@yPq8u&>cgBkOq8s_YC%U(i#QC}8MN=8YHhsBY&=zOjOy(m^h#1s zqt;Gp?ZVa#*4F2ntsAmhC-Ss*YeCokMr-pS;%npPM2Wb_6irs13y9}b<{`@dX;$(c zBA>=&qD0&zqS?x`mv~k)4^bi>;%Tw+>?58v%tMrjmv~yOJo|}fE%Oj1;v=5vR-OaI zvyOR)5-A`9`1KjshgmFo;QkrbM#H8VXJnc2+&pIV1no#U&*IsL=*`25YigpgNKR-Q zEp39%NTF!jm#3*Os3E0452XOLpJ~CnD%^T2V=`BzdNcH>JVSh8?t*?4N7x@YAMJ zM2Qq(hsm=@dReq0SeD#E)pBqK%adnQPk3hZOadezqo?uBHw%Jg4K4&j6fEC>Ip3vI zmos%XMyX&)>L5NMoklxna;s=wynmimjn9~B%(JRd5#1E55NhB_DOkyBl?c$GMwH((@0HrRmA z0(mwi{DTP7nZH!C;*Vq4{R~d^iY$Cpvj*oQ4&y^mY+W8Lb+w_ZmikdvJqs_!pzbL~ z^~BzawJ4oCC0IgWHG$)8Fpz4)g6X-;{KgsPx-@#jYv?FAXBzWrv&Da9pxA7JjbnK~-+n?Xg+aF>`wJaU1 zyP(tqWu8m3dDEMPA^VBa2<0x)CsCR6XzsRugmYIIQcsjlG^x@$nv~ybNYre)`FMIY zoKI~kDAhDSk3+0lDHL;cE!;3q)G22~JJ7vM5Y$vH>L0*hkSG8(g1MphiOm`w?g-yeX3ApHK5+3;kmeJ(X^ zc(P%`MOL26OdBrxAG6`+|JQ7IFWRv1U$Wt1t9=fcHe77jaEX=Y^QH}#qyVg|J&rmdcaMmz|tK=S^jR#m=0svKZdh!Vk#BHHLi zW=!R@s3Wx(4PWHc#(77btIHj7i=cV>vY4l!ljcZFT8%!7wW;Hb80Xd-kMoQ=kMlk{ zp>GspPo)c|(uI3`wb-){(0u{U;l*Me<(}<^l#RcK2&V6(v!^_Cs>y>g#M1$GwR7~q z{amg?>Vcc>l+Pj4pQ3qGlbCRNici>RCK@KV1gzS!W|X%Sp1R~kG)PVGOynB?2Tx;U z2F=`Z>&#tFGxuqpIif_W$kA3+I7c&o0=$a);Hz3h{oxGi2LJoY2wapdO=5ySJ zD3Mx`kl&>{3SE^%_qSOaU1_=zQJALy+{sI6ik#6YL1*$Zo-J3fKOK>OoKio=j~ul&LUi(alvRtKh-+UFPWzm zqRa(kC1tMQlp@j^=`C9UeG#R)`C}u^KGLP0^FZD)C)CeBCHC(7Z7bEOt-Y7Vy zE*y6veK!&&s{4Ax)feY~$0>HQJQ4Cvv(Dkwrmvo+hddOGeffm_y>o_1OEDLpL4zc( zptbC3D9XZdR_TqNAyHTAY?uxeW#J@St3=(PvvE>cl!cXyZm9wdkM8ki(wKNGHg4D8 zR&9|h**c}DahY1G^7+!nA-VhQ`;p?+G+DGbXsf@?M z69sLm{vDxco4lHW#VV^Uzf89LGTV|UkqHzVR$FbQ+8)KAs9hJG*QnjYvfVarS1eqlxFEVhO; ztUBCaYD^Sf1JcqoUb@Su;_;Ry?;vSk1^!YZawlySWy!nrjnP;)D&R1nn%fLwUPVE# zOiSJk`Z4bwO~n77fJ;8|Ds57c`$+ozB!~r9OB(u5RSpez3AVNa#Y8(*Uc$7-70$RA+vXJez(%We zkDB`cQ6f`mhF#Q>W{6uBW{pPoH1Yik222?ulvjGGX0tnZlQuVHU(~1S zSYH%e-?q@9_E)*)$U<)O`yv@K(}-`OK+y8C%kKViFi)Uh0yeNvx-ADc!zCl4z*q0V~D zWbGV7_dLtP(0yxu-7z0GdRfE0JV2dOJ}a}Kf;qDY&&yV9o*qp6Hmh>8WS`x`F1v?3 zHnN;N|2-7Q>9>;?5bnZ{=|>T92#M-RdFp*yBo}Z;FZ0wsND6p^-iGdv*@v1uM!|EF zb$Q=N9X`a%n<#W6Jfg?wIqF~&jtdiPAC0UaSkMp+`Z&1d>6XqHsSou<&Dp~k3i4)7 zv7!&{S10x*GH!OF*}*2qEQijBxRNIbfMNxY@dO_zPNiGXPHr%s8$1m1D_fgcO=6zo zp_KAb#y@J#aw$gHDVRV;PU9`RT%H4hb~;9}@EaqmDEplA4W59j% z%OIsX4P|&&ne!#e;O#1Z?Mkk#$Ih)FkCvxfr{pG@lE-;Uh(Z_1QT9MrsuX2=qbpPO z_;jdze#jaof9V`~0`%`&jUj0ArrJ7=tbK>_*Lq=l)@ZX;qnpjc?q>b4n=e0JA@buU z@}X&F{;C0{LNK1?^Bue`M`!+`JOs%nfo?3!>@>r#(b>f`g_Pt|U|uzMKzcJBY6Owq z*t1X61YnEc=~~-IckvTdfg0CTntYm6TuBtNhF8dT(wk{^XA)0C^j*BnWvkF8ms`!`woKd4>%`lt?oT8c$uwYm2nd7eimCy(c=)m3)rY0=S)JO>WG1zCkYM z;G?HFkJ`1MonAtS>h~-N7in+SfJ>b8pL)~lYH+&rFAC_Tf#|iION#rsrLf`>`nrYY z(*@r||DQ;E=Hq;iquIn2KlQZlTyjQw3y{7deS!w?Ei%k>J>Gbo$>$MK#CaDd1f3g^0SRlq(hdrI&O6SyrpvMxDOERwD}C1Vrgz z7md6K^a{sIh6khKy)Iqx^Rg9xaxBH!fMKD!5J1O9(*^}|ZiDRM(0-F|IOpXb&KB!% zZa0UsW$fXkcDY8enBG@~>?^C0ezwA-hH}}U+~UNcVZ3o@kV%e&6G2OUpJA09!Kbl6@s*6`7Eh30xqLp+`h@j+GqN?kcRWShC$M30Gjj1_r8^26 zixc10CWX~2EJ(Uz;A4ex#Zc6&(7Bk-@nm1ROlxqd$=Afj!(o!gh-Yeu=FV|AcaH64 z1<}Pa{+7x3OZ3#=T*kSiOw4s@L9{F@LVGm6BJzqjcdCeND!<0V-?Y+uQbi!&li~^@ zN^}HQSkE>3Sn@`4DUj}88YYer@ss}{W=%Iiy?Db7rmj)b|4A#plJ`x4Gl(=ljr2XW zm>=9WejvoqsUlV8h5_4U%PGZsotDslaTpP&35x4>*pHE{kz(Uh92?crYrSgOwUHl^ zZPjv7DTutmK{$sdsdTI5aAtrvB3@9)>0yN{jwSv@LE93~3KCJa_j z>k&f4hA1CUON*T7Z^<81N3J;!(ruh8@)kk#Mw%n&b~)*_0u2*Mw+LNtgGl)zKOxHo zutMJf2aN=V^0S5-JbtAH-E=jYy2P#DuCnG34HNMeCJI+&e9((B-eC@Sv!SQ}%IF=a z)WgK*&gQcR3z9!I#l6WY{|xK%7K<;eT_;LcnBPO7j28{F1)Yty(x_5WJ~c_6ns1m>GoVk6dP3_Y^e;f%x)5S3A>Jj#NffM4>C> z=)PjnVam$-EpuBS3f%-nlN~e$k3Bt=R-xu3SJ0i4VlbxLFpd2>{c9T8I2=@2%hhQ7d*V($6lOK?TKLNcIOa4PSZ40gQ)5X0( z^3P;7cAj#|Ap~MynW%qAb=rD0bx$n^EW#9@(6*5LzmWXD5(}pvd|shFqSc5&e=}lG zi}4-IH6H#3!A4)UJjwM6elL>0;LCb1Qg{H_9k+9so+qyHz34h|FKXA!`%iRHn8EW@ zswV$VN?yfLe*Z3g&IftUU!p<$gXf$mbfFfd43bU&G?qdAeI8+8x<>y9)}?kncFFdLs*aHTouHhL6gs{apA7}#$<9T()CySG`6R2IT5J)_ z!nB4dw$vBABJI-}s&kBBE3=F(CH*#(I~Vzg4`vfl6Q3A4zr{JVRak;KM*sx~4C0bf zaI8r`4a{Xr7AnTvDg4gCY#vKMdP`84W+eOnFu(4WPfHtmI1Vq8@zBPTB)<2W65*?n zWmbPWY+j8l)2~J*Hfodj5`@eZl4iSII#5WFeQYxN7|q`r=a~JM>iw^@_J5UmS+r8W zEW+%c)^5nUc1QX$9Ye6gVMti+r{73S#vXmz=;E%o2JKQ;zzsqsDuh(zD; z$2`%c&f5DwWjM7^iIgHoYNJn|ygaCnFDBv3_5m8-9QGl*?%b)g&e1Tg97miT^5}ak z3VD$-MgQGSmG|?x{Che1z7o3HXMT-D^D!XRH74%Wxg)Qm4Ig^eX1=ew{|u{F+)7?i zu8>y{g`y8RBVPkfZRJ-RY`lF~0g7i8a-mczbU#|9=-nE-!X|Z3CvS43VX|7`9A)ac zl8nd1t(>XV(Ei><{mC;mdN0hQ-?iC83}_3=H_MtPM4@!5TEeX$dJ?GW9!w_f`(h-e zjL~H}UD8H;8NH9NAczfhk}2N-TD}tCbv9mIN=IAjWNKx)7InQq2Wj5ud#jTSUB{i6 zUasz;vGAy-d(~2*4({=#{Az^2vcv(!CwhP83JjtRgslmPTu5`Y!9$T(UU zz52ZZvOPy^Nef%6%{&>9mzDFyfjFpYmyL3l}TvP;i{aowF>cB9wrN8qo@bb5(` zdOuHm#|xN51LoB56!$KEy?;>n4E;VCy$eF`CD89P!e$U{>2ysm^WgCm7IQD}mWUB) zFjVBK(y$qoU*Yomp{FW~;6N2o=M+JS2A?W^tyF{mT}0(&T;9QDnDI8QKN@mXd0=Dl zQ(OW_91 zS6&LeE?>C@uOU7JpK{rJY4`=&;e6OuNm|`m(p>6?KbO8<(kU@tWC3;H5(1dA9;;G&o)eHI>j&@uC+kR@Piv3%gy;a6PgCrh5f+Wwfw@{m^RD}`qY$r?|W5r0ulb7?&+4v>70pV~ggoJ)8_ ze=H~ce_KxYJ4>nlW7cg+DV2}%xE|y3fQQQcT%P8n@>DKw;PGD1<-M$-EkNZDSk9Ip zl}CNd&oaMSX7f#j4FS^X?{zPFD`8j3i{5(pLm8D9^Qe16Z&&-liQ}q-XKSg|m1V^L z6Qq(CKEfrhG9>`3(2W-u(4U8!s>x7xim|J~RU&Zy8xL(2aKXUzqkLuHze+S|f zc(!0SrsnTp8HAe(_ZDbyRoyU_pYsnR{$K&sV^tSo{icG;u>LAj&n=;{AxLGk`bsQU zRec4^!+yf-V(O&Ne!Lri*I+jnne}?5G50xvuzsK_LT)*D?S1c9q`b%Mvy&B76XA741y4GWvaPP2;NBrBK7qJ}nQauV(7OQVzxy$ieELW)?V)^*<&j#g`_Qj#%l*qoQ&g$eT`FO{!x z`EtcD&(w`5|3pn2iQ1XHFLj!iIS7Qo*p zm@@q^W1=b356@2&Qhx4jMCers{l**6{P2T`rc6J)H_?|dcSk;Bl zdP(~l(n{bANqYflCD0Sm`+E)j=|hIDfU9bLSXc(frxA1*$^!2cR>0O40i9iPzoQCX zl~7OkSA{iDJY7Hw5E=)YX9#Ezp*lD+Q$Xtx8V{M-0=gKXi4ZtRK#}@C7EXrM5_+-b z!@>w`mC%0%?13rJFke8Sy89hdVL(EEt?~pK;4TSyt3826@GT(dOYpm*vOp6olTdr@ zxIi-;lhC1XB+v>I77FNdz8Qh(@YX^h<#WE10yALq$%6J#$&A2ESh+~ho~>xqX2IS? zf_6vYiok5RPeP~Htq#nA_a)R2S{;}R&n*`1YJ!^r^T4%4Ko6H}3M_>8mJ8^=16_e7 z(0ht#_t(n4zzTRtLNE9)2%G|R??9ZN4O|##gZXU&ni#k=a2fCOdnI&%|9-~?cy*QN;o_P<7IwhA@i!5R|8w%{dIyCss2Hr6ZWoWzlN9U-VSU9 z{xV<6jKR1Kf;MFTc_0RhB(&c7UZ4wZ*dV0z*ZnQf4ev{6QN?3{Z7`u-KyzxG!5z@s zuFLFF&V}E$n?0Nde`4rD_|SGNa2^CY1oTU1VXzlgNa#6FX|NBrN~qgg8tjJ)B=lXR zCE-d5&GjA&48V6Jv=cdZ!mlM%4W+>p6mJyJx%Sdv8Wu?C+pf}J22Phy8Oj`loeUi= zKUO(DxC{1eG_~FZpOKtlMIn0-k+vW-#hSMcfq$!~5-L}HemGHcTR(h&K zSHY_iifI!=UxFV<=s{<7=xTUNLT|gL1-}eS&JfTYo`%ph&@G`_oUv=+JPA!xrUkzO z7fa|(WqRlc+#sP&$Mn#3@KXtWTP+O!FL0bGpe9>k@Oqdep*h;T&({3H?fK2;BzNX9;Mt ztvYl&OpuUISsA(mHcIFbdwb}saJGbgXn#9!C!8yxzq{TJ+y&=L=uzd2(A_XBp?Qv; z(7kZQS?21v4~|IMbhPJv@PI*c!2R$tLvJgYkOB|Ds}gz`PrwgAd<#SFgX5ge2cS|u-01Nz?3w z!3V*8wn;k%p|hnWY!gGrpdpL)5X_Xc+ik0~hhU|IUU9C{z6NJyaXt(^lD1cSJMb{1 z7!ncX5!j!_`3PJrIq!s3+9PmH7U!dIOBUy&aF67C1UVmt$0hU=*ZHBx;Oi2)*Zp?j zad=Teab;iV3HY9bRL3gqN%-%q9-e}avU+$5T;~YR3zdsPbdRJ!w1#e;Vj=q5b$<#I z<|lNhW{e7+auYMbPME8+cs|q!^Y>yC^D8f5-t(H6Cn^c^PMwL#E;ChBPGTJ%tuX6b z>2)=rw}4c5C1C19)PKGHm#~h}>oigo#?_g4QPOx-JfoNrMEwU9I#q#C$gH0p%#~o4 zDxPx4s-%M*PdT3yuiGTM{yiR7b0O8g;-^+WtT6cx2X$!*{D?XK#^XKHZ}NowxpN`# z&(slTJ6q<0Y91-S>v=8fHjk|#W^+}EKEJ{@6d2^+CY&22&VpdBv_+*)Z#S}N~!nfS*m zO-~c$$L~wDb(H7YL6p&&e694AEBX@p-19LkAm&t*!XHNR#Q8RRiLV4aPy#>0kA|PO z@$(~a14XAG&^}VZ^*Ss)(1K+E=5o21%Qi08b9n}rF)kC_YA4q*bEz!Bte!9}$~~1; zFr;vNRW8Pz=^5UUeDJ$*jaWaWmN37=ou?SOD;L5GN;mE_)qDq5&39ncdeCh2j8W2@Lk##zDwJ}cWFI* zm)65~X}x@x*2{Nk8NN%)@Lk$9!b++rcUCM`?uU3_C6=+e^~zB=5ZI(lQ4a*DFRgxy zat&Nm*QMOSt?q}@s#mFdvEHf9RkwxWSl%AKNWBOqhL5O<`m357)Ws@U?6wiCjY z99)b$Mfx~jwV1k2p1k`Fw?o-kKU*Y0(#N6l|@Emj_=IfndK)jsVyLwUNm73vh? zS*-lJ>Nl>JxNS^%rPk?wPI;lY9-c#wi*bstnCsAodCuBOL5SG5J6c1=g7qO^t>-t=wqFR{Wq+UT z_II}1qpTa+zxqs%T_v8qJl8%|@XxNh%tJQ6)^UPV2rex~;hAm4rl_WA0eS~;a|wRZ;3{sdL%_J^A7Ubl^7ow~64a&ORfZ}>~z z?;BTt*5lAd+8RO$VW_3Aq{GrjB8AB1o7zOKXzAA}hy`Cgsv3#E

xFhvppMVL=U;6dX-jZTM=x;@{-{FjtU#e-@@^y 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 literal 0 HcmV?d00001 diff --git a/Signum.TSGenerator/Signum.TSGenerator.csproj b/Signum.TSGenerator/Signum.TSGenerator.csproj index b9cf6bc8c8..e5ac2c61c6 100644 --- a/Signum.TSGenerator/Signum.TSGenerator.csproj +++ b/Signum.TSGenerator/Signum.TSGenerator.csproj @@ -9,7 +9,7 @@ true latest x64 - 2.0.0-beta + 2.0.0-beta2 diff --git a/Signum.TSGenerator/Signum.TSGenerator.nuspec b/Signum.TSGenerator/Signum.TSGenerator.nuspec index 820edc202d..8d2408752d 100644 --- a/Signum.TSGenerator/Signum.TSGenerator.nuspec +++ b/Signum.TSGenerator/Signum.TSGenerator.nuspec @@ -2,7 +2,7 @@ Signum.TSGenerator - 2.0.0-beta + 2.0.0-beta2 TypeScript generator for Signum Framework applications Olmo del Corral https://opensource.org/licenses/MIT diff --git a/Signum.Test/Environment/Entities.cs b/Signum.Test/Environment/Entities.cs index 91a05885e6..d824605606 100644 --- a/Signum.Test/Environment/Entities.cs +++ b/Signum.Test/Environment/Entities.cs @@ -160,7 +160,6 @@ public class BandEntity : Entity, IAuthorEntity [StringLengthValidator(Min = 3, Max = 100)] public string Name { get; set; } - [NotNullValidator] public MList Members { get; set; } = new MList(); [ImplementedBy(typeof(GrammyAwardEntity), typeof(AmericanMusicAwardEntity))] diff --git a/Signum.Utilities/Csv.cs b/Signum.Utilities/Csv.cs index 4d135b1f1b..55acdb37bf 100644 --- a/Signum.Utilities/Csv.cs +++ b/Signum.Utilities/Csv.cs @@ -394,8 +394,7 @@ public class ParseCsvException : Exception public int? Row { get; set; } public string Member { get; set; } public string Value { get; set; } - - public ParseCsvException() { } + public ParseCsvException(Exception inner) : base(inner.Message, inner) { this.Row = (int?)inner.Data["row"]; @@ -403,10 +402,6 @@ public ParseCsvException(Exception inner) : base(inner.Message, inner) this.Member = (string)inner.Data["member"]; } - protected ParseCsvException( - System.Runtime.Serialization.SerializationInfo info, - System.Runtime.Serialization.StreamingContext context) : base(info, context) - { } public override string Message { diff --git a/Signum.Utilities/DescriptionManager.cs b/Signum.Utilities/DescriptionManager.cs index 2e878a970e..692a725941 100644 --- a/Signum.Utilities/DescriptionManager.cs +++ b/Signum.Utilities/DescriptionManager.cs @@ -376,7 +376,9 @@ public class LocalizedAssembly public CultureInfo Culture; public bool IsDefault; - private LocalizedAssembly() { } +#pragma warning disable CS8618 // Non-nullable field is uninitialized. + LocalizedAssembly() { } +#pragma warning restore CS8618 // Non-nullable field is uninitialized. public Dictionary Types = new Dictionary(); @@ -504,7 +506,9 @@ public class LocalizedType public Dictionary? Members { get; set; } +#pragma warning disable CS8618 // Non-nullable field is uninitialized. LocalizedType() { } +#pragma warning restore CS8618 // Non-nullable field is uninitialized. public XElement ExportXml() { diff --git a/Signum.Utilities/ExpressionExpanderAttributes.cs b/Signum.Utilities/ExpressionExpanderAttributes.cs index a79709e873..ee2ff85200 100644 --- a/Signum.Utilities/ExpressionExpanderAttributes.cs +++ b/Signum.Utilities/ExpressionExpanderAttributes.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq.Expressions; using System.Reflection; @@ -77,7 +77,6 @@ public sealed class EagerBindingAttribute : Attribute public sealed class ExpressionFieldAttribute : Attribute { public string Name { get; set; } - public Type Type { get; set; } /// The name of the field for the expression that defines the content. If not set, will be automatically found from the method body. public ExpressionFieldAttribute(string name = "auto") { diff --git a/Signum.Utilities/ExpressionTrees/ExpressionCleaner.cs b/Signum.Utilities/ExpressionTrees/ExpressionCleaner.cs index 72346ef88e..4bfff7020f 100644 --- a/Signum.Utilities/ExpressionTrees/ExpressionCleaner.cs +++ b/Signum.Utilities/ExpressionTrees/ExpressionCleaner.cs @@ -20,6 +20,12 @@ public class ExpressionCleaner : ExpressionVisitor bool shortCircuit; + public ExpressionCleaner(Func partialEval, bool shortCircuit) + { + this.partialEval = partialEval; + this.shortCircuit = shortCircuit; + } + public static Expression? Clean(Expression? expr) { return Clean(expr, ExpressionEvaluator.PartialEval, true); @@ -27,11 +33,7 @@ public class ExpressionCleaner : ExpressionVisitor public static Expression? Clean(Expression? expr, Func partialEval, bool shortCircuit) { - ExpressionCleaner ee = new ExpressionCleaner() - { - partialEval = partialEval, - shortCircuit = shortCircuit - }; + ExpressionCleaner ee = new ExpressionCleaner(partialEval, shortCircuit); var result = ee.Visit(expr); return partialEval(result); } @@ -199,6 +201,8 @@ static bool IsStatic(MemberInfo mi) static readonly BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; + + static MemberInfo? GetMember(Type decType, MemberInfo mi) { if (mi is MethodInfo) diff --git a/Signum.Utilities/Extensions/EnumerableExtensions.cs b/Signum.Utilities/Extensions/EnumerableExtensions.cs index 0b8a9fcc71..3f89428ddf 100644 --- a/Signum.Utilities/Extensions/EnumerableExtensions.cs +++ b/Signum.Utilities/Extensions/EnumerableExtensions.cs @@ -1356,7 +1356,9 @@ public enum CollectionMessage MoreThanOne0Found, } +#pragma warning disable CS8618 // Non-nullable field is uninitialized. public class JoinStrictResult +#pragma warning restore CS8618 // Non-nullable field is uninitialized. { public List Extra; public List Missing; diff --git a/Signum.Utilities/Extensions/FileExtensions.cs b/Signum.Utilities/Extensions/FileExtensions.cs index 17400c4bb1..195376dc3c 100644 --- a/Signum.Utilities/Extensions/FileExtensions.cs +++ b/Signum.Utilities/Extensions/FileExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; namespace Signum.Utilities @@ -34,7 +34,7 @@ public static void CreateParentDirectory(string filePath) public class TemporalFile : IDisposable { - string tempFile; + string tempFile = null!; public string Path { get { return tempFile; } diff --git a/Signum.Utilities/Extensions/TreeHelper.cs b/Signum.Utilities/Extensions/TreeHelper.cs index 6e09b5e3b8..a77a250cac 100644 --- a/Signum.Utilities/Extensions/TreeHelper.cs +++ b/Signum.Utilities/Extensions/TreeHelper.cs @@ -8,7 +8,7 @@ namespace Signum.Utilities { public static class TreeHelper { - public static ObservableCollection> ToTreeC(IEnumerable collection, Func getParent) + public static ObservableCollection> ToTreeC(IEnumerable collection, Func getParent) where T : class { Node top = new Node(); @@ -20,7 +20,7 @@ public static ObservableCollection> ToTreeC(IEnumerable collection createNode = item => dic.GetOrCreate(item, () => { Node itemNode = new Node(item); - T parent = getParent(item); + T? parent = getParent(item); Node parentNode = parent != null ? createNode(parent) : top; parentNode.Children.Add(itemNode); return itemNode; @@ -148,6 +148,7 @@ public Node(T value) public Node() { + Value = default(T)!; Children = new ObservableCollection>(); } diff --git a/Signum.Utilities/NaturalLanguage/NaturalLanguageTools.cs b/Signum.Utilities/NaturalLanguage/NaturalLanguageTools.cs index b40e5148b9..b42dfe4316 100644 --- a/Signum.Utilities/NaturalLanguage/NaturalLanguageTools.cs +++ b/Signum.Utilities/NaturalLanguage/NaturalLanguageTools.cs @@ -286,7 +286,9 @@ public interface INumberWriter string ToNumber(decimal number, NumberWriterSettings settings); } +#pragma warning disable CS8618 // Non-nullable field is uninitialized. public class NumberWriterSettings +#pragma warning restore CS8618 // Non-nullable field is uninitialized. { public string Unit; public string UnitPlural; diff --git a/Signum.Utilities/NotNullAttributes.cs b/Signum.Utilities/NotNullAttributes.cs index 91db8e26c7..308553f626 100644 --- a/Signum.Utilities/NotNullAttributes.cs +++ b/Signum.Utilities/NotNullAttributes.cs @@ -8,7 +8,8 @@ namespace System.Runtime.CompilerServices [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] public class NullableAttribute : Attribute { - public NullableAttribute(byte b) { + public NullableAttribute(byte b) + { B = b; } @@ -17,6 +18,18 @@ public NullableAttribute(byte[] bs) Bs = bs; } + public bool? IsNullableMain + { + get + { + var first = B ?? Bs![0]; + + return first == 1 ? (bool?)false : + first == 2 ? (bool?)true : + null; + } + } + public byte? B { get; } public byte[]? Bs { get; } } diff --git a/Signum.Utilities/Profiler/HeavyProfiler.cs b/Signum.Utilities/Profiler/HeavyProfiler.cs index 458e4d609c..b37f97f444 100644 --- a/Signum.Utilities/Profiler/HeavyProfiler.cs +++ b/Signum.Utilities/Profiler/HeavyProfiler.cs @@ -298,7 +298,7 @@ public static HeavyProfilerEntry Find(string fullIndex) return entry!; } } - +#pragma warning disable CS8618 // Non-nullable field is uninitialized. [Serializable] public class HeavyProfilerEntry { diff --git a/Signum.Utilities/Reflection/GenericInvoker.cs b/Signum.Utilities/Reflection/GenericInvoker.cs index ace9897443..54f487601a 100644 --- a/Signum.Utilities/Reflection/GenericInvoker.cs +++ b/Signum.Utilities/Reflection/GenericInvoker.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -96,11 +96,16 @@ protected override Expression VisitNew(NewExpression nex) class GeneratorVisitor : ExpressionVisitor { - Type[] types; + readonly Type[] types; + + public GeneratorVisitor(Type[] types) + { + this.types = types; + } public static Expression GetGenerator(Expression expression, Type[] types) { - return (Expression)new GeneratorVisitor { types = types }.Visit(expression); + return (Expression)new GeneratorVisitor(types).Visit(expression); } protected override Expression VisitMethodCall(MethodCallExpression m) @@ -135,7 +140,7 @@ protected override Expression VisitLambda(Expression lambda) } static MethodInfo giInside = ReflectionTools.GetMethodInfo(() => Inside(null)).GetGenericMethodDefinition(); - + static T Inside(Func lambda) { return HeavyProfiler.LogNoStackTrace("inside").Using(_ => lambda()); diff --git a/Signum.Utilities/Signum.Utilities.csproj b/Signum.Utilities/Signum.Utilities.csproj index 0b16398a45..e1c63c87cd 100644 --- a/Signum.Utilities/Signum.Utilities.csproj +++ b/Signum.Utilities/Signum.Utilities.csproj @@ -9,10 +9,6 @@ x64 - - 1701;1702;8618 - - PreserveNewest diff --git a/Signum.Utilities/Statics.cs b/Signum.Utilities/Statics.cs index 01dc2aa263..3897aa022b 100644 --- a/Signum.Utilities/Statics.cs +++ b/Signum.Utilities/Statics.cs @@ -158,7 +158,7 @@ public override void Clean() public abstract class SessionVariable: Variable { - public abstract Func ValueFactory { get; set; } + public abstract Func? ValueFactory { get; set; } protected internal SessionVariable(string name) : base(name) @@ -191,7 +191,7 @@ public SessionVariable CreateVariable(string name) class VoidVariable : SessionVariable { - public override Func ValueFactory { get; set; } + public override Func? ValueFactory { get; set; } public VoidVariable(string name) : base(name) @@ -227,7 +227,7 @@ public SessionVariable CreateVariable(string name) class SingletonVariable : SessionVariable { - public override Func ValueFactory { get; set; } + public override Func? ValueFactory { get; set; } public SingletonVariable(string name) : base(name) @@ -297,7 +297,7 @@ public OverrideableVariable(SessionVariable variable) this.variable = variable; } - public override Func ValueFactory + public override Func? ValueFactory { get { return variable.ValueFactory; } set { variable.ValueFactory = value; } diff --git a/Signum.Utilities/StringDistance.cs b/Signum.Utilities/StringDistance.cs index ed354281e4..313265dd48 100644 --- a/Signum.Utilities/StringDistance.cs +++ b/Signum.Utilities/StringDistance.cs @@ -376,7 +376,7 @@ public override string ToString() } - public List>>> DiffText(string textOld, string textNew, bool lineEndingDifferences = true) + public List>>> DiffText(string? textOld, string? textNew, bool lineEndingDifferences = true) { textOld = textOld ?? ""; textNew = textNew ?? ""; From 28c71a1cb3a02ca2a2ab286e4ddc9f4b7bc36d7c Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Sat, 16 Feb 2019 05:43:40 +0100 Subject: [PATCH 22/25] fixes in no nullable --- Signum.Engine/Operations/Graph.cs | 1 - Signum.Utilities/Extensions/StringExtensions.cs | 14 ++------------ Signum.Utilities/Reflection/TupleExtensions.cs | 4 +++- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/Signum.Engine/Operations/Graph.cs b/Signum.Engine/Operations/Graph.cs index acda29d67b..d19a8d4adf 100644 --- a/Signum.Engine/Operations/Graph.cs +++ b/Signum.Engine/Operations/Graph.cs @@ -459,7 +459,6 @@ public class Execute : _Execute, IExecuteOperation Type? IOperation.ReturnType { get { return null; } } Type? IOperation.StateType { get { return null; } } public bool AvoidImplicitSave { get; set; } - public bool AvoidImplicitSave { get; set; } Type IEntityOperation.BaseType { get { return Symbol.BaseType; } } bool IEntityOperation.HasCanExecute { get { return CanExecute != null; } } diff --git a/Signum.Utilities/Extensions/StringExtensions.cs b/Signum.Utilities/Extensions/StringExtensions.cs index f9a3432c62..0773154ae1 100644 --- a/Signum.Utilities/Extensions/StringExtensions.cs +++ b/Signum.Utilities/Extensions/StringExtensions.cs @@ -34,10 +34,10 @@ public static string DefaultText(this string? str, string defaultText) } #pragma warning disable IDE0052 // Remove unread private members - static readonly Expression> EmtpyToNullExpression = a => a == null || a.Length == 0 ? null : a; + static readonly Expression> DefaultToNullExpression = a => a == null || a.Length == 0 ? null : a; #pragma warning restore IDE0052 // Remove unread private members [ExpressionField("EmtpyToNullExpression")] - public static string? EmtpyToNull(this string? str) + public static string? DefaultToNull(this string? str) { if (!str.HasText()) return null; @@ -836,15 +836,5 @@ public static string[] SplitNoEmpty(this string text, params char[] separators) { return text.Split(separators, StringSplitOptions.RemoveEmptyEntries); } - - public static string EmptyToNull(this string text) - { - return string.IsNullOrEmpty(text) ? null : text; - } - - public static string WhiteSpaceToNull(this string text) - { - return string.IsNullOrWhiteSpace(text) ? null : text; - } } } diff --git a/Signum.Utilities/Reflection/TupleExtensions.cs b/Signum.Utilities/Reflection/TupleExtensions.cs index 4696ec5cef..2326b8796e 100644 --- a/Signum.Utilities/Reflection/TupleExtensions.cs +++ b/Signum.Utilities/Reflection/TupleExtensions.cs @@ -16,7 +16,9 @@ public static bool IsTuple(Type type) private static bool IsTupleDefinition(Type genericTypeDefinition) { - return genericTypeDefinition == TupleOf(genericTypeDefinition.GetGenericArguments().Length); + var numParameters = genericTypeDefinition.GetGenericArguments().Length; + + return numParameters <= 8 && genericTypeDefinition == TupleOf(numParameters); } public static Type TupleOf(int numParameters) From 3a4cd48368b9fd7c6892a525ed0f98532567dd3e Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Wed, 13 Mar 2019 17:21:56 +0100 Subject: [PATCH 23/25] update to new C# 8 beta --- .../CodeGeneration/ReactHookConverter.cs | 16 ++-- Signum.Engine/Database.cs | 6 +- Signum.Engine/DynamicQuery/DynamicQuery.cs | 2 +- Signum.Engine/Engine/SchemaSynchronizer.cs | 2 +- Signum.Engine/GlobalLazy.cs | 2 +- .../OverloadingSimplifier.cs | 86 +++++++++---------- .../Linq/ExpressionVisitor/QueryBinder.cs | 8 +- .../Linq/ExpressionVisitor/QueryFilterer.cs | 8 +- .../ExpressionVisitor/TranslatorBuilder.cs | 12 +-- Signum.Engine/Operations/OperationLogic.cs | 4 +- Signum.Engine/Patterns/DeletePart.cs | 4 +- Signum.Engine/Retriever.cs | 2 +- Signum.Engine/Schema/Schema.Save.cs | 16 ++-- Signum.Entities/Basics/OperationLog.cs | 2 +- Signum.Entities/DynamicQuery/QueryUtils.cs | 2 +- .../DynamicQuery/Tokens/SystemTimeToken.cs | 2 +- .../FieldNotificationAttributes.cs | 2 +- Signum.Entities/Lite.cs | 2 +- Signum.Entities/ModifiableEntity.cs | 2 +- Signum.React/Filters/SignumFilters.cs | 2 +- Signum.React/Scripts/Modals.tsx | 2 + Signum.Utilities/Csv.cs | 2 +- Signum.Utilities/ExpressionExpanderSamples.cs | 8 +- .../ExpressionTrees/ExpressionNominator.cs | 4 +- .../Extensions/StringExtensions.cs | 2 +- Signum.Utilities/Reflection/GenericInvoker.cs | 11 --- 26 files changed, 100 insertions(+), 111 deletions(-) diff --git a/Signum.Engine/CodeGeneration/ReactHookConverter.cs b/Signum.Engine/CodeGeneration/ReactHookConverter.cs index d419addc54..75d334c3f8 100644 --- a/Signum.Engine/CodeGeneration/ReactHookConverter.cs +++ b/Signum.Engine/CodeGeneration/ReactHookConverter.cs @@ -14,7 +14,7 @@ public void ConvertFilesToHooks() { while (true) { - IEnumerable files = GetFiles(); + IEnumerable? files = GetFiles(); if (files == null) return; @@ -32,7 +32,7 @@ public void ConvertFilesToHooks() } } - public virtual IEnumerable GetFiles() + public virtual IEnumerable? GetFiles() { string folder = GetFolder(); @@ -49,11 +49,11 @@ public virtual string GetFolder() return folder; } - public virtual IEnumerable SelectFiles(string folder, IEnumerable files) + public virtual IEnumerable? SelectFiles(string folder, IEnumerable files) { var result = files.Select(a => a.After(folder)).ChooseConsoleMultiple(); - if (result.IsEmpty()) + if (result == null) return null; return result.Select(a => folder + a); @@ -105,13 +105,13 @@ public virtual string SimplifyClass(string content, HashSet hookImports) var pairs = matches.Select(m => new { isStart = true, m }) .Concat(endMatch.Select(m => new { isStart = false, m })) - .OrderBy(p => p.m.Index) - .BiSelect((start, end) => new { start, end }) + .OrderBy(p => p.m!.Index) + .BiSelectC((start, end) => (start: start!, end: end!)) .Where(a => a.start.isStart && !a.end.isStart) - .Select(a => new { start = a.start.m, end = a.end.m }) + .Select(a => (start: a.start.m, end: a.end.m)) .ToList(); - string render = null; + string? render = null; foreach (var p in pairs.AsEnumerable().Reverse()) { diff --git a/Signum.Engine/Database.cs b/Signum.Engine/Database.cs index 44a85af0e3..51ac660aaf 100644 --- a/Signum.Engine/Database.cs +++ b/Signum.Engine/Database.cs @@ -1119,7 +1119,7 @@ public static IQueryable> MListElementsLite(this Lite Database.MListQuery(null)).GetGenericMethodDefinition(); + static readonly MethodInfo miMListQuery = ReflectionTools.GetMethodInfo(() => Database.MListQuery(null!)).GetGenericMethodDefinition(); static readonly MethodInfo miWhere = ReflectionTools.GetMethodInfo(() => Queryable.Where(null, a => false)).GetGenericMethodDefinition(); static readonly MethodInfo miToLite = ReflectionTools.GetMethodInfo((Entity e) => e.ToLite()).GetGenericMethodDefinition(); @@ -1212,8 +1212,8 @@ static IQueryable InDB(Lite lite) public class InDbExpander : IMethodExpander { - static readonly MethodInfo miSelect = ReflectionTools.GetMethodInfo(() => ((IQueryable)null).Select(a => a)).GetGenericMethodDefinition(); - static readonly MethodInfo miSingleEx = ReflectionTools.GetMethodInfo(() => ((IQueryable)null).SingleEx()).GetGenericMethodDefinition(); + static readonly MethodInfo miSelect = ReflectionTools.GetMethodInfo(() => ((IQueryable)null!).Select(a => a)).GetGenericMethodDefinition(); + static readonly MethodInfo miSingleEx = ReflectionTools.GetMethodInfo(() => ((IQueryable)null!).SingleEx()).GetGenericMethodDefinition(); public Expression Expand(Expression instance, Expression[] arguments, MethodInfo mi) { diff --git a/Signum.Engine/DynamicQuery/DynamicQuery.cs b/Signum.Engine/DynamicQuery/DynamicQuery.cs index da11b3f249..28219dcd66 100644 --- a/Signum.Engine/DynamicQuery/DynamicQuery.cs +++ b/Signum.Engine/DynamicQuery/DynamicQuery.cs @@ -801,7 +801,7 @@ public static DEnumerable GroupBy(this DEnumerable collection, HashSet< return new DEnumerable(resultCollection, newContext); } - static MethodInfo miGroupByQ = ReflectionTools.GetMethodInfo(() => Queryable.GroupBy((IQueryable)null, (Expression>)null, (Expression, double>>)null)).GetGenericMethodDefinition(); + static MethodInfo miGroupByQ = ReflectionTools.GetMethodInfo(() => Queryable.GroupBy((IQueryable)null!, (Expression>)null!, (Expression, double>>)null!)).GetGenericMethodDefinition(); public static DQueryable GroupBy(this DQueryable query, HashSet keyTokens, HashSet aggregateTokens) { var keySelector = KeySelector(query.Context, keyTokens); diff --git a/Signum.Engine/Engine/SchemaSynchronizer.cs b/Signum.Engine/Engine/SchemaSynchronizer.cs index 356fc46757..5176834fd9 100644 --- a/Signum.Engine/Engine/SchemaSynchronizer.cs +++ b/Signum.Engine/Engine/SchemaSynchronizer.cs @@ -649,7 +649,7 @@ private static Dictionary ApplyIndexAutoReplacements(DiffTabl tabCol.ReferenceTable.Name.Name)); } - public static Func IgnoreTable = null; + public static Func? IgnoreTable = null; public static Dictionary DefaultGetDatabaseDescription(List databases) { diff --git a/Signum.Engine/GlobalLazy.cs b/Signum.Engine/GlobalLazy.cs index 51bae85fdb..15ce4ee4f7 100644 --- a/Signum.Engine/GlobalLazy.cs +++ b/Signum.Engine/GlobalLazy.cs @@ -45,7 +45,7 @@ public static List Statistics() } - public static ResetLazy WithoutInvalidations(Func func, LazyThreadSafetyMode mode = LazyThreadSafetyMode.ExecutionAndPublication) where T : class + public static ResetLazy WithoutInvalidations(Func func, LazyThreadSafetyMode mode = LazyThreadSafetyMode.ExecutionAndPublication) { ResetLazy result = new ResetLazy(() => { diff --git a/Signum.Engine/Linq/ExpressionVisitor/OverloadingSimplifier.cs b/Signum.Engine/Linq/ExpressionVisitor/OverloadingSimplifier.cs index 9f38bad865..0a0efb2098 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/OverloadingSimplifier.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/OverloadingSimplifier.cs @@ -17,73 +17,73 @@ namespace Signum.Engine.Linq /// internal class OverloadingSimplifier : ExpressionVisitor { - public static MethodInfo miDistinctQ = ReflectionTools.GetMethodInfo(() => Queryable.Distinct((IQueryable)null)).GetGenericMethodDefinition(); - public static MethodInfo miDistinctE = ReflectionTools.GetMethodInfo(() => Enumerable.Distinct((IQueryable)null)).GetGenericMethodDefinition(); + public static MethodInfo miDistinctQ = ReflectionTools.GetMethodInfo(() => Queryable.Distinct((IQueryable)null!)).GetGenericMethodDefinition(); + public static MethodInfo miDistinctE = ReflectionTools.GetMethodInfo(() => Enumerable.Distinct((IQueryable)null!)).GetGenericMethodDefinition(); - public static MethodInfo miSelectQ = ReflectionTools.GetMethodInfo(() => Queryable.Select((IQueryable)null, s => s)).GetGenericMethodDefinition(); - public static MethodInfo miSelectE = ReflectionTools.GetMethodInfo(() => Enumerable.Select((IEnumerable)null, s => s)).GetGenericMethodDefinition(); + public static MethodInfo miSelectQ = ReflectionTools.GetMethodInfo(() => Queryable.Select((IQueryable)null!, s => s)).GetGenericMethodDefinition(); + public static MethodInfo miSelectE = ReflectionTools.GetMethodInfo(() => Enumerable.Select((IEnumerable)null!, s => s)).GetGenericMethodDefinition(); - static MethodInfo miGroupBySQ = ReflectionTools.GetMethodInfo(() => Queryable.GroupBy((IQueryable)null, s => s)).GetGenericMethodDefinition(); - static MethodInfo miGroupBySE = ReflectionTools.GetMethodInfo(() => Enumerable.GroupBy((IEnumerable)null, s => s)).GetGenericMethodDefinition(); + static MethodInfo miGroupBySQ = ReflectionTools.GetMethodInfo(() => Queryable.GroupBy((IQueryable)null!, s => s)).GetGenericMethodDefinition(); + static MethodInfo miGroupBySE = ReflectionTools.GetMethodInfo(() => Enumerable.GroupBy((IEnumerable)null!, s => s)).GetGenericMethodDefinition(); - static MethodInfo miGroupByNQ = ReflectionTools.GetMethodInfo(() => Queryable.GroupBy((IQueryable)null, s => s, s => s)).GetGenericMethodDefinition(); - static MethodInfo miGroupByNE = ReflectionTools.GetMethodInfo(() => Enumerable.GroupBy((IQueryable)null, s => s, s => s)).GetGenericMethodDefinition(); + static MethodInfo miGroupByNQ = ReflectionTools.GetMethodInfo(() => Queryable.GroupBy((IQueryable)null!, s => s, s => s)).GetGenericMethodDefinition(); + static MethodInfo miGroupByNE = ReflectionTools.GetMethodInfo(() => Enumerable.GroupBy((IQueryable)null!, s => s, s => s)).GetGenericMethodDefinition(); - static MethodInfo miGroupBySRQ = ReflectionTools.GetMethodInfo(() => Queryable.GroupBy((IQueryable)null, s => s, (s,g)=>s)).GetGenericMethodDefinition(); - static MethodInfo miGroupBySRE = ReflectionTools.GetMethodInfo(() => Enumerable.GroupBy((IEnumerable)null, s => s, (s, g) => s)).GetGenericMethodDefinition(); + static MethodInfo miGroupBySRQ = ReflectionTools.GetMethodInfo(() => Queryable.GroupBy((IQueryable)null!, s => s, (s,g)=>s)).GetGenericMethodDefinition(); + static MethodInfo miGroupBySRE = ReflectionTools.GetMethodInfo(() => Enumerable.GroupBy((IEnumerable)null!, s => s, (s, g) => s)).GetGenericMethodDefinition(); - static MethodInfo miGroupByNRQ = ReflectionTools.GetMethodInfo(() => Queryable.GroupBy((IQueryable)null, s => s, s => s, (s, g) => s)).GetGenericMethodDefinition(); - static MethodInfo miGroupByNRE = ReflectionTools.GetMethodInfo(() => Queryable.GroupBy((IQueryable)null, s => s, s => s, (s, g) => s)).GetGenericMethodDefinition(); + static MethodInfo miGroupByNRQ = ReflectionTools.GetMethodInfo(() => Queryable.GroupBy((IQueryable)null!, s => s, s => s, (s, g) => s)).GetGenericMethodDefinition(); + static MethodInfo miGroupByNRE = ReflectionTools.GetMethodInfo(() => Queryable.GroupBy((IQueryable)null!, s => s, s => s, (s, g) => s)).GetGenericMethodDefinition(); - static MethodInfo miGroupJoinQ = ReflectionTools.GetMethodInfo(() => Queryable.GroupJoin((IQueryable)null, (IQueryable)null, a => a, a => a, (a, g) => a)).GetGenericMethodDefinition(); - static MethodInfo miGroupJoinE = ReflectionTools.GetMethodInfo(() => Enumerable.GroupJoin((IEnumerable)null, (IEnumerable)null, a => a, a => a, (a, g) => a)).GetGenericMethodDefinition(); + static MethodInfo miGroupJoinQ = ReflectionTools.GetMethodInfo(() => Queryable.GroupJoin((IQueryable)null!, (IQueryable)null!, a => a, a => a, (a, g) => a)).GetGenericMethodDefinition(); + static MethodInfo miGroupJoinE = ReflectionTools.GetMethodInfo(() => Enumerable.GroupJoin((IEnumerable)null!, (IEnumerable)null!, a => a, a => a, (a, g) => a)).GetGenericMethodDefinition(); - static MethodInfo miJoinQ = ReflectionTools.GetMethodInfo(() => Queryable.Join((IQueryable)null, (IQueryable)null, a => a, a => a, (a, g) => a)).GetGenericMethodDefinition(); - static MethodInfo miJoinE = ReflectionTools.GetMethodInfo(() => Enumerable.Join((IEnumerable)null, (IEnumerable)null, a => a, a => a, (a, g) => a)).GetGenericMethodDefinition(); + static MethodInfo miJoinQ = ReflectionTools.GetMethodInfo(() => Queryable.Join((IQueryable)null!, (IQueryable)null!, a => a, a => a, (a, g) => a)).GetGenericMethodDefinition(); + static MethodInfo miJoinE = ReflectionTools.GetMethodInfo(() => Enumerable.Join((IEnumerable)null!, (IEnumerable)null!, a => a, a => a, (a, g) => a)).GetGenericMethodDefinition(); static MethodInfo miDefaultIfEmptyQ = ReflectionTools.GetMethodInfo(() => Queryable.DefaultIfEmpty(null)).GetGenericMethodDefinition(); static MethodInfo miDefaultIfEmptyE = ReflectionTools.GetMethodInfo(() => Enumerable.DefaultIfEmpty(null)).GetGenericMethodDefinition(); - static MethodInfo miCountE = ReflectionTools.GetMethodInfo(() => Enumerable.Count((IEnumerable)null)).GetGenericMethodDefinition(); - public static MethodInfo miWhereQ = ReflectionTools.GetMethodInfo(() => Queryable.Where((IQueryable)null, a => false)).GetGenericMethodDefinition(); - public static MethodInfo miWhereE = ReflectionTools.GetMethodInfo(() => Enumerable.Where((IEnumerable)null, a=>false)).GetGenericMethodDefinition(); + static MethodInfo miCountE = ReflectionTools.GetMethodInfo(() => Enumerable.Count((IEnumerable)null!)).GetGenericMethodDefinition(); + public static MethodInfo miWhereQ = ReflectionTools.GetMethodInfo(() => Queryable.Where((IQueryable)null!, a => false)).GetGenericMethodDefinition(); + public static MethodInfo miWhereE = ReflectionTools.GetMethodInfo(() => Enumerable.Where((IEnumerable)null!, a=>false)).GetGenericMethodDefinition(); - static MethodInfo miWhereIndexQ = ReflectionTools.GetMethodInfo(() => Queryable.Where((IQueryable)null, (a, i) => false)).GetGenericMethodDefinition(); - static MethodInfo miWhereIndexE = ReflectionTools.GetMethodInfo(() => Enumerable.Where((IEnumerable)null, (a, i) => false)).GetGenericMethodDefinition(); + static MethodInfo miWhereIndexQ = ReflectionTools.GetMethodInfo(() => Queryable.Where((IQueryable)null!, (a, i) => false)).GetGenericMethodDefinition(); + static MethodInfo miWhereIndexE = ReflectionTools.GetMethodInfo(() => Enumerable.Where((IEnumerable)null!, (a, i) => false)).GetGenericMethodDefinition(); - static MethodInfo miElementAtQ = ReflectionTools.GetMethodInfo(() => Queryable.ElementAt((IQueryable)null, 0)).GetGenericMethodDefinition(); - static MethodInfo miElementAtE = ReflectionTools.GetMethodInfo(() => Enumerable.ElementAt((IEnumerable)null, 0)).GetGenericMethodDefinition(); + static MethodInfo miElementAtQ = ReflectionTools.GetMethodInfo(() => Queryable.ElementAt((IQueryable)null!, 0)).GetGenericMethodDefinition(); + static MethodInfo miElementAtE = ReflectionTools.GetMethodInfo(() => Enumerable.ElementAt((IEnumerable)null!, 0)).GetGenericMethodDefinition(); - static MethodInfo miElementAtOrDefaultQ = ReflectionTools.GetMethodInfo(() => Queryable.ElementAtOrDefault((IQueryable)null, 0)).GetGenericMethodDefinition(); - static MethodInfo miElementAtOrDefaultE = ReflectionTools.GetMethodInfo(() => Enumerable.ElementAtOrDefault((IEnumerable)null, 0)).GetGenericMethodDefinition(); + static MethodInfo miElementAtOrDefaultQ = ReflectionTools.GetMethodInfo(() => Queryable.ElementAtOrDefault((IQueryable)null!, 0)).GetGenericMethodDefinition(); + static MethodInfo miElementAtOrDefaultE = ReflectionTools.GetMethodInfo(() => Enumerable.ElementAtOrDefault((IEnumerable)null!, 0)).GetGenericMethodDefinition(); - static MethodInfo miSkipQ = ReflectionTools.GetMethodInfo(() => Queryable.Skip((IQueryable)null, 0)).GetGenericMethodDefinition(); - static MethodInfo miSkipE = ReflectionTools.GetMethodInfo(() => Enumerable.Skip((IEnumerable)null, 0)).GetGenericMethodDefinition(); + static MethodInfo miSkipQ = ReflectionTools.GetMethodInfo(() => Queryable.Skip((IQueryable)null!, 0)).GetGenericMethodDefinition(); + static MethodInfo miSkipE = ReflectionTools.GetMethodInfo(() => Enumerable.Skip((IEnumerable)null!, 0)).GetGenericMethodDefinition(); - static MethodInfo miTakeQ = ReflectionTools.GetMethodInfo(() => Queryable.Take((IQueryable)null, 0)).GetGenericMethodDefinition(); - static MethodInfo miTakeE = ReflectionTools.GetMethodInfo(() => Enumerable.Take((IEnumerable)null, 0)).GetGenericMethodDefinition(); + static MethodInfo miTakeQ = ReflectionTools.GetMethodInfo(() => Queryable.Take((IQueryable)null!, 0)).GetGenericMethodDefinition(); + static MethodInfo miTakeE = ReflectionTools.GetMethodInfo(() => Enumerable.Take((IEnumerable)null!, 0)).GetGenericMethodDefinition(); - static MethodInfo miFirstQ = ReflectionTools.GetMethodInfo(() => Queryable.First((IQueryable)null)).GetGenericMethodDefinition(); - static MethodInfo miFirstE = ReflectionTools.GetMethodInfo(() => Enumerable.First((IEnumerable)null)).GetGenericMethodDefinition(); + static MethodInfo miFirstQ = ReflectionTools.GetMethodInfo(() => Queryable.First((IQueryable)null!)).GetGenericMethodDefinition(); + static MethodInfo miFirstE = ReflectionTools.GetMethodInfo(() => Enumerable.First((IEnumerable)null!)).GetGenericMethodDefinition(); - static MethodInfo miFirstOrDefaultQ = ReflectionTools.GetMethodInfo(() => Queryable.FirstOrDefault((IQueryable)null)).GetGenericMethodDefinition(); - static MethodInfo miFirstOrDefaultE = ReflectionTools.GetMethodInfo(() => Enumerable.FirstOrDefault((IEnumerable)null)).GetGenericMethodDefinition(); + static MethodInfo miFirstOrDefaultQ = ReflectionTools.GetMethodInfo(() => Queryable.FirstOrDefault((IQueryable)null!)).GetGenericMethodDefinition(); + static MethodInfo miFirstOrDefaultE = ReflectionTools.GetMethodInfo(() => Enumerable.FirstOrDefault((IEnumerable)null!)).GetGenericMethodDefinition(); - static MethodInfo miReverseQ = ReflectionTools.GetMethodInfo(() => Queryable.Reverse((IQueryable)null)).GetGenericMethodDefinition(); - static MethodInfo miReverseE = ReflectionTools.GetMethodInfo(() => Enumerable.Reverse((IEnumerable)null)).GetGenericMethodDefinition(); + static MethodInfo miReverseQ = ReflectionTools.GetMethodInfo(() => Queryable.Reverse((IQueryable)null!)).GetGenericMethodDefinition(); + static MethodInfo miReverseE = ReflectionTools.GetMethodInfo(() => Enumerable.Reverse((IEnumerable)null!)).GetGenericMethodDefinition(); - static MethodInfo miCastQ = ReflectionTools.GetMethodInfo(() => Queryable.Cast((IQueryable)null)).GetGenericMethodDefinition(); - static MethodInfo miCastE = ReflectionTools.GetMethodInfo(() => Enumerable.Cast((IEnumerable)null)).GetGenericMethodDefinition(); + static MethodInfo miCastQ = ReflectionTools.GetMethodInfo(() => Queryable.Cast((IQueryable)null!)).GetGenericMethodDefinition(); + static MethodInfo miCastE = ReflectionTools.GetMethodInfo(() => Enumerable.Cast((IEnumerable)null!)).GetGenericMethodDefinition(); - static MethodInfo miOfTypeQ = ReflectionTools.GetMethodInfo(() => Queryable.OfType((IQueryable)null)).GetGenericMethodDefinition(); - static MethodInfo miOfTypeE = ReflectionTools.GetMethodInfo(() => Enumerable.OfType((IEnumerable)null)).GetGenericMethodDefinition(); + static MethodInfo miOfTypeQ = ReflectionTools.GetMethodInfo(() => Queryable.OfType((IQueryable)null!)).GetGenericMethodDefinition(); + static MethodInfo miOfTypeE = ReflectionTools.GetMethodInfo(() => Enumerable.OfType((IEnumerable)null!)).GetGenericMethodDefinition(); - internal static MethodInfo miToString = ReflectionTools.GetMethodInfo(() => ((object)null).ToString()); + internal static MethodInfo miToString = ReflectionTools.GetMethodInfo(() => ((object)null!).ToString()); static MethodInfo miStringConcat = ReflectionTools.GetMethodInfo(() => string.Concat("", "")); - static MethodInfo miToStringSeparator = ReflectionTools.GetMethodInfo(() => EnumerableExtensions.ToString((IEnumerable)null, " ")).GetGenericMethodDefinition(); - static MethodInfo miToStringSeparatorE = ReflectionTools.GetMethodInfo(() => EnumerableExtensions.ToString((IEnumerable)null, a => a, " ")).GetGenericMethodDefinition(); - static MethodInfo miToStringSeparatorQ = ReflectionTools.GetMethodInfo(() => EnumerableExtensions.ToString((IQueryable)null, a => a, " ")).GetGenericMethodDefinition(); + static MethodInfo miToStringSeparator = ReflectionTools.GetMethodInfo(() => EnumerableExtensions.ToString((IEnumerable)null!, " ")).GetGenericMethodDefinition(); + static MethodInfo miToStringSeparatorE = ReflectionTools.GetMethodInfo(() => EnumerableExtensions.ToString((IEnumerable)null!, a => a, " ")).GetGenericMethodDefinition(); + static MethodInfo miToStringSeparatorQ = ReflectionTools.GetMethodInfo(() => EnumerableExtensions.ToString((IQueryable)null!, a => a, " ")).GetGenericMethodDefinition(); static int i = 0; diff --git a/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs b/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs index 30ef635e43..be1cde168a 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/QueryBinder.cs @@ -755,7 +755,7 @@ bool ExtractDistinct(Expression? source, out Expression? innerSource) if (info != null) { Expression? exp = aggregateFunction == AggregateSqlFunction.Count && selector == null ? null : //Count(*) - aggregateFunction == AggregateSqlFunction.Count && !distinct ? MapVisitExpand(ToNotNullPredicate(selector), info.Projector, info.Source) : + aggregateFunction == AggregateSqlFunction.Count && !distinct ? MapVisitExpand(ToNotNullPredicate(selector!), info.Projector, info.Source) : selector != null ? MapVisitExpand(selector, info.Projector, info.Source) : //Sum(Amount), Avg(Amount), ... info.Projector; @@ -776,7 +776,7 @@ bool ExtractDistinct(Expression? source, out Expression? innerSource) else //Complicated SubQuery { Expression? exp = aggregateFunction == AggregateSqlFunction.Count && selector == null ? null : - aggregateFunction == AggregateSqlFunction.Count && !distinct ? MapVisitExpand(ToNotNullPredicate(selector), projection) : + aggregateFunction == AggregateSqlFunction.Count && !distinct ? MapVisitExpand(ToNotNullPredicate(selector!), projection) : selector != null ? MapVisitExpand(selector, projection) : projection.Projector; @@ -2360,8 +2360,8 @@ internal CommandExpression BindInsert(Expression source, LambdaExpression constr return (CommandAggregateExpression)QueryJoinExpander.ExpandJoins(result, this, cleanRequests: true); } - static readonly MethodInfo miSetReadonly = ReflectionTools.GetMethodInfo(() => UnsafeEntityExtensions.SetReadonly(null, (Entity a) => a.Id, 1)).GetGenericMethodDefinition(); - static readonly MethodInfo miSetMixin = ReflectionTools.GetMethodInfo(() => ((Entity)null).SetMixin((CorruptMixin m) => m.Corrupt, true)).GetGenericMethodDefinition(); + static readonly MethodInfo miSetReadonly = ReflectionTools.GetMethodInfo(() => UnsafeEntityExtensions.SetReadonly(null!, (Entity a) => a.Id, 1)).GetGenericMethodDefinition(); + static readonly MethodInfo miSetMixin = ReflectionTools.GetMethodInfo(() => ((Entity)null!).SetMixin((CorruptMixin m) => m.Corrupt, true)).GetGenericMethodDefinition(); public void FillColumnAssigments(List assignments, ParameterExpression toInsert, Expression body, Func visitValue) { diff --git a/Signum.Engine/Linq/ExpressionVisitor/QueryFilterer.cs b/Signum.Engine/Linq/ExpressionVisitor/QueryFilterer.cs index dce2404f94..90341f48a9 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/QueryFilterer.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/QueryFilterer.cs @@ -13,7 +13,7 @@ namespace Signum.Engine.Linq { public class QueryFilterer : ExpressionVisitor { - static GenericInvoker> giFilter = new GenericInvoker>(s => s.GetInDatabaseFilter()); + static GenericInvoker> giFilter = new GenericInvoker>(s => s.GetInDatabaseFilter()); static MethodInfo miWhere = ReflectionTools.GetMethodInfo((IQueryable q) => q.Where(a => true)).GetGenericMethodDefinition(); bool filter; @@ -35,8 +35,7 @@ protected override Expression VisitConstant(ConstantExpression c) { if (typeof(Entity).IsAssignableFrom(queryType)) { - LambdaExpression rawFilter = giFilter.GetInvoker(queryType)(Schema.Current); - + LambdaExpression? rawFilter = giFilter.GetInvoker(queryType)(Schema.Current); if (rawFilter != null) { Expression clean = ExpressionCleaner.Clean(rawFilter)!; @@ -49,8 +48,7 @@ protected override Expression VisitConstant(ConstantExpression c) { Type entityType = queryType.GetGenericArguments()[0]; - LambdaExpression rawFilter = giFilter.GetInvoker(entityType)(Schema.Current); - + LambdaExpression? rawFilter = giFilter.GetInvoker(entityType)(Schema.Current); if (rawFilter != null) { var param = Expression.Parameter(queryType, "mle"); diff --git a/Signum.Engine/Linq/ExpressionVisitor/TranslatorBuilder.cs b/Signum.Engine/Linq/ExpressionVisitor/TranslatorBuilder.cs index bc7aed2a05..b84e75fa0e 100644 --- a/Signum.Engine/Linq/ExpressionVisitor/TranslatorBuilder.cs +++ b/Signum.Engine/Linq/ExpressionVisitor/TranslatorBuilder.cs @@ -166,7 +166,7 @@ public class ProjectionBuilder : DbExpressionVisitor static readonly FieldInfo fiId = ReflectionTools.GetFieldInfo((Entity i) => i.id); - static readonly MethodInfo miCached = ReflectionTools.GetMethodInfo((IRetriever r) => r.Complete(null, null)).GetGenericMethodDefinition(); + static readonly MethodInfo miCached = ReflectionTools.GetMethodInfo((IRetriever r) => r.Complete(null, null!)).GetGenericMethodDefinition(); static readonly MethodInfo miRequest = ReflectionTools.GetMethodInfo((IRetriever r) => r.Request(null)).GetGenericMethodDefinition(); static readonly MethodInfo miRequestIBA = ReflectionTools.GetMethodInfo((IRetriever r) => r.RequestIBA(null, null)).GetGenericMethodDefinition(); static readonly MethodInfo miRequestLite = ReflectionTools.GetMethodInfo((IRetriever r) => r.RequestLite(null)).GetGenericMethodDefinition(); @@ -460,7 +460,7 @@ protected internal override Expression VisitLiteValue(LiteValueExpression lite) return Expression.Call(retriever, miRequestLite.MakeGenericMethod(Lite.Extract(lite.Type)), liteConstructor); } - static readonly MethodInfo miLiteCreateParse = ReflectionTools.GetMethodInfo(() => LiteCreateParse(null, null, null, null)); + static readonly MethodInfo miLiteCreateParse = ReflectionTools.GetMethodInfo(() => LiteCreateParse(null!, null, null!, null!)); static Lite? LiteCreateParse(Schema schema, PrimaryKey? typeId, string id, string toString) { @@ -472,7 +472,7 @@ protected internal override Expression VisitLiteValue(LiteValueExpression lite) return Lite.Create(type, PrimaryKey.Parse(id, type), toString); } - static MethodInfo miLiteCreate = ReflectionTools.GetMethodInfo(() => Lite.Create(null, 0, null)); + static MethodInfo miLiteCreate = ReflectionTools.GetMethodInfo(() => Lite.Create(null!, 0, null)); protected internal override Expression VisitMListElement(MListElementExpression mle) { @@ -529,7 +529,7 @@ protected internal override Expression VisitPrimaryKeyString(PrimaryKeyStringExp return Expression.Call(miTryParse, type, id); } - static readonly MethodInfo miTryParse = ReflectionTools.GetMethodInfo(() => TryParse(null, null)); + static readonly MethodInfo miTryParse = ReflectionTools.GetMethodInfo(() => TryParse(null!, null!)); @@ -597,8 +597,8 @@ public Expression GetColumnExpression(Expression row, Alias alias, string name, return FieldReader.GetExpression(Expression.Property(row, miReader), position, type); } - static readonly MethodInfo miLookupRequest = ReflectionTools.GetMethodInfo((IProjectionRow row) => row.LookupRequest(null, 0, null)).GetGenericMethodDefinition(); - static readonly MethodInfo miLookup = ReflectionTools.GetMethodInfo((IProjectionRow row) => row.Lookup(null, 0)).GetGenericMethodDefinition(); + static readonly MethodInfo miLookupRequest = ReflectionTools.GetMethodInfo((IProjectionRow row) => row.LookupRequest(null!, 0, null!)).GetGenericMethodDefinition(); + static readonly MethodInfo miLookup = ReflectionTools.GetMethodInfo((IProjectionRow row) => row.Lookup(null!, 0)).GetGenericMethodDefinition(); public Expression LookupEager(Expression row, ChildProjectionExpression cProj) { diff --git a/Signum.Engine/Operations/OperationLogic.cs b/Signum.Engine/Operations/OperationLogic.cs index c1c9b4c13e..527d48671f 100644 --- a/Signum.Engine/Operations/OperationLogic.cs +++ b/Signum.Engine/Operations/OperationLogic.cs @@ -31,7 +31,7 @@ public static IQueryable OperationLogs(this Entity e) static Expression> CurrentOperationLogExpression = - e => e.OperationLogs().Where(ol => ol.End.HasValue && e.SystemPeriod().Contains(ol.End.Value)).OrderBy(a => a.End.Value).FirstOrDefault(); + e => e.OperationLogs().Where(ol => ol.End.HasValue && e.SystemPeriod().Contains(ol.End.Value)).OrderBy(a => a.End!.Value).FirstOrDefault(); [ExpressionField] public static OperationLogEntity PreviousOperationLog(this Entity e) { @@ -51,7 +51,7 @@ public static IQueryable Logs(this OperationSymbol o) static ResetLazy>> operationsFromKey = new ResetLazy>>(() => { return (from t in operations.OverridenTypes - from d in operations.GetDefinition(t).Keys + from d in operations.GetDefinition(t)!.Keys group t by d into g select KVP.Create(g.Key, g.ToList())).ToDictionary(); }); diff --git a/Signum.Engine/Patterns/DeletePart.cs b/Signum.Engine/Patterns/DeletePart.cs index 63d605bab3..f5d7123e8f 100644 --- a/Signum.Engine/Patterns/DeletePart.cs +++ b/Signum.Engine/Patterns/DeletePart.cs @@ -26,7 +26,7 @@ public static IDisposable AvoidDeletePart(Type partType) return new Disposable(() => avoidTypes.Value = avoidTypes.Value.Pop()); } - public static FluentInclude WithDeletePart(this FluentInclude fi, Expression> relatedEntity, Func handleOnSaving = null) + public static FluentInclude WithDeletePart(this FluentInclude fi, Expression> relatedEntity, Func? handleOnSaving = null) where T : Entity where L : Entity { @@ -45,7 +45,7 @@ public static FluentInclude WithDeletePart(this FluentInclude fi, Ex if (handleOnSaving != null) fi.SchemaBuilder.Schema.EntityEvents().Saving += e => { - if (!e.IsNew && handleOnSaving(e)) + if (!e.IsNew && handleOnSaving!(e)) { var lite = e.InDB().Select(relatedEntity).Select(a => a.ToLite()).SingleEx(); if(!lite.Is(relatedEntity.Evaluate(e))) diff --git a/Signum.Engine/Retriever.cs b/Signum.Engine/Retriever.cs index fbff836006..c398835d20 100644 --- a/Signum.Engine/Retriever.cs +++ b/Signum.Engine/Retriever.cs @@ -90,7 +90,7 @@ bool TryGetRequest((Type type, PrimaryKey id) key, out Entity value) } static GenericInvoker> giRequest = - new GenericInvoker>((rr, id) => rr.Request(id)); + new GenericInvoker>((rr, id) => rr.Request(id)!); public T? Request(PrimaryKey? id) where T : Entity { if (id == null) diff --git a/Signum.Engine/Schema/Schema.Save.cs b/Signum.Engine/Schema/Schema.Save.cs index 71091ac51a..88aa70c43a 100644 --- a/Signum.Engine/Schema/Schema.Save.cs +++ b/Signum.Engine/Schema/Schema.Save.cs @@ -1238,9 +1238,9 @@ internal Expression ConvertTicks(ParameterExpression paramOldTicks) public static partial class FieldReferenceExtensions { - static MethodInfo miGetIdForLite = ReflectionTools.GetMethodInfo(() => GetIdForLite(null, new Forbidden())); - static MethodInfo miGetIdForEntity = ReflectionTools.GetMethodInfo(() => GetIdForEntity(null, new Forbidden())); - static MethodInfo miGetIdForLiteCleanEntity = ReflectionTools.GetMethodInfo(() => GetIdForLiteCleanEntity(null, new Forbidden())); + static MethodInfo miGetIdForLite = ReflectionTools.GetMethodInfo(() => GetIdForLite(null!, new Forbidden())); + static MethodInfo miGetIdForEntity = ReflectionTools.GetMethodInfo(() => GetIdForEntity(null!, new Forbidden())); + static MethodInfo miGetIdForLiteCleanEntity = ReflectionTools.GetMethodInfo(() => GetIdForLiteCleanEntity(null!, new Forbidden())); public static void AssertIsLite(this IFieldReference fr) { @@ -1299,8 +1299,8 @@ public static Expression GetIdFactory(this IFieldReference fr, Expression value, return forbidden.Contains(ie) ? (PrimaryKey?)null : ie.Id; } - static MethodInfo miGetTypeForLite = ReflectionTools.GetMethodInfo(() => GetTypeForLite(null, new Forbidden())); - static MethodInfo miGetTypeForEntity = ReflectionTools.GetMethodInfo(() => GetTypeForEntity(null, new Forbidden())); + static MethodInfo miGetTypeForLite = ReflectionTools.GetMethodInfo(() => GetTypeForLite(null!, new Forbidden())); + static MethodInfo miGetTypeForEntity = ReflectionTools.GetMethodInfo(() => GetTypeForEntity(null!, new Forbidden())); public static Expression GetTypeFactory(this IFieldReference fr, Expression value, Expression forbidden) { @@ -1368,7 +1368,7 @@ protected internal override void CreateParameter(List trios, List fe.CheckType(null)); + static MethodInfo miCheckType = ReflectionTools.GetMethodInfo((FieldImplementedBy fe) => fe.CheckType(null!)); Type CheckType(Type type) { @@ -1394,7 +1394,7 @@ protected internal override void CreateParameter(List trios, List PrimaryKey.UnwrapToString(null)); - static MethodInfo miConvertType = ReflectionTools.GetMethodInfo(() => ConvertType(null)); + static MethodInfo miConvertType = ReflectionTools.GetMethodInfo(() => ConvertType(null!)); static IComparable? ConvertType(Type type) { @@ -1432,7 +1432,7 @@ protected internal override void CreateParameter(List trios, List fe.CheckNull(null)); + static MethodInfo miCheckNull = ReflectionTools.GetMethodInfo((FieldEmbedded fe) => fe.CheckNull(null!)); object CheckNull(object obj) { if (obj == null) diff --git a/Signum.Entities/Basics/OperationLog.cs b/Signum.Entities/Basics/OperationLog.cs index c16352d81b..15926cb251 100644 --- a/Signum.Entities/Basics/OperationLog.cs +++ b/Signum.Entities/Basics/OperationLog.cs @@ -23,7 +23,7 @@ public class OperationLogEntity : Entity public DateTime? End { get; set; } static Expression> DurationExpression = - log => (double?)(log.End - log.Start).Value.TotalMilliseconds; + log => (double?)(log.End - log.Start)!.Value.TotalMilliseconds; #pragma warning disable SF0002 // Use ExpressionFieldAttribute in non-trivial method or property [ExpressionField("DurationExpression"), Unit("ms")] #pragma warning restore SF0002 // Use ExpressionFieldAttribute in non-trivial method or property diff --git a/Signum.Entities/DynamicQuery/QueryUtils.cs b/Signum.Entities/DynamicQuery/QueryUtils.cs index c0ef15ae9d..376afe3a4b 100644 --- a/Signum.Entities/DynamicQuery/QueryUtils.cs +++ b/Signum.Entities/DynamicQuery/QueryUtils.cs @@ -298,7 +298,7 @@ private static IEnumerable AggregateTokens(QueryToken? token, QueryD } } - public static Func MergeEntityColumns = null; + public static Func? MergeEntityColumns = null; static List SubTokensBasic(QueryToken? token, QueryDescription qd, SubTokensOptions options) { if (token == null) diff --git a/Signum.Entities/DynamicQuery/Tokens/SystemTimeToken.cs b/Signum.Entities/DynamicQuery/Tokens/SystemTimeToken.cs index 3de3c8050a..34876a1b32 100644 --- a/Signum.Entities/DynamicQuery/Tokens/SystemTimeToken.cs +++ b/Signum.Entities/DynamicQuery/Tokens/SystemTimeToken.cs @@ -37,7 +37,7 @@ public override string Key { get { return this.property.ToString(); } } - static MethodInfo miSystemPeriod = ReflectionTools.GetMethodInfo((object o) => SystemTimeExtensions.SystemPeriod(null)); + static MethodInfo miSystemPeriod = ReflectionTools.GetMethodInfo((object o) => SystemTimeExtensions.SystemPeriod(null!)); protected override Expression BuildExpressionInternal(BuildExpressionContext context) { diff --git a/Signum.Entities/FieldNotificationAttributes.cs b/Signum.Entities/FieldNotificationAttributes.cs index a649ff2957..a6554a35e5 100644 --- a/Signum.Entities/FieldNotificationAttributes.cs +++ b/Signum.Entities/FieldNotificationAttributes.cs @@ -26,7 +26,7 @@ internal static class AttributeManager where T : Attribute { //Consider using ImmutableAVLTree instead - readonly static Dictionary fieldAndProperties = new Dictionary(); + readonly static Dictionary fieldAndProperties = new Dictionary(); static TypeAttributePack? GetFieldsAndProperties(Type type) { diff --git a/Signum.Entities/Lite.cs b/Signum.Entities/Lite.cs index f3b1cf5006..70b1b16e6e 100644 --- a/Signum.Entities/Lite.cs +++ b/Signum.Entities/Lite.cs @@ -75,7 +75,7 @@ public LiteImp(PrimaryKey id, string? toStr) this.Modified = ModifiedState.Clean; } - public LiteImp(T entity, string toStr) + public LiteImp(T entity, string? toStr) { if (typeof(T).IsAbstract) throw new InvalidOperationException(typeof(T).Name + " is abstract"); diff --git a/Signum.Entities/ModifiableEntity.cs b/Signum.Entities/ModifiableEntity.cs index aaecbc8e32..c0bac116f2 100644 --- a/Signum.Entities/ModifiableEntity.cs +++ b/Signum.Entities/ModifiableEntity.cs @@ -27,7 +27,7 @@ public interface IModifiableEntity : INotifyPropertyChanged, IDataErrorInfo [Serializable, DescriptionOptions(DescriptionOptions.Members | DescriptionOptions.Description), InTypeScript(false)] public abstract class ModifiableEntity : Modifiable, IModifiableEntity, ICloneable { - static Func isRetrievingFunc = null; + static Func? isRetrievingFunc = null; static public bool IsRetrieving { get { return isRetrievingFunc != null && isRetrievingFunc(); } diff --git a/Signum.React/Filters/SignumFilters.cs b/Signum.React/Filters/SignumFilters.cs index ad6aef32d9..ef5f9d06d2 100644 --- a/Signum.React/Filters/SignumFilters.cs +++ b/Signum.React/Filters/SignumFilters.cs @@ -43,7 +43,7 @@ public class SignumAuthenticationFilter : SignumDisposableResourceFilter { public SignumAuthenticationFilter() : base("Signum_User"){ } - public static readonly IList> Authenticators = new List>(); + public static readonly IList> Authenticators = new List>(); private static SignumAuthenticationResult? Authenticate(ResourceExecutingContext actionContext) { diff --git a/Signum.React/Scripts/Modals.tsx b/Signum.React/Scripts/Modals.tsx index 358f32fd72..a284528710 100644 --- a/Signum.React/Scripts/Modals.tsx +++ b/Signum.React/Scripts/Modals.tsx @@ -1,6 +1,7 @@ import * as Navigator from './Navigator'; import * as React from 'react' +import { FunctionalAdapter } from './Frames/FrameModal'; export interface IModalProps { onExited?: (val: any) => void; @@ -12,6 +13,7 @@ export interface GlobalModalContainerState { } let current: GlobalModalContainer; +let modalInstances: React.Component[] = []; export class GlobalModalContainer extends React.Component<{}, GlobalModalContainerState> { constructor(props: {}) { diff --git a/Signum.Utilities/Csv.cs b/Signum.Utilities/Csv.cs index 55acdb37bf..cf997a8e63 100644 --- a/Signum.Utilities/Csv.cs +++ b/Signum.Utilities/Csv.cs @@ -18,7 +18,7 @@ public static class Csv // Default changed since Excel exports not to UTF8 and https://stackoverflow.com/questions/49215791/vs-code-c-sharp-system-notsupportedexception-no-data-is-available-for-encodin public static Encoding DefaultEncoding => Encoding.UTF8; - public static CultureInfo DefaultCulture = null; + public static CultureInfo? DefaultCulture = null; public static string ToCsvFile(this IEnumerable collection, string fileName, Encoding? encoding = null, CultureInfo? culture = null, bool writeHeaders = true, bool autoFlush = false, bool append = false, Func, CultureInfo, Func>? toStringFactory = null) diff --git a/Signum.Utilities/ExpressionExpanderSamples.cs b/Signum.Utilities/ExpressionExpanderSamples.cs index dcd0f7be03..34707ca5d3 100644 --- a/Signum.Utilities/ExpressionExpanderSamples.cs +++ b/Signum.Utilities/ExpressionExpanderSamples.cs @@ -114,10 +114,10 @@ public Expression Expand(Expression instance, Expression[] parameters, MethodInf class ExpandNone : IMethodExpander { - static readonly MethodInfo miAnyEnumerable = ReflectionTools.GetMethodInfo(() => Enumerable.Any((IEnumerable)null)).GetGenericMethodDefinition(); - static readonly MethodInfo miAnyQueryable = ReflectionTools.GetMethodInfo(() =>Queryable.Any((IQueryable)null)).GetGenericMethodDefinition(); - static readonly MethodInfo miAnyEnumerableWithPredicate = ReflectionTools.GetMethodInfo(() =>Enumerable.Any((IEnumerable)null, null)).GetGenericMethodDefinition(); - static readonly MethodInfo miAnyQueryableWithPredicate = ReflectionTools.GetMethodInfo(() => Queryable.Any((IQueryable)null, null)).GetGenericMethodDefinition(); + static readonly MethodInfo miAnyEnumerable = ReflectionTools.GetMethodInfo(() => Enumerable.Any((IEnumerable)null!)).GetGenericMethodDefinition(); + static readonly MethodInfo miAnyQueryable = ReflectionTools.GetMethodInfo(() =>Queryable.Any((IQueryable)null!)).GetGenericMethodDefinition(); + static readonly MethodInfo miAnyEnumerableWithPredicate = ReflectionTools.GetMethodInfo(() =>Enumerable.Any((IEnumerable)null!, null)).GetGenericMethodDefinition(); + static readonly MethodInfo miAnyQueryableWithPredicate = ReflectionTools.GetMethodInfo(() => Queryable.Any((IQueryable)null!, null)).GetGenericMethodDefinition(); public Expression Expand(Expression instance, Expression[] arguments, MethodInfo mi) { diff --git a/Signum.Utilities/ExpressionTrees/ExpressionNominator.cs b/Signum.Utilities/ExpressionTrees/ExpressionNominator.cs index 814fc3a878..010d9caa36 100644 --- a/Signum.Utilities/ExpressionTrees/ExpressionNominator.cs +++ b/Signum.Utilities/ExpressionTrees/ExpressionNominator.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -113,7 +113,7 @@ public static IQueryable OrderAlsoByKeys(this IQueryable source) [MethodExpander(typeof(DistinctNullExpander))] - public static bool DistinctNull(T a, T b) where T : class + public static bool DistinctNull(T? a, T? b) where T : class { return (a == null && b != null) || (a != null && b == null) || diff --git a/Signum.Utilities/Extensions/StringExtensions.cs b/Signum.Utilities/Extensions/StringExtensions.cs index 0773154ae1..25c79d90f4 100644 --- a/Signum.Utilities/Extensions/StringExtensions.cs +++ b/Signum.Utilities/Extensions/StringExtensions.cs @@ -34,7 +34,7 @@ public static string DefaultText(this string? str, string defaultText) } #pragma warning disable IDE0052 // Remove unread private members - static readonly Expression> DefaultToNullExpression = a => a == null || a.Length == 0 ? null : a; + static readonly Expression> DefaultToNullExpression = a => a == null || a.Length == 0 ? null : a; #pragma warning restore IDE0052 // Remove unread private members [ExpressionField("EmtpyToNullExpression")] public static string? DefaultToNull(this string? str) diff --git a/Signum.Utilities/Reflection/GenericInvoker.cs b/Signum.Utilities/Reflection/GenericInvoker.cs index 54f487601a..be80c07e42 100644 --- a/Signum.Utilities/Reflection/GenericInvoker.cs +++ b/Signum.Utilities/Reflection/GenericInvoker.cs @@ -128,10 +128,6 @@ protected override Expression VisitLambda(Expression lambda) Expression body = Convert(this.Visit(lambda.Body), returnType); - //if (returnType != typeof(void)) - // body = Expression.Call(giInside.MakeGenericMethod(returnType), - // Expression.Lambda(body)); - if (body != lambda.Body) { return Expression.Lambda(lambda.Type, body, lambda.Parameters); @@ -139,13 +135,6 @@ protected override Expression VisitLambda(Expression lambda) return lambda; } - static MethodInfo giInside = ReflectionTools.GetMethodInfo(() => Inside(null)).GetGenericMethodDefinition(); - - static T Inside(Func lambda) - { - return HeavyProfiler.LogNoStackTrace("inside").Using(_ => lambda()); - } - private Expression Convert(Expression result, Type type) { if (result.Type == type) From fb5206ac62f320c81c5c11098efee68ba3cef96c Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Thu, 14 Mar 2019 08:24:56 +0100 Subject: [PATCH 24/25] initial handleKeyDown in GlobalModalContainer --- Signum.React/Scripts/Frames/ButtonBar.tsx | 8 +----- Signum.React/Scripts/Frames/FrameModal.tsx | 9 +++++-- Signum.React/Scripts/Frames/FramePage.tsx | 14 +++++++++- Signum.React/Scripts/Modals.tsx | 31 ++++++++++++++++++++-- Signum.React/Scripts/SelectorModal.tsx | 1 - 5 files changed, 50 insertions(+), 13 deletions(-) diff --git a/Signum.React/Scripts/Frames/ButtonBar.tsx b/Signum.React/Scripts/Frames/ButtonBar.tsx index 95e5639c95..4b512810c0 100644 --- a/Signum.React/Scripts/Frames/ButtonBar.tsx +++ b/Signum.React/Scripts/Frames/ButtonBar.tsx @@ -13,13 +13,7 @@ export default class ButtonBar extends React.Component{ static onButtonBarRender: Array<(ctx: ButtonsContext) => Array | undefined> = []; - componentDidMount() { - window.addEventListener("keydown", this.hanldleKeyDown); - } - - componentWillUnmount() { - window.removeEventListener("keydown", this.hanldleKeyDown); - } + hanldleKeyDown = (e: KeyboardEvent) => { var s = this.shortcuts; diff --git a/Signum.React/Scripts/Frames/FrameModal.tsx b/Signum.React/Scripts/Frames/FrameModal.tsx index 10d5d27570..68a4f0583e 100644 --- a/Signum.React/Scripts/Frames/FrameModal.tsx +++ b/Signum.React/Scripts/Frames/FrameModal.tsx @@ -1,6 +1,6 @@ import * as React from 'react' -import { openModal, IModalProps } from '../Modals' +import { openModal, IModalProps, IHandleKeyboard } from '../Modals' import MessageModal from '../Modals/MessageModal' import * as Navigator from '../Navigator' import ButtonBar from './ButtonBar' @@ -48,7 +48,7 @@ interface FrameModalState { let modalCount = 0; -export default class FrameModal extends React.Component { +export default class FrameModal extends React.Component implements IHandleKeyboard { prefix = "modal" + (modalCount++); static defaultProps: FrameModalProps = { @@ -77,6 +77,9 @@ export default class FrameModal extends React.Component).EntityType || @@ -230,6 +233,8 @@ export default class FrameModal extends React.Component { + if (!e.defaultPrevented) + this.buttonBar && this.buttonBar.hanldleKeyDown(e); } load(props: FramePageProps) { @@ -131,6 +141,8 @@ export default class FramePage extends React.Component {this.renderTitle()} {renderWidgets(wc)} - {this.entityComponent && } + {this.entityComponent && this.buttonBar = bb} frame={frame} pack={this.state.pack} />} this.validationErrors = ve} prefix="framePage" /> {embeddedWidgets.top}
diff --git a/Signum.React/Scripts/Modals.tsx b/Signum.React/Scripts/Modals.tsx index a284528710..3bf481fa48 100644 --- a/Signum.React/Scripts/Modals.tsx +++ b/Signum.React/Scripts/Modals.tsx @@ -2,18 +2,25 @@ import * as Navigator from './Navigator'; import * as React from 'react' import { FunctionalAdapter } from './Frames/FrameModal'; +import { Modal } from 'react-overlays'; export interface IModalProps { onExited?: (val: any) => void; } + +export interface IHandleKeyboard { + handleKeyDown?: (e: KeyboardEvent) => void; +} + export interface GlobalModalContainerState { modals: React.ReactElement[]; currentUrl: string; } let current: GlobalModalContainer; -let modalInstances: React.Component[] = []; + +let modalInstances: (React.Component & IHandleKeyboard)[] = []; export class GlobalModalContainer extends React.Component<{}, GlobalModalContainerState> { constructor(props: {}) { @@ -22,6 +29,25 @@ export class GlobalModalContainer extends React.Component<{}, GlobalModalContain current = this; } + componentDidMount() { + window.addEventListener("keydown", this.hanldleKeyDown); + } + + componentWillUnmount() { + window.removeEventListener("keydown", this.hanldleKeyDown); + } + + hanldleKeyDown = (e: KeyboardEvent) => { + if (modalInstances.length) { + e.preventDefault(); + var topMost = modalInstances[modalInstances.length - 1]; + + if (topMost.handleKeyDown) { + topMost.handleKeyDown(e); + } + } + } + componentWillReceiveProps(nextProps: {}, nextContext: any): void { var newUrl = Navigator.history.location.pathname; @@ -44,7 +70,8 @@ export function openModal(modal: React.ReactElement): Promise c ? modalInstances.push(c) : modalInstances.pop()); current.state.modals.push(cloned); current.forceUpdate(); diff --git a/Signum.React/Scripts/SelectorModal.tsx b/Signum.React/Scripts/SelectorModal.tsx index 11f9d1f1e3..13ccd75912 100644 --- a/Signum.React/Scripts/SelectorModal.tsx +++ b/Signum.React/Scripts/SelectorModal.tsx @@ -1,4 +1,3 @@ - import * as React from 'react' import { openModal, IModalProps } from './Modals'; import { SelectorMessage } from './Signum.Entities' From cf7f4e63ee774cb379d8e6acca6baccaf19f6660 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Fri, 15 Mar 2019 09:05:01 +0100 Subject: [PATCH 25/25] fix openedModals --- Signum.React/Scripts/Frames/FrameModal.tsx | 2 +- Signum.React/Scripts/Frames/FramePage.tsx | 4 ++-- Signum.React/Scripts/Modals.tsx | 8 +++++++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Signum.React/Scripts/Frames/FrameModal.tsx b/Signum.React/Scripts/Frames/FrameModal.tsx index 68a4f0583e..cc324108d7 100644 --- a/Signum.React/Scripts/Frames/FrameModal.tsx +++ b/Signum.React/Scripts/Frames/FrameModal.tsx @@ -277,7 +277,7 @@ export default class FrameModal extends React.Component {renderWidgets({ ctx: ctx, pack: pack })} - {this.entityComponent && } + {this.entityComponent && this.buttonBar = bb} frame={frame} pack={pack} isOperationVisible={this.props.isOperationVisible} />} this.validationErrors = ve} prefix={this.prefix} /> {embeddedWidgets.top}
diff --git a/Signum.React/Scripts/Frames/FramePage.tsx b/Signum.React/Scripts/Frames/FramePage.tsx index 83e7f29915..0eab05d6b0 100644 --- a/Signum.React/Scripts/Frames/FramePage.tsx +++ b/Signum.React/Scripts/Frames/FramePage.tsx @@ -67,8 +67,8 @@ export default class FramePage extends React.Component { - if (!e.defaultPrevented) - this.buttonBar && this.buttonBar.hanldleKeyDown(e); + if (!e.openedModals && this.buttonBar) + this.buttonBar.hanldleKeyDown(e); } load(props: FramePageProps) { diff --git a/Signum.React/Scripts/Modals.tsx b/Signum.React/Scripts/Modals.tsx index 3bf481fa48..d2716d865f 100644 --- a/Signum.React/Scripts/Modals.tsx +++ b/Signum.React/Scripts/Modals.tsx @@ -4,6 +4,12 @@ import * as React from 'react' import { FunctionalAdapter } from './Frames/FrameModal'; import { Modal } from 'react-overlays'; +declare global { + interface KeyboardEvent { + openedModals?: boolean; + } +} + export interface IModalProps { onExited?: (val: any) => void; } @@ -39,7 +45,7 @@ export class GlobalModalContainer extends React.Component<{}, GlobalModalContain hanldleKeyDown = (e: KeyboardEvent) => { if (modalInstances.length) { - e.preventDefault(); + e.openedModals = true; var topMost = modalInstances[modalInstances.length - 1]; if (topMost.handleKeyDown) {