From 088f08f8e1f178f4b55a067d156f8c40e2511b41 Mon Sep 17 00:00:00 2001 From: Marko Lahma Date: Sun, 12 Nov 2023 14:21:00 +0200 Subject: [PATCH] Enable code analysis with latest-Recommended (#1681) --- .editorconfig | 15 ++++++ Jint.Tests/Runtime/EngineTests.cs | 7 +-- Jint/Constraints/TimeConstraint.cs | 2 + Jint/Jint.csproj | 1 + Jint/Native/ArrayBuffer/JsArrayBuffer.cs | 2 + Jint/Native/BigInt/BigIntPrototype.cs | 5 +- Jint/Native/Date/DatePrototype.cs | 19 +++---- Jint/Native/Date/MimeKit.cs | 8 ++- .../FinalizationRegistryInstance.cs | 2 +- .../FinalizationRegistryPrototype.cs | 2 +- Jint/Native/Function/ClassDefinition.cs | 2 +- .../Native/Function/ScriptFunctionInstance.cs | 4 +- Jint/Native/Global/GlobalObject.cs | 30 +++++------ Jint/Native/Intl/DateTimeFormatConstructor.cs | 2 +- Jint/Native/Intl/NumberFormatConstructor.cs | 6 +-- Jint/Native/Intl/PluralRulesConstructor.cs | 2 +- .../Intl/RelativeTimeFormatConstructor.cs | 2 +- Jint/Native/JsBigInt.cs | 15 ++---- Jint/Native/JsBoolean.cs | 7 ++- Jint/Native/JsNull.cs | 15 +++--- Jint/Native/JsNumber.cs | 21 ++++---- Jint/Native/JsString.cs | 27 +++------- Jint/Native/JsSymbol.cs | 17 ++----- Jint/Native/JsUndefined.cs | 15 +++--- Jint/Native/JsValue.cs | 15 ++---- Jint/Native/Json/JsonParser.cs | 4 +- Jint/Native/Json/JsonSerializer.cs | 3 +- Jint/Native/Number/Dtoa/Bignum.cs | 18 +++---- Jint/Native/Number/NumberPrototype.cs | 50 +++++++++---------- Jint/Native/Object/ObjectInstance.cs | 11 ++-- Jint/Native/Promise/PromiseOperations.cs | 2 +- Jint/Native/Proxy/JsProxy.cs | 2 +- Jint/Native/RegExp/RegExpPrototype.cs | 6 +++ Jint/Native/String/StringPrototype.cs | 12 +++-- Jint/Native/TypedArray/JsTypedArray.cs | 3 +- .../TypedArray/TypedArrayConstructor.cs | 3 +- Jint/Options.cs | 4 +- Jint/Pooling/ConcurrentObjectPool.cs | 2 + Jint/Pooling/ObjectPool.cs | 2 + Jint/Runtime/CallStack/JintCallStack.cs | 12 +++-- Jint/Runtime/CallStack/StackGuard.cs | 4 +- Jint/Runtime/Debugger/BreakPointCollection.cs | 2 - Jint/Runtime/DefaultTimeSystem.cs | 2 + Jint/Runtime/Interop/ClrFunctionInstance.cs | 6 ++- Jint/Runtime/Interop/ClrHelper.cs | 8 ++- .../Runtime/Interop/DefaultObjectConverter.cs | 13 ++--- Jint/Runtime/Interop/DelegateWrapper.cs | 8 +-- Jint/Runtime/Interop/MethodDescriptor.cs | 2 +- Jint/Runtime/Interop/NamespaceReference.cs | 2 +- Jint/Runtime/Interop/ObjectWrapper.cs | 11 ++-- Jint/Runtime/Interop/TypeReference.cs | 6 +-- .../BindingPatternAssignmentExpression.cs | 3 +- .../Expressions/JintCallExpression.cs | 3 +- .../Expressions/JintMemberExpression.cs | 2 +- .../Interpreter/JintFunctionDefinition.cs | 2 +- .../JintExportDefaultDeclaration.cs | 2 +- .../Statements/JintForInForOfStatement.cs | 2 + Jint/Runtime/Modules/DefaultModuleLoader.cs | 2 +- Jint/Runtime/Modules/FailFastModuleLoader.cs | 2 + .../Runtime/Modules/SourceTextModuleRecord.cs | 4 +- Jint/Runtime/OrderedDictionary.cs | 2 +- Jint/Runtime/TypeConverter.cs | 12 ++--- 62 files changed, 248 insertions(+), 229 deletions(-) diff --git a/.editorconfig b/.editorconfig index 758216668c..570d06a3c5 100644 --- a/.editorconfig +++ b/.editorconfig @@ -36,6 +36,21 @@ indent_size = 2 # IDE0055: Fix formatting dotnet_diagnostic.IDE0055.severity = warning +# Error CA1051 : Do not declare visible instance fields +dotnet_diagnostic.CA1051.severity = none + +# Error CA1720 : Identifiers should not contain type names +dotnet_diagnostic.CA1720.severity = none + +# Error CA1711: Identifiers should not have incorrect suffix +dotnet_diagnostic.CA1711.severity = none + +# Error CA1710: Identifiers should have correct suffix +dotnet_diagnostic.CA1710.severity = none + +# Error CA1716: Identifiers should have correct suffix +dotnet_diagnostic.CA1716.severity = none + # Sort using and Import directives with System.* appearing first dotnet_sort_system_directives_first = true dotnet_separate_import_directive_groups = false diff --git a/Jint.Tests/Runtime/EngineTests.cs b/Jint.Tests/Runtime/EngineTests.cs index d898f99a8e..ef6f84c3ba 100644 --- a/Jint.Tests/Runtime/EngineTests.cs +++ b/Jint.Tests/Runtime/EngineTests.cs @@ -4,6 +4,7 @@ using Esprima.Ast; using Jint.Native; using Jint.Native.Array; +using Jint.Native.Number; using Jint.Native.Object; using Jint.Runtime; using Jint.Runtime.Debugger; @@ -823,8 +824,8 @@ public void ShouldHandleEscapedSlashesInRegex() [Fact] public void ShouldComputeFractionInBase() { - Assert.Equal("011", _engine.Realm.Intrinsics.Number.PrototypeObject.ToFractionBase(0.375, 2)); - Assert.Equal("14141414141414141414141414141414141414141414141414", _engine.Realm.Intrinsics.Number.PrototypeObject.ToFractionBase(0.375, 5)); + Assert.Equal("011", NumberPrototype.ToFractionBase(0.375, 2)); + Assert.Equal("14141414141414141414141414141414141414141414141414", NumberPrototype.ToFractionBase(0.375, 5)); } [Fact] @@ -910,7 +911,7 @@ public void ShouldNotAllowModifyingSharedUndefinedDescriptor() [InlineData("2qgpckvng1s", 10000000000000000L, 36)] public void ShouldConvertNumbersToDifferentBase(string expected, long number, int radix) { - var result = _engine.Realm.Intrinsics.Number.PrototypeObject.ToBase(number, radix); + var result = NumberPrototype.ToBase(number, radix); Assert.Equal(expected, result); } diff --git a/Jint/Constraints/TimeConstraint.cs b/Jint/Constraints/TimeConstraint.cs index a6b052b48d..b7f295c671 100644 --- a/Jint/Constraints/TimeConstraint.cs +++ b/Jint/Constraints/TimeConstraint.cs @@ -3,7 +3,9 @@ namespace Jint.Constraints; +#pragma warning disable CA1001 internal sealed class TimeConstraint : Constraint +#pragma warning restore CA1001 { private readonly TimeSpan _timeout; private CancellationTokenSource? _cts; diff --git a/Jint/Jint.csproj b/Jint/Jint.csproj index 1a061147e2..a83d5581a0 100644 --- a/Jint/Jint.csproj +++ b/Jint/Jint.csproj @@ -9,6 +9,7 @@ enable enable true + latest-Recommended diff --git a/Jint/Native/ArrayBuffer/JsArrayBuffer.cs b/Jint/Native/ArrayBuffer/JsArrayBuffer.cs index c745a66ce6..1c84164be5 100644 --- a/Jint/Native/ArrayBuffer/JsArrayBuffer.cs +++ b/Jint/Native/ArrayBuffer/JsArrayBuffer.cs @@ -37,7 +37,9 @@ private byte[] CreateByteDataBlock(ulong byteLength) internal byte[]? ArrayBufferData => _arrayBufferData; internal bool IsDetachedBuffer => _arrayBufferData is null; +#pragma warning disable CA1822 internal bool IsSharedArrayBuffer => false; // TODO SharedArrayBuffer +#pragma warning restore CA1822 /// /// https://tc39.es/ecma262/#sec-detacharraybuffer diff --git a/Jint/Native/BigInt/BigIntPrototype.cs b/Jint/Native/BigInt/BigIntPrototype.cs index 8d801fce9a..86875afaed 100644 --- a/Jint/Native/BigInt/BigIntPrototype.cs +++ b/Jint/Native/BigInt/BigIntPrototype.cs @@ -1,3 +1,4 @@ +using System.Globalization; using System.Numerics; using Jint.Collections; using Jint.Native.Object; @@ -55,7 +56,7 @@ private JsValue ToLocaleString(JsValue thisObject, JsValue[] arguments) var x = ThisBigIntValue(thisObject); //var numberFormat = (NumberFormat) Construct(_realm.Intrinsics.NumberFormat, new[] { locales, options }); // numberFormat.FormatNumeric(x); - return x._value.ToString("R"); + return x._value.ToString("R", CultureInfo.InvariantCulture); } /// @@ -103,7 +104,7 @@ private JsValue ToBigIntString(JsValue thisObject, JsValue[] arguments) if (radixMV == 10) { - return value.ToString("R"); + return value.ToString("R", CultureInfo.InvariantCulture); } var negative = value < 0; diff --git a/Jint/Native/Date/DatePrototype.cs b/Jint/Native/Date/DatePrototype.cs index 16796707d9..19abde6aa5 100644 --- a/Jint/Native/Date/DatePrototype.cs +++ b/Jint/Native/Date/DatePrototype.cs @@ -1,3 +1,4 @@ +using System.Globalization; using System.Runtime.CompilerServices; using Jint.Collections; using Jint.Native.Object; @@ -775,9 +776,9 @@ private JsValue ToUtcString(JsValue thisObject, JsValue[] arguments) var weekday = _dayNames[WeekDay(tv)]; var month = _monthNames[MonthFromTime(tv)]; - var day = DateFromTime(tv).ToString("00"); + var day = DateFromTime(tv).ToString("00", CultureInfo.InvariantCulture); var yv = YearFromTime(tv); - var paddedYear = yv.ToString("0000"); + var paddedYear = yv.ToString("0000", CultureInfo.InvariantCulture); return $"{weekday}, {day} {month} {paddedYear} {TimeString(tv)}"; } @@ -1355,11 +1356,11 @@ private static string DateString(DatePresentation tv) var month = _monthNames[MonthFromTime(tv)]; var dateFromTime = DateFromTime(tv); - var day = System.Math.Max(1, dateFromTime).ToString("00"); + var day = System.Math.Max(1, dateFromTime).ToString("00", CultureInfo.InvariantCulture); var yv = YearFromTime(tv); var yearSign = yv < 0 ? "-" : ""; var year = System.Math.Abs(yv); - var paddedYear = year.ToString("0000"); + var paddedYear = year.ToString("0000", CultureInfo.InvariantCulture); return weekday + " " + month + " " + day + " " + yearSign + paddedYear; } @@ -1369,9 +1370,9 @@ private static string DateString(DatePresentation tv) /// private static string TimeString(DatePresentation t) { - var hour = HourFromTime(t).ToString("00"); - var minute = MinFromTime(t).ToString("00"); - var second = SecFromTime(t).ToString("00"); + var hour = HourFromTime(t).ToString("00", CultureInfo.InvariantCulture); + var minute = MinFromTime(t).ToString("00", CultureInfo.InvariantCulture); + var second = SecFromTime(t).ToString("00", CultureInfo.InvariantCulture); return hour + ":" + minute + ":" + second + " GMT"; } @@ -1396,8 +1397,8 @@ private string TimeZoneString(DatePresentation tv) absOffset = -1 * offset; } - var offsetMin = MinFromTime(absOffset).ToString("00"); - var offsetHour = HourFromTime(absOffset).ToString("00"); + var offsetMin = MinFromTime(absOffset).ToString("00", CultureInfo.InvariantCulture); + var offsetHour = HourFromTime(absOffset).ToString("00", CultureInfo.InvariantCulture); var tzName = " (" + _timeSystem.DefaultTimeZone.StandardName + ")"; diff --git a/Jint/Native/Date/MimeKit.cs b/Jint/Native/Date/MimeKit.cs index 3672ac480d..61ba981024 100644 --- a/Jint/Native/Date/MimeKit.cs +++ b/Jint/Native/Date/MimeKit.cs @@ -180,6 +180,7 @@ static DateUtils() any[1] = (char) c; } +#pragma warning disable CA2249 if (NumericZoneCharacters.IndexOf((char) c) == -1) datetok[c] |= DateTokenFlags.NonNumericZone; if (AlphaZoneCharacters.IndexOf((char) c) == -1) @@ -192,6 +193,7 @@ static DateUtils() datetok[c] |= DateTokenFlags.NonMonth; if (TimeCharacters.IndexOf((char) c) == -1) datetok[c] |= DateTokenFlags.NonTime; +#pragma warning restore CA2249 } datetok[':'] |= DateTokenFlags.HasColon; @@ -518,7 +520,9 @@ private static bool TryParseUnknownDateFormat(IList tokens, byte[] te int endIndex = tokens[i].Start + tokens[i].Length; int index = tokens[i].Start; +#pragma warning disable CA1806 ParseUtils.TryParseInt32(text, ref index, endIndex, out value); +#pragma warning restore CA1806 if (month == null && value > 0 && value <= 12) { @@ -727,7 +731,9 @@ public static bool SkipCommentsAndWhiteSpace(byte[] text, ref int index, int end if (!SkipComment(text, ref index, endIndex)) { if (throwOnError) - throw new Exception($"Incomplete comment token at offset {startIndex}"); + { + throw new ArgumentException($"Incomplete comment token at offset {startIndex}"); + } return false; } diff --git a/Jint/Native/FinalizationRegistry/FinalizationRegistryInstance.cs b/Jint/Native/FinalizationRegistry/FinalizationRegistryInstance.cs index f6b1529b32..1dd7e6dfc9 100644 --- a/Jint/Native/FinalizationRegistry/FinalizationRegistryInstance.cs +++ b/Jint/Native/FinalizationRegistry/FinalizationRegistryInstance.cs @@ -19,7 +19,7 @@ public FinalizationRegistryInstance(Engine engine, Realm realm, ICallable cleanu _callable = engine._host.MakeJobCallBack(cleanupCallback); } - public void CleanupFinalizationRegistry(ICallable? callback) + public static void CleanupFinalizationRegistry(ICallable? callback) { } diff --git a/Jint/Native/FinalizationRegistry/FinalizationRegistryPrototype.cs b/Jint/Native/FinalizationRegistry/FinalizationRegistryPrototype.cs index 0f39c5e6dd..22df9c2c35 100644 --- a/Jint/Native/FinalizationRegistry/FinalizationRegistryPrototype.cs +++ b/Jint/Native/FinalizationRegistry/FinalizationRegistryPrototype.cs @@ -98,7 +98,7 @@ private JsValue CleanupSome(JsValue thisObject, JsValue[] arguments) ExceptionHelper.ThrowTypeError(_realm, callback + " must be callable"); } - finalizationRegistry.CleanupFinalizationRegistry(callback as ICallable); + FinalizationRegistryInstance.CleanupFinalizationRegistry(callback as ICallable); return Undefined; } diff --git a/Jint/Native/Function/ClassDefinition.cs b/Jint/Native/Function/ClassDefinition.cs index 24a8fa7f4a..f82d7fba2e 100644 --- a/Jint/Native/Function/ClassDefinition.cs +++ b/Jint/Native/Function/ClassDefinition.cs @@ -276,7 +276,7 @@ private static ClassFieldDefinition ClassFieldDefinitionEvaluation(Engine engine private sealed class ClassFieldFunction : Node, IFunction { - private readonly NodeList _nodeList = new(); + private readonly NodeList _nodeList; private readonly BlockStatement _statement; public ClassFieldFunction(Expression expression) : base(Nodes.ExpressionStatement) diff --git a/Jint/Native/Function/ScriptFunctionInstance.cs b/Jint/Native/Function/ScriptFunctionInstance.cs index d794635ada..b01c08f7ee 100644 --- a/Jint/Native/Function/ScriptFunctionInstance.cs +++ b/Jint/Native/Function/ScriptFunctionInstance.cs @@ -57,7 +57,7 @@ internal ScriptFunctionInstance( /// /// https://tc39.es/ecma262/#sec-ecmascript-function-objects-call-thisargument-argumentslist /// - protected internal override JsValue Call(JsValue thisArgument, JsValue[] arguments) + protected internal override JsValue Call(JsValue thisObject, JsValue[] arguments) { var strict = _functionDefinition.Strict || _thisMode == FunctionThisMode.Strict; using (new StrictModeScope(strict, true)) @@ -71,7 +71,7 @@ protected internal override JsValue Call(JsValue thisArgument, JsValue[] argumen ExceptionHelper.ThrowTypeError(calleeContext.Realm, $"Class constructor {_functionDefinition.Name} cannot be invoked without 'new'"); } - OrdinaryCallBindThis(calleeContext, thisArgument); + OrdinaryCallBindThis(calleeContext, thisObject); // actual call var context = _engine._activeEvaluationContext ?? new EvaluationContext(_engine); diff --git a/Jint/Native/Global/GlobalObject.cs b/Jint/Native/Global/GlobalObject.cs index c3d053d956..86ee63c231 100644 --- a/Jint/Native/Global/GlobalObject.cs +++ b/Jint/Native/Global/GlobalObject.cs @@ -138,7 +138,7 @@ public static JsValue ParseFloat(JsValue thisObject, JsValue[] arguments) if (trimmedString[0] == '-') { i++; - if (trimmedString.Length > 1 && trimmedString[1] == 'I' && trimmedString.StartsWith("-Infinity")) + if (trimmedString.Length > 1 && trimmedString[1] == 'I' && trimmedString.StartsWith("-Infinity", StringComparison.Ordinal)) { return JsNumber.DoubleNegativeInfinity; } @@ -147,18 +147,18 @@ public static JsValue ParseFloat(JsValue thisObject, JsValue[] arguments) if (trimmedString[0] == '+') { i++; - if (trimmedString.Length > 1 && trimmedString[1] == 'I' && trimmedString.StartsWith("+Infinity")) + if (trimmedString.Length > 1 && trimmedString[1] == 'I' && trimmedString.StartsWith("+Infinity", StringComparison.Ordinal)) { return JsNumber.DoublePositiveInfinity; } } - if (trimmedString.StartsWith("Infinity")) + if (trimmedString.StartsWith("Infinity", StringComparison.Ordinal)) { return JsNumber.DoublePositiveInfinity; } - if (trimmedString.StartsWith("NaN")) + if (trimmedString.StartsWith("NaN", StringComparison.Ordinal)) { return JsNumber.DoubleNaN; } @@ -462,7 +462,9 @@ private JsValue Decode(string uriString, string? reservedSet) if ((B & 0x80) == 0) { C = (char)B; +#pragma warning disable CA2249 if (reservedSet == null || reservedSet.IndexOf(C) == -1) +#pragma warning restore CA2249 { _stringBuilder.Append(C); } @@ -590,7 +592,7 @@ private static bool IsDigit(char c, int radix, out int result) /// public JsValue Escape(JsValue thisObject, JsValue[] arguments) { - const string whiteList = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_ + -./"; + const string WhiteList = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_ + -./"; var uriString = TypeConverter.ToString(arguments.At(0)); var strLen = uriString.Length; @@ -601,17 +603,17 @@ public JsValue Escape(JsValue thisObject, JsValue[] arguments) for (var k = 0; k < strLen; k++) { var c = uriString[k]; - if (whiteList.IndexOf(c) != -1) + if (WhiteList.IndexOf(c) != -1) { _stringBuilder.Append(c); } else if (c < 256) { - _stringBuilder.Append($"%{((int) c):X2}"); + _stringBuilder.Append('%').AppendFormat(CultureInfo.InvariantCulture, "{0:X2}", (int) c); } else { - _stringBuilder.Append($"%u{((int) c):X4}"); + _stringBuilder.Append("%u").AppendFormat(CultureInfo.InvariantCulture, "{0:X4}", (int) c); } } @@ -639,18 +641,16 @@ public JsValue Unescape(JsValue thisObject, JsValue[] arguments) && uriString[k + 1] == 'u' && uriString.Skip(k + 2).Take(4).All(IsValidHexaChar)) { - c = (char)int.Parse( - string.Join(string.Empty, uriString.Skip(k + 2).Take(4)), - NumberStyles.AllowHexSpecifier); + var joined = string.Join(string.Empty, uriString.Skip(k + 2).Take(4)); + c = (char) int.Parse(joined, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture); k += 5; } else if (k <= strLen - 3 - && uriString.Skip(k + 1).Take(2).All(IsValidHexaChar)) + && uriString.Skip(k + 1).Take(2).All(IsValidHexaChar)) { - c = (char)int.Parse( - string.Join(string.Empty, uriString.Skip(k + 1).Take(2)), - NumberStyles.AllowHexSpecifier); + var joined = string.Join(string.Empty, uriString.Skip(k + 1).Take(2)); + c = (char) int.Parse(joined, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture); k += 2; } diff --git a/Jint/Native/Intl/DateTimeFormatConstructor.cs b/Jint/Native/Intl/DateTimeFormatConstructor.cs index bffd0a861a..11c1d4d5ee 100644 --- a/Jint/Native/Intl/DateTimeFormatConstructor.cs +++ b/Jint/Native/Intl/DateTimeFormatConstructor.cs @@ -48,7 +48,7 @@ public override ObjectInstance Construct(JsValue[] arguments, JsValue newTarget) /// /// https://tc39.es/ecma402/#sec-initializedatetimeformat /// - private void InitializeDateTimeFormat(JsObject dateTimeFormat, JsValue locales, JsValue options) + private static void InitializeDateTimeFormat(JsObject dateTimeFormat, JsValue locales, JsValue options) { // TODO } diff --git a/Jint/Native/Intl/NumberFormatConstructor.cs b/Jint/Native/Intl/NumberFormatConstructor.cs index 1589b1b889..a180225ac4 100644 --- a/Jint/Native/Intl/NumberFormatConstructor.cs +++ b/Jint/Native/Intl/NumberFormatConstructor.cs @@ -201,7 +201,7 @@ private void SetNumberFormatUnitOptions(JsObject intlObj, JsValue options) /// /// https://tc39.es/ecma402/#sec-iswellformedunitidentifier /// - private bool IsWellFormedUnitIdentifier(JsValue unitIdentifier) + private static bool IsWellFormedUnitIdentifier(JsValue unitIdentifier) { var value = unitIdentifier.ToString(); if (IsSanctionedSingleUnitIdentifier(value)) @@ -209,8 +209,8 @@ private bool IsWellFormedUnitIdentifier(JsValue unitIdentifier) return true; } - var i = value.IndexOf("-per-"); - if (i == -1 || value.IndexOf("-per-", i + 1) != -1) + var i = value.IndexOf("-per-", StringComparison.Ordinal); + if (i == -1 || value.IndexOf("-per-", i + 1, StringComparison.Ordinal) != -1) { return false; } diff --git a/Jint/Native/Intl/PluralRulesConstructor.cs b/Jint/Native/Intl/PluralRulesConstructor.cs index 66b0052304..877ebe7488 100644 --- a/Jint/Native/Intl/PluralRulesConstructor.cs +++ b/Jint/Native/Intl/PluralRulesConstructor.cs @@ -48,7 +48,7 @@ public override ObjectInstance Construct(JsValue[] arguments, JsValue newTarget) /// /// https://tc39.es/ecma402/#sec-initializepluralrules /// - private void InitializePluralRules(JsObject pluralRules, JsValue locales, JsValue options) + private static void InitializePluralRules(JsObject pluralRules, JsValue locales, JsValue options) { // TODO } diff --git a/Jint/Native/Intl/RelativeTimeFormatConstructor.cs b/Jint/Native/Intl/RelativeTimeFormatConstructor.cs index 0afb13dca2..0679add371 100644 --- a/Jint/Native/Intl/RelativeTimeFormatConstructor.cs +++ b/Jint/Native/Intl/RelativeTimeFormatConstructor.cs @@ -48,7 +48,7 @@ public override ObjectInstance Construct(JsValue[] arguments, JsValue newTarget) /// /// https://tc39.es/ecma402/#sec-InitializeRelativeTimeFormat /// - private void InitializeRelativeTimeFormat(JsObject relativeTimeFormat, JsValue locales, JsValue options) + private static void InitializeRelativeTimeFormat(JsObject relativeTimeFormat, JsValue locales, JsValue options) { // TODO } diff --git a/Jint/Native/JsBigInt.cs b/Jint/Native/JsBigInt.cs index a9d2867b2f..18cbe8e0fd 100644 --- a/Jint/Native/JsBigInt.cs +++ b/Jint/Native/JsBigInt.cs @@ -95,15 +95,9 @@ public override bool IsLooselyEqual(JsValue value) return false; } - public override bool Equals(object? other) - { - return Equals(other as JsBigInt); - } + public override bool Equals(object? obj) => Equals(obj as JsBigInt); - public override bool Equals(JsValue? other) - { - return Equals(other as JsBigInt); - } + public override bool Equals(JsValue? other) => Equals(other as JsBigInt); public bool Equals(JsBigInt? other) { @@ -115,8 +109,5 @@ public bool Equals(JsBigInt? other) return ReferenceEquals(this, other) || _value == other._value; } - public override int GetHashCode() - { - return _value.GetHashCode(); - } + public override int GetHashCode() => _value.GetHashCode(); } diff --git a/Jint/Native/JsBoolean.cs b/Jint/Native/JsBoolean.cs index e735c5d94a..c74866a672 100644 --- a/Jint/Native/JsBoolean.cs +++ b/Jint/Native/JsBoolean.cs @@ -38,11 +38,16 @@ public override bool IsLooselyEqual(JsValue value) return !value.IsNullOrUndefined() && base.IsLooselyEqual(value); } - public override bool Equals(JsValue? obj) + public override bool Equals(object? obj) { return Equals(obj as JsBoolean); } + public override bool Equals(JsValue? other) + { + return Equals(other as JsBoolean); + } + public bool Equals(JsBoolean? other) { if (ReferenceEquals(this, other)) diff --git a/Jint/Native/JsNull.cs b/Jint/Native/JsNull.cs index ee65963f12..96179300f4 100644 --- a/Jint/Native/JsNull.cs +++ b/Jint/Native/JsNull.cs @@ -1,3 +1,4 @@ +using System.Runtime.CompilerServices; using Jint.Runtime; namespace Jint.Native; @@ -17,13 +18,11 @@ public override bool IsLooselyEqual(JsValue value) return ReferenceEquals(Null, value) || ReferenceEquals(Undefined, value); } - public override bool Equals(JsValue? obj) - { - return Equals(obj as JsNull); - } + public override bool Equals(object? obj) => Equals(obj as JsNull); - public bool Equals(JsNull? other) - { - return other is not null; - } + public override bool Equals(JsValue? other) => Equals(other as JsNull); + + public bool Equals(JsNull? other) => other is not null; + + public override int GetHashCode() => RuntimeHelpers.GetHashCode(this); } diff --git a/Jint/Native/JsNumber.cs b/Jint/Native/JsNumber.cs index df6267717f..e4cb66833d 100644 --- a/Jint/Native/JsNumber.cs +++ b/Jint/Native/JsNumber.cs @@ -1,4 +1,5 @@ using System.Diagnostics; +using System.Globalization; using System.Numerics; using System.Runtime.CompilerServices; using Jint.Native.Number; @@ -90,10 +91,10 @@ internal static JsNumber Create(object value) var underlyingType = System.Type.GetTypeCode(Enum.GetUnderlyingType(value.GetType())); return underlyingType switch { - TypeCode.Int64 => Create(Convert.ToInt64(value)), - TypeCode.UInt32 => Create(Convert.ToUInt64(value)), - TypeCode.UInt64 => Create(Convert.ToUInt64(value)), - _ => Create(Convert.ToInt32(value)) + TypeCode.Int64 => Create(Convert.ToInt64(value, CultureInfo.InvariantCulture)), + TypeCode.UInt32 => Create(Convert.ToUInt64(value, CultureInfo.InvariantCulture)), + TypeCode.UInt64 => Create(Convert.ToUInt64(value, CultureInfo.InvariantCulture)), + _ => Create(Convert.ToInt32(value, CultureInfo.InvariantCulture)) }; } @@ -265,10 +266,9 @@ public override bool IsLooselyEqual(JsValue value) return base.IsLooselyEqual(value); } - public override bool Equals(JsValue? obj) - { - return Equals(obj as JsNumber); - } + public override bool Equals(object? obj) => Equals(obj as JsNumber); + + public override bool Equals(JsValue? other) => Equals(other as JsNumber); public bool Equals(JsNumber? other) { @@ -290,8 +290,5 @@ public bool Equals(JsNumber? other) return _value == other._value; } - public override int GetHashCode() - { - return _value.GetHashCode(); - } + public override int GetHashCode() => _value.GetHashCode(); } diff --git a/Jint/Native/JsString.cs b/Jint/Native/JsString.cs index 307281db32..819c232f77 100644 --- a/Jint/Native/JsString.cs +++ b/Jint/Native/JsString.cs @@ -286,15 +286,11 @@ internal string Substring(int startIndex) return ToString().Substring(startIndex); } - public sealed override bool Equals(JsValue? obj) - { - return Equals(obj as JsString); - } + public sealed override bool Equals(object? obj) => Equals(obj as JsString); - public virtual bool Equals(string? s) - { - return s != null && ToString() == s; - } + 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(JsString? other) { @@ -326,15 +322,7 @@ public override bool IsLooselyEqual(JsValue value) return base.IsLooselyEqual(value); } - public sealed override bool Equals(object? obj) - { - return Equals(obj as JsString); - } - - public override int GetHashCode() - { - return _value.GetHashCode(); - } + public override int GetHashCode() => _value.GetHashCode(); internal sealed class ConcatenatedString : JsString { @@ -445,10 +433,7 @@ public override bool Equals(JsString? other) return ToString() == other.ToString(); } - public override int GetHashCode() - { - return _stringBuilder?.GetHashCode() ?? _value.GetHashCode(); - } + public override int GetHashCode() => _stringBuilder?.GetHashCode() ?? _value.GetHashCode(); internal override JsValue DoClone() { diff --git a/Jint/Native/JsSymbol.cs b/Jint/Native/JsSymbol.cs index d2f3262891..664d1a3383 100644 --- a/Jint/Native/JsSymbol.cs +++ b/Jint/Native/JsSymbol.cs @@ -27,18 +27,11 @@ public override string ToString() return "Symbol(" + value + ")"; } - public override bool Equals(JsValue? obj) - { - return Equals(obj as JsSymbol); - } + public override bool Equals(object? obj) => Equals(obj as JsSymbol); - public bool Equals(JsSymbol? other) - { - return ReferenceEquals(this, other); - } + public override bool Equals(JsValue? other) => Equals(other as JsSymbol); - public override int GetHashCode() - { - return RuntimeHelpers.GetHashCode(this); - } + public bool Equals(JsSymbol? other) => ReferenceEquals(this, other); + + public override int GetHashCode() => RuntimeHelpers.GetHashCode(this); } diff --git a/Jint/Native/JsUndefined.cs b/Jint/Native/JsUndefined.cs index 745f99dd45..ea7ab6a75d 100644 --- a/Jint/Native/JsUndefined.cs +++ b/Jint/Native/JsUndefined.cs @@ -1,3 +1,4 @@ +using System.Runtime.CompilerServices; using Jint.Runtime; namespace Jint.Native; @@ -17,13 +18,11 @@ public override bool IsLooselyEqual(JsValue value) return ReferenceEquals(Undefined, value) || ReferenceEquals(Null, value); } - public override bool Equals(JsValue? obj) - { - return Equals(obj as JsUndefined); - } + public override bool Equals(object? obj) => Equals(obj as JsUndefined); - public bool Equals(JsUndefined? other) - { - return !ReferenceEquals(null, other); - } + public override bool Equals(JsValue? other) => Equals(other as JsUndefined); + + public bool Equals(JsUndefined? other) => !ReferenceEquals(null, other); + + public override int GetHashCode() => RuntimeHelpers.GetHashCode(this); } diff --git a/Jint/Native/JsValue.cs b/Jint/Native/JsValue.cs index ae5e6b1ac4..1a6e413efb 100644 --- a/Jint/Native/JsValue.cs +++ b/Jint/Native/JsValue.cs @@ -350,23 +350,14 @@ public virtual bool IsLooselyEqual(JsValue value) /// /// Strict equality. /// - public override bool Equals(object? obj) - { - return Equals(obj as JsValue); - } + public override bool Equals(object? obj) => Equals(obj as JsValue); /// /// Strict equality. /// - public virtual bool Equals(JsValue? other) - { - return ReferenceEquals(this, other); - } + public virtual bool Equals(JsValue? other) => ReferenceEquals(this, other); - public override int GetHashCode() - { - return _type.GetHashCode(); - } + public override int GetHashCode() => _type.GetHashCode(); /// /// Some values need to be cloned in order to be assigned, like ConcatenatedString. diff --git a/Jint/Native/Json/JsonParser.cs b/Jint/Native/Json/JsonParser.cs index f23e9aae49..449371e4b5 100644 --- a/Jint/Native/Json/JsonParser.cs +++ b/Jint/Native/Json/JsonParser.cs @@ -460,7 +460,7 @@ private void ThrowError(Token token, string messageFormat, params object[] argum [DoesNotReturn] private void ThrowError(int position, string messageFormat, params object[] arguments) { - string msg = System.String.Format(messageFormat, arguments); + var msg = string.Format(CultureInfo.InvariantCulture, messageFormat, arguments); ExceptionHelper.ThrowSyntaxError(_engine.Realm, $"{msg} at position {position}"); } @@ -756,7 +756,7 @@ private sealed class Token public char FirstCharacter; public JsValue Value = JsValue.Undefined; public string Text = null!; - public TextRange Range = default; + public TextRange Range; } private readonly struct TextRange diff --git a/Jint/Native/Json/JsonSerializer.cs b/Jint/Native/Json/JsonSerializer.cs index fe17770993..c13da3cb97 100644 --- a/Jint/Native/Json/JsonSerializer.cs +++ b/Jint/Native/Json/JsonSerializer.cs @@ -1,3 +1,4 @@ +using System.Globalization; using System.Runtime.CompilerServices; using System.Text; using Jint.Collections; @@ -398,7 +399,7 @@ private static void AppendJsonStringCharacter(string value, ref int index, Strin else if (c < 0x20 || char.IsSurrogate(c)) { target.Append("\\u"); - target.Append(((int) c).ToString("x4")); + target.Append(((int) c).ToString("x4", CultureInfo.InvariantCulture)); } else { diff --git a/Jint/Native/Number/Dtoa/Bignum.cs b/Jint/Native/Number/Dtoa/Bignum.cs index ac874ccbe3..8c8196e469 100644 --- a/Jint/Native/Number/Dtoa/Bignum.cs +++ b/Jint/Native/Number/Dtoa/Bignum.cs @@ -108,7 +108,7 @@ void Align(Bignum other) // We replace some of the hidden digits (X) of a with 0 digits. // a: aaaaaa000X or a: aaaaa0XX int zero_digits = exponent_ - other.exponent_; - EnsureCapacity(used_digits_ + zero_digits); + ValidateCapacity(used_digits_ + zero_digits); for (int i = used_digits_ - 1; i >= 0; --i) { bigits_[i + zero_digits] = bigits_[i]; @@ -126,7 +126,7 @@ void Align(Bignum other) } } - void EnsureCapacity(int size) + private static void ValidateCapacity(int size) { if (size > kBigitCapacity) { @@ -161,7 +161,7 @@ internal void AssignUInt16(uint value) Zero(); if (value == 0) return; - EnsureCapacity(1); + ValidateCapacity(1); bigits_[0] = value; used_digits_ = 1; } @@ -174,7 +174,7 @@ internal void AssignUInt64(ulong value) if (value == 0) return; int needed_bigits = kUInt64Size / kBigitSize + 1; - EnsureCapacity(needed_bigits); + ValidateCapacity(needed_bigits); for (int i = 0; i < needed_bigits; ++i) { bigits_[i] = (uint) (value & kBigitMask); @@ -419,7 +419,7 @@ internal void MultiplyByUInt32(uint factor) while (carry != 0) { - EnsureCapacity(used_digits_ + 1); + ValidateCapacity(used_digits_ + 1); bigits_[used_digits_] = (uint) (carry & kBigitMask); used_digits_++; carry >>= kBigitSize; @@ -449,7 +449,7 @@ internal void MultiplyByUInt64(ulong factor) } while (carry != 0) { - EnsureCapacity(used_digits_ + 1); + ValidateCapacity(used_digits_ + 1); bigits_[used_digits_] = (uint) (carry & kBigitMask); used_digits_++; carry >>= kBigitSize; @@ -461,7 +461,7 @@ internal void ShiftLeft(int shift_amount) if (used_digits_ == 0) return; exponent_ += shift_amount / kBigitSize; int local_shift = shift_amount % kBigitSize; - EnsureCapacity(used_digits_ + 1); + ValidateCapacity(used_digits_ + 1); BigitsShiftLeft(local_shift); } @@ -516,7 +516,7 @@ internal void AssignPowerUInt16(uint baseValue, int power_exponent) int final_size = bit_size * power_exponent; // 1 extra bigit for the shifting, and one for rounded final_size. - EnsureCapacity(final_size / kBigitSize + 2); + ValidateCapacity(final_size / kBigitSize + 2); // Left to Right exponentiation. int mask = 1; @@ -578,7 +578,7 @@ void Square() { Debug.Assert(IsClamped()); int product_length = 2 * used_digits_; - EnsureCapacity(product_length); + ValidateCapacity(product_length); // Comba multiplication: compute each column separately. // Example: r = a2a1a0 * b2b1b0. diff --git a/Jint/Native/Number/NumberPrototype.cs b/Jint/Native/Number/NumberPrototype.cs index af302d7e5a..333e5a80d0 100644 --- a/Jint/Native/Number/NumberPrototype.cs +++ b/Jint/Native/Number/NumberPrototype.cs @@ -303,7 +303,7 @@ private JsValue ToPrecision(JsValue thisObject, JsValue[] arguments) } } - private string CreateExponentialRepresentation( + private static string CreateExponentialRepresentation( DtoaBuilder buffer, int exponent, bool negative, @@ -384,63 +384,59 @@ private JsValue ToNumberString(JsValue thisObject, JsValue[] arguments) var integer = (long) x; var fraction = x - integer; - string result = ToBase(integer, radix); + string result = NumberPrototype.ToBase(integer, radix); if (fraction != 0) { - result += "." + ToFractionBase(fraction, radix); + result += "." + NumberPrototype.ToFractionBase(fraction, radix); } return result; } - public string ToBase(long n, int radix) + internal static string ToBase(long n, int radix) { - const string digits = "0123456789abcdefghijklmnopqrstuvwxyz"; + const string Digits = "0123456789abcdefghijklmnopqrstuvwxyz"; if (n == 0) { return "0"; } - using (var result = StringBuilderPool.Rent()) + using var result = StringBuilderPool.Rent(); + while (n > 0) { - while (n > 0) - { - var digit = (int) (n % radix); - n = n / radix; - result.Builder.Insert(0, digits[digit]); - } - - return result.ToString(); + var digit = (int) (n % radix); + n = n / radix; + result.Builder.Insert(0, Digits[digit]); } + + return result.ToString(); } - public string ToFractionBase(double n, int radix) + internal static string ToFractionBase(double n, int radix) { // based on the repeated multiplication method // http://www.mathpath.org/concepts/Num/frac.htm - const string digits = "0123456789abcdefghijklmnopqrstuvwxyz"; + const string Digits = "0123456789abcdefghijklmnopqrstuvwxyz"; if (n == 0) { return "0"; } - using (var result = StringBuilderPool.Rent()) + using var result = StringBuilderPool.Rent(); + while (n > 0 && result.Length < 50) // arbitrary limit { - while (n > 0 && result.Length < 50) // arbitrary limit - { - var c = n*radix; - var d = (int) c; - n = c - d; - - result.Builder.Append(digits[d]); - } + var c = n*radix; + var d = (int) c; + n = c - d; - return result.ToString(); + result.Builder.Append(Digits[d]); } + + return result.ToString(); } - private string ToNumberString(double m) + private static string ToNumberString(double m) { using var stringBuilder = StringBuilderPool.Rent(); NumberToString(m, new DtoaBuilder(), stringBuilder.Builder); diff --git a/Jint/Native/Object/ObjectInstance.cs b/Jint/Native/Object/ObjectInstance.cs index 0942141081..29e2ccc25e 100644 --- a/Jint/Native/Object/ObjectInstance.cs +++ b/Jint/Native/Object/ObjectInstance.cs @@ -1073,7 +1073,7 @@ private object ToObject(ObjectTraverseStack stack) TypedArrayElementType.Uint16 => typedArrayInstance.ToNativeArray(), TypedArrayElementType.Uint32 => typedArrayInstance.ToNativeArray(), TypedArrayElementType.BigUint64 => typedArrayInstance.ToNativeArray(), - _ => throw new ArgumentOutOfRangeException() + _ => throw new ArgumentOutOfRangeException("", "cannot handle element type") }; break; @@ -1475,10 +1475,9 @@ private void ThrowIncompatibleReceiver(JsValue value, string methodName) ExceptionHelper.ThrowTypeError(_engine.Realm, $"Method {methodName} called on incompatible receiver {value}"); } - public override bool Equals(JsValue? obj) - { - return Equals(obj as ObjectInstance); - } + public override bool Equals(object? obj) => Equals(obj as ObjectInstance); + + public override bool Equals(JsValue? other) => Equals(other as ObjectInstance); public bool Equals(ObjectInstance? other) { @@ -1495,6 +1494,8 @@ public bool Equals(ObjectInstance? other) return false; } + public override int GetHashCode() => RuntimeHelpers.GetHashCode(this); + internal IEnumerable GetKeys() { var visited = new HashSet(); diff --git a/Jint/Native/Promise/PromiseOperations.cs b/Jint/Native/Promise/PromiseOperations.cs index ea7100642b..7791befbd5 100644 --- a/Jint/Native/Promise/PromiseOperations.cs +++ b/Jint/Native/Promise/PromiseOperations.cs @@ -58,7 +58,7 @@ private static Action NewPromiseReactionJob(PromiseReaction reaction, JsValue va break; default: - throw new ArgumentOutOfRangeException(); + throw new ArgumentOutOfRangeException(nameof(reaction), "Unknown reaction type"); } } }; diff --git a/Jint/Native/Proxy/JsProxy.cs b/Jint/Native/Proxy/JsProxy.cs index a5877e9803..76be0210dc 100644 --- a/Jint/Native/Proxy/JsProxy.cs +++ b/Jint/Native/Proxy/JsProxy.cs @@ -288,7 +288,7 @@ public override PropertyDescriptor GetOwnProperty(JsValue property) /// /// https://tc39.es/ecma262/#sec-completepropertydescriptor /// - private void CompletePropertyDescriptor(PropertyDescriptor desc) + private static void CompletePropertyDescriptor(PropertyDescriptor desc) { if (desc.IsGenericDescriptor() || desc.IsDataDescriptor()) { diff --git a/Jint/Native/RegExp/RegExpPrototype.cs b/Jint/Native/RegExp/RegExpPrototype.cs index 279f229a53..cad5be23a5 100644 --- a/Jint/Native/RegExp/RegExpPrototype.cs +++ b/Jint/Native/RegExp/RegExpPrototype.cs @@ -286,9 +286,11 @@ string Evaluator(Match match) if (position >= nextSourcePosition) { +#pragma warning disable CA1845 accumulatedResult = accumulatedResult + s.Substring(nextSourcePosition, position - nextSourcePosition) + replacement; +#pragma warning restore CA1845 nextSourcePosition = position + matchLength; } @@ -299,7 +301,9 @@ string Evaluator(Match match) return accumulatedResult; } +#pragma warning disable CA1845 return accumulatedResult + s.Substring(nextSourcePosition); +#pragma warning restore CA1845 } private static string CallFunctionalReplace(JsValue replacer, List replacerArgs) @@ -347,12 +351,14 @@ internal static string GetSubstitution( case '&': sb.Append(matched); break; +#pragma warning disable CA1846 case '`': sb.Append(str.Substring(0, position)); break; case '\'': sb.Append(str.Substring(position + matched.Length)); break; +#pragma warning restore CA1846 case '<': var gtPos = replacement.IndexOf('>', i + 1); if (gtPos == -1 || namedCaptures.IsUndefined()) diff --git a/Jint/Native/String/StringPrototype.cs b/Jint/Native/String/StringPrototype.cs index c781875a96..d17530bfb8 100644 --- a/Jint/Native/String/StringPrototype.cs +++ b/Jint/Native/String/StringPrototype.cs @@ -1,3 +1,4 @@ +using System.Globalization; using System.Runtime.CompilerServices; using System.Text; using Jint.Collections; @@ -228,7 +229,7 @@ private JsValue ToLocaleUpperCase(JsValue thisObject, JsValue[] arguments) { TypeConverter.CheckObjectCoercible(_engine, thisObject); var s = TypeConverter.ToString(thisObject); - return new JsString(s.ToUpper()); + return new JsString(s.ToUpper(CultureInfo.InvariantCulture)); } private JsValue ToUpperCase(JsValue thisObject, JsValue[] arguments) @@ -242,7 +243,7 @@ private JsValue ToLocaleLowerCase(JsValue thisObject, JsValue[] arguments) { TypeConverter.CheckObjectCoercible(_engine, thisObject); var s = TypeConverter.ToString(thisObject); - return new JsString(s.ToLower()); + return new JsString(s.ToLower(CultureInfo.InvariantCulture)); } private JsValue ToLowerCase(JsValue thisObject, JsValue[] arguments) @@ -666,7 +667,11 @@ static int StringIndexOf(string s, string search, int fromIndex) if (endOfLastMatch < thisString.Length) { +#if NETFRAMEWORK result.Append(thisString.Substring(endOfLastMatch)); +#else + result.Append(thisString[endOfLastMatch..]); +#endif } return result.ToString(); @@ -1168,7 +1173,8 @@ private JsValue ToWellFormed(JsValue thisObject, JsValue[] arguments) var cp = CodePointAt(s, k); if (cp.IsUnpairedSurrogate) { - result.Append("\uFFFD"); + // \uFFFD + result.Append('�'); } else { diff --git a/Jint/Native/TypedArray/JsTypedArray.cs b/Jint/Native/TypedArray/JsTypedArray.cs index 3991cc84d7..f13fa8ceb7 100644 --- a/Jint/Native/TypedArray/JsTypedArray.cs +++ b/Jint/Native/TypedArray/JsTypedArray.cs @@ -1,3 +1,4 @@ +using System.Globalization; using System.Runtime.CompilerServices; using Esprima; using Jint.Native.ArrayBuffer; @@ -376,7 +377,7 @@ internal T[] ToNativeArray() { var indexedPosition = i * elementSize + byteOffset; var value = buffer.RawBytesToNumeric(_arrayElementType, indexedPosition, BitConverter.IsLittleEndian); - array[i] = (T) Convert.ChangeType(value, conversionType); + array[i] = (T) Convert.ChangeType(value, conversionType, CultureInfo.InvariantCulture); } return array; diff --git a/Jint/Native/TypedArray/TypedArrayConstructor.cs b/Jint/Native/TypedArray/TypedArrayConstructor.cs index 7871980228..0d1fb2060c 100644 --- a/Jint/Native/TypedArray/TypedArrayConstructor.cs +++ b/Jint/Native/TypedArray/TypedArrayConstructor.cs @@ -1,3 +1,4 @@ +using System.Globalization; using Jint.Collections; using Jint.Native.Array; using Jint.Native.ArrayBuffer; @@ -271,7 +272,7 @@ internal static void FillTypedArrayInstance(JsTypedArray target, T[] values) { for (var i = 0; i < values.Length; ++i) { - target.DoIntegerIndexedElementSet(i, Convert.ToDouble(values[i])); + target.DoIntegerIndexedElementSet(i, Convert.ToDouble(values[i], CultureInfo.InvariantCulture)); } } diff --git a/Jint/Options.cs b/Jint/Options.cs index 980524e4ea..0341414a37 100644 --- a/Jint/Options.cs +++ b/Jint/Options.cs @@ -201,7 +201,7 @@ PropertyDescriptor CreateMethodInstancePropertyDescriptor(ClrFunctionInstance? f // make sure we register both lower case and upper case if (char.IsUpper(overloads.Key[0])) { - key = char.ToLower(overloads.Key[0]) + overloads.Key.Substring(1); + key = char.ToLower(overloads.Key[0], CultureInfo.InvariantCulture) + overloads.Key.Substring(1); if (prototype.HasOwnProperty(key) && prototype.GetOwnProperty(key).Value is ClrFunctionInstance lowerclrFunctionInstance) @@ -281,7 +281,7 @@ public class InteropOptions /// memory usage to grow when targeting large set and freeing of memory can be delayed due to ConditionalWeakTable semantics. /// Defaults to false. /// - public bool TrackObjectWrapperIdentity { get; set; } = false; + public bool TrackObjectWrapperIdentity { get; set; } /// /// If no known type could be guessed, objects are by default wrapped as an diff --git a/Jint/Pooling/ConcurrentObjectPool.cs b/Jint/Pooling/ConcurrentObjectPool.cs index 596579c364..72582b9a67 100644 --- a/Jint/Pooling/ConcurrentObjectPool.cs +++ b/Jint/Pooling/ConcurrentObjectPool.cs @@ -1,3 +1,5 @@ +#pragma warning disable CA1822 + #nullable disable // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. diff --git a/Jint/Pooling/ObjectPool.cs b/Jint/Pooling/ObjectPool.cs index 7eb41caeea..050c43b63e 100644 --- a/Jint/Pooling/ObjectPool.cs +++ b/Jint/Pooling/ObjectPool.cs @@ -1,3 +1,5 @@ +#pragma warning disable CA1822 + #nullable disable // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. diff --git a/Jint/Runtime/CallStack/JintCallStack.cs b/Jint/Runtime/CallStack/JintCallStack.cs index eb19b289cc..7c67db4bf1 100644 --- a/Jint/Runtime/CallStack/JintCallStack.cs +++ b/Jint/Runtime/CallStack/JintCallStack.cs @@ -62,7 +62,9 @@ public int Push(FunctionInstance functionInstance, JintExpression? expression, i _stack.Push(item); if (_statistics is not null) { +#pragma warning disable CA1854 if (_statistics.ContainsKey(item)) +#pragma warning restore CA1854 { return ++_statistics[item]; } @@ -126,7 +128,7 @@ static void AppendLocation( if (!string.IsNullOrWhiteSpace(shortDescription)) { sb - .Append(" ") + .Append(' ') .Append(shortDescription); } @@ -144,15 +146,15 @@ static void AppendLocation( var arg = element.Value.Arguments.Value[index]; sb.Append(GetPropertyKey(arg)); } - sb.Append(")"); + sb.Append(')'); } sb - .Append(" ") + .Append(' ') .Append(loc.Source) - .Append(":") + .Append(':') .Append(loc.End.Line) - .Append(":") + .Append(':') .Append(loc.Start.Column + 1) // report column number instead of index .AppendLine(); } diff --git a/Jint/Runtime/CallStack/StackGuard.cs b/Jint/Runtime/CallStack/StackGuard.cs index 2ddf5946a7..e815e02e32 100644 --- a/Jint/Runtime/CallStack/StackGuard.cs +++ b/Jint/Runtime/CallStack/StackGuard.cs @@ -50,7 +50,7 @@ public bool TryEnterOnCurrentStack() return false; } - public TR RunOnEmptyStack(Func action, T1 arg1) + public static TR RunOnEmptyStack(Func action, T1 arg1) { #if NETFRAMEWORK || NETSTANDARD2_0 return RunOnEmptyStackCore(static s => @@ -69,7 +69,7 @@ public TR RunOnEmptyStack(Func action, T1 arg1) } - private R RunOnEmptyStackCore(Func action, object state) + private static R RunOnEmptyStackCore(Func action, object state) { // Using default scheduler rather than picking up the current scheduler. Task task = Task.Factory.StartNew((Func) action, state, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); diff --git a/Jint/Runtime/Debugger/BreakPointCollection.cs b/Jint/Runtime/Debugger/BreakPointCollection.cs index 7407b63e5f..4a660e0629 100644 --- a/Jint/Runtime/Debugger/BreakPointCollection.cs +++ b/Jint/Runtime/Debugger/BreakPointCollection.cs @@ -25,8 +25,6 @@ public BreakPointCollection() public int Count => _breakPoints.Count; - public bool IsReadOnly => false; - /// /// Sets a new breakpoint. Note that this will replace any breakpoint at the same location (source/column/line). /// diff --git a/Jint/Runtime/DefaultTimeSystem.cs b/Jint/Runtime/DefaultTimeSystem.cs index 5340c070ec..b5c7e80661 100644 --- a/Jint/Runtime/DefaultTimeSystem.cs +++ b/Jint/Runtime/DefaultTimeSystem.cs @@ -137,7 +137,9 @@ private static bool TryParseLargeYear(string date, out long epochMilliseconds) } // create replacement string +#pragma warning disable CA1845 var dateToParse = "2000" + date.Substring(7); +#pragma warning restore CA1845 if (!DateTime.TryParse(dateToParse, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out var parsed)) { return false; diff --git a/Jint/Runtime/Interop/ClrFunctionInstance.cs b/Jint/Runtime/Interop/ClrFunctionInstance.cs index 674baf3c4e..f36efceff6 100644 --- a/Jint/Runtime/Interop/ClrFunctionInstance.cs +++ b/Jint/Runtime/Interop/ClrFunctionInstance.cs @@ -57,7 +57,9 @@ private JsValue CallSlow(JsValue thisObject, JsValue[] arguments) } } - public override bool Equals(JsValue? obj) => Equals(obj as ClrFunctionInstance); + public override bool Equals(JsValue? other) => Equals(other as ClrFunctionInstance); + + public override bool Equals(object? obj) => Equals(obj as ClrFunctionInstance); public bool Equals(ClrFunctionInstance? other) { @@ -78,4 +80,6 @@ public bool Equals(ClrFunctionInstance? other) return false; } + + public override int GetHashCode() => _func.GetHashCode(); } diff --git a/Jint/Runtime/Interop/ClrHelper.cs b/Jint/Runtime/Interop/ClrHelper.cs index e11763216c..f59fcc1faa 100644 --- a/Jint/Runtime/Interop/ClrHelper.cs +++ b/Jint/Runtime/Interop/ClrHelper.cs @@ -14,7 +14,9 @@ internal ClrHelper(InteropOptions interopOptions) /// /// Call JsValue.ToString(), mainly for NamespaceReference. /// +#pragma warning disable CA1822 public JsValue ToString(JsValue value) +#pragma warning restore CA1822 { return value.ToString(); } @@ -22,7 +24,9 @@ public JsValue ToString(JsValue value) /// /// Cast `obj as ISomeInterface` to `obj` /// +#pragma warning disable CA1822 public JsValue Unwrap(ObjectWrapper obj) +#pragma warning restore CA1822 { return new ObjectWrapper(obj.Engine, obj.Target); } @@ -30,7 +34,9 @@ public JsValue Unwrap(ObjectWrapper obj) /// /// Cast `obj` to `obj as ISomeInterface` /// +#pragma warning disable CA1822 public JsValue Wrap(ObjectWrapper obj, TypeReference type) +#pragma warning restore CA1822 { if (!type.ReferenceType.IsInstanceOfType(obj.Target)) { @@ -70,7 +76,7 @@ public JsValue ObjectToType(ObjectWrapper obj) } else { - ExceptionHelper.ThrowArgumentException("Must be an ObjectWrapper of Type", "obj"); + ExceptionHelper.ThrowArgumentException("Must be an ObjectWrapper of Type", nameof(obj)); } return JsValue.Undefined; } diff --git a/Jint/Runtime/Interop/DefaultObjectConverter.cs b/Jint/Runtime/Interop/DefaultObjectConverter.cs index acf36264c9..f94fa7bf10 100644 --- a/Jint/Runtime/Interop/DefaultObjectConverter.cs +++ b/Jint/Runtime/Interop/DefaultObjectConverter.cs @@ -1,4 +1,5 @@ using System.Diagnostics.CodeAnalysis; +using System.Globalization; using System.Runtime.CompilerServices; using System.Threading; using Jint.Native; @@ -74,10 +75,10 @@ public static bool TryConvert(Engine engine, object value, Type? type, [NotNullW var t = value.GetType(); if (!engine.Options.Interop.AllowSystemReflection - && t.Namespace?.StartsWith("System.Reflection") == true) + && t.Namespace?.StartsWith("System.Reflection", StringComparison.Ordinal) == true) { - const string message = "Cannot access System.Reflection namespace, check Engine's interop options"; - ExceptionHelper.ThrowInvalidOperationException(message); + const string Message = "Cannot access System.Reflection namespace, check Engine's interop options"; + ExceptionHelper.ThrowInvalidOperationException(Message); } if (t.IsEnum) @@ -86,17 +87,17 @@ public static bool TryConvert(Engine engine, object value, Type? type, [NotNullW if (ut == typeof(ulong)) { - result = JsNumber.Create(Convert.ToDouble(value)); + result = JsNumber.Create(Convert.ToDouble(value, CultureInfo.InvariantCulture)); } else { if (ut == typeof(uint) || ut == typeof(long)) { - result = JsNumber.Create(Convert.ToInt64(value)); + result = JsNumber.Create(Convert.ToInt64(value, CultureInfo.InvariantCulture)); } else { - result = JsNumber.Create(Convert.ToInt32(value)); + result = JsNumber.Create(Convert.ToInt32(value, CultureInfo.InvariantCulture)); } } } diff --git a/Jint/Runtime/Interop/DelegateWrapper.cs b/Jint/Runtime/Interop/DelegateWrapper.cs index 36bd49b898..4a6c1e1f4e 100644 --- a/Jint/Runtime/Interop/DelegateWrapper.cs +++ b/Jint/Runtime/Interop/DelegateWrapper.cs @@ -36,7 +36,7 @@ public DelegateWrapper( } } - protected internal override JsValue Call(JsValue thisObject, JsValue[] jsArguments) + protected internal override JsValue Call(JsValue thisObject, JsValue[] arguments) { var parameterInfos = _d.Method.GetParameters(); @@ -53,7 +53,7 @@ protected internal override JsValue Call(JsValue thisObject, JsValue[] jsArgumen int delegateArgumentsCount = parameterInfos.Length; int delegateNonParamsArgumentsCount = _delegateContainsParamsArgument ? delegateArgumentsCount - 1 : delegateArgumentsCount; - int jsArgumentsCount = jsArguments.Length; + int jsArgumentsCount = arguments.Length; int jsArgumentsWithoutParamsCount = Math.Min(jsArgumentsCount, delegateNonParamsArgumentsCount); var clrTypeConverter = Engine.ClrTypeConverter; @@ -64,7 +64,7 @@ protected internal override JsValue Call(JsValue thisObject, JsValue[] jsArgumen for (var i = 0; i < jsArgumentsWithoutParamsCount; i++) { var parameterType = parameterInfos[i].ParameterType; - var value = jsArguments[i]; + var value = arguments[i]; object? converted; if (parameterType == typeof(JsValue)) @@ -107,7 +107,7 @@ protected internal override JsValue Call(JsValue thisObject, JsValue[] jsArgumen for (var i = paramsArgumentIndex; i < jsArgumentsCount; i++) { var paramsIndex = i - paramsArgumentIndex; - var value = jsArguments[i]; + var value = arguments[i]; object? converted; if (paramsParameterType == typeof(JsValue)) diff --git a/Jint/Runtime/Interop/MethodDescriptor.cs b/Jint/Runtime/Interop/MethodDescriptor.cs index 831cbe60ad..9295371cc9 100644 --- a/Jint/Runtime/Interop/MethodDescriptor.cs +++ b/Jint/Runtime/Interop/MethodDescriptor.cs @@ -148,7 +148,7 @@ public JsValue Call(Engine engine, object? instance, JsValue[] arguments) } else { - throw new Exception("Method is unknown type"); + throw new ArgumentException("Method is unknown type"); } } catch (TargetInvocationException exception) diff --git a/Jint/Runtime/Interop/NamespaceReference.cs b/Jint/Runtime/Interop/NamespaceReference.cs index e72bb9a124..ef6088b40c 100644 --- a/Jint/Runtime/Interop/NamespaceReference.cs +++ b/Jint/Runtime/Interop/NamespaceReference.cs @@ -124,7 +124,7 @@ public JsValue GetPath(string path) { foreach (Type nType in GetAllNestedTypes(type)) { - if (nType.FullName != null && nType.FullName.Replace("+", ".").Equals(comparedPath)) + if (nType.FullName != null && nType.FullName.Replace("+", ".").Equals(comparedPath, StringComparison.Ordinal)) { _engine.TypeCache.Add(comparedPath, nType); return TypeReference.CreateTypeReference(_engine, nType); diff --git a/Jint/Runtime/Interop/ObjectWrapper.cs b/Jint/Runtime/Interop/ObjectWrapper.cs index 245251fee7..b219f69a67 100644 --- a/Jint/Runtime/Interop/ObjectWrapper.cs +++ b/Jint/Runtime/Interop/ObjectWrapper.cs @@ -301,7 +301,9 @@ internal override ulong GetSmallestIndex(ulong length) return Target is ICollection ? 0 : base.GetSmallestIndex(length); } - public override bool Equals(JsValue? obj) => Equals(obj as ObjectWrapper); + public override bool Equals(object? obj) => Equals(obj as ObjectWrapper); + + public override bool Equals(JsValue? other) => Equals(other as ObjectWrapper); public bool Equals(ObjectWrapper? other) { @@ -318,12 +320,7 @@ public bool Equals(ObjectWrapper? other) return Equals(Target, other.Target); } - public override int GetHashCode() - { - var hashCode = -1468639730; - hashCode = hashCode * -1521134295 + Target.GetHashCode(); - return hashCode; - } + public override int GetHashCode() => Target.GetHashCode(); private sealed class DictionaryIterator : IteratorInstance { diff --git a/Jint/Runtime/Interop/TypeReference.cs b/Jint/Runtime/Interop/TypeReference.cs index d340795568..ea1a990eab 100644 --- a/Jint/Runtime/Interop/TypeReference.cs +++ b/Jint/Runtime/Interop/TypeReference.cs @@ -204,14 +204,14 @@ static ObjectInstance ObjectCreator(Engine engine, Realm realm, ObjectCreateStat private readonly record struct ObjectCreateState(TypeReference TypeReference, JsValue[] Arguments); - public override bool Equals(JsValue? obj) + public override bool Equals(JsValue? other) { - if (obj is TypeReference typeReference) + if (other is TypeReference typeReference) { return this.ReferenceType == typeReference.ReferenceType; } - return base.Equals(obj); + return base.Equals(other); } internal override bool OrdinaryHasInstance(JsValue v) diff --git a/Jint/Runtime/Interpreter/Expressions/BindingPatternAssignmentExpression.cs b/Jint/Runtime/Interpreter/Expressions/BindingPatternAssignmentExpression.cs index 9a808961bf..4b98329267 100644 --- a/Jint/Runtime/Interpreter/Expressions/BindingPatternAssignmentExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/BindingPatternAssignmentExpression.cs @@ -265,8 +265,7 @@ private static JsValue HandleArrayPattern( } else { - ExceptionHelper.ThrowArgumentOutOfRangeException("pattern", - "Unable to determine how to handle array pattern element " + left); + ExceptionHelper.ThrowArgumentOutOfRangeException(nameof(pattern), $"Unable to determine how to handle array pattern element {left}"); break; } } diff --git a/Jint/Runtime/Interpreter/Expressions/JintCallExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintCallExpression.cs index fa0421a36f..6f0ba09c61 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintCallExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintCallExpression.cs @@ -4,6 +4,7 @@ using Jint.Native; using Jint.Native.Function; using Jint.Native.Object; +using Jint.Runtime.CallStack; using Jint.Runtime.Environments; using Jint.Runtime.References; @@ -86,7 +87,7 @@ protected override object EvaluateInternal(EvaluationContext context) if (!context.Engine._stackGuard.TryEnterOnCurrentStack()) { - return context.Engine._stackGuard.RunOnEmptyStack(EvaluateInternal, context); + return StackGuard.RunOnEmptyStack(EvaluateInternal, context); } if (_calleeExpression._expression.Type == Nodes.Super) diff --git a/Jint/Runtime/Interpreter/Expressions/JintMemberExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintMemberExpression.cs index d5a9f32036..22229a0454 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintMemberExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintMemberExpression.cs @@ -140,7 +140,7 @@ protected override object EvaluateInternal(EvaluationContext context) /// /// https://tc39.es/ecma262/#sec-makeprivatereference /// - private object MakePrivateReference(Engine engine, JsValue baseValue, JsValue privateIdentifier) + private static object MakePrivateReference(Engine engine, JsValue baseValue, JsValue privateIdentifier) { var privEnv = engine.ExecutionContext.PrivateEnvironment; var privateName = privEnv!.ResolvePrivateIdentifier(privateIdentifier.ToString()); diff --git a/Jint/Runtime/Interpreter/JintFunctionDefinition.cs b/Jint/Runtime/Interpreter/JintFunctionDefinition.cs index 7903f5ba10..8781bf9ac7 100644 --- a/Jint/Runtime/Interpreter/JintFunctionDefinition.cs +++ b/Jint/Runtime/Interpreter/JintFunctionDefinition.cs @@ -148,7 +148,7 @@ 8. Return unused. /// /// https://tc39.es/ecma262/#sec-runtime-semantics-evaluategeneratorbody /// - private Completion EvaluateGeneratorBody(FunctionInstance functionObject, JsValue[] argumentsList) + private static Completion EvaluateGeneratorBody(FunctionInstance functionObject, JsValue[] argumentsList) { ExceptionHelper.ThrowNotImplementedException("generators not implemented"); return default; diff --git a/Jint/Runtime/Interpreter/Statements/JintExportDefaultDeclaration.cs b/Jint/Runtime/Interpreter/Statements/JintExportDefaultDeclaration.cs index f0e03c046d..4d280895eb 100644 --- a/Jint/Runtime/Interpreter/Statements/JintExportDefaultDeclaration.cs +++ b/Jint/Runtime/Interpreter/Statements/JintExportDefaultDeclaration.cs @@ -80,7 +80,7 @@ protected override Completion ExecuteInternal(EvaluationContext context) /// /// https://tc39.es/ecma262/#sec-initializeboundname /// - private void InitializeBoundName(string name, JsValue value, EnvironmentRecord? environment) + private static void InitializeBoundName(string name, JsValue value, EnvironmentRecord? environment) { if (environment is not null) { diff --git a/Jint/Runtime/Interpreter/Statements/JintForInForOfStatement.cs b/Jint/Runtime/Interpreter/Statements/JintForInForOfStatement.cs index 2396f3b888..e77f932a1a 100644 --- a/Jint/Runtime/Interpreter/Statements/JintForInForOfStatement.cs +++ b/Jint/Runtime/Interpreter/Statements/JintForInForOfStatement.cs @@ -317,7 +317,9 @@ private Completion BodyEvaluation( // if we already have and exception, use it if (completionType != CompletionType.Throw) { +#pragma warning disable CA2219 throw; +#pragma warning restore CA2219 } } } diff --git a/Jint/Runtime/Modules/DefaultModuleLoader.cs b/Jint/Runtime/Modules/DefaultModuleLoader.cs index 67dd9f30c5..ee6fbfa5c7 100644 --- a/Jint/Runtime/Modules/DefaultModuleLoader.cs +++ b/Jint/Runtime/Modules/DefaultModuleLoader.cs @@ -151,6 +151,6 @@ public Module LoadModule(Engine engine, ResolvedSpecifier resolved) private static bool IsRelative(string specifier) { - return specifier.StartsWith(".") || specifier.StartsWith("/"); + return specifier.StartsWith(".", StringComparison.Ordinal) || specifier.StartsWith("/", StringComparison.Ordinal); } } diff --git a/Jint/Runtime/Modules/FailFastModuleLoader.cs b/Jint/Runtime/Modules/FailFastModuleLoader.cs index a89163809c..a00e414d11 100644 --- a/Jint/Runtime/Modules/FailFastModuleLoader.cs +++ b/Jint/Runtime/Modules/FailFastModuleLoader.cs @@ -6,7 +6,9 @@ internal sealed class FailFastModuleLoader : IModuleLoader { public static readonly IModuleLoader Instance = new FailFastModuleLoader(); +#pragma warning disable CA1822 public Uri BasePath +#pragma warning restore CA1822 { get { diff --git a/Jint/Runtime/Modules/SourceTextModuleRecord.cs b/Jint/Runtime/Modules/SourceTextModuleRecord.cs index f1c1881366..11a1fb478f 100644 --- a/Jint/Runtime/Modules/SourceTextModuleRecord.cs +++ b/Jint/Runtime/Modules/SourceTextModuleRecord.cs @@ -107,7 +107,7 @@ public override List GetExportedNames(List exportSta for (var j = 0; j < starNames.Count; j++) { var n = starNames[j]; - if (!"default".Equals(n) && !exportedNames.Contains(n)) + if (!"default".Equals(n, StringComparison.Ordinal) && !exportedNames.Contains(n)) { exportedNames.Add(n); } @@ -164,7 +164,7 @@ internal override ResolvedBinding ResolveExport(string exportName, List array.Length - arrayIndex) { diff --git a/Jint/Runtime/TypeConverter.cs b/Jint/Runtime/TypeConverter.cs index 3b6f7e88c6..50da476c8b 100644 --- a/Jint/Runtime/TypeConverter.cs +++ b/Jint/Runtime/TypeConverter.cs @@ -78,7 +78,7 @@ static TypeConverter() { for (var i = 0; i < intToString.Length; ++i) { - intToString[i] = i.ToString(); + intToString[i] = i.ToString(CultureInfo.InvariantCulture); } for (var i = 0; i < charToString.Length; ++i) @@ -848,7 +848,7 @@ internal static string ToString(long i) var temp = intToString; return (ulong) i < (ulong) temp.Length ? temp[i] - : i.ToString(); + : i.ToString(CultureInfo.InvariantCulture); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -857,7 +857,7 @@ internal static string ToString(int i) var temp = intToString; return (uint) i < (uint) temp.Length ? temp[i] - : i.ToString(); + : i.ToString(CultureInfo.InvariantCulture); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -866,7 +866,7 @@ internal static string ToString(uint i) var temp = intToString; return i < (uint) temp.Length ? temp[i] - : i.ToString(); + : i.ToString(CultureInfo.InvariantCulture); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -884,7 +884,7 @@ internal static string ToString(ulong i) var temp = intToString; return i < (ulong) temp.Length ? temp[i] - : i.ToString(); + : i.ToString(CultureInfo.InvariantCulture); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -925,7 +925,7 @@ internal static bool CanBeStringifiedAsLong(double d) [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static string ToString(BigInteger bigInteger) { - return bigInteger.ToString(); + return bigInteger.ToString(CultureInfo.InvariantCulture); } ///