diff --git a/.editorconfig b/.editorconfig index 40cdffa5..391bcc01 100644 --- a/.editorconfig +++ b/.editorconfig @@ -57,6 +57,9 @@ dotnet_diagnostic.CA1305.severity = none # CA1305: Specify IFormatProvide dotnet_diagnostic.CA1307.severity = suggestion # CA1307: Specify StringComparison for clarity dotnet_diagnostic.CA1309.severity = suggestion # CA1309: Use ordinal string comparison dotnet_diagnostic.CA1310.severity = warning # CA1310: Specify StringComparison for correctness +dotnet_diagnostic.CA1510.severity = none # CA1510: Use ArgumentNullException throw helper +dotnet_diagnostic.CA1512.severity = none # CA1512: Use ArgumentOutOfRangeException throw helper +dotnet_diagnostic.CA1513.severity = none # CA1513: Use ObjectDisposedException throw helper dotnet_diagnostic.CA1707.severity = none # CA1707: Identifiers should not contain underscores dotnet_diagnostic.CA1708.severity = none # CA1708: Identifiers should differ by more than case dotnet_diagnostic.CA1710.severity = none # CA1710: Identifiers should have correct suffix @@ -70,7 +73,6 @@ dotnet_diagnostic.CA1805.severity = suggestion # CA1805: Do not initialize unne dotnet_diagnostic.CA1806.severity = none # CA1806: Do not ignore method results dotnet_diagnostic.CA1816.severity = suggestion # CA1816: Dispose methods should call SuppressFinalize dotnet_diagnostic.CA1822.severity = none # CA1822: Mark members as static -dotnet_diagnostic.CA1825.severity = none # CA1825: Avoid zero-length array allocations dotnet_diagnostic.CA1830.severity = suggestion # CA1830: Prefer strongly-typed Append and Insert method overloads on StringBuilder dotnet_diagnostic.CA1834.severity = suggestion # CA1834: Consider using 'StringBuilder.Append(char)' when applicable dotnet_diagnostic.CA1837.severity = suggestion # CA1837: Use 'Environment.ProcessId' @@ -79,9 +81,9 @@ dotnet_diagnostic.CA1845.severity = none # CA1845: Use span-based 'string dotnet_diagnostic.CA1846.severity = none # CA1846: Prefer 'AsSpan' over 'Substring' dotnet_diagnostic.CA1847.severity = none # CA1847: Use char literal for a single character lookup dotnet_diagnostic.CA1852.severity = suggestion # CA1852: Seal internal types -dotnet_diagnostic.CA1854.severity = suggestion # CA1854: Prefer the 'IDictionary.TryGetValue(TKey, out TValue)' method dotnet_diagnostic.CA1859.severity = suggestion # CA1859: Use concrete types when possible for improved performance dotnet_diagnostic.CA1861.severity = suggestion # CA1861: Avoid constant arrays as arguments +dotnet_diagnostic.CA1863.severity = none # CA1863: Use 'CompositeFormat' dotnet_diagnostic.CA2101.severity = suggestion # CA2101: Specify marshaling for P/Invoke string arguments dotnet_diagnostic.CA2201.severity = none # CA2201: Do not raise reserved exception types dotnet_diagnostic.CA2208.severity = suggestion # CA2208: Instantiate argument exceptions correctly @@ -94,3 +96,6 @@ dotnet_diagnostic.CA5350.severity = suggestion # CA5350: Do Not Use Weak Crypto dotnet_diagnostic.CA5351.severity = suggestion # CA5351: Do Not Use Broken Cryptographic Algorithms dotnet_diagnostic.CA5359.severity = suggestion # CA5359: Do Not Disable Certificate Validation dotnet_diagnostic.CA5372.severity = suggestion # CA5372: Use XmlReader For XPathDocument + +dotnet_diagnostic.SYSLIB1045.severity = suggestion # SYSLIB1045: Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time +dotnet_diagnostic.SYSLIB1054.severity = suggestion # SYSLIB1054: Use 'LibraryImportAttribute' instead of 'DllImportAttribute' to generate P/Invoke marshalling code at compile time diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8eb387a2..73b4ba7f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -26,7 +26,6 @@ jobs: uses: actions/setup-dotnet@v1 with: dotnet-version: '8.0.x' - include-prerelease: true - name: Build run: pwsh make.ps1 - name: Package diff --git a/Build.proj b/Build.proj index 1b81dbec..6ba917cf 100644 --- a/Build.proj +++ b/Build.proj @@ -108,7 +108,7 @@ Outputs="$(PackageDir)\DynamicLanguageRuntime.$(PackageVersion).zip"> + Exclude="$(StageDir)\netcoreapp3.1\*;$(StageDir)\net7.0*\*;$(StageDir)\net8.0*\*;$(StageDir)\net9.0*\*" /> diff --git a/Build/net8.0.props b/Build/net8.0.props new file mode 100644 index 00000000..97529b54 --- /dev/null +++ b/Build/net8.0.props @@ -0,0 +1,37 @@ + + + + false + + + + $(Features);FEATURE_APARTMENTSTATE + $(Features);FEATURE_ASSEMBLY_GETFORWARDEDTYPES + $(Features);FEATURE_ASSEMBLY_RESOLVE + $(Features);FEATURE_ASSEMBLYBUILDER_DEFINEDYNAMICASSEMBLY + $(Features);FEATURE_CODEDOM + $(Features);FEATURE_COM + $(Features);FEATURE_CONFIGURATION + $(Features);FEATURE_CUSTOM_TYPE_DESCRIPTOR + $(Features);FEATURE_EXCEPTION_STATE + $(Features);FEATURE_FILESYSTEM + $(Features);FEATURE_FULL_CRYPTO + $(Features);FEATURE_FULL_NET + $(Features);FEATURE_LCG + $(Features);FEATURE_LOADWITHPARTIALNAME + $(Features);FEATURE_METADATA_READER + $(Features);FEATURE_MMAP + $(Features);FEATURE_NATIVE + $(Features);FEATURE_PIPES + $(Features);FEATURE_PROCESS + $(Features);FEATURE_REFEMIT + $(Features);FEATURE_REGISTRY + $(Features);FEATURE_SECURITY_RULES + $(Features);FEATURE_STACK_TRACE + $(Features);FEATURE_SYNC_SOCKETS + $(Features);FEATURE_THREAD + $(Features);FEATURE_TYPE_EQUIVALENCE + $(Features);FEATURE_TYPECONVERTER + $(Features);FEATURE_XMLDOC + + diff --git a/Dlr.sln b/Dlr.sln index a371de9b..de18fe0e 100644 --- a/Dlr.sln +++ b/Dlr.sln @@ -37,6 +37,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{60056F49 Build\After.targets = Build\After.targets Build\net462.props = Build\net462.props Build\net6.0.props = Build\net6.0.props + Build\net8.0.props = Build\net8.0.props Build\netstandard2.0.props = Build\netstandard2.0.props Build\steps.yml = Build\steps.yml EndProjectSection diff --git a/Package/nuget/DynamicLanguageRuntime.nuspec b/Package/nuget/DynamicLanguageRuntime.nuspec index f89f6e54..970b0204 100644 --- a/Package/nuget/DynamicLanguageRuntime.nuspec +++ b/Package/nuget/DynamicLanguageRuntime.nuspec @@ -26,6 +26,9 @@ + + + diff --git a/Src/Microsoft.Dynamic/Actions/Calls/ArgumentBinding.cs b/Src/Microsoft.Dynamic/Actions/Calls/ArgumentBinding.cs index 082682b7..edea0c67 100644 --- a/Src/Microsoft.Dynamic/Actions/Calls/ArgumentBinding.cs +++ b/Src/Microsoft.Dynamic/Actions/Calls/ArgumentBinding.cs @@ -7,7 +7,7 @@ namespace Microsoft.Scripting.Actions.Calls { [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes")] // TODO public struct ArgumentBinding { - private static readonly int[] _EmptyBinding = new int[0]; + private static readonly int[] _EmptyBinding = System.Array.Empty(); private readonly int _positionalArgCount; private readonly int[] _binding; // immutable diff --git a/Src/Microsoft.Dynamic/Actions/MemberTracker.cs b/Src/Microsoft.Dynamic/Actions/MemberTracker.cs index c9f06f0e..a9e6ec7b 100644 --- a/Src/Microsoft.Dynamic/Actions/MemberTracker.cs +++ b/Src/Microsoft.Dynamic/Actions/MemberTracker.cs @@ -24,7 +24,7 @@ namespace Microsoft.Scripting.Actions { /// public abstract class MemberTracker { [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2105:ArrayFieldsShouldNotBeReadOnly")] - public static readonly MemberTracker[] EmptyTrackers = new MemberTracker[0]; + public static readonly MemberTracker[] EmptyTrackers = Array.Empty(); private static readonly Dictionary _trackers = new Dictionary(); diff --git a/Src/Microsoft.Dynamic/Actions/NamespaceTracker.cs b/Src/Microsoft.Dynamic/Actions/NamespaceTracker.cs index eea45589..5c76c1c0 100644 --- a/Src/Microsoft.Dynamic/Actions/NamespaceTracker.cs +++ b/Src/Microsoft.Dynamic/Actions/NamespaceTracker.cs @@ -54,7 +54,7 @@ internal NamespaceTracker GetOrMakeChildPackage(string childName, Assembly assem if (_dict.TryGetValue(childName, out MemberTracker ret)) { // If we have a module, then we add the assembly to the InnerModule - // If it's not a module, we'll wipe it out below, eg "def System(): pass" then + // If it's not a module, we'll wipe it out below, eg "def System(): pass" then // "import System" will result in the namespace being visible. if (ret is NamespaceTracker package) { if (!package._packageAssemblies.Contains(assem)) { @@ -102,10 +102,11 @@ internal void AddTypeName(string typeName, Assembly assem) { Assert.NotNull(typeName, assem); Debug.Assert(typeName.IndexOf('.') == -1); // This is the simple name, not the full name - if (!_typeNames.ContainsKey(assem)) { - _typeNames[assem] = new TypeNames(assem, _fullName); + if (!_typeNames.TryGetValue(assem, out TypeNames typeNames)) { + typeNames = new TypeNames(assem, _fullName); + _typeNames[assem] = typeNames; } - _typeNames[assem].AddTypeName(typeName); + typeNames.AddTypeName(typeName); string normalizedTypeName = ReflectionUtils.GetNormalizedTypeName(typeName); if (_dict.ContainsKey(normalizedTypeName)) { @@ -194,9 +195,9 @@ private NamespaceTracker GetOrMakePackageHierarchy(Assembly assem, string fullNa } /// /// As a fallback, so if the type does exist in any assembly. This would happen if a new type was added - /// that was not in the hardcoded list of types. + /// that was not in the hardcoded list of types. /// This code is not accurate because: - /// 1. We dont deal with generic types (TypeCollision). + /// 1. We dont deal with generic types (TypeCollision). /// 2. Previous calls to GetCustomMemberNames (eg. "from foo import *" in Python) would not have included this type. /// 3. This does not deal with new namespaces added to the assembly /// @@ -215,7 +216,7 @@ private MemberTracker CheckForUnlistedType(string nameString) { continue; } - // We dont use TypeCollision.UpdateTypeEntity here because we do not handle generic type names + // We dont use TypeCollision.UpdateTypeEntity here because we do not handle generic type names return TypeTracker.GetTypeTracker(type); } @@ -309,7 +310,7 @@ private IList AddKeys(IList res) { } } } - + return res; } @@ -405,10 +406,7 @@ internal void AddTypeName(string typeName) { if (normalizedName == typeName) { _simpleTypeNames.Add(typeName); } else { - List actualNames; - if (_genericTypeNames.ContainsKey(normalizedName)) { - actualNames = _genericTypeNames[normalizedName]; - } else { + if (!_genericTypeNames.TryGetValue(normalizedName, out List actualNames)) { actualNames = new List(); _genericTypeNames[normalizedName] = actualNames; } diff --git a/Src/Microsoft.Dynamic/ComInterop/ComInterop.cs b/Src/Microsoft.Dynamic/ComInterop/ComInterop.cs index 0dcff69c..55c26dd3 100644 --- a/Src/Microsoft.Dynamic/ComInterop/ComInterop.cs +++ b/Src/Microsoft.Dynamic/ComInterop/ComInterop.cs @@ -25,7 +25,9 @@ internal interface IDispatchForReflection { InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00020400-0000-0000-C000-000000000046"), ] +#pragma warning disable SYSLIB1096 // Convert to 'GeneratedComInterface' internal interface IDispatch { +#pragma warning restore SYSLIB1096 // Convert to 'GeneratedComInterface' [PreserveSig] int TryGetTypeInfoCount(out uint pctinfo); @@ -75,7 +77,9 @@ internal enum IDispatchMethodIndices { InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("B196B283-BAB4-101A-B69C-00AA00341D07") ] +#pragma warning disable SYSLIB1096 // Convert to 'GeneratedComInterface' internal interface IProvideClassInfo { +#pragma warning restore SYSLIB1096 // Convert to 'GeneratedComInterface' void GetClassInfo(out IntPtr info); } diff --git a/Src/Microsoft.Dynamic/ComInterop/ComParamDesc.cs b/Src/Microsoft.Dynamic/ComInterop/ComParamDesc.cs index 41f92086..35b2f917 100644 --- a/Src/Microsoft.Dynamic/ComInterop/ComParamDesc.cs +++ b/Src/Microsoft.Dynamic/ComInterop/ComParamDesc.cs @@ -60,7 +60,7 @@ internal ComParamDesc(ref ELEMDESC elemDesc, string name) { break; } - TYPEDESC childTypeDesc = (TYPEDESC)Marshal.PtrToStructure(typeDesc.lpValue, typeof(TYPEDESC)); + TYPEDESC childTypeDesc = Marshal.PtrToStructure(typeDesc.lpValue); _vt = (VarEnum)childTypeDesc.vt; typeDesc = childTypeDesc; } diff --git a/Src/Microsoft.Dynamic/ComInterop/ComRuntimeHelpers.cs b/Src/Microsoft.Dynamic/ComInterop/ComRuntimeHelpers.cs index 9ac8902a..24f0bbbb 100644 --- a/Src/Microsoft.Dynamic/ComInterop/ComRuntimeHelpers.cs +++ b/Src/Microsoft.Dynamic/ComInterop/ComRuntimeHelpers.cs @@ -186,7 +186,7 @@ internal static ComTypes.TYPEATTR GetTypeAttrForTypeInfo(ComTypes.ITypeInfo type } try { - return (ComTypes.TYPEATTR)Marshal.PtrToStructure(pAttrs, typeof(ComTypes.TYPEATTR)); + return Marshal.PtrToStructure(pAttrs); } finally { typeInfo.ReleaseTypeAttr(pAttrs); } @@ -203,7 +203,7 @@ internal static ComTypes.TYPELIBATTR GetTypeAttrForTypeLib(ComTypes.ITypeLib typ } try { - return (ComTypes.TYPELIBATTR)Marshal.PtrToStructure(pAttrs, typeof(ComTypes.TYPELIBATTR)); + return Marshal.PtrToStructure(pAttrs); } finally { typeLib.ReleaseTLibAttr(pAttrs); } @@ -541,7 +541,7 @@ private static IUnknownReleaseDelegate Create_IUnknownRelease() { method.Emit(OpCodes.Ldarg_0); // functionPtr = *(IntPtr*)(*(interfacePointer) + VTABLE_OFFSET) - int iunknownReleaseOffset = ((int)IDispatchMethodIndices.IUnknown_Release) * Marshal.SizeOf(typeof(IntPtr)); + int iunknownReleaseOffset = ((int)IDispatchMethodIndices.IUnknown_Release) * Marshal.SizeOf(); method.Emit(OpCodes.Ldarg_0); method.Emit(OpCodes.Ldind_I); method.Emit(OpCodes.Ldc_I4, iunknownReleaseOffset); @@ -653,7 +653,7 @@ private static IDispatchInvokeDelegate Create_IDispatchInvoke(bool returnResult) EmitLoadArg(method, argErrIndex); // functionPtr = *(IntPtr*)(*(dispatchPointer) + VTABLE_OFFSET) - int idispatchInvokeOffset = ((int)IDispatchMethodIndices.IDispatch_Invoke) * Marshal.SizeOf(typeof(IntPtr)); + int idispatchInvokeOffset = ((int)IDispatchMethodIndices.IDispatch_Invoke) * Marshal.SizeOf(); EmitLoadArg(method, dispatchPointerIndex); method.Emit(OpCodes.Ldind_I); method.Emit(OpCodes.Ldc_I4, idispatchInvokeOffset); diff --git a/Src/Microsoft.Dynamic/ComInterop/ComTypeEnumDesc.cs b/Src/Microsoft.Dynamic/ComInterop/ComTypeEnumDesc.cs index 0983ae83..f3f00627 100644 --- a/Src/Microsoft.Dynamic/ComInterop/ComTypeEnumDesc.cs +++ b/Src/Microsoft.Dynamic/ComInterop/ComTypeEnumDesc.cs @@ -40,7 +40,7 @@ internal ComTypeEnumDesc(ComTypes.ITypeInfo typeInfo, ComTypeLibDesc typeLibDesc ComTypes.VARDESC varDesc; try { - varDesc = (ComTypes.VARDESC)Marshal.PtrToStructure(p, typeof(ComTypes.VARDESC)); + varDesc = Marshal.PtrToStructure(p); if (varDesc.varkind == ComTypes.VARKIND.VAR_CONST) { memberValues[i] = Marshal.GetObjectForNativeVariant(varDesc.desc.lpvarValue); diff --git a/Src/Microsoft.Dynamic/ComInterop/ExcepInfo.cs b/Src/Microsoft.Dynamic/ComInterop/ExcepInfo.cs index c344eebe..65110aa4 100644 --- a/Src/Microsoft.Dynamic/ComInterop/ExcepInfo.cs +++ b/Src/Microsoft.Dynamic/ComInterop/ExcepInfo.cs @@ -31,7 +31,7 @@ internal struct ExcepInfo { #if DEBUG [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2207:InitializeValueTypeStaticFieldsInline")] static ExcepInfo() { - Debug.Assert(Marshal.SizeOf(typeof(ExcepInfo)) == Marshal.SizeOf(typeof(ComTypes.EXCEPINFO))); + Debug.Assert(Marshal.SizeOf() == Marshal.SizeOf()); } #endif @@ -99,4 +99,4 @@ internal Exception GetException() { } } -#endif \ No newline at end of file +#endif diff --git a/Src/Microsoft.Dynamic/ComInterop/IDispatchComObject.cs b/Src/Microsoft.Dynamic/ComInterop/IDispatchComObject.cs index f2d7bada..7dc37142 100644 --- a/Src/Microsoft.Dynamic/ComInterop/IDispatchComObject.cs +++ b/Src/Microsoft.Dynamic/ComInterop/IDispatchComObject.cs @@ -335,7 +335,7 @@ private static void GetFuncDescForDescIndex(ComTypes.ITypeInfo typeInfo, int fun throw Error.CannotRetrieveTypeInformation(); } - funcDesc = (ComTypes.FUNCDESC)Marshal.PtrToStructure(pFuncDesc, typeof(ComTypes.FUNCDESC)); + funcDesc = Marshal.PtrToStructure(pFuncDesc); funcDescHandle = pFuncDesc; } diff --git a/Src/Microsoft.Dynamic/ComInterop/Variant.cs b/Src/Microsoft.Dynamic/ComInterop/Variant.cs index cc6a6894..53d13605 100644 --- a/Src/Microsoft.Dynamic/ComInterop/Variant.cs +++ b/Src/Microsoft.Dynamic/ComInterop/Variant.cs @@ -34,8 +34,8 @@ internal struct Variant { static Variant() { // Variant size is the size of 4 pointers (16 bytes) on a 32-bit processor, // and 3 pointers (24 bytes) on a 64-bit processor. - int intPtrSize = Marshal.SizeOf(typeof(IntPtr)); - int variantSize = Marshal.SizeOf(typeof(Variant)); + int intPtrSize = Marshal.SizeOf(); + int variantSize = Marshal.SizeOf(); if (intPtrSize == 4) { Debug.Assert(variantSize == (4 * intPtrSize)); } else { diff --git a/Src/Microsoft.Dynamic/Debugging/ThreadLocal.cs b/Src/Microsoft.Dynamic/Debugging/ThreadLocal.cs index e7927459..1cba52d2 100644 --- a/Src/Microsoft.Dynamic/Debugging/ThreadLocal.cs +++ b/Src/Microsoft.Dynamic/Debugging/ThreadLocal.cs @@ -10,7 +10,7 @@ namespace Microsoft.Scripting.Debugging { internal class ThreadLocal { private StorageInfo[] _stores; // array of storage indexed by managed thread ID - private static readonly StorageInfo[] Updating = new StorageInfo[0]; // a marker used when updating the array + private static readonly StorageInfo[] Updating = Array.Empty(); // a marker used when updating the array internal T Value { get { diff --git a/Src/Microsoft.Dynamic/Hosting/Shell/ConsoleHostOptionsParser.cs b/Src/Microsoft.Dynamic/Hosting/Shell/ConsoleHostOptionsParser.cs index f24d1fdf..84892902 100644 --- a/Src/Microsoft.Dynamic/Hosting/Shell/ConsoleHostOptionsParser.cs +++ b/Src/Microsoft.Dynamic/Hosting/Shell/ConsoleHostOptionsParser.cs @@ -110,8 +110,8 @@ private void ParseOption(string arg, out string name, out string value) { } if (name.StartsWith("--", StringComparison.Ordinal)) name = name.Substring("--".Length); - else if (name.StartsWith("-", StringComparison.Ordinal) && name.Length > 1) name = name.Substring("-".Length); - else if (name.StartsWith("/", StringComparison.Ordinal) && name.Length > 1) name = name.Substring("/".Length); + else if (name.StartsWith('-') && name.Length > 1) name = name.Substring("-".Length); + else if (name.StartsWith('/') && name.Length > 1) name = name.Substring("/".Length); else { value = name; name = null; diff --git a/Src/Microsoft.Dynamic/Interpreter/LightCompiler.cs b/Src/Microsoft.Dynamic/Interpreter/LightCompiler.cs index 724dc915..f610b4f3 100644 --- a/Src/Microsoft.Dynamic/Interpreter/LightCompiler.cs +++ b/Src/Microsoft.Dynamic/Interpreter/LightCompiler.cs @@ -164,7 +164,7 @@ public sealed class LightCompiler { private readonly LightCompiler _parent; - private static readonly LocalDefinition[] EmptyLocals = new LocalDefinition[0]; + private static readonly LocalDefinition[] EmptyLocals = Array.Empty(); internal LightCompiler(int compilationThreshold) { Instructions = new InstructionList(); diff --git a/Src/Microsoft.Dynamic/Microsoft.Dynamic.csproj b/Src/Microsoft.Dynamic/Microsoft.Dynamic.csproj index 402d7ddd..2590bf12 100644 --- a/Src/Microsoft.Dynamic/Microsoft.Dynamic.csproj +++ b/Src/Microsoft.Dynamic/Microsoft.Dynamic.csproj @@ -1,7 +1,7 @@  - net462;netstandard2.0;net6.0 + net462;netstandard2.0;net6.0;net8.0 Microsoft.Scripting 859832320 true diff --git a/Src/Microsoft.Dynamic/Runtime/SavableScriptCode.cs b/Src/Microsoft.Dynamic/Runtime/SavableScriptCode.cs index 4a165676..3f83745c 100644 --- a/Src/Microsoft.Dynamic/Runtime/SavableScriptCode.cs +++ b/Src/Microsoft.Dynamic/Runtime/SavableScriptCode.cs @@ -173,7 +173,7 @@ public static ScriptCode[] LoadFromAssembly(ScriptDomainManager runtime, Assembl // get the type which has our cached code... Type t = assembly.GetType("DLRCachedCode"); if (t == null) { - return new ScriptCode[0]; + return Array.Empty(); } List codes = new List(); diff --git a/Src/Microsoft.Dynamic/SerializationStubs.cs b/Src/Microsoft.Dynamic/SerializationStubs.cs new file mode 100644 index 00000000..b460fbfb --- /dev/null +++ b/Src/Microsoft.Dynamic/SerializationStubs.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the Apache 2.0 license. +// See the LICENSE file in the project root for more information. + +#if !FEATURE_SERIALIZATION + +using System; +using System.Diagnostics; + +namespace Microsoft.Scripting { + [Conditional("STUB")] + internal class SerializableAttribute : Attribute { + } + + [Conditional("STUB")] + internal class NonSerializedAttribute : Attribute { + } + + namespace Runtime { + internal interface ISerializable { + } + + internal interface IDeserializationCallback { + } + } + + internal class SerializationException : Exception { + } +} + +#endif diff --git a/Src/Microsoft.Dynamic/StringExtensions.cs b/Src/Microsoft.Dynamic/StringExtensions.cs new file mode 100644 index 00000000..eb5373da --- /dev/null +++ b/Src/Microsoft.Dynamic/StringExtensions.cs @@ -0,0 +1,19 @@ +using System; + +namespace Microsoft.Scripting +{ + internal static class StringExtensions + { +#if !NETCOREAPP + public static bool EndsWith(this string str, char value) + { + return str.EndsWith(value.ToString(), StringComparison.Ordinal); + } + + public static bool StartsWith(this string str, char value) + { + return str.StartsWith(value.ToString(), StringComparison.Ordinal); + } +#endif + } +} diff --git a/Src/Microsoft.Dynamic/Utils/CollectionExtensions.cs b/Src/Microsoft.Dynamic/Utils/CollectionExtensions.cs index a7eb9a4b..25b6c52a 100644 --- a/Src/Microsoft.Dynamic/Utils/CollectionExtensions.cs +++ b/Src/Microsoft.Dynamic/Utils/CollectionExtensions.cs @@ -138,7 +138,7 @@ internal static T[] RotateRight(this T[] array, int count) { internal static class EmptyReadOnlyCollection { - internal static readonly ReadOnlyCollection Instance = new ReadOnlyCollection(new T[0]); + internal static readonly ReadOnlyCollection Instance = new ReadOnlyCollection(Array.Empty()); } internal static class EmptyReadOnlyDictionary { @@ -151,6 +151,6 @@ internal static readonly IReadOnlyDictionary Instance } internal static class EmptyArray { - internal static readonly T[] Instance = new T[0]; + internal static readonly T[] Instance = Array.Empty(); } } diff --git a/Src/Microsoft.Dynamic/Utils/ReflectionUtils.cs b/Src/Microsoft.Dynamic/Utils/ReflectionUtils.cs index d19802f4..393aa6fa 100644 --- a/Src/Microsoft.Dynamic/Utils/ReflectionUtils.cs +++ b/Src/Microsoft.Dynamic/Utils/ReflectionUtils.cs @@ -615,7 +615,7 @@ public static GenericParameterAttributes GetGenericParameterAttributes(this Type return type.GenericParameterAttributes; } - public static readonly Type[] EmptyTypes = new Type[0]; + public static readonly Type[] EmptyTypes = Array.Empty(); public static object GetRawConstantValue(this FieldInfo field) { if (!field.IsLiteral) { diff --git a/Src/Microsoft.Dynamic/Utils/ThreadLocal.cs b/Src/Microsoft.Dynamic/Utils/ThreadLocal.cs index d624449c..ba7b55a7 100644 --- a/Src/Microsoft.Dynamic/Utils/ThreadLocal.cs +++ b/Src/Microsoft.Dynamic/Utils/ThreadLocal.cs @@ -13,7 +13,7 @@ namespace Microsoft.Scripting.Utils { /// public class ThreadLocal { private StorageInfo[] _stores; // array of storage indexed by managed thread ID - private static readonly StorageInfo[] Updating = new StorageInfo[0]; // a marker used when updating the array + private static readonly StorageInfo[] Updating = Array.Empty(); // a marker used when updating the array private readonly bool _refCounted; public ThreadLocal() { diff --git a/Src/Microsoft.Dynamic/Utils/WeakDictionary.cs b/Src/Microsoft.Dynamic/Utils/WeakDictionary.cs index 5b15db56..3f477dff 100644 --- a/Src/Microsoft.Dynamic/Utils/WeakDictionary.cs +++ b/Src/Microsoft.Dynamic/Utils/WeakDictionary.cs @@ -35,7 +35,7 @@ public class WeakDictionary : IDictionary { static WeakDictionary() { - valueConstructor = typeof(TValue).GetConstructor(new Type[] { }); + valueConstructor = typeof(TValue).GetConstructor(Array.Empty()); } #region IDictionary Members @@ -78,7 +78,7 @@ public TValue GetOrCreateValue(TKey key) { throw new InvalidOperationException($"{typeof(TValue).Name} does not have a default constructor."); } - value = (TValue)valueConstructor.Invoke(new object[] { }); + value = (TValue)valueConstructor.Invoke(Array.Empty()); Add(key, value); } diff --git a/Src/Microsoft.Scripting/Microsoft.Scripting.csproj b/Src/Microsoft.Scripting/Microsoft.Scripting.csproj index 358d3dd6..4be4bff9 100644 --- a/Src/Microsoft.Scripting/Microsoft.Scripting.csproj +++ b/Src/Microsoft.Scripting/Microsoft.Scripting.csproj @@ -1,7 +1,7 @@  - net462;netstandard2.0;net6.0 + net462;netstandard2.0;net6.0;net8.0 857735168 true @@ -25,6 +25,13 @@ + + + all + + + + diff --git a/Src/Microsoft.Scripting/Runtime/LanguageContext.cs b/Src/Microsoft.Scripting/Runtime/LanguageContext.cs index 114ab419..13e3d48d 100644 --- a/Src/Microsoft.Scripting/Runtime/LanguageContext.cs +++ b/Src/Microsoft.Scripting/Runtime/LanguageContext.cs @@ -256,7 +256,7 @@ public virtual string FormatException(Exception exception) { } public virtual IList GetStackFrames(Exception exception) { - return new DynamicStackFrame[0]; + return Array.Empty(); } public virtual LanguageOptions Options => new LanguageOptions(); diff --git a/Src/Microsoft.Scripting/Runtime/ScopeExtension.cs b/Src/Microsoft.Scripting/Runtime/ScopeExtension.cs index d47d8ae3..f1e064a5 100644 --- a/Src/Microsoft.Scripting/Runtime/ScopeExtension.cs +++ b/Src/Microsoft.Scripting/Runtime/ScopeExtension.cs @@ -9,7 +9,7 @@ namespace Microsoft.Scripting.Runtime { // TODO: this class should be abstract public class ScopeExtension { [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2105:ArrayFieldsShouldNotBeReadOnly")] - public static readonly ScopeExtension[] EmptyArray = new ScopeExtension[0]; + public static readonly ScopeExtension[] EmptyArray = System.Array.Empty(); public Scope Scope { get; } diff --git a/Src/Microsoft.Scripting/Stubs.cs b/Src/Microsoft.Scripting/Stubs.cs deleted file mode 100644 index 5766f6e7..00000000 --- a/Src/Microsoft.Scripting/Stubs.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the Apache 2.0 License. -// See the LICENSE file in the project root for more information. - -using System.Reflection; - -#if !FEATURE_SERIALIZATION - -namespace System { - using System.Diagnostics; - - [Conditional("STUB")] - public class SerializableAttribute : Attribute { - } - - [Conditional("STUB")] - public class NonSerializedAttribute : Attribute { - } - - namespace Runtime.Serialization { - public interface ISerializable { - } - - public interface IDeserializationCallback { - } - } - - public class SerializationException : Exception { - } -} - -#endif diff --git a/Src/Microsoft.Scripting/Utils/CollectionExtensions.cs b/Src/Microsoft.Scripting/Utils/CollectionExtensions.cs index 0c4a5580..1c01a962 100644 --- a/Src/Microsoft.Scripting/Utils/CollectionExtensions.cs +++ b/Src/Microsoft.Scripting/Utils/CollectionExtensions.cs @@ -88,10 +88,10 @@ internal static bool TrueForAll(this IEnumerable collection, Predicate internal static class EmptyReadOnlyCollection { - internal static readonly ReadOnlyCollection Instance = new ReadOnlyCollection(new T[0]); + internal static readonly ReadOnlyCollection Instance = new ReadOnlyCollection(Array.Empty()); } internal static class EmptyArray { - internal static readonly T[] Instance = new T[0]; + internal static readonly T[] Instance = Array.Empty(); } } diff --git a/Tests/Metadata/TypeNestings.cs b/Tests/Metadata/TypeNestings.cs index 53e56397..8a83def9 100644 --- a/Tests/Metadata/TypeNestings.cs +++ b/Tests/Metadata/TypeNestings.cs @@ -14,7 +14,7 @@ namespace Metadata { public sealed class TypeNestings { private readonly MetadataTables _tables; private readonly Dictionary> _mapping; - private static readonly TypeDef[] _EmptyTypeDefs = new TypeDef[0]; + private static readonly TypeDef[] _EmptyTypeDefs = Array.Empty(); public TypeNestings(MetadataTables tables) { ContractUtils.Requires(tables != null); diff --git a/Tests/Microsoft.Dynamic.Test/InterpreterTest.cs b/Tests/Microsoft.Dynamic.Test/InterpreterTest.cs index 701460ff..f4671bd0 100644 --- a/Tests/Microsoft.Dynamic.Test/InterpreterTest.cs +++ b/Tests/Microsoft.Dynamic.Test/InterpreterTest.cs @@ -30,7 +30,7 @@ public void PopTest() { // Equal gets converted to an EqualReference instruction which does two pops and a push. // If pop doesn't clear the stack one of the two TestGc objects should remain alive. var lambda = Expression.Lambda(Expression.Block( - Expression.Equal(Expression.New(typeof(TestGc).GetConstructor(new Type[0])), Expression.New(typeof(TestGc).GetConstructor(new Type[0]))), + Expression.Equal(Expression.New(typeof(TestGc).GetConstructor(Array.Empty())), Expression.New(typeof(TestGc).GetConstructor(Array.Empty()))), Expression.Call(typeof(TestGc).GetMethod(nameof(TestGc.CheckCount))) ));