浏览代码

Enable Meziantou.Analyzer (#1682)

Marko Lahma 1 年之前
父节点
当前提交
c5657939fc
共有 72 个文件被更改,包括 257 次插入190 次删除
  1. 27 0
      .editorconfig
  2. 1 0
      Directory.Packages.props
  3. 2 0
      Jint/Collections/DictionarySlim.cs
  4. 3 0
      Jint/Collections/StringDictionarySlim.cs
  5. 1 1
      Jint/Engine.Ast.cs
  6. 2 2
      Jint/Engine.Modules.cs
  7. 3 3
      Jint/Engine.cs
  8. 3 3
      Jint/Extensions/ReflectionExtensions.cs
  9. 7 7
      Jint/HoistingScope.cs
  10. 1 0
      Jint/Jint.csproj
  11. 5 5
      Jint/JsValueExtensions.cs
  12. 6 6
      Jint/Key.cs
  13. 1 1
      Jint/ModuleBuilder.cs
  14. 1 1
      Jint/Native/Argument/ArgumentsInstance.cs
  15. 4 4
      Jint/Native/Array/ArrayInstance.cs
  16. 3 3
      Jint/Native/Array/ArrayOperations.cs
  17. 2 2
      Jint/Native/Array/ArrayPrototype.cs
  18. 4 2
      Jint/Native/Date/DatePrototype.cs
  19. 12 8
      Jint/Native/Date/MimeKit.cs
  20. 6 4
      Jint/Native/DatePresentation.cs
  21. 2 0
      Jint/Native/FinalizationRegistry/FinalizationRegistryInstance.cs
  22. 1 1
      Jint/Native/Function/ClassDefinition.cs
  23. 3 3
      Jint/Native/Function/EvalFunctionInstance.cs
  24. 6 4
      Jint/Native/Global/GlobalObject.cs
  25. 1 1
      Jint/Native/Intl/NumberFormatConstructor.cs
  26. 10 10
      Jint/Native/JsString.cs
  27. 4 4
      Jint/Native/JsValue.cs
  28. 3 1
      Jint/Native/Json/JsonParser.cs
  29. 3 1
      Jint/Native/Number/Dtoa/CachePowers.cs
  30. 8 6
      Jint/Native/Number/Dtoa/DiyFp.cs
  31. 3 1
      Jint/Native/Number/Dtoa/DoubleHelper.cs
  32. 1 1
      Jint/Native/Object/ObjectConstructor.cs
  33. 16 14
      Jint/Native/Object/ObjectInstance.cs
  34. 3 9
      Jint/Native/PrivateName.cs
  35. 1 1
      Jint/Native/RegExp/JsRegExp.cs
  36. 2 2
      Jint/Native/RegExp/RegExpPrototype.cs
  37. 3 1
      Jint/Native/ShadowRealm/ShadowRealm.cs
  38. 4 4
      Jint/Native/String/StringInstance.cs
  39. 3 1
      Jint/Native/String/StringPrototype.cs
  40. 2 0
      Jint/Native/TypedArray/TypedArrayValue.cs
  41. 1 1
      Jint/Options.cs
  42. 1 1
      Jint/Pooling/ArgumentsInstancePool.cs
  43. 1 1
      Jint/Pooling/ReferencePool.cs
  44. 1 1
      Jint/Runtime/Debugger/OptionalSourceBreakLocationEqualityComparer.cs
  45. 3 1
      Jint/Runtime/DefaultTimeSystem.cs
  46. 18 14
      Jint/Runtime/Descriptors/PropertyDescriptor.cs
  47. 1 1
      Jint/Runtime/Environments/FunctionEnvironmentRecord.cs
  48. 1 1
      Jint/Runtime/Environments/PrivateEnvironmentRecord.cs
  49. 2 0
      Jint/Runtime/ExceptionHelper.cs
  50. 3 1
      Jint/Runtime/Host.cs
  51. 1 1
      Jint/Runtime/Interop/MethodDescriptor.cs
  52. 1 1
      Jint/Runtime/Interop/NamespaceReference.cs
  53. 1 1
      Jint/Runtime/Interop/ObjectWrapper.cs
  54. 1 1
      Jint/Runtime/Interop/Reflection/IndexerAccessor.cs
  55. 6 5
      Jint/Runtime/Interop/TypeResolver.cs
  56. 0 4
      Jint/Runtime/Interpreter/Expressions/JintAssignmentExpression.cs
  57. 1 1
      Jint/Runtime/Interpreter/Expressions/JintBinaryExpression.cs
  58. 2 2
      Jint/Runtime/Interpreter/Expressions/JintMetaPropertyExpression.cs
  59. 2 2
      Jint/Runtime/Interpreter/Expressions/JintObjectExpression.cs
  60. 1 1
      Jint/Runtime/Interpreter/Expressions/JintUnaryExpression.cs
  61. 3 3
      Jint/Runtime/Interpreter/JintFunctionDefinition.cs
  62. 2 2
      Jint/Runtime/Interpreter/Statements/JintDoWhileStatement.cs
  63. 6 2
      Jint/Runtime/Interpreter/Statements/JintForInForOfStatement.cs
  64. 2 2
      Jint/Runtime/Interpreter/Statements/JintForStatement.cs
  65. 1 1
      Jint/Runtime/Interpreter/Statements/JintLabeledStatement.cs
  66. 1 1
      Jint/Runtime/Interpreter/Statements/JintSwitchStatement.cs
  67. 2 2
      Jint/Runtime/Interpreter/Statements/JintWhileStatement.cs
  68. 1 1
      Jint/Runtime/Modules/CyclicModuleRecord.cs
  69. 3 3
      Jint/Runtime/Modules/ModuleNamespace.cs
  70. 9 9
      Jint/Runtime/Modules/SourceTextModuleRecord.cs
  71. 3 3
      Jint/Runtime/References/Reference.cs
  72. 3 3
      Jint/Runtime/TypeConverter.cs

+ 27 - 0
.editorconfig

@@ -51,6 +51,33 @@ dotnet_diagnostic.CA1710.severity = none
 #  Error CA1716: Identifiers should have correct suffix
 dotnet_diagnostic.CA1716.severity = none
 
+#  Error MA0026: TODO
+dotnet_diagnostic.MA0026.severity = none
+
+#  Error MA0048 : File name must match type name
+dotnet_diagnostic.MA0048.severity = none
+
+#  Error MA0016 : Prefer using collection abstraction instead of implementation
+dotnet_diagnostic.MA0016.severity = none
+
+#  Error MA0017 : Abstract types should not have public or internal constructors
+dotnet_diagnostic.MA0017.severity = none
+
+#  Error MA0051 : Method is too long
+dotnet_diagnostic.MA0051.severity = none
+
+#  Error MA0046 : The delegate must return void
+dotnet_diagnostic.MA0046.severity = none
+
+#  Error MA0097 : A class that implements IComparable<T> or IComparable should override comparison operators
+dotnet_diagnostic.MA0097.severity = none
+
+#  Error MA0025 : Implement the functionality (or raise NotSupportedException or PlatformNotSupportedException)
+dotnet_diagnostic.MA0025.severity = none
+
+#  Error MA0091 : Sender parameter should be 'this' for instance events
+dotnet_diagnostic.MA0091.severity = none
+
 # Sort using and Import directives with System.* appearing first
 dotnet_sort_system_directives_first = true
 dotnet_separate_import_directive_groups = false

+ 1 - 0
Directory.Packages.props

@@ -8,6 +8,7 @@
     <PackageVersion Include="Esprima" Version="3.0.2" />
     <PackageVersion Include="Flurl.Http.Signed" Version="3.2.4" />
     <PackageVersion Include="Jurassic" Version="3.2.7" />
+    <PackageVersion Include="Meziantou.Analyzer" Version="2.0.106" />
     <PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
     <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
     <PackageVersion Include="MongoDB.Bson.signed" Version="2.19.0" />

+ 2 - 0
Jint/Collections/DictionarySlim.cs

@@ -7,6 +7,7 @@
 using System.Collections;
 using System.Diagnostics;
 using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
 
 namespace Jint.Collections
 {
@@ -32,6 +33,7 @@ namespace Jint.Collections
         private Entry[] _entries;
 
         [DebuggerDisplay("({key}, {value})->{next}")]
+        [StructLayout(LayoutKind.Auto)]
         private struct Entry
         {
             public TKey key;

+ 3 - 0
Jint/Collections/StringDictionarySlim.cs

@@ -1,3 +1,6 @@
+#pragma warning disable MA0006
+#pragma warning disable MA0008
+
 #nullable disable
 
 // Licensed to the .NET Foundation under one or more agreements.

+ 1 - 1
Jint/Engine.Ast.cs

@@ -43,7 +43,7 @@ public partial class Engine
 
     private sealed class AstAnalyzer
     {
-        private readonly Dictionary<string, EnvironmentRecord.BindingName> _bindingNames = new();
+        private readonly Dictionary<string, EnvironmentRecord.BindingName> _bindingNames = new(StringComparer.Ordinal);
 
         public void NodeVisitor(Node node)
         {

+ 2 - 2
Jint/Engine.Modules.cs

@@ -12,8 +12,8 @@ namespace Jint
     {
         internal IModuleLoader ModuleLoader { get; set; } = null!;
 
-        private readonly Dictionary<string, ModuleRecord> _modules = new();
-        private readonly Dictionary<string, ModuleBuilder> _builders = new();
+        private readonly Dictionary<string, ModuleRecord> _modules = new(StringComparer.Ordinal);
+        private readonly Dictionary<string, ModuleBuilder> _builders = new(StringComparer.Ordinal);
 
         /// <summary>
         /// https://tc39.es/ecma262/#sec-getactivescriptormodule

+ 3 - 3
Jint/Engine.cs

@@ -59,7 +59,7 @@ namespace Jint
         public ITypeConverter ClrTypeConverter { get; internal set; }
 
         // cache of types used when resolving CLR type names
-        internal readonly Dictionary<string, Type?> TypeCache = new();
+        internal readonly Dictionary<string, Type?> TypeCache = new(StringComparer.Ordinal);
 
         // we use registered type reference as prototype if it's known
         internal Dictionary<Type,TypeReference>? _typeReferences;
@@ -553,7 +553,7 @@ namespace Jint
                 ExceptionHelper.ThrowReferenceError(Realm, reference);
             }
 
-            if ((baseValue._type & InternalTypes.ObjectEnvironmentRecord) == 0
+            if ((baseValue._type & InternalTypes.ObjectEnvironmentRecord) == InternalTypes.None
                 && _referenceResolver.TryPropertyReference(this, reference, ref baseValue))
             {
                 return baseValue;
@@ -584,7 +584,7 @@ namespace Jint
                     // check if we are accessing a string, boxing operation can be costly to do index access
                     // we have good chance to have fast path with integer or string indexer
                     ObjectInstance? o = null;
-                    if ((property._type & (InternalTypes.String | InternalTypes.Integer)) != 0
+                    if ((property._type & (InternalTypes.String | InternalTypes.Integer)) != InternalTypes.None
                         && baseValue is JsString s
                         && TryHandleStringValue(property, s, ref o, out var jsValue))
                     {

+ 3 - 3
Jint/Extensions/ReflectionExtensions.cs

@@ -139,7 +139,7 @@ namespace Jint.Extensions
                 return true;
             }
 
-            if (memberType == typeof(bool) && (valueCoercionType & ValueCoercionType.Boolean) != 0)
+            if (memberType == typeof(bool) && (valueCoercionType & ValueCoercionType.Boolean) != ValueCoercionType.None)
             {
                 converted = TypeConverter.ToBoolean(value);
                 return true;
@@ -147,7 +147,7 @@ namespace Jint.Extensions
 
             if (memberType == typeof(string)
                 && !value.IsNullOrUndefined()
-                && (valueCoercionType & ValueCoercionType.String) != 0)
+                && (valueCoercionType & ValueCoercionType.String) != ValueCoercionType.None)
             {
                 // we know how to print out correct string presentation for primitives
                 // that are non-null and non-undefined
@@ -155,7 +155,7 @@ namespace Jint.Extensions
                 return true;
             }
 
-            if (memberType is not null && memberType.IsClrNumericCoercible() && (valueCoercionType & ValueCoercionType.Number) != 0)
+            if (memberType is not null && memberType.IsClrNumericCoercible() && (valueCoercionType & ValueCoercionType.Number) != ValueCoercionType.None)
             {
                 // we know how to print out correct string presentation for primitives
                 // that are non-null and non-undefined

+ 7 - 7
Jint/HoistingScope.cs

@@ -133,8 +133,8 @@ namespace Jint
             treeWalker.Visit(module);
 
             importEntries = treeWalker._importEntries;
-            requestedModules = treeWalker._requestedModules ?? new();
-            var importedBoundNames = new HashSet<string>();
+            requestedModules = treeWalker._requestedModules ?? new(StringComparer.Ordinal);
+            var importedBoundNames = new HashSet<string>(StringComparer.Ordinal);
 
             if (importEntries != null)
             {
@@ -171,9 +171,9 @@ namespace Jint
                             for (var j = 0; j < importEntries!.Count; j++)
                             {
                                 var ie = importEntries[j];
-                                if (ie.LocalName == ee.LocalName)
+                                if (string.Equals(ie.LocalName, ee.LocalName, StringComparison.Ordinal))
                                 {
-                                    if (ie.ImportName == "*")
+                                    if (string.Equals(ie.ImportName, "*", StringComparison.Ordinal))
                                     {
                                         localExportEntries.Add(ee);
                                     }
@@ -187,7 +187,7 @@ namespace Jint
                             }
                         }
                     }
-                    else if (ee.ImportName == "*" && ee.ExportName is null)
+                    else if (string.Equals(ee.ImportName, "*", StringComparison.Ordinal) && ee.ExportName is null)
                     {
                         starExportEntries.Add(ee);
                     }
@@ -300,14 +300,14 @@ namespace Jint
                     if (childNode.Type == Nodes.ImportDeclaration)
                     {
                         _importEntries ??= new();
-                        _requestedModules ??= new();
+                        _requestedModules ??= new(StringComparer.Ordinal);
                         var import = (ImportDeclaration) childNode;
                         import.GetImportEntries(_importEntries, _requestedModules);
                     }
                     else if (childNode.Type is Nodes.ExportAllDeclaration or Nodes.ExportDefaultDeclaration or Nodes.ExportNamedDeclaration)
                     {
                         _exportEntries ??= new();
-                        _requestedModules ??= new();
+                        _requestedModules ??= new(StringComparer.Ordinal);
                         var export = (ExportDeclaration) childNode;
                         export.GetExportEntries(_exportEntries, _requestedModules);
                     }

+ 1 - 0
Jint/Jint.csproj

@@ -18,6 +18,7 @@
 
   <ItemGroup>
     <PackageReference Include="Esprima" />
+    <PackageReference Include="Meziantou.Analyzer" PrivateAssets="all" />
   </ItemGroup>
 
   <ItemGroup>

+ 5 - 5
Jint/JsValueExtensions.cs

@@ -19,7 +19,7 @@ namespace Jint
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static bool IsPrimitive(this JsValue value)
         {
-            return (value._type & (InternalTypes.Primitive | InternalTypes.Undefined | InternalTypes.Null)) != 0;
+            return (value._type & (InternalTypes.Primitive | InternalTypes.Undefined | InternalTypes.Null)) != InternalTypes.None;
         }
 
         [Pure]
@@ -76,28 +76,28 @@ namespace Jint
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static bool IsObject(this JsValue value)
         {
-            return (value._type & InternalTypes.Object) != 0;
+            return (value._type & InternalTypes.Object) != InternalTypes.None;
         }
 
         [Pure]
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static bool IsString(this JsValue value)
         {
-            return (value._type & InternalTypes.String) != 0;
+            return (value._type & InternalTypes.String) != InternalTypes.None;
         }
 
         [Pure]
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static bool IsNumber(this JsValue value)
         {
-            return (value._type & (InternalTypes.Number | InternalTypes.Integer)) != 0;
+            return (value._type & (InternalTypes.Number | InternalTypes.Integer)) != InternalTypes.None;
         }
 
         [Pure]
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static bool IsBigInt(this JsValue value)
         {
-            return (value._type & InternalTypes.BigInt) != 0;
+            return (value._type & InternalTypes.BigInt) != InternalTypes.None;
         }
 
         [Pure]

+ 6 - 6
Jint/Key.cs

@@ -13,7 +13,7 @@ namespace Jint
         private Key(string name)
         {
             Name = name;
-            HashCode = name.GetHashCode();
+            HashCode = StringComparer.Ordinal.GetHashCode(name);
         }
 
         internal readonly string Name;
@@ -29,28 +29,28 @@ namespace Jint
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static bool operator ==(in Key a, in Key b)
         {
-            return a.HashCode == b.HashCode && a.Name == b.Name;
+            return a.HashCode == b.HashCode && string.Equals(a.Name, b.Name, StringComparison.Ordinal);
         }
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static bool operator !=(in Key a, in Key b)
         {
-            return a.HashCode != b.HashCode || a.Name != b.Name;
+            return a.HashCode != b.HashCode || !string.Equals(a.Name, b.Name, StringComparison.Ordinal);
         }
 
         public static bool operator ==(in Key a, string b)
         {
-            return a.Name == b;
+            return string.Equals(a.Name, b, StringComparison.Ordinal);
         }
 
         public static bool operator !=(in Key a, string b)
         {
-            return a.Name != b;
+            return !string.Equals(a.Name, b, StringComparison.Ordinal);
         }
 
         public bool Equals(Key other)
         {
-            return HashCode == other.HashCode && Name == other.Name;
+            return HashCode == other.HashCode && string.Equals(Name, other.Name, StringComparison.Ordinal);
         }
 
         public override bool Equals(object? obj)

+ 1 - 1
Jint/ModuleBuilder.cs

@@ -13,7 +13,7 @@ public sealed class ModuleBuilder
     private readonly string _specifier;
     private Module? _module;
     private readonly List<string> _sourceRaw = new();
-    private readonly Dictionary<string, JsValue> _exports = new();
+    private readonly Dictionary<string, JsValue> _exports = new(StringComparer.Ordinal);
     private readonly ParserOptions _options;
 
     internal ModuleBuilder(Engine engine, string specifier)

+ 1 - 1
Jint/Native/Argument/ArgumentsInstance.cs

@@ -16,7 +16,7 @@ namespace Jint.Native.Argument
     internal sealed class ArgumentsInstance : ObjectInstance
     {
         // cache property container for array iteration for less allocations
-        private static readonly ThreadLocal<HashSet<string>> _mappedNamed = new(() => new HashSet<string>());
+        private static readonly ThreadLocal<HashSet<string>> _mappedNamed = new(() => new HashSet<string>(StringComparer.Ordinal));
 
         private FunctionInstance _func = null!;
         private Key[] _names = null!;

+ 4 - 4
Jint/Native/Array/ArrayInstance.cs

@@ -79,7 +79,7 @@ namespace Jint.Native.Array
         {
             get
             {
-                if ((_objectChangeFlags & ObjectChangeFlags.NonDefaultDataDescriptorUsage) != 0)
+                if ((_objectChangeFlags & ObjectChangeFlags.NonDefaultDataDescriptorUsage) != ObjectChangeFlags.None)
                 {
                     // could be a mutating property for example, length might change, not safe anymore
                     return false;
@@ -92,7 +92,7 @@ namespace Jint.Native.Array
                     return false;
                 }
 
-                if ((arrayPrototype._objectChangeFlags & ObjectChangeFlags.ArrayIndex) != 0)
+                if ((arrayPrototype._objectChangeFlags & ObjectChangeFlags.ArrayIndex) != ObjectChangeFlags.None)
                 {
                     // maybe somebody moved integer property to prototype? not safe anymore
                     return false;
@@ -104,7 +104,7 @@ namespace Jint.Native.Array
                     return false;
                 }
 
-                return (arrayPrototypePrototype._objectChangeFlags & ObjectChangeFlags.ArrayIndex) == 0;
+                return (arrayPrototypePrototype._objectChangeFlags & ObjectChangeFlags.ArrayIndex) == ObjectChangeFlags.None;
             }
         }
 
@@ -316,7 +316,7 @@ namespace Jint.Native.Array
 
         public sealed override List<JsValue> GetOwnPropertyKeys(Types types = Types.None | Types.String | Types.Symbol)
         {
-            if ((types & Types.String) == 0)
+            if ((types & Types.String) == Types.None)
             {
                 return base.GetOwnPropertyKeys(types);
             }

+ 3 - 3
Jint/Native/Array/ArrayOperations.cs

@@ -56,7 +56,7 @@ namespace Jint.Native.Array
             for (uint i = 0; i < (uint) jsValues.Length; i++)
             {
                 var jsValue = skipHoles && !HasProperty(i) ? JsValue.Undefined : Get(i);
-                if ((jsValue.Type & elementTypes) == 0)
+                if ((jsValue.Type & elementTypes) == Types.None)
                 {
                     ExceptionHelper.ThrowTypeErrorNoEngine("invalid type");
                 }
@@ -231,7 +231,7 @@ namespace Jint.Native.Array
 
             public override JsValue Get(ulong index) => _target.Get((uint) index);
 
-            public override JsValue[] GetAll(Types elementTypes, bool skipHoles = false)
+            public override JsValue[] GetAll(Types elementTypes = Types.Undefined | Types.Null | Types.Boolean | Types.String | Types.Symbol | Types.Number | Types.Object, bool skipHoles = false)
             {
                 var n = _target.GetLength();
 
@@ -251,7 +251,7 @@ namespace Jint.Native.Array
                         value = _target.Prototype?.Get(i) ?? JsValue.Undefined;
                     }
 
-                    if ((value.Type & elementTypes) == 0)
+                    if ((value.Type & elementTypes) == Types.None)
                     {
                         ExceptionHelper.ThrowTypeErrorNoEngine("invalid type");
                     }

+ 2 - 2
Jint/Native/Array/ArrayPrototype.cs

@@ -487,7 +487,7 @@ namespace Jint.Native.Array
 
             if (len > ArrayOperations.MaxArrayLength)
             {
-                ExceptionHelper.ThrowRangeError(_realm, "Invalid array length");;
+                ExceptionHelper.ThrowRangeError(_realm, "Invalid array length");
             }
 
             var callbackfn = arguments.At(0);
@@ -1136,7 +1136,7 @@ namespace Jint.Native.Array
 
             if (k < final && final - k > ArrayOperations.MaxArrayLength)
             {
-                ExceptionHelper.ThrowRangeError(_realm, "Invalid array length");;
+                ExceptionHelper.ThrowRangeError(_realm, "Invalid array length");
             }
 
             var length = (uint) System.Math.Max(0, (long) final - (long) k);

+ 4 - 2
Jint/Native/Date/DatePrototype.cs

@@ -1,5 +1,6 @@
 using System.Globalization;
 using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
 using Jint.Collections;
 using Jint.Native.Object;
 using Jint.Native.Symbol;
@@ -116,11 +117,11 @@ namespace Jint.Native.Date
 
             var hintString = hint.ToString();
             var tryFirst = Types.None;
-            if (hintString == "default" || hintString == "string")
+            if (string.Equals(hintString, "default", StringComparison.Ordinal) || string.Equals(hintString, "string", StringComparison.Ordinal))
             {
                 tryFirst = Types.String;
             }
-            else  if (hintString == "number")
+            else  if (string.Equals(hintString, "number", StringComparison.Ordinal))
             {
                 tryFirst = Types.Number;
             }
@@ -1262,6 +1263,7 @@ namespace Jint.Native.Date
         private static bool AreFinite(double value1, double value2, double value3, double value4)
             => IsFinite(value1) && IsFinite(value2) &&  IsFinite(value3) && IsFinite(value4);
 
+        [StructLayout(LayoutKind.Auto)]
         private readonly record struct Date(int Year, int Month, int Day);
 
         private static readonly int[] kDaysInMonths = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

+ 12 - 8
Jint/Native/Date/MimeKit.cs

@@ -31,6 +31,7 @@ namespace Jint.Native.Date;
 using System;
 using System.Text;
 using System.Collections.Generic;
+using System.Runtime.InteropServices;
 
 [Flags]
 internal enum DateTokenFlags : byte
@@ -46,6 +47,7 @@ internal enum DateTokenFlags : byte
     HasSign = (1 << 7),
 }
 
+[StructLayout(LayoutKind.Auto)]
 internal readonly struct DateToken
 {
     public DateToken(DateTokenFlags flags, int start, int length)
@@ -63,32 +65,32 @@ internal readonly struct DateToken
 
     public bool IsNumeric
     {
-        get { return (Flags & DateTokenFlags.NonNumeric) == 0; }
+        get { return (Flags & DateTokenFlags.NonNumeric) == DateTokenFlags.None; }
     }
 
     public bool IsWeekday
     {
-        get { return (Flags & DateTokenFlags.NonWeekday) == 0; }
+        get { return (Flags & DateTokenFlags.NonWeekday) == DateTokenFlags.None; }
     }
 
     public bool IsMonth
     {
-        get { return (Flags & DateTokenFlags.NonMonth) == 0; }
+        get { return (Flags & DateTokenFlags.NonMonth) == DateTokenFlags.None; }
     }
 
     public bool IsTimeOfDay
     {
-        get { return (Flags & DateTokenFlags.NonTime) == 0 && (Flags & DateTokenFlags.HasColon) != 0; }
+        get { return (Flags & DateTokenFlags.NonTime) == DateTokenFlags.None && (Flags & DateTokenFlags.HasColon) != DateTokenFlags.None; }
     }
 
     public bool IsNumericZone
     {
-        get { return (Flags & DateTokenFlags.NonNumericZone) == 0 && (Flags & DateTokenFlags.HasSign) != 0; }
+        get { return (Flags & DateTokenFlags.NonNumericZone) == DateTokenFlags.None && (Flags & DateTokenFlags.HasSign) != DateTokenFlags.None; }
     }
 
     public bool IsAlphaZone
     {
-        get { return (Flags & DateTokenFlags.NonAlphaZone) == 0; }
+        get { return (Flags & DateTokenFlags.NonAlphaZone) == DateTokenFlags.None; }
     }
 
     public bool IsTimeZone
@@ -732,7 +734,9 @@ internal static class ParseUtils
             {
                 if (throwOnError)
                 {
+#pragma warning disable MA0015
                     throw new ArgumentException($"Incomplete comment token at offset {startIndex}");
+#pragma warning restore MA0015
                 }
 
                 return false;
@@ -814,7 +818,7 @@ internal static class ByteExtensions
             {
                 for (i = 0; i < 256; i++)
                 {
-                    if ((table[i] & bitcopy) != 0)
+                    if ((table[i] & bitcopy) != CharType.None)
                         table[i] |= bit;
                 }
             }
@@ -871,6 +875,6 @@ internal static class ByteExtensions
 
     public static bool IsWhitespace(this byte c)
     {
-        return (table[c] & CharType.IsWhitespace) != 0;
+        return (table[c] & CharType.IsWhitespace) != CharType.None;
     }
 }

+ 6 - 4
Jint/Native/DatePresentation.cs

@@ -1,3 +1,4 @@
+using System.Runtime.InteropServices;
 using Jint.Native.Date;
 
 namespace Jint.Native;
@@ -12,6 +13,7 @@ internal enum DateFlags : byte
     DateTimeMaxValue = 8
 }
 
+[StructLayout(LayoutKind.Auto)]
 internal readonly record struct DatePresentation(long Value, DateFlags Flags)
 {
     public static readonly DatePresentation NaN = new(0, DateFlags.NaN);
@@ -19,9 +21,9 @@ internal readonly record struct DatePresentation(long Value, DateFlags Flags)
     public static readonly DatePresentation MaxValue = new(JsDate.Max, DateFlags.DateTimeMaxValue);
 
     public bool DateTimeRangeValid => IsFinite && Value <= JsDate.Max && Value >= JsDate.Min;
-    public bool IsNaN => (Flags & DateFlags.NaN) != 0;
-    public bool IsInfinity => (Flags & DateFlags.Infinity) != 0;
-    public bool IsFinite => (Flags & (DateFlags.NaN | DateFlags.Infinity)) == 0;
+    public bool IsNaN => (Flags & DateFlags.NaN) != DateFlags.None;
+    public bool IsInfinity => (Flags & DateFlags.Infinity) != DateFlags.None;
+    public bool IsFinite => (Flags & (DateFlags.NaN | DateFlags.Infinity)) == DateFlags.None;
 
     public DateTime ToDateTime()
     {
@@ -64,7 +66,7 @@ internal readonly record struct DatePresentation(long Value, DateFlags Flags)
 
     internal DatePresentation TimeClip()
     {
-        if ((Flags & (DateFlags.NaN | DateFlags.Infinity)) != 0)
+        if ((Flags & (DateFlags.NaN | DateFlags.Infinity)) != DateFlags.None)
         {
             return NaN;
         }

+ 2 - 0
Jint/Native/FinalizationRegistry/FinalizationRegistryInstance.cs

@@ -60,7 +60,9 @@ internal sealed class FinalizationRegistryInstance : ObjectInstance
             _callable = callable;
         }
 
+#pragma warning disable MA0055
         ~Observer()
+#pragma warning restore MA0055
         {
             _callable.Callback.Call(Undefined);
         }

+ 1 - 1
Jint/Native/Function/ClassDefinition.cs

@@ -169,7 +169,7 @@ internal sealed class ClassDefinition
                 if (element is PrivateElement privateElement)
                 {
                     var container = !isStatic ? instancePrivateMethods : staticPrivateMethods;
-                    var index = container.FindIndex(x => x.Key.Description == privateElement.Key.Description);
+                    var index = container.FindIndex(x => string.Equals(x.Key.Description, privateElement.Key.Description, StringComparison.Ordinal));
                     if (index != -1)
                     {
                         var pe = container[index];

+ 3 - 3
Jint/Native/Function/EvalFunctionInstance.cs

@@ -83,7 +83,7 @@ internal sealed class EvalFunctionInstance : FunctionInstance
         }
         catch (ParserException e)
         {
-            if (e.Description == Messages.InvalidLHSInAssignment)
+            if (string.Equals(e.Description, Messages.InvalidLHSInAssignment, StringComparison.Ordinal))
             {
                 ExceptionHelper.ThrowReferenceError(callerRealm, (string?) null);
             }
@@ -201,13 +201,13 @@ internal sealed class EvalFunctionInstance : FunctionInstance
 
         protected override object VisitIdentifier(Identifier identifier)
         {
-            _containsArguments |= identifier.Name == "arguments";
+            _containsArguments |= string.Equals(identifier.Name, "arguments", StringComparison.Ordinal);
             return identifier;
         }
 
         protected override object VisitMetaProperty(MetaProperty metaProperty)
         {
-            _containsNewTarget |= metaProperty.Meta.Name == "new" && metaProperty.Property.Name == "target";
+            _containsNewTarget |= string.Equals(metaProperty.Meta.Name, "new", StringComparison.Ordinal) && string.Equals(metaProperty.Property.Name, "target", StringComparison.Ordinal);
             return metaProperty;
         }
 

+ 6 - 4
Jint/Native/Global/GlobalObject.cs

@@ -54,7 +54,7 @@ namespace Jint.Native.Global
             }
 
             // check fast case
-            if (radix == 10 && int.TryParse(trimmed, out var number))
+            if (radix == 10 && int.TryParse(trimmed, NumberStyles.Integer, CultureInfo.InvariantCulture, out var number))
             {
                 return JsNumber.Create(number);
             }
@@ -476,7 +476,9 @@ uriError:
                     else
                     {
                         var n = 0;
-                        for (; ((B << n) & 0x80) != 0; n++);
+                        for (; ((B << n) & 0x80) != 0; n++)
+                        {
+                        }
 
                         if (n == 1 || n > 4)
                         {
@@ -689,7 +691,7 @@ uriError:
             }
 
             // check fast path
-            if ((current._flags & PropertyFlag.MutableBinding) != 0)
+            if ((current._flags & PropertyFlag.MutableBinding) != PropertyFlag.None)
             {
                 current._value = desc.Value;
                 return true;
@@ -728,7 +730,7 @@ uriError:
                 }
 
                 // check fast path
-                if ((existingDescriptor._flags & PropertyFlag.MutableBinding) != 0)
+                if ((existingDescriptor._flags & PropertyFlag.MutableBinding) != PropertyFlag.None)
                 {
                     existingDescriptor._value = value;
                     return true;

+ 1 - 1
Jint/Native/Intl/NumberFormatConstructor.cs

@@ -225,7 +225,7 @@ internal sealed class NumberFormatConstructor : Constructor
         return false;
     }
 
-    private static readonly HashSet<string> _sanctionedSingleUnitIdentifiers = new()
+    private static readonly HashSet<string> _sanctionedSingleUnitIdentifiers = new(StringComparer.Ordinal)
     {
         "acre",
         "bit",

+ 10 - 10
Jint/Native/JsString.cs

@@ -54,7 +54,7 @@ public class JsString : JsValue, IEquatable<JsString>, IEquatable<string>
         }
 
 
-        _stringCache = new ConcurrentDictionary<string, JsString>();
+        _stringCache = new ConcurrentDictionary<string, JsString>(StringComparer.Ordinal);
         Empty = new JsString("", InternalTypes.String);
         NullString = CachedCreate("null");
         UndefinedString = CachedCreate("undefined");
@@ -267,13 +267,13 @@ public class JsString : JsValue, IEquatable<JsString>, IEquatable<string>
 
     internal bool StartsWith(string value, int start = 0)
     {
-        return value.Length + start <= Length && ToString().AsSpan(start).StartsWith(value.AsSpan());
+        return value.Length + start <= Length && ToString().AsSpan(start).StartsWith(value.AsSpan(), StringComparison.Ordinal);
     }
 
     internal bool EndsWith(string value, int end = 0)
     {
         var start = end - value.Length;
-        return start >= 0 && ToString().AsSpan(start, value.Length).EndsWith(value.AsSpan());
+        return start >= 0 && ToString().AsSpan(start, value.Length).EndsWith(value.AsSpan(), StringComparison.Ordinal);
     }
 
     internal string Substring(int startIndex, int length)
@@ -290,7 +290,7 @@ public class JsString : JsValue, IEquatable<JsString>, IEquatable<string>
 
     public sealed override bool Equals(JsValue? other) => Equals(other as JsString);
 
-    public virtual bool Equals(string? other) => other != null && ToString() == other;
+    public virtual bool Equals(string? other) => other != null && string.Equals(ToString(), other, StringComparison.Ordinal);
 
     public virtual bool Equals(JsString? other)
     {
@@ -304,7 +304,7 @@ public class JsString : JsValue, IEquatable<JsString>, IEquatable<string>
             return true;
         }
 
-        return _value == other.ToString();
+        return string.Equals(_value, other.ToString(), StringComparison.Ordinal);
     }
 
     public override bool IsLooselyEqual(JsValue value)
@@ -322,7 +322,7 @@ public class JsString : JsValue, IEquatable<JsString>, IEquatable<string>
         return base.IsLooselyEqual(value);
     }
 
-    public override int GetHashCode() => _value.GetHashCode();
+    public override int GetHashCode() => StringComparer.Ordinal.GetHashCode(_value);
 
     internal sealed class ConcatenatedString : JsString
     {
@@ -398,7 +398,7 @@ public class JsString : JsValue, IEquatable<JsString>, IEquatable<string>
                 return true;
             }
 
-            return _value == s;
+            return string.Equals(_value, s, StringComparison.Ordinal);
         }
 
         public override bool Equals(JsString? other)
@@ -422,7 +422,7 @@ public class JsString : JsValue, IEquatable<JsString>, IEquatable<string>
                     return true;
                 }
 
-                return ToString() == cs.ToString();
+                return string.Equals(ToString(), cs.ToString(), StringComparison.Ordinal);
             }
 
             if (other is null || other.Length != Length)
@@ -430,10 +430,10 @@ public class JsString : JsValue, IEquatable<JsString>, IEquatable<string>
                 return false;
             }
 
-            return ToString() == other.ToString();
+            return string.Equals(ToString(), other.ToString(), StringComparison.Ordinal);
         }
 
-        public override int GetHashCode() => _stringBuilder?.GetHashCode() ?? _value.GetHashCode();
+        public override int GetHashCode() => _stringBuilder?.GetHashCode() ?? StringComparer.Ordinal.GetHashCode(_value);
 
         internal override JsValue DoClone()
         {

+ 4 - 4
Jint/Native/JsValue.cs

@@ -334,12 +334,12 @@ namespace Jint.Native
                 return x.IsLooselyEqual(TypeConverter.ToNumber(y));
             }
 
-            if (y.IsObject() && (x._type & InternalTypes.Primitive) != 0)
+            if (y.IsObject() && (x._type & InternalTypes.Primitive) != InternalTypes.None)
             {
                 return x.IsLooselyEqual(TypeConverter.ToPrimitive(y));
             }
 
-            if (x.IsObject() && (y._type & InternalTypes.Primitive) != 0)
+            if (x.IsObject() && (y._type & InternalTypes.Primitive) != InternalTypes.None)
             {
                 return y.IsLooselyEqual(TypeConverter.ToPrimitive(x));
             }
@@ -366,7 +366,7 @@ namespace Jint.Native
         internal JsValue Clone()
         {
             // concatenated string and arguments currently may require cloning
-            return (_type & InternalTypes.RequiresCloning) == 0
+            return (_type & InternalTypes.RequiresCloning) == InternalTypes.None
                 ? this
                 : DoClone();
         }
@@ -458,7 +458,7 @@ namespace Jint.Native
 
                     return false;
                 case Types.String:
-                    return TypeConverter.ToString(x) == TypeConverter.ToString(y);
+                    return string.Equals(TypeConverter.ToString(x), TypeConverter.ToString(y), StringComparison.Ordinal);
                 case Types.Boolean:
                     return TypeConverter.ToBoolean(x) == TypeConverter.ToBoolean(y);
                 case Types.Undefined:

+ 3 - 1
Jint/Native/Json/JsonParser.cs

@@ -2,6 +2,7 @@ using System.Buffers;
 using System.Diagnostics.CodeAnalysis;
 using System.Globalization;
 using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
 using System.Text;
 using Esprima;
 using Jint.Native.Object;
@@ -251,7 +252,7 @@ namespace Jint.Native.Json
             sb.Clear();
 
             JsNumber value;
-            if (canBeInteger && long.TryParse(number, out var longResult) && longResult != -0)
+            if (canBeInteger && long.TryParse(number, NumberStyles.Integer, CultureInfo.InvariantCulture, out var longResult) && longResult != -0)
             {
                 value = JsNumber.Create(longResult);
             }
@@ -759,6 +760,7 @@ namespace Jint.Native.Json
             public TextRange Range;
         }
 
+        [StructLayout(LayoutKind.Auto)]
         private readonly struct TextRange
         {
             public TextRange(int start, int end)

+ 3 - 1
Jint/Native/Number/Dtoa/CachePowers.cs

@@ -31,6 +31,7 @@
 // The original revision was 67d1049b0bf9 from the mozilla-central tree.
 
 using System.Diagnostics;
+using System.Runtime.InteropServices;
 
 namespace Jint.Native.Number.Dtoa
 {
@@ -52,6 +53,7 @@ namespace Jint.Native.Number.Dtoa
             }
         }
 
+        [StructLayout(LayoutKind.Auto)]
         internal readonly struct GetCachedPowerResult
         {
             public GetCachedPowerResult(short decimalExponent, DiyFp cMk)
@@ -180,4 +182,4 @@ namespace Jint.Native.Number.Dtoa
         const int kMinDecimalExponent = -348;
         const int kMaxDecimalExponent = 340;
     }
-}
+}

+ 8 - 6
Jint/Native/Number/Dtoa/DiyFp.cs

@@ -31,15 +31,17 @@
 // The original revision was 67d1049b0bf9 from the mozilla-central tree.
 
 using System.Diagnostics;
+using System.Runtime.InteropServices;
 
 namespace Jint.Native.Number.Dtoa
 {
 
-// This "Do It Yourself Floating Point" class implements a floating-point number
-// with a uint64 significand and an int exponent. Normalized DiyFp numbers will
-// have the most significant bit of the significand set.
-// Multiplication and Subtraction do not normalize their results.
-// DiyFp are not designed to contain special doubles (NaN and Infinity).
+    // This "Do It Yourself Floating Point" class implements a floating-point number
+    // with a uint64 significand and an int exponent. Normalized DiyFp numbers will
+    // have the most significant bit of the significand set.
+    // Multiplication and Subtraction do not normalize their results.
+    // DiyFp are not designed to contain special doubles (NaN and Infinity).
+    [StructLayout(LayoutKind.Auto)]
     internal readonly struct DiyFp
     {
         internal const int KSignificandSize = 64;
@@ -114,4 +116,4 @@ namespace Jint.Native.Number.Dtoa
             return "[DiyFp f:" + F + ", e:" + E + "]";
         }
     }
-}
+}

+ 3 - 1
Jint/Native/Number/Dtoa/DoubleHelper.cs

@@ -31,6 +31,7 @@
 // The original revision was 67d1049b0bf9 from the mozilla-central tree.
 
 using System.Diagnostics;
+using System.Runtime.InteropServices;
 
 namespace Jint.Native.Number.Dtoa
 {
@@ -112,6 +113,7 @@ namespace Jint.Native.Number.Dtoa
             return (d64 & KExponentMask) == KExponentMask;
         }
 
+        [StructLayout(LayoutKind.Auto)]
         internal readonly struct NormalizedBoundariesResult
         {
             public NormalizedBoundariesResult(DiyFp minus, DiyFp plus)
@@ -155,4 +157,4 @@ namespace Jint.Native.Number.Dtoa
         private const int KExponentBias = 0x3FF + KSignificandSize;
         private const int KDenormalExponent = -KExponentBias + 1;
     }
-}
+}

+ 1 - 1
Jint/Native/Object/ObjectConstructor.cs

@@ -552,7 +552,7 @@ namespace Jint.Native.Object
             {
             }
 
-            public JsValue Call(JsValue thisObject, JsValue[] arguments)
+            public JsValue Call(JsValue thisObject, params JsValue[] arguments)
             {
                 var o = (ObjectInstance) thisObject;
                 var key = arguments.At(0);

+ 16 - 14
Jint/Native/Object/ObjectInstance.cs

@@ -44,7 +44,9 @@ namespace Jint.Native.Object
             _class = objectClass;
             // if engine is ready, we can take default prototype for object
             _prototype = engine.Realm.Intrinsics?.Object?.PrototypeObject;
+#pragma warning disable MA0056
             Extensible = true;
+#pragma warning restore MA0056
         }
 
         public Engine Engine
@@ -230,11 +232,11 @@ namespace Jint.Native.Object
         {
             EnsureInitialized();
 
-            var returningSymbols = (types & Types.Symbol) != 0 && _symbols?.Count > 0;
-            var returningStringKeys = (types & Types.String) != 0 && _properties?.Count > 0;
+            var returningSymbols = (types & Types.Symbol) != Types.None && _symbols?.Count > 0;
+            var returningStringKeys = (types & Types.String) != Types.None && _properties?.Count > 0;
 
             var propertyKeys = new List<JsValue>();
-            if ((types & Types.String) != 0)
+            if ((types & Types.String) != Types.None)
             {
                 var initialOwnStringPropertyKeys = GetInitialOwnStringPropertyKeys();
                 if (!ReferenceEquals(initialOwnStringPropertyKeys, System.Linq.Enumerable.Empty<JsValue>()))
@@ -270,7 +272,7 @@ namespace Jint.Native.Object
                 return propertyKeys;
             }
 
-            if ((types & Types.String) == 0 && (types & Types.Symbol) != 0)
+            if ((types & Types.String) == Types.None && (types & Types.Symbol) != Types.None)
             {
                 // only symbols requested
                 if (_symbols != null)
@@ -363,7 +365,7 @@ namespace Jint.Native.Object
 
         public override JsValue Get(JsValue property, JsValue receiver)
         {
-            if ((_type & InternalTypes.PlainObject) != 0 && ReferenceEquals(this, receiver) && property is JsString jsString)
+            if ((_type & InternalTypes.PlainObject) != InternalTypes.None && ReferenceEquals(this, receiver) && property is JsString jsString)
             {
                 EnsureInitialized();
                 if (_properties?.TryGetValue(jsString.ToString(), out var ownDesc) == true)
@@ -391,12 +393,12 @@ namespace Jint.Native.Object
 
         internal static JsValue UnwrapJsValue(PropertyDescriptor desc, JsValue thisObject)
         {
-            var value = (desc._flags & PropertyFlag.CustomJsValue) != 0
+            var value = (desc._flags & PropertyFlag.CustomJsValue) != PropertyFlag.None
                 ? desc.CustomValue
                 : desc._value;
 
             // IsDataDescriptor inlined
-            if ((desc._flags & (PropertyFlag.WritableSet | PropertyFlag.Writable)) != 0 || value is not null)
+            if ((desc._flags & (PropertyFlag.WritableSet | PropertyFlag.Writable)) != PropertyFlag.None || value is not null)
             {
                 return value ?? Undefined;
             }
@@ -519,12 +521,12 @@ namespace Jint.Native.Object
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public bool Set(JsValue property, JsValue value)
         {
-            if ((_type & InternalTypes.PlainObject) != 0 && property is JsString jsString)
+            if ((_type & InternalTypes.PlainObject) != InternalTypes.None && property is JsString jsString)
             {
                 var key = (Key) jsString.ToString();
                 if (_properties?.TryGetValue(key, out var ownDesc) == true)
                 {
-                    if ((ownDesc._flags & PropertyFlag.Writable) != 0)
+                    if ((ownDesc._flags & PropertyFlag.Writable) != PropertyFlag.None)
                     {
                         ownDesc._value = value;
                         return true;
@@ -542,12 +544,12 @@ namespace Jint.Native.Object
         /// </summary>
         public override bool Set(JsValue property, JsValue value, JsValue receiver)
         {
-            if ((_type & InternalTypes.PlainObject) != 0 && ReferenceEquals(this, receiver) && property is JsString jsString)
+            if ((_type & InternalTypes.PlainObject) != InternalTypes.None && ReferenceEquals(this, receiver) && property is JsString jsString)
             {
                 var key = (Key) jsString.ToString();
                 if (_properties?.TryGetValue(key, out var ownDesc) == true)
                 {
-                    if ((ownDesc._flags & PropertyFlag.Writable) != 0)
+                    if ((ownDesc._flags & PropertyFlag.Writable) != PropertyFlag.None)
                     {
                         ownDesc._value = value;
                         return true;
@@ -781,7 +783,7 @@ namespace Jint.Native.Object
                         {
                             propertyDescriptor = new PropertyDescriptor(descValue ?? Undefined, PropertyFlag.ConfigurableEnumerableWritable);
                         }
-                        else if ((desc._flags & PropertyFlag.ConfigurableEnumerableWritable) == 0)
+                        else if ((desc._flags & PropertyFlag.ConfigurableEnumerableWritable) == PropertyFlag.None)
                         {
                             propertyDescriptor = new PropertyDescriptor(descValue ?? Undefined, PropertyFlag.AllForbidden);
                         }
@@ -816,7 +818,7 @@ namespace Jint.Native.Object
             var currentValue = current.Value;
 
             // 4. If every field in Desc is absent, return true.
-            if ((current._flags & (PropertyFlag.ConfigurableSet | PropertyFlag.EnumerableSet | PropertyFlag.WritableSet)) == 0 &&
+            if ((current._flags & (PropertyFlag.ConfigurableSet | PropertyFlag.EnumerableSet | PropertyFlag.WritableSet)) == PropertyFlag.None &&
                 ReferenceEquals(currentGet, null) &&
                 ReferenceEquals(currentSet, null) &&
                 ReferenceEquals(currentValue, null))
@@ -1073,7 +1075,7 @@ namespace Jint.Native.Object
                             TypedArrayElementType.Uint16 => typedArrayInstance.ToNativeArray<ushort>(),
                             TypedArrayElementType.Uint32 => typedArrayInstance.ToNativeArray<uint>(),
                             TypedArrayElementType.BigUint64 => typedArrayInstance.ToNativeArray<ulong>(),
-                            _ => throw new ArgumentOutOfRangeException("", "cannot handle element type")
+                            _ => throw new NotSupportedException("cannot handle element type")
                         };
 
                         break;

+ 3 - 9
Jint/Native/PrivateName.cs

@@ -50,7 +50,7 @@ internal sealed class PrivateName : JsValue, IEquatable<PrivateName>
 
     public override int GetHashCode()
     {
-        return _identifier.Name.GetHashCode();
+        return StringComparer.Ordinal.GetHashCode(_identifier.Name);
     }
 }
 
@@ -61,14 +61,8 @@ internal sealed class PrivateIdentifierNameComparer : IEqualityComparer<PrivateI
 {
     internal static readonly PrivateIdentifierNameComparer _instance = new();
 
-    public bool Equals(PrivateIdentifier? x, PrivateIdentifier? y)
-    {
-        return x?.Name == y?.Name;
-    }
+    public bool Equals(PrivateIdentifier? x, PrivateIdentifier? y) => string.Equals(x?.Name, y?.Name, StringComparison.Ordinal);
 
-    public int GetHashCode(PrivateIdentifier obj)
-    {
-        return obj.Name.GetHashCode();
-    }
+    public int GetHashCode(PrivateIdentifier obj) => StringComparer.Ordinal.GetHashCode(obj.Name);
 }
 

+ 1 - 1
Jint/Native/RegExp/JsRegExp.cs

@@ -110,7 +110,7 @@ namespace Jint.Native.RegExp
             }
         }
 
-        public override List<JsValue> GetOwnPropertyKeys(Types types)
+        public override List<JsValue> GetOwnPropertyKeys(Types types = Types.String | Types.Symbol)
         {
             var keys = new List<JsValue>();
             if (_prototypeDescriptor != null)

+ 2 - 2
Jint/Native/RegExp/RegExpPrototype.cs

@@ -473,7 +473,7 @@ namespace Jint.Native.RegExp
             {
                 // we can take faster path
 
-                if (R.Source == JsRegExp.regExpForMatchingAllCharacters)
+                if (string.Equals(R.Source, JsRegExp.regExpForMatchingAllCharacters, StringComparison.Ordinal))
                 {
                     // if empty string, just a string split
                     return StringPrototype.SplitWithStringSeparator(_realm, "", s, (uint) s.Length);
@@ -855,7 +855,7 @@ namespace Jint.Native.RegExp
                 lastIndex = 0;
             }
 
-            if (R.Source == JsRegExp.regExpForMatchingAllCharacters)  // Reg Exp is really ""
+            if (string.Equals(R.Source, JsRegExp.regExpForMatchingAllCharacters, StringComparison.Ordinal))  // Reg Exp is really ""
             {
                 if (lastIndex > (ulong) s.Length)
                 {

+ 3 - 1
Jint/Native/ShadowRealm/ShadowRealm.cs

@@ -17,7 +17,9 @@ namespace Jint.Native.ShadowRealm;
 /// <summary>
 /// https://tc39.es/proposal-shadowrealm/#sec-properties-of-shadowrealm-instances
 /// </summary>
+#pragma warning disable MA0049
 public sealed class ShadowRealm : ObjectInstance
+#pragma warning restore MA0049
 {
     private readonly JavaScriptParser _parser;
     internal readonly Realm _shadowRealm;
@@ -111,7 +113,7 @@ public sealed class ShadowRealm : ObjectInstance
         }
         catch (ParserException e)
         {
-            if (e.Description == Messages.InvalidLHSInAssignment)
+            if (string.Equals(e.Description, Messages.InvalidLHSInAssignment, StringComparison.Ordinal))
             {
                 ExceptionHelper.ThrowReferenceError(callerRealm, Messages.InvalidLHSInAssignment);
             }

+ 4 - 4
Jint/Native/String/StringInstance.cs

@@ -51,7 +51,7 @@ internal class StringInstance : ObjectInstance, IPrimitiveInstance
             return desc;
         }
 
-        if ((property._type & (InternalTypes.Number | InternalTypes.Integer | InternalTypes.String)) == 0)
+        if ((property._type & (InternalTypes.Number | InternalTypes.Integer | InternalTypes.String)) == InternalTypes.None)
         {
             return PropertyDescriptor.Undefined;
         }
@@ -84,10 +84,10 @@ internal class StringInstance : ObjectInstance, IPrimitiveInstance
         yield return JsString.LengthString;
     }
 
-    public sealed override List<JsValue> GetOwnPropertyKeys(Types types)
+    public sealed override List<JsValue> GetOwnPropertyKeys(Types types = Types.String | Types.Symbol)
     {
         var keys = new List<JsValue>(StringData.Length + 1);
-        if ((types & Types.String) != 0)
+        if ((types & Types.String) != Types.None)
         {
             for (uint i = 0; i < StringData.Length; ++i)
             {
@@ -97,7 +97,7 @@ internal class StringInstance : ObjectInstance, IPrimitiveInstance
             keys.AddRange(base.GetOwnPropertyKeys(Types.String));
         }
 
-        if ((types & Types.Symbol) != 0)
+        if ((types & Types.Symbol) != Types.None)
         {
             keys.AddRange(base.GetOwnPropertyKeys(Types.Symbol));
         }

+ 3 - 1
Jint/Native/String/StringPrototype.cs

@@ -1,5 +1,6 @@
 using System.Globalization;
 using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
 using System.Text;
 using Jint.Collections;
 using Jint.Native.Json;
@@ -351,7 +352,7 @@ namespace Jint.Native.String
             var limit = arguments.At(1);
 
             // fast path for empty regexp
-            if (separator is JsRegExp R && R.Source == JsRegExp.regExpForMatchingAllCharacters)
+            if (separator is JsRegExp R && string.Equals(R.Source, JsRegExp.regExpForMatchingAllCharacters, StringComparison.Ordinal))
             {
                 separator = JsString.Empty;
             }
@@ -873,6 +874,7 @@ namespace Jint.Native.String
             return CodePointAt(s, position).CodePoint;
         }
 
+        [StructLayout(LayoutKind.Auto)]
         private readonly record struct CodePointResult(int CodePoint, int CodeUnitCount, bool IsUnpairedSurrogate);
 
         private static CodePointResult CodePointAt(string s, int position)

+ 2 - 0
Jint/Native/TypedArray/TypedArrayValue.cs

@@ -1,4 +1,5 @@
 using System.Numerics;
+using System.Runtime.InteropServices;
 using Jint.Runtime;
 
 namespace Jint.Native.TypedArray;
@@ -6,6 +7,7 @@ namespace Jint.Native.TypedArray;
 /// <summary>
 /// Container for either double or BigInteger.
 /// </summary>
+[StructLayout(LayoutKind.Auto)]
 internal readonly record struct TypedArrayValue(Types Type, double DoubleValue, BigInteger BigInteger) : IConvertible
 {
     public static implicit operator TypedArrayValue(double value)

+ 1 - 1
Jint/Options.cs

@@ -167,7 +167,7 @@ namespace Jint
                 return;
             }
 
-            foreach (var overloads in methods.GroupBy(x => x.Name))
+            foreach (var overloads in methods.GroupBy(x => x.Name, StringComparer.Ordinal))
             {
                 PropertyDescriptor CreateMethodInstancePropertyDescriptor(ClrFunctionInstance? function)
                 {

+ 1 - 1
Jint/Pooling/ArgumentsInstancePool.cs

@@ -49,7 +49,7 @@ namespace Jint.Pooling
             {
                 return;
             }
-            _pool.Free(instance);;
+            _pool.Free(instance);
         }
     }
 }

+ 1 - 1
Jint/Pooling/ReferencePool.cs

@@ -32,7 +32,7 @@ namespace Jint.Pooling
             {
                 return;
             }
-            _pool.Free(reference);;
+            _pool.Free(reference);
         }
     }
 }

+ 1 - 1
Jint/Runtime/Debugger/OptionalSourceBreakLocationEqualityComparer.cs

@@ -24,7 +24,7 @@ internal sealed class OptionalSourceBreakLocationEqualityComparer : IEqualityCom
         return
             x.Line == y.Line &&
             x.Column == y.Column &&
-            (x.Source == null || y.Source == null || x.Source == y.Source);
+            (x.Source == null || y.Source == null || string.Equals(x.Source, y.Source, StringComparison.Ordinal));
     }
 
     public int GetHashCode(BreakLocation? obj)

+ 3 - 1
Jint/Runtime/DefaultTimeSystem.cs

@@ -89,7 +89,9 @@ public class DefaultTimeSystem : ITimeSystem
                         if (DateUtils.TryParse(date, out var mimeKitResult))
                         {
                             var dateAsUtc = mimeKitResult.ToUniversalTime();
+#pragma warning disable MA0132
                             epochMilliseconds = (long) Math.Floor((dateAsUtc - DateConstructor.Epoch).TotalMilliseconds);
+#pragma warning restore MA0132
                             return true;
                         }
 
@@ -125,7 +127,7 @@ public class DefaultTimeSystem : ITimeSystem
         epochMilliseconds = long.MinValue;
 
         var yearString = date.Substring(0, 7);
-        if (!int.TryParse(yearString, out var year))
+        if (!int.TryParse(yearString, NumberStyles.Integer, CultureInfo.InvariantCulture, out var year))
         {
             return false;
         }

+ 18 - 14
Jint/Runtime/Descriptors/PropertyDescriptor.cs

@@ -27,9 +27,11 @@ namespace Jint.Runtime.Descriptors
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         protected internal PropertyDescriptor(JsValue? value, PropertyFlag flags) : this(flags)
         {
-            if ((_flags & PropertyFlag.CustomJsValue) != 0)
+            if ((_flags & PropertyFlag.CustomJsValue) != PropertyFlag.None)
             {
+#pragma warning disable MA0056
                 CustomValue = value;
+#pragma warning restore MA0056
             }
             _value = value;
         }
@@ -37,9 +39,11 @@ namespace Jint.Runtime.Descriptors
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public PropertyDescriptor(JsValue? value, bool? writable, bool? enumerable, bool? configurable)
         {
-            if ((_flags & PropertyFlag.CustomJsValue) != 0)
+            if ((_flags & PropertyFlag.CustomJsValue) != PropertyFlag.None)
             {
+#pragma warning disable MA0056
                 CustomValue = value;
+#pragma warning restore MA0056
             }
             _value = value;
 
@@ -82,7 +86,7 @@ namespace Jint.Runtime.Descriptors
         public bool Enumerable
         {
             [MethodImpl(MethodImplOptions.AggressiveInlining)]
-            get => (_flags & PropertyFlag.Enumerable) != 0;
+            get => (_flags & PropertyFlag.Enumerable) != PropertyFlag.None;
             [MethodImpl(MethodImplOptions.AggressiveInlining)]
             set
             {
@@ -101,7 +105,7 @@ namespace Jint.Runtime.Descriptors
         public bool EnumerableSet
         {
             [MethodImpl(MethodImplOptions.AggressiveInlining)]
-            get => (_flags & (PropertyFlag.EnumerableSet | PropertyFlag.Enumerable)) != 0;
+            get => (_flags & (PropertyFlag.EnumerableSet | PropertyFlag.Enumerable)) != PropertyFlag.None;
             [MethodImpl(MethodImplOptions.AggressiveInlining)]
             private set
             {
@@ -119,7 +123,7 @@ namespace Jint.Runtime.Descriptors
         public bool Writable
         {
             [MethodImpl(MethodImplOptions.AggressiveInlining)]
-            get => (_flags & PropertyFlag.Writable) != 0;
+            get => (_flags & PropertyFlag.Writable) != PropertyFlag.None;
             [MethodImpl(MethodImplOptions.AggressiveInlining)]
             set
             {
@@ -138,7 +142,7 @@ namespace Jint.Runtime.Descriptors
         public bool WritableSet
         {
             [MethodImpl(MethodImplOptions.AggressiveInlining)]
-            get => (_flags & (PropertyFlag.WritableSet | PropertyFlag.Writable)) != 0;
+            get => (_flags & (PropertyFlag.WritableSet | PropertyFlag.Writable)) != PropertyFlag.None;
             [MethodImpl(MethodImplOptions.AggressiveInlining)]
             private set
             {
@@ -156,7 +160,7 @@ namespace Jint.Runtime.Descriptors
         public bool Configurable
         {
             [MethodImpl(MethodImplOptions.AggressiveInlining)]
-            get => (_flags & PropertyFlag.Configurable) != 0;
+            get => (_flags & PropertyFlag.Configurable) != PropertyFlag.None;
             [MethodImpl(MethodImplOptions.AggressiveInlining)]
             set
             {
@@ -175,7 +179,7 @@ namespace Jint.Runtime.Descriptors
         public bool ConfigurableSet
         {
             [MethodImpl(MethodImplOptions.AggressiveInlining)]
-            get => (_flags & (PropertyFlag.ConfigurableSet | PropertyFlag.Configurable)) != 0;
+            get => (_flags & (PropertyFlag.ConfigurableSet | PropertyFlag.Configurable)) != PropertyFlag.None;
             [MethodImpl(MethodImplOptions.AggressiveInlining)]
             private set
             {
@@ -195,7 +199,7 @@ namespace Jint.Runtime.Descriptors
             [MethodImpl(MethodImplOptions.AggressiveInlining)]
             get
             {
-                if ((_flags & PropertyFlag.CustomJsValue) != 0)
+                if ((_flags & PropertyFlag.CustomJsValue) != PropertyFlag.None)
                 {
                     return CustomValue!;
                 }
@@ -205,7 +209,7 @@ namespace Jint.Runtime.Descriptors
             [MethodImpl(MethodImplOptions.AggressiveInlining)]
             set
             {
-                if ((_flags & PropertyFlag.CustomJsValue) != 0)
+                if ((_flags & PropertyFlag.CustomJsValue) != PropertyFlag.None)
                 {
                     CustomValue = value;
                 }
@@ -396,8 +400,8 @@ namespace Jint.Runtime.Descriptors
             {
                 return false;
             }
-            return (_flags & (PropertyFlag.WritableSet | PropertyFlag.Writable)) != 0
-                   || (_flags & PropertyFlag.CustomJsValue) != 0 && !ReferenceEquals(CustomValue, null)
+            return (_flags & (PropertyFlag.WritableSet | PropertyFlag.Writable)) != PropertyFlag.None
+                   || (_flags & PropertyFlag.CustomJsValue) != PropertyFlag.None && !ReferenceEquals(CustomValue, null)
                    || !ReferenceEquals(_value, null);
         }
 
@@ -417,9 +421,9 @@ namespace Jint.Runtime.Descriptors
             value = JsValue.Undefined;
 
             // IsDataDescriptor logic inlined
-            if ((_flags & (PropertyFlag.WritableSet | PropertyFlag.Writable)) != 0)
+            if ((_flags & (PropertyFlag.WritableSet | PropertyFlag.Writable)) != PropertyFlag.None)
             {
-                var val = (_flags & PropertyFlag.CustomJsValue) != 0
+                var val = (_flags & PropertyFlag.CustomJsValue) != PropertyFlag.None
                     ? CustomValue
                     : _value;
 

+ 1 - 1
Jint/Runtime/Environments/FunctionEnvironmentRecord.cs

@@ -320,7 +320,7 @@ namespace Jint.Runtime.Environments
             var idLeft = left as Identifier;
             if (idLeft != null
                 && right is Identifier idRight
-                && idLeft.Name == idRight.Name)
+                && string.Equals(idLeft.Name, idRight.Name, StringComparison.Ordinal))
             {
                 ExceptionHelper.ThrowReferenceNameError(_functionObject._realm, idRight.Name);
             }

+ 1 - 1
Jint/Runtime/Environments/PrivateEnvironmentRecord.cs

@@ -23,7 +23,7 @@ internal sealed class PrivateEnvironmentRecord
     {
         foreach (var pn in Names)
         {
-            if (pn.Value.Description == identifier)
+            if (string.Equals(pn.Value.Description, identifier, StringComparison.Ordinal))
             {
                 return pn.Value;
             }

+ 2 - 0
Jint/Runtime/ExceptionHelper.cs

@@ -114,7 +114,9 @@ namespace Jint.Runtime
         [DoesNotReturn]
         public static void ThrowArgumentOutOfRangeException()
         {
+#pragma warning disable MA0015
             throw new ArgumentOutOfRangeException();
+#pragma warning restore MA0015
         }
 
         [DoesNotReturn]

+ 3 - 1
Jint/Runtime/Host.cs

@@ -211,6 +211,8 @@ namespace Jint.Runtime
             Engine.AddToEventLoop(job);
         }
     }
+
+    internal sealed record JobCallback(ICallable Callback, object? HostDefined);
 }
 
-internal sealed record JobCallback(ICallable Callback, object? HostDefined);
+

+ 1 - 1
Jint/Runtime/Interop/MethodDescriptor.cs

@@ -148,7 +148,7 @@ namespace Jint.Runtime.Interop
                 }
                 else
                 {
-                    throw new ArgumentException("Method is unknown type");
+                    throw new NotSupportedException("Method is unknown type");
                 }
             }
             catch (TargetInvocationException exception)

+ 1 - 1
Jint/Runtime/Interop/NamespaceReference.cs

@@ -159,7 +159,7 @@ namespace Jint.Runtime.Interop
             Type[] types = assembly.GetTypes();
             foreach (Type t in types)
             {
-                if (t.FullName?.Replace("+", ".") == compared)
+                if (string.Equals(t.FullName?.Replace("+", "."), compared, StringComparison.Ordinal))
                 {
                     return t;
                 }

+ 1 - 1
Jint/Runtime/Interop/ObjectWrapper.cs

@@ -135,7 +135,7 @@ namespace Jint.Runtime.Interop
         private IEnumerable<JsValue> EnumerateOwnPropertyKeys(Types types)
         {
             // prefer object order, add possible other properties after
-            var includeStrings = (types & Types.String) != 0;
+            var includeStrings = (types & Types.String) != Types.None;
             if (includeStrings && _typeDescriptor.IsStringKeyedGenericDictionary) // expando object for instance
             {
                 var keys = _typeDescriptor.GetKeys(Target);

+ 1 - 1
Jint/Runtime/Interop/Reflection/IndexerAccessor.cs

@@ -44,7 +44,7 @@ namespace Jint.Runtime.Interop.Reflection
             // integer keys can be ambiguous as we only know string keys
             int? integerKey = null;
 
-            if (int.TryParse(propertyName, out var intKeyTemp))
+            if (int.TryParse(propertyName, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intKeyTemp))
             {
                 integerKey = intKeyTemp;
             }

+ 6 - 5
Jint/Runtime/Interop/TypeResolver.cs

@@ -1,5 +1,6 @@
 using System.Diagnostics.CodeAnalysis;
 using System.Dynamic;
+using System.Globalization;
 using System.Reflection;
 using System.Threading;
 using Jint.Runtime.Interop.Reflection;
@@ -22,7 +23,7 @@ namespace Jint.Runtime.Interop
 
         internal bool Filter(Engine engine, MemberInfo m)
         {
-            return (engine.Options.Interop.AllowGetType || m.Name != nameof(GetType)) && MemberFilter(m);
+            return (engine.Options.Interop.AllowGetType || !string.Equals(m.Name, nameof(GetType), StringComparison.Ordinal)) && MemberFilter(m);
         }
 
         /// <summary>
@@ -75,7 +76,7 @@ namespace Jint.Runtime.Interop
             string memberName,
             bool forWrite)
         {
-            var isInteger = long.TryParse(memberName, out _);
+            var isInteger = long.TryParse(memberName, NumberStyles.Integer, CultureInfo.InvariantCulture, out _);
 
             // we can always check indexer if there's one, and then fall back to properties if indexer returns null
             IndexerAccessor.TryFindIndexer(engine, type, memberName, out var indexerAccessor, out var indexer);
@@ -111,7 +112,7 @@ namespace Jint.Runtime.Interop
                             continue;
                         }
 
-                        if (iprop.Name == "Item" && iprop.GetIndexParameters().Length == 1)
+                        if (string.Equals(iprop.Name, "Item", StringComparison.Ordinal) && iprop.GetIndexParameters().Length == 1)
                         {
                             // never take indexers, should use the actual indexer
                             continue;
@@ -262,7 +263,7 @@ namespace Jint.Runtime.Interop
                     }
 
                     // only if it's not an indexer, we can do case-ignoring matches
-                    var isStandardIndexer = p.GetIndexParameters().Length == 1 && p.Name == "Item";
+                    var isStandardIndexer = p.GetIndexParameters().Length == 1 && string.Equals(p.Name, "Item", StringComparison.Ordinal);
                     if (!isStandardIndexer)
                     {
                         foreach (var name in typeResolverMemberNameCreator(p))
@@ -431,7 +432,7 @@ namespace Jint.Runtime.Interop
 #if SUPPORTS_SPAN_PARSE
                     equals = x.AsSpan(1).SequenceEqual(y.AsSpan(1));
 #else
-                    equals = x.Substring(1) == y.Substring(1);
+                    equals = string.Equals(x.Substring(1), y.Substring(1), StringComparison.Ordinal);
 #endif
                 }
 

+ 0 - 4
Jint/Runtime/Interpreter/Expressions/JintAssignmentExpression.cs

@@ -199,10 +199,6 @@ namespace Jint.Runtime.Interpreter.Expressions
                         {
                             newLeftValue = JsValue.Undefined;
                         }
-                        else if (!AreIntegerOperands(originalLeftValue, rval))
-                        {
-                            newLeftValue = TypeConverter.ToNumber(originalLeftValue) % TypeConverter.ToNumber(rval);
-                        }
                         else
                         {
                             newLeftValue = TypeConverter.ToNumber(originalLeftValue) % TypeConverter.ToNumber(rval);

+ 1 - 1
Jint/Runtime/Interpreter/Expressions/JintBinaryExpression.cs

@@ -63,7 +63,7 @@ namespace Jint.Runtime.Interpreter.Expressions
                     var leftMethods = leftType.GetOperatorOverloadMethods();
                     var rightMethods = rightType.GetOperatorOverloadMethods();
 
-                    var methods = leftMethods.Concat(rightMethods).Where(x => x.Name == clrName && x.GetParameters().Length == 2);
+                    var methods = leftMethods.Concat(rightMethods).Where(x => string.Equals(x.Name, clrName, StringComparison.Ordinal) && x.GetParameters().Length == 2);
                     var methodDescriptors = MethodDescriptor.Build(methods.ToArray());
 
                     return TypeConverter.FindBestMatch(context.Engine, methodDescriptors, _ => arguments).FirstOrDefault().Method;

+ 2 - 2
Jint/Runtime/Interpreter/Expressions/JintMetaPropertyExpression.cs

@@ -15,12 +15,12 @@ namespace Jint.Runtime.Interpreter.Expressions
         protected override object EvaluateInternal(EvaluationContext context)
         {
             var expression = (MetaProperty) _expression;
-            if (expression.Meta.Name == "new" && expression.Property.Name == "target")
+            if (string.Equals(expression.Meta.Name, "new", StringComparison.Ordinal) && string.Equals(expression.Property.Name, "target", StringComparison.Ordinal))
             {
                 return context.Engine.GetNewTarget();
             }
 
-            if (expression.Meta.Name == "import" && expression.Property.Name == "meta")
+            if (string.Equals(expression.Meta.Name, "import", StringComparison.Ordinal) && string.Equals(expression.Property.Name, "meta", StringComparison.Ordinal))
             {
                 var module = (SourceTextModuleRecord) context.Engine.ExecutionContext.ScriptOrModule!;
                 var importMeta = module.ImportMeta;

+ 2 - 2
Jint/Runtime/Interpreter/Expressions/JintObjectExpression.cs

@@ -87,7 +87,7 @@ namespace Jint.Runtime.Interpreter.Expressions
                     if (!p.Computed && p.Key is Identifier identifier)
                     {
                         propName = identifier.Name;
-                        _canBuildFast &= propName != "__proto__";
+                        _canBuildFast &= !string.Equals(propName, "__proto__", StringComparison.Ordinal);
                     }
 
                     _properties[i] = new ObjectProperty(propName, p);
@@ -206,7 +206,7 @@ namespace Jint.Runtime.Interpreter.Expressions
                     }
 
                     var propValue = completion.Clone();
-                    if (objectProperty._key == "__proto__" && !objectProperty._value.Computed && !objectProperty._value.Shorthand)
+                    if (string.Equals(objectProperty._key, "__proto__", StringComparison.Ordinal) && !objectProperty._value.Computed && !objectProperty._value.Shorthand)
                     {
                         if (propValue.IsObject() || propValue.IsNull())
                         {

+ 1 - 1
Jint/Runtime/Interpreter/Expressions/JintUnaryExpression.cs

@@ -306,7 +306,7 @@ namespace Jint.Runtime.Interpreter.Expressions
                     MethodInfo? foundMethod = null;
                     foreach (var x in operandType.GetOperatorOverloadMethods())
                     {
-                        if (x.Name == clrName && x.GetParameters().Length == 1)
+                        if (string.Equals(x.Name, clrName, StringComparison.Ordinal) && x.GetParameters().Length == 1)
                         {
                             foundMethod = x;
                             break;

+ 3 - 3
Jint/Runtime/Interpreter/JintFunctionDefinition.cs

@@ -341,7 +341,7 @@ internal sealed class JintFunctionDefinition
         {
             _hasDuplicates |= checkDuplicates && target.Contains(identifier.Name);
             target.Add(identifier.Name);
-            hasArguments |= identifier.Name == "arguments";
+            hasArguments |= string.Equals(identifier.Name, "arguments", StringComparison.Ordinal);
             return;
         }
 
@@ -431,7 +431,7 @@ internal sealed class JintFunctionDefinition
             {
                 var id = (Identifier) parameter;
                 state.HasDuplicates |= parameterNames.Contains(id.Name);
-                hasArguments = id.Name == "arguments";
+                hasArguments = string.Equals(id.Name, "arguments", StringComparison.Ordinal);
                 parameterNames.Add(id.Name);
             }
             else if (type != Nodes.Literal)
@@ -485,7 +485,7 @@ internal sealed class JintFunctionDefinition
                 var childType = childNode.Type;
                 if (childType == Nodes.Identifier)
                 {
-                    if (((Identifier) childNode).Name == "arguments")
+                    if (string.Equals(((Identifier) childNode).Name, "arguments", StringComparison.Ordinal))
                     {
                         return true;
                     }

+ 2 - 2
Jint/Runtime/Interpreter/Statements/JintDoWhileStatement.cs

@@ -37,9 +37,9 @@ internal sealed class JintDoWhileStatement : JintStatement<DoWhileStatement>
                 v = completion.Value;
             }
 
-            if (completion.Type != CompletionType.Continue || context.Target != _labelSetName)
+            if (completion.Type != CompletionType.Continue || !string.Equals(context.Target, _labelSetName, StringComparison.Ordinal))
             {
-                if (completion.Type == CompletionType.Break && (context.Target == null || context.Target == _labelSetName))
+                if (completion.Type == CompletionType.Break && (context.Target == null || string.Equals(context.Target, _labelSetName, StringComparison.Ordinal)))
                 {
                     return new Completion(CompletionType.Normal, v, _statement);
                 }

+ 6 - 2
Jint/Runtime/Interpreter/Statements/JintForInForOfStatement.cs

@@ -246,6 +246,7 @@ namespace Jint.Runtime.Interpreter.Statements
                         {
                             // DestructuringAssignmentEvaluation of assignmentPattern using nextValue as the argument.
                         }
+#pragma warning disable MA0140
                         else if (lhsKind == LhsKind.VarBinding)
                         {
                             // BindingInitialization for lhs passing nextValue and undefined as the arguments.
@@ -254,6 +255,7 @@ namespace Jint.Runtime.Interpreter.Statements
                         {
                             // BindingInitialization for lhs passing nextValue and iterationEnv as arguments
                         }
+#pragma warning restore MA0140
                     }
 
                     if (status != CompletionType.Normal)
@@ -282,13 +284,13 @@ namespace Jint.Runtime.Interpreter.Statements
                         v = result.Value;
                     }
 
-                    if (result.Type == CompletionType.Break && (context.Target == null || context.Target == _statement?.LabelSet?.Name))
+                    if (result.Type == CompletionType.Break && (context.Target == null || string.Equals(context.Target, _statement?.LabelSet?.Name, StringComparison.Ordinal)))
                     {
                         completionType = CompletionType.Normal;
                         return new Completion(CompletionType.Normal, v, _statement!);
                     }
 
-                    if (result.Type != CompletionType.Continue || (context.Target != null && context.Target != _statement?.LabelSet?.Name))
+                    if (result.Type != CompletionType.Continue || (context.Target != null && !string.Equals(context.Target, _statement?.LabelSet?.Name, StringComparison.Ordinal)))
                     {
                         completionType = result.Type;
                         if (result.IsAbrupt())
@@ -318,7 +320,9 @@ namespace Jint.Runtime.Interpreter.Statements
                         if (completionType != CompletionType.Throw)
                         {
 #pragma warning disable CA2219
+#pragma warning disable MA0072
                             throw;
+#pragma warning restore MA0072
 #pragma warning restore CA2219
                         }
                     }

+ 2 - 2
Jint/Runtime/Interpreter/Statements/JintForStatement.cs

@@ -141,12 +141,12 @@ namespace Jint.Runtime.Interpreter.Statements
                     v = result.Value;
                 }
 
-                if (result.Type == CompletionType.Break && (context.Target == null || context.Target == _statement?.LabelSet?.Name))
+                if (result.Type == CompletionType.Break && (context.Target == null || string.Equals(context.Target, _statement?.LabelSet?.Name, StringComparison.Ordinal)))
                 {
                     return new Completion(CompletionType.Normal, result.Value!, ((JintStatement) this)._statement);
                 }
 
-                if (result.Type != CompletionType.Continue || (context.Target != null && context.Target != _statement?.LabelSet?.Name))
+                if (result.Type != CompletionType.Continue || (context.Target != null && !string.Equals(context.Target, _statement?.LabelSet?.Name, StringComparison.Ordinal)))
                 {
                     if (result.Type != CompletionType.Normal)
                     {

+ 1 - 1
Jint/Runtime/Interpreter/Statements/JintLabeledStatement.cs

@@ -23,7 +23,7 @@ namespace Jint.Runtime.Interpreter.Statements
             // containing label and could keep a table per program with all the labels
             // labeledStatement.Body.LabelSet = labeledStatement.Label;
             var result = _body.Execute(context);
-            if (result.Type == CompletionType.Break && context.Target == _labelName)
+            if (result.Type == CompletionType.Break && string.Equals(context.Target, _labelName, StringComparison.Ordinal))
             {
                 var value = result.Value;
                 return new Completion(CompletionType.Normal, value, _statement);

+ 1 - 1
Jint/Runtime/Interpreter/Statements/JintSwitchStatement.cs

@@ -25,7 +25,7 @@ namespace Jint.Runtime.Interpreter.Statements
         {
             var value = _discriminant.GetValue(context);
             var r = _switchBlock.Execute(context, value);
-            if (r.Type == CompletionType.Break && context.Target == _statement.LabelSet?.Name)
+            if (r.Type == CompletionType.Break && string.Equals(context.Target, _statement.LabelSet?.Name, StringComparison.Ordinal))
             {
                 return new Completion(CompletionType.Normal, r.Value, ((JintStatement) this)._statement);
             }

+ 2 - 2
Jint/Runtime/Interpreter/Statements/JintWhileStatement.cs

@@ -47,9 +47,9 @@ namespace Jint.Runtime.Interpreter.Statements
                     v = completion.Value;
                 }
 
-                if (completion.Type != CompletionType.Continue || context.Target != _labelSetName)
+                if (completion.Type != CompletionType.Continue || !string.Equals(context.Target, _labelSetName, StringComparison.Ordinal))
                 {
-                    if (completion.Type == CompletionType.Break && (context.Target == null || context.Target == _labelSetName))
+                    if (completion.Type == CompletionType.Break && (context.Target == null || string.Equals(context.Target, _labelSetName, StringComparison.Ordinal)))
                     {
                         return new Completion(CompletionType.Normal, v, _statement);
                     }

+ 1 - 1
Jint/Runtime/Modules/CyclicModuleRecord.cs

@@ -435,7 +435,7 @@ public abstract class CyclicModuleRecord : ModuleRecord
     /// <summary>
     /// https://tc39.es/ecma262/#sec-async-module-execution-fulfilled
     /// </summary>
-    private JsValue AsyncModuleExecutionFulfilled(JsValue thisObject, JsValue[] arguments)
+    private static JsValue AsyncModuleExecutionFulfilled(JsValue thisObject, JsValue[] arguments)
     {
         var module = (CyclicModuleRecord) arguments.At(0);
         if (module.Status == ModuleStatus.Evaluated)

+ 3 - 3
Jint/Runtime/Modules/ModuleNamespace.cs

@@ -20,7 +20,7 @@ internal sealed class ModuleNamespace : ObjectInstance
     public ModuleNamespace(Engine engine, ModuleRecord module, List<string> exports) : base(engine)
     {
         _module = module;
-        _exports = new HashSet<string>(exports);
+        _exports = new HashSet<string>(exports, StringComparer.Ordinal);
     }
 
     protected override void Initialize()
@@ -162,7 +162,7 @@ internal sealed class ModuleNamespace : ObjectInstance
         var binding = m.ResolveExport(p);
         var targetModule = binding.Module;
 
-        if (binding.BindingName == "*namespace*")
+        if (string.Equals(binding.BindingName, "*namespace*", StringComparison.Ordinal))
         {
             return ModuleRecord.GetModuleNamespace(targetModule);
         }
@@ -204,7 +204,7 @@ internal sealed class ModuleNamespace : ObjectInstance
     public override List<JsValue> GetOwnPropertyKeys(Types types = Types.String | Types.Symbol)
     {
         var result = new List<JsValue>();
-        if ((types & Types.String) != 0)
+        if ((types & Types.String) != Types.None)
         {
             result.Capacity = _exports.Count;
             foreach (var export in _exports)

+ 9 - 9
Jint/Runtime/Modules/SourceTextModuleRecord.cs

@@ -127,7 +127,7 @@ internal class SourceTextModuleRecord : CyclicModuleRecord
         for (var i = 0; i < resolveSet.Count; i++)
         {
             var r = resolveSet[i];
-            if (ReferenceEquals(this, r.Module) && exportName == r.ExportName)
+            if (ReferenceEquals(this, r.Module) && string.Equals(exportName, r.ExportName, StringComparison.Ordinal))
             {
                 // circular import request
                 return null;
@@ -138,7 +138,7 @@ internal class SourceTextModuleRecord : CyclicModuleRecord
         for (var i = 0; i < _localExportEntries.Count; i++)
         {
             var e = _localExportEntries[i];
-            if (exportName == e.ExportName)
+            if (string.Equals(exportName, e.ExportName, StringComparison.Ordinal))
             {
                 // i. Assert: module provides the direct binding for this export.
                 return new ResolvedBinding(this, e.LocalName);
@@ -148,10 +148,10 @@ internal class SourceTextModuleRecord : CyclicModuleRecord
         for (var i = 0; i < _indirectExportEntries.Count; i++)
         {
             var e = _indirectExportEntries[i];
-            if (exportName == e.ExportName)
+            if (string.Equals(exportName, e.ExportName, StringComparison.Ordinal))
             {
                 var importedModule = _engine._host.ResolveImportedModule(this, e.ModuleRequest);
-                if (e.ImportName == "*")
+                if (string.Equals(e.ImportName, "*", StringComparison.Ordinal))
                 {
                     // 1. Assert: module does not provide the direct binding for this export.
                     return new ResolvedBinding(importedModule, "*namespace*");
@@ -190,7 +190,7 @@ internal class SourceTextModuleRecord : CyclicModuleRecord
                 }
                 else
                 {
-                    if (resolution.Module != starResolution.Module || resolution.BindingName != starResolution.BindingName)
+                    if (resolution.Module != starResolution.Module || !string.Equals(resolution.BindingName, starResolution.BindingName, StringComparison.Ordinal))
                     {
                         return ResolvedBinding.Ambiguous;
                     }
@@ -226,7 +226,7 @@ internal class SourceTextModuleRecord : CyclicModuleRecord
             {
                 var ie = _importEntries[i];
                 var importedModule = _engine._host.ResolveImportedModule(this, ie.ModuleRequest);
-                if (ie.ImportName == "*")
+                if (string.Equals(ie.ImportName, "*", StringComparison.Ordinal))
                 {
                     var ns = GetModuleNamespace(importedModule);
                     env.CreateImmutableBinding(ie.LocalName, true);
@@ -240,7 +240,7 @@ internal class SourceTextModuleRecord : CyclicModuleRecord
                         ExceptionHelper.ThrowSyntaxError(_realm, "Ambiguous import statement for identifier " + ie.ImportName);
                     }
 
-                    if (resolution.BindingName == "*namespace*")
+                    if (string.Equals(resolution.BindingName, "*namespace*", StringComparison.Ordinal))
                     {
                         var ns = GetModuleNamespace(resolution.Module);
                         env.CreateImmutableBinding(ie.LocalName, true);
@@ -262,7 +262,7 @@ internal class SourceTextModuleRecord : CyclicModuleRecord
         var hoistingScope = HoistingScope.GetModuleLevelDeclarations(_source);
 
         var varDeclarations = hoistingScope._variablesDeclarations;
-        var declaredVarNames = new HashSet<string>();
+        var declaredVarNames = new HashSet<string>(StringComparer.Ordinal);
         if (varDeclarations != null)
         {
             var boundNames = new List<string>();
@@ -320,7 +320,7 @@ internal class SourceTextModuleRecord : CyclicModuleRecord
                 env.CreateMutableBinding(fn, true);
                 // TODO private scope
                 var fo = realm.Intrinsics.Function.InstantiateFunctionObject(fd, env, privateEnv: null);
-                if (fn == "*default*")
+                if (string.Equals(fn, "*default*", StringComparison.Ordinal))
                 {
                     fo.SetFunctionName("default");
                 }

+ 3 - 3
Jint/Runtime/References/Reference.cs

@@ -52,7 +52,7 @@ public sealed class Reference
     public bool HasPrimitiveBase
     {
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        get => (_base._type & InternalTypes.Primitive) != 0;
+        get => (_base._type & InternalTypes.Primitive) != InternalTypes.None;
     }
 
     public bool IsUnresolvableReference
@@ -68,7 +68,7 @@ public sealed class Reference
     public bool IsPropertyReference
     {
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        get => (_base._type & (InternalTypes.Primitive | InternalTypes.Object)) != 0;
+        get => (_base._type & (InternalTypes.Primitive | InternalTypes.Object)) != InternalTypes.None;
     }
 
     public JsValue ThisValue
@@ -96,7 +96,7 @@ public sealed class Reference
     internal void AssertValid(Realm realm)
     {
         if (_strict
-            && (_base._type & InternalTypes.ObjectEnvironmentRecord) != 0
+            && (_base._type & InternalTypes.ObjectEnvironmentRecord) != InternalTypes.None
             && (CommonProperties.Eval.Equals(_referencedName) || CommonProperties.Arguments.Equals(_referencedName)))
         {
             ExceptionHelper.ThrowSyntaxError(realm);

+ 3 - 3
Jint/Runtime/TypeConverter.cs

@@ -800,7 +800,7 @@ namespace Jint.Runtime
 
             if (value is JsString jsString)
             {
-                if (jsString.ToString() == "-0")
+                if (string.Equals(jsString.ToString(), "-0", StringComparison.Ordinal))
                 {
                     return JsNumber.NegativeZero._value;
                 }
@@ -935,7 +935,7 @@ namespace Jint.Runtime
         public static JsValue ToPropertyKey(JsValue o)
         {
             const InternalTypes PropertyKeys = InternalTypes.String | InternalTypes.Symbol | InternalTypes.PrivateName;
-            return (o._type & PropertyKeys) != 0
+            return (o._type & PropertyKeys) != InternalTypes.None
                 ? o
                 : ToPropertyKeyNonString(o);
         }
@@ -945,7 +945,7 @@ namespace Jint.Runtime
         {
             const InternalTypes PropertyKeys = InternalTypes.String | InternalTypes.Symbol | InternalTypes.PrivateName;
             var primitive = ToPrimitive(o, Types.String);
-            return (primitive._type & PropertyKeys) != 0
+            return (primitive._type & PropertyKeys) != InternalTypes.None
                 ? primitive
                 : ToStringNonString(primitive);
         }