|
@@ -1,385 +1,383 @@
|
|
|
using System.Text;
|
|
|
-using Jint.Native.Array;
|
|
|
using Jint.Runtime;
|
|
|
|
|
|
-namespace Jint.Native
|
|
|
+namespace Jint.Native;
|
|
|
+
|
|
|
+public class JsString : JsValue, IEquatable<JsString>
|
|
|
{
|
|
|
- public class JsString : JsValue, IEquatable<JsString>
|
|
|
+ private const int AsciiMax = 126;
|
|
|
+ private static readonly JsString[] _charToJsValue;
|
|
|
+ private static readonly JsString[] _charToStringJsValue;
|
|
|
+ private static readonly JsString[] _intToStringJsValue;
|
|
|
+
|
|
|
+ public static readonly JsString Empty = new JsString("");
|
|
|
+ internal static readonly JsString NullString = new JsString("null");
|
|
|
+ internal static readonly JsString UndefinedString = new JsString("undefined");
|
|
|
+ internal static readonly JsString ObjectString = new JsString("object");
|
|
|
+ internal static readonly JsString FunctionString = new JsString("function");
|
|
|
+ internal static readonly JsString BooleanString = new JsString("boolean");
|
|
|
+ internal static readonly JsString StringString = new JsString("string");
|
|
|
+ internal static readonly JsString NumberString = new JsString("number");
|
|
|
+ internal static readonly JsString BigIntString = new JsString("bigint");
|
|
|
+ internal static readonly JsString SymbolString = new JsString("symbol");
|
|
|
+ internal static readonly JsString DefaultString = new JsString("default");
|
|
|
+ internal static readonly JsString NumberZeroString = new JsString("0");
|
|
|
+ internal static readonly JsString NumberOneString = new JsString("1");
|
|
|
+ internal static readonly JsString TrueString = new JsString("true");
|
|
|
+ internal static readonly JsString FalseString = new JsString("false");
|
|
|
+ internal static readonly JsString LengthString = new JsString("length");
|
|
|
+ internal static readonly JsValue CommaString = new JsString(",");
|
|
|
+
|
|
|
+ internal string _value;
|
|
|
+
|
|
|
+ static JsString()
|
|
|
{
|
|
|
- private const int AsciiMax = 126;
|
|
|
- private static readonly JsString[] _charToJsValue;
|
|
|
- private static readonly JsString[] _charToStringJsValue;
|
|
|
- private static readonly JsString[] _intToStringJsValue;
|
|
|
-
|
|
|
- public static readonly JsString Empty = new JsString("");
|
|
|
- internal static readonly JsString NullString = new JsString("null");
|
|
|
- internal static readonly JsString UndefinedString = new JsString("undefined");
|
|
|
- internal static readonly JsString ObjectString = new JsString("object");
|
|
|
- internal static readonly JsString FunctionString = new JsString("function");
|
|
|
- internal static readonly JsString BooleanString = new JsString("boolean");
|
|
|
- internal static readonly JsString StringString = new JsString("string");
|
|
|
- internal static readonly JsString NumberString = new JsString("number");
|
|
|
- internal static readonly JsString BigIntString = new JsString("bigint");
|
|
|
- internal static readonly JsString SymbolString = new JsString("symbol");
|
|
|
- internal static readonly JsString DefaultString = new JsString("default");
|
|
|
- internal static readonly JsString NumberZeroString = new JsString("0");
|
|
|
- internal static readonly JsString NumberOneString = new JsString("1");
|
|
|
- internal static readonly JsString TrueString = new JsString("true");
|
|
|
- internal static readonly JsString FalseString = new JsString("false");
|
|
|
- internal static readonly JsString LengthString = new JsString("length");
|
|
|
- internal static readonly JsValue CommaString = new JsString(",");
|
|
|
-
|
|
|
- internal string _value;
|
|
|
-
|
|
|
- static JsString()
|
|
|
- {
|
|
|
- _charToJsValue = new JsString[AsciiMax + 1];
|
|
|
- _charToStringJsValue = new JsString[AsciiMax + 1];
|
|
|
-
|
|
|
- for (var i = 0; i <= AsciiMax; i++)
|
|
|
- {
|
|
|
- _charToJsValue[i] = new JsString((char) i);
|
|
|
- _charToStringJsValue[i] = new JsString(((char) i).ToString());
|
|
|
- }
|
|
|
+ _charToJsValue = new JsString[AsciiMax + 1];
|
|
|
+ _charToStringJsValue = new JsString[AsciiMax + 1];
|
|
|
|
|
|
- _intToStringJsValue = new JsString[1024];
|
|
|
- for (var i = 0; i < _intToStringJsValue.Length; ++i)
|
|
|
- {
|
|
|
- _intToStringJsValue[i] = new JsString(TypeConverter.ToString(i));
|
|
|
- }
|
|
|
+ for (var i = 0; i <= AsciiMax; i++)
|
|
|
+ {
|
|
|
+ _charToJsValue[i] = new JsString((char) i);
|
|
|
+ _charToStringJsValue[i] = new JsString(((char) i).ToString());
|
|
|
}
|
|
|
|
|
|
- public JsString(string value) : this(value, InternalTypes.String)
|
|
|
+ _intToStringJsValue = new JsString[1024];
|
|
|
+ for (var i = 0; i < _intToStringJsValue.Length; ++i)
|
|
|
{
|
|
|
+ _intToStringJsValue[i] = new JsString(TypeConverter.ToString(i));
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ public JsString(string value) : this(value, InternalTypes.String)
|
|
|
+ {
|
|
|
+ }
|
|
|
|
|
|
- private JsString(string value, InternalTypes type) : base(type)
|
|
|
+ private JsString(string value, InternalTypes type) : base(type)
|
|
|
+ {
|
|
|
+ _value = value;
|
|
|
+ }
|
|
|
+
|
|
|
+ public JsString(char value) : base(Types.String)
|
|
|
+ {
|
|
|
+ _value = value.ToString();
|
|
|
+ }
|
|
|
+
|
|
|
+ public override object ToObject()
|
|
|
+ {
|
|
|
+ return _value;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static bool operator ==(JsValue? a, JsString? b)
|
|
|
+ {
|
|
|
+ if (a is JsString s && b is not null)
|
|
|
{
|
|
|
- _value = value;
|
|
|
+ return s.ToString() == b.ToString();
|
|
|
}
|
|
|
|
|
|
- public override object ToObject()
|
|
|
+ if (a is null)
|
|
|
{
|
|
|
- return _value;
|
|
|
+ return b is null;
|
|
|
}
|
|
|
|
|
|
- public JsString(char value) : base(Types.String)
|
|
|
+ return b is not null && a.Equals(b);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static bool operator ==(JsString? a, JsValue? b)
|
|
|
+ {
|
|
|
+ if (a is not null && b is JsString s)
|
|
|
{
|
|
|
- _value = value.ToString();
|
|
|
+ return s.ToString() == b.ToString();
|
|
|
}
|
|
|
|
|
|
- public static bool operator ==(JsValue? a, JsString? b)
|
|
|
+ if (a is null)
|
|
|
{
|
|
|
- if (a is JsString s && b is not null)
|
|
|
- {
|
|
|
- return s.ToString() == b.ToString();
|
|
|
- }
|
|
|
+ return b is null;
|
|
|
+ }
|
|
|
|
|
|
- if (a is null)
|
|
|
- {
|
|
|
- return b is null;
|
|
|
- }
|
|
|
+ return b is not null && a.Equals(b);
|
|
|
+ }
|
|
|
|
|
|
- return b is not null && a.Equals(b);
|
|
|
- }
|
|
|
+ public static bool operator !=(JsString a, JsValue b)
|
|
|
+ {
|
|
|
+ return !(a == b);
|
|
|
+ }
|
|
|
|
|
|
- public static bool operator ==(JsString? a, JsValue? b)
|
|
|
- {
|
|
|
- if (a is not null && b is JsString s)
|
|
|
- {
|
|
|
- return s.ToString() == b.ToString();
|
|
|
- }
|
|
|
+ public static bool operator !=(JsValue a, JsString b)
|
|
|
+ {
|
|
|
+ return !(a == b);
|
|
|
+ }
|
|
|
|
|
|
- if (a is null)
|
|
|
- {
|
|
|
- return b is null;
|
|
|
- }
|
|
|
+ public virtual char this[int index] => _value[index];
|
|
|
|
|
|
- return b is not null && a.Equals(b);
|
|
|
- }
|
|
|
+ public virtual JsString Append(JsValue jsValue)
|
|
|
+ {
|
|
|
+ return new ConcatenatedString(string.Concat(_value, TypeConverter.ToString(jsValue)));
|
|
|
+ }
|
|
|
|
|
|
- public static bool operator !=(JsString a, JsValue b)
|
|
|
- {
|
|
|
- return !(a == b);
|
|
|
- }
|
|
|
+ internal virtual JsString EnsureCapacity(int capacity)
|
|
|
+ {
|
|
|
+ return new ConcatenatedString(_value, capacity);
|
|
|
+ }
|
|
|
+
|
|
|
+ internal virtual bool IsNullOrEmpty()
|
|
|
+ {
|
|
|
+ return string.IsNullOrEmpty(_value);
|
|
|
+ }
|
|
|
+
|
|
|
+ public virtual int Length => _value.Length;
|
|
|
|
|
|
- public static bool operator !=(JsValue a, JsString b)
|
|
|
+ internal static JsString Create(string value)
|
|
|
+ {
|
|
|
+ if (value.Length > 1)
|
|
|
{
|
|
|
- return !(a == b);
|
|
|
+ return new JsString(value);
|
|
|
}
|
|
|
|
|
|
- public virtual char this[int index] => _value[index];
|
|
|
-
|
|
|
- public virtual JsString Append(JsValue jsValue)
|
|
|
+ if (value.Length == 0)
|
|
|
{
|
|
|
- return new ConcatenatedString(string.Concat(_value, TypeConverter.ToString(jsValue)));
|
|
|
+ return Empty;
|
|
|
}
|
|
|
|
|
|
- internal virtual JsString EnsureCapacity(int capacity)
|
|
|
+ var i = (uint) value[0];
|
|
|
+ var temp = _charToStringJsValue;
|
|
|
+ if (i < (uint) temp.Length)
|
|
|
{
|
|
|
- return new ConcatenatedString(_value, capacity);
|
|
|
+ return temp[i];
|
|
|
}
|
|
|
+ return new JsString(value);
|
|
|
+ }
|
|
|
|
|
|
- internal virtual bool IsNullOrEmpty()
|
|
|
+ internal static JsString Create(char value)
|
|
|
+ {
|
|
|
+ var temp = _charToJsValue;
|
|
|
+ if (value < (uint) temp.Length)
|
|
|
{
|
|
|
- return string.IsNullOrEmpty(_value);
|
|
|
+ return temp[value];
|
|
|
}
|
|
|
|
|
|
- public virtual int Length => _value.Length;
|
|
|
+ return new JsString(value);
|
|
|
+ }
|
|
|
|
|
|
- internal static JsString Create(string value)
|
|
|
+ internal static JsString Create(int value)
|
|
|
+ {
|
|
|
+ var temp = _intToStringJsValue;
|
|
|
+ if (value < (uint) temp.Length)
|
|
|
{
|
|
|
- if (value.Length > 1)
|
|
|
- {
|
|
|
- return new JsString(value);
|
|
|
- }
|
|
|
+ return temp[value];
|
|
|
+ }
|
|
|
|
|
|
- if (value.Length == 0)
|
|
|
- {
|
|
|
- return Empty;
|
|
|
- }
|
|
|
+ return new JsString(TypeConverter.ToString(value));
|
|
|
+ }
|
|
|
|
|
|
- var i = (uint) value[0];
|
|
|
- var temp = _charToStringJsValue;
|
|
|
- if (i < (uint) temp.Length)
|
|
|
- {
|
|
|
- return temp[i];
|
|
|
- }
|
|
|
- return new JsString(value);
|
|
|
+ internal static JsValue Create(uint value)
|
|
|
+ {
|
|
|
+ var temp = _intToStringJsValue;
|
|
|
+ if (value < (uint) temp.Length)
|
|
|
+ {
|
|
|
+ return temp[value];
|
|
|
}
|
|
|
|
|
|
- internal static JsString Create(char value)
|
|
|
- {
|
|
|
- var temp = _charToJsValue;
|
|
|
- if (value < (uint) temp.Length)
|
|
|
- {
|
|
|
- return temp[value];
|
|
|
- }
|
|
|
+ return new JsString(TypeConverter.ToString(value));
|
|
|
+ }
|
|
|
|
|
|
- return new JsString(value);
|
|
|
+ internal static JsValue Create(ulong value)
|
|
|
+ {
|
|
|
+ var temp = _intToStringJsValue;
|
|
|
+ if (value < (uint) temp.Length)
|
|
|
+ {
|
|
|
+ return temp[value];
|
|
|
}
|
|
|
|
|
|
- internal static JsString Create(int value)
|
|
|
- {
|
|
|
- var temp = _intToStringJsValue;
|
|
|
- if (value < (uint) temp.Length)
|
|
|
- {
|
|
|
- return temp[value];
|
|
|
- }
|
|
|
+ return new JsString(TypeConverter.ToString(value));
|
|
|
+ }
|
|
|
|
|
|
- return new JsString(TypeConverter.ToString(value));
|
|
|
- }
|
|
|
+ public override string ToString()
|
|
|
+ {
|
|
|
+ return _value;
|
|
|
+ }
|
|
|
|
|
|
- internal static JsValue Create(uint value)
|
|
|
+ public JsArray ToArray(Engine engine)
|
|
|
+ {
|
|
|
+ var array = engine.Realm.Intrinsics.Array.ArrayCreate((uint) _value.Length);
|
|
|
+ for (int i = 0; i < _value.Length; ++i)
|
|
|
{
|
|
|
- var temp = _intToStringJsValue;
|
|
|
- if (value < (uint) temp.Length)
|
|
|
- {
|
|
|
- return temp[value];
|
|
|
- }
|
|
|
-
|
|
|
- return new JsString(TypeConverter.ToString(value));
|
|
|
+ array.SetIndexValue((uint) i, _value[i], updateLength: false);
|
|
|
}
|
|
|
|
|
|
- internal static JsValue Create(ulong value)
|
|
|
- {
|
|
|
- var temp = _intToStringJsValue;
|
|
|
- if (value < (uint) temp.Length)
|
|
|
- {
|
|
|
- return temp[value];
|
|
|
- }
|
|
|
+ return array;
|
|
|
+ }
|
|
|
|
|
|
- return new JsString(TypeConverter.ToString(value));
|
|
|
- }
|
|
|
+ internal int IndexOf(string value, StringComparison comparisonType)
|
|
|
+ {
|
|
|
+ return ToString().IndexOf(value, comparisonType);
|
|
|
+ }
|
|
|
|
|
|
- public override string ToString()
|
|
|
- {
|
|
|
- return _value;
|
|
|
- }
|
|
|
+ internal int IndexOf(char value)
|
|
|
+ {
|
|
|
+ return ToString().IndexOf(value);
|
|
|
+ }
|
|
|
|
|
|
- public ArrayInstance ToArray(Engine engine)
|
|
|
- {
|
|
|
- var array = engine.Realm.Intrinsics.Array.ArrayCreate((uint) _value.Length);
|
|
|
- for (int i = 0; i < _value.Length; ++i)
|
|
|
- {
|
|
|
- array.SetIndexValue((uint) i, _value[i], updateLength: false);
|
|
|
- }
|
|
|
+ internal string Substring(int startIndex, int length)
|
|
|
+ {
|
|
|
+ return ToString().Substring(startIndex, length);
|
|
|
+ }
|
|
|
|
|
|
- return array;
|
|
|
- }
|
|
|
+ internal string Substring(int startIndex)
|
|
|
+ {
|
|
|
+ return ToString().Substring(startIndex);
|
|
|
+ }
|
|
|
|
|
|
- internal int IndexOf(string value, StringComparison comparisonType)
|
|
|
- {
|
|
|
- return ToString().IndexOf(value, comparisonType);
|
|
|
- }
|
|
|
+ public override bool Equals(JsValue? obj)
|
|
|
+ {
|
|
|
+ return Equals(obj as JsString);
|
|
|
+ }
|
|
|
|
|
|
- internal int IndexOf(char value)
|
|
|
+ public bool Equals(JsString? other)
|
|
|
+ {
|
|
|
+ if (other is null)
|
|
|
{
|
|
|
- return ToString().IndexOf(value);
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
- internal string Substring(int startIndex, int length)
|
|
|
+ if (ReferenceEquals(this, other))
|
|
|
{
|
|
|
- return ToString().Substring(startIndex, length);
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
- internal string Substring(int startIndex)
|
|
|
+ return _value == other.ToString();
|
|
|
+ }
|
|
|
+
|
|
|
+ public override bool IsLooselyEqual(JsValue value)
|
|
|
+ {
|
|
|
+ if (value is JsString jsString)
|
|
|
{
|
|
|
- return ToString().Substring(startIndex);
|
|
|
+ return Equals(jsString);
|
|
|
}
|
|
|
|
|
|
- public override bool Equals(JsValue? obj)
|
|
|
+ if (value.IsBigInt())
|
|
|
{
|
|
|
- return Equals(obj as JsString);
|
|
|
+ return value.IsBigInt() && TypeConverter.TryStringToBigInt(ToString(), out var temp) && temp == value.AsBigInt();
|
|
|
}
|
|
|
|
|
|
- public bool Equals(JsString? other)
|
|
|
- {
|
|
|
- if (other is null)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
+ return base.IsLooselyEqual(value);
|
|
|
+ }
|
|
|
|
|
|
- if (ReferenceEquals(this, other))
|
|
|
- {
|
|
|
- return true;
|
|
|
- }
|
|
|
+ public override bool Equals(object obj)
|
|
|
+ {
|
|
|
+ return Equals(obj as JsString);
|
|
|
+ }
|
|
|
|
|
|
- return _value == other.ToString();
|
|
|
- }
|
|
|
+ public override int GetHashCode()
|
|
|
+ {
|
|
|
+ return _value.GetHashCode();
|
|
|
+ }
|
|
|
+
|
|
|
+ internal sealed class ConcatenatedString : JsString
|
|
|
+ {
|
|
|
+ private StringBuilder? _stringBuilder;
|
|
|
+ private bool _dirty;
|
|
|
|
|
|
- public override bool IsLooselyEqual(JsValue value)
|
|
|
+ internal ConcatenatedString(string value, int capacity = 0)
|
|
|
+ : base(value, InternalTypes.String | InternalTypes.RequiresCloning)
|
|
|
{
|
|
|
- if (value is JsString jsString)
|
|
|
+ if (capacity > 0)
|
|
|
{
|
|
|
- return Equals(jsString);
|
|
|
+ _stringBuilder = new StringBuilder(value, capacity);
|
|
|
}
|
|
|
-
|
|
|
- if (value.IsBigInt())
|
|
|
+ else
|
|
|
{
|
|
|
- return value.IsBigInt() && TypeConverter.TryStringToBigInt(ToString(), out var temp) && temp == value.AsBigInt();
|
|
|
+ _value = value;
|
|
|
}
|
|
|
-
|
|
|
- return base.IsLooselyEqual(value);
|
|
|
}
|
|
|
|
|
|
- public override bool Equals(object obj)
|
|
|
+ public override string ToString()
|
|
|
{
|
|
|
- return Equals(obj as JsString);
|
|
|
- }
|
|
|
+ if (_dirty)
|
|
|
+ {
|
|
|
+ _value = _stringBuilder!.ToString();
|
|
|
+ _dirty = false;
|
|
|
+ }
|
|
|
|
|
|
- public override int GetHashCode()
|
|
|
- {
|
|
|
- return _value.GetHashCode();
|
|
|
+ return _value;
|
|
|
}
|
|
|
|
|
|
- internal sealed class ConcatenatedString : JsString
|
|
|
- {
|
|
|
- private StringBuilder? _stringBuilder;
|
|
|
- private bool _dirty;
|
|
|
+ public override char this[int index] => _stringBuilder?[index] ?? _value[index];
|
|
|
|
|
|
- internal ConcatenatedString(string value, int capacity = 0)
|
|
|
- : base(value, InternalTypes.String | InternalTypes.RequiresCloning)
|
|
|
+ public override JsString Append(JsValue jsValue)
|
|
|
+ {
|
|
|
+ var value = TypeConverter.ToString(jsValue);
|
|
|
+ if (_stringBuilder == null)
|
|
|
{
|
|
|
- if (capacity > 0)
|
|
|
- {
|
|
|
- _stringBuilder = new StringBuilder(value, capacity);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- _value = value;
|
|
|
- }
|
|
|
+ _stringBuilder = new StringBuilder(_value, _value.Length + value.Length);
|
|
|
}
|
|
|
|
|
|
- public override string ToString()
|
|
|
- {
|
|
|
- if (_dirty)
|
|
|
- {
|
|
|
- _value = _stringBuilder!.ToString();
|
|
|
- _dirty = false;
|
|
|
- }
|
|
|
-
|
|
|
- return _value;
|
|
|
- }
|
|
|
+ _stringBuilder.Append(value);
|
|
|
+ _dirty = true;
|
|
|
|
|
|
- public override char this[int index] => _stringBuilder?[index] ?? _value[index];
|
|
|
+ return this;
|
|
|
+ }
|
|
|
|
|
|
- public override JsString Append(JsValue jsValue)
|
|
|
- {
|
|
|
- var value = TypeConverter.ToString(jsValue);
|
|
|
- if (_stringBuilder == null)
|
|
|
- {
|
|
|
- _stringBuilder = new StringBuilder(_value, _value.Length + value.Length);
|
|
|
- }
|
|
|
+ internal override JsString EnsureCapacity(int capacity)
|
|
|
+ {
|
|
|
+ _stringBuilder!.EnsureCapacity(capacity);
|
|
|
+ return this;
|
|
|
+ }
|
|
|
|
|
|
- _stringBuilder.Append(value);
|
|
|
- _dirty = true;
|
|
|
+ internal override bool IsNullOrEmpty()
|
|
|
+ {
|
|
|
+ return _stringBuilder == null && string.IsNullOrEmpty(_value)
|
|
|
+ || _stringBuilder != null && _stringBuilder.Length == 0;
|
|
|
+ }
|
|
|
|
|
|
- return this;
|
|
|
- }
|
|
|
+ public override int Length => _stringBuilder?.Length ?? _value?.Length ?? 0;
|
|
|
|
|
|
- internal override JsString EnsureCapacity(int capacity)
|
|
|
- {
|
|
|
- _stringBuilder!.EnsureCapacity(capacity);
|
|
|
- return this;
|
|
|
- }
|
|
|
+ public override object ToObject() => ToString();
|
|
|
|
|
|
- internal override bool IsNullOrEmpty()
|
|
|
+ public override bool Equals(JsValue? other)
|
|
|
+ {
|
|
|
+ if (other is ConcatenatedString cs)
|
|
|
{
|
|
|
- return _stringBuilder == null && string.IsNullOrEmpty(_value)
|
|
|
- || _stringBuilder != null && _stringBuilder.Length == 0;
|
|
|
- }
|
|
|
-
|
|
|
- public override int Length => _stringBuilder?.Length ?? _value?.Length ?? 0;
|
|
|
+ var stringBuilder = _stringBuilder;
|
|
|
+ var csStringBuilder = cs._stringBuilder;
|
|
|
|
|
|
- public override object ToObject() => ToString();
|
|
|
-
|
|
|
- public override bool Equals(JsValue? other)
|
|
|
- {
|
|
|
- if (other is ConcatenatedString cs)
|
|
|
+ // we cannot use StringBuilder.Equals as it also checks Capacity on full framework / pre .NET Core 3
|
|
|
+ if (stringBuilder != null && csStringBuilder != null && stringBuilder.Length == csStringBuilder.Length)
|
|
|
{
|
|
|
- var stringBuilder = _stringBuilder;
|
|
|
- var csStringBuilder = cs._stringBuilder;
|
|
|
-
|
|
|
- // we cannot use StringBuilder.Equals as it also checks Capacity on full framework / pre .NET Core 3
|
|
|
- if (stringBuilder != null && csStringBuilder != null && stringBuilder.Length == csStringBuilder.Length)
|
|
|
+ for (var i = 0; i < stringBuilder.Length; ++i)
|
|
|
{
|
|
|
- for (var i = 0; i < stringBuilder.Length; ++i)
|
|
|
+ if (stringBuilder[i] != csStringBuilder[i])
|
|
|
{
|
|
|
- if (stringBuilder[i] != csStringBuilder[i])
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
+ return false;
|
|
|
}
|
|
|
-
|
|
|
- return true;
|
|
|
}
|
|
|
|
|
|
- return ToString() == cs.ToString();
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
- if (other is JsString jsString)
|
|
|
- {
|
|
|
- if (jsString._value.Length != Length)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
+ return ToString() == cs.ToString();
|
|
|
+ }
|
|
|
|
|
|
- return ToString() == jsString._value;
|
|
|
+ if (other is JsString jsString)
|
|
|
+ {
|
|
|
+ if (jsString._value.Length != Length)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
- return base.Equals(other);
|
|
|
+ return ToString() == jsString._value;
|
|
|
}
|
|
|
|
|
|
- public override int GetHashCode()
|
|
|
- {
|
|
|
- return _stringBuilder?.GetHashCode() ?? _value.GetHashCode();
|
|
|
- }
|
|
|
+ return base.Equals(other);
|
|
|
+ }
|
|
|
|
|
|
- internal override JsValue DoClone()
|
|
|
- {
|
|
|
- return new JsString(ToString());
|
|
|
- }
|
|
|
+ public override int GetHashCode()
|
|
|
+ {
|
|
|
+ return _stringBuilder?.GetHashCode() ?? _value.GetHashCode();
|
|
|
+ }
|
|
|
+
|
|
|
+ internal override JsValue DoClone()
|
|
|
+ {
|
|
|
+ return new JsString(ToString());
|
|
|
}
|
|
|
}
|
|
|
}
|