From 30643e9667f54842dded022b2c071daa1d5667e1 Mon Sep 17 00:00:00 2001 From: scgm0 <2682963017@qq.com> Date: Sat, 6 Jan 2024 01:35:06 +0800 Subject: [PATCH 1/7] The toString() of 'class' and 'function' return SourceText --- Jint/Native/Function/ClassDefinition.cs | 4 ++++ Jint/Native/Function/Function.cs | 12 ++++++++++-- .../Interpreter/Expressions/JintClassExpression.cs | 3 ++- .../Statements/JintClassDeclarationStatement.cs | 3 ++- .../Statements/JintExportDefaultDeclaration.cs | 3 ++- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/Jint/Native/Function/ClassDefinition.cs b/Jint/Native/Function/ClassDefinition.cs index 8cf1ecb224..ce13491cb4 100644 --- a/Jint/Native/Function/ClassDefinition.cs +++ b/Jint/Native/Function/ClassDefinition.cs @@ -19,6 +19,7 @@ internal sealed class ClassDefinition internal static readonly MethodDefinition _emptyConstructor; internal readonly string? _className; + private readonly string _classSource; private readonly Expression? _superClass; private readonly ClassBody _body; @@ -39,10 +40,12 @@ static MethodDefinition CreateConstructorMethodDefinition(string source) public ClassDefinition( string? className, + string classSource, Expression? superClass, ClassBody body) { _className = className; + _classSource = classSource; _superClass = superClass; _body = body; } @@ -145,6 +148,7 @@ public JsValue BuildConstructor(EvaluationContext context, Environment env) F = constructorInfo.Closure; F.SetFunctionName(_className ?? ""); + F._sourceText = _classSource; F.MakeConstructor(writableProperty: false, proto); F._constructorKind = _superClass is null ? ConstructorKind.Base : ConstructorKind.Derived; diff --git a/Jint/Native/Function/Function.cs b/Jint/Native/Function/Function.cs index 881edbe974..528b6b1030 100644 --- a/Jint/Native/Function/Function.cs +++ b/Jint/Native/Function/Function.cs @@ -28,6 +28,7 @@ public abstract partial class Function : ObjectInstance, ICallable internal Realm _realm; internal PrivateEnvironment? _privateEnvironment; + internal string? _sourceText; private readonly IScriptOrModule? _scriptOrModule; protected Function( @@ -367,7 +368,14 @@ internal void SetFunctionLength(JsNumber length) public override string ToString() { - // TODO no way to extract SourceText from Esprima at the moment, just returning native code + if (_sourceText != null) + { + return _sourceText; + } + if ((_sourceText = _functionDefinition?.Function?.ToString()) != null) + { + return _sourceText; + } var nameValue = _nameDescriptor != null ? UnwrapJsValue(_nameDescriptor) : JsString.Empty; var name = ""; if (!nameValue.IsUndefined()) @@ -377,7 +385,7 @@ public override string ToString() name = name.TrimStart(_functionNameTrimStartChars); - return "function " + name + "() { [native code] }"; + return _sourceText = "function " + name + "() { [native code] }"; } private sealed class ObjectInstanceWithConstructor : ObjectInstance diff --git a/Jint/Runtime/Interpreter/Expressions/JintClassExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintClassExpression.cs index f721bb539f..0d38ac9c22 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintClassExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintClassExpression.cs @@ -1,4 +1,5 @@ using Esprima.Ast; +using Esprima.Utils; using Jint.Native.Function; namespace Jint.Runtime.Interpreter.Expressions @@ -9,7 +10,7 @@ internal sealed class JintClassExpression : JintExpression public JintClassExpression(ClassExpression expression) : base(expression) { - _classDefinition = new ClassDefinition(expression.Id?.Name, expression.SuperClass, expression.Body); + _classDefinition = new ClassDefinition(className: expression.Id?.Name, classSource: expression.ToString(), superClass: expression.SuperClass, body: expression.Body); } protected override object EvaluateInternal(EvaluationContext context) diff --git a/Jint/Runtime/Interpreter/Statements/JintClassDeclarationStatement.cs b/Jint/Runtime/Interpreter/Statements/JintClassDeclarationStatement.cs index bb55ae6536..f0f6ebd63e 100644 --- a/Jint/Runtime/Interpreter/Statements/JintClassDeclarationStatement.cs +++ b/Jint/Runtime/Interpreter/Statements/JintClassDeclarationStatement.cs @@ -1,4 +1,5 @@ using Esprima.Ast; +using Esprima.Utils; using Jint.Native; using Jint.Native.Function; @@ -10,7 +11,7 @@ internal sealed class JintClassDeclarationStatement : JintStatement Date: Sat, 6 Jan 2024 09:40:24 +0800 Subject: [PATCH 2/7] Fix method names in SourceText --- Jint/Native/Function/ClassDefinition.cs | 5 +++++ Jint/Native/Function/Function.cs | 5 +++++ Jint/Runtime/Interpreter/JintFunctionDefinition.cs | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Jint/Native/Function/ClassDefinition.cs b/Jint/Native/Function/ClassDefinition.cs index ce13491cb4..0bc0a55517 100644 --- a/Jint/Native/Function/ClassDefinition.cs +++ b/Jint/Native/Function/ClassDefinition.cs @@ -1,3 +1,4 @@ +using System.Text.RegularExpressions; using Esprima; using Esprima.Ast; using Esprima.Utils; @@ -363,6 +364,10 @@ public ClassStaticBlockFunction(StaticBlock staticBlock) : base(Nodes.StaticBloc { var methodDef = method.DefineMethod(obj); methodDef.Closure.SetFunctionName(methodDef.Key); + // TODO currently in the SourceText retrieved from Esprima, the method name is incorrect, so for now, use a regular replacement. +#pragma warning disable MA0009 + methodDef.Closure._sourceText = new Regex("function").Replace(methodDef.Closure.ToString(), methodDef.Key.AsString(), 1); +#pragma warning restore MA0009 return DefineMethodProperty(obj, methodDef.Key, methodDef.Closure, enumerable); } diff --git a/Jint/Native/Function/Function.cs b/Jint/Native/Function/Function.cs index 528b6b1030..242d28ac11 100644 --- a/Jint/Native/Function/Function.cs +++ b/Jint/Native/Function/Function.cs @@ -209,6 +209,11 @@ internal void SetFunctionName(JsValue name, string? prefix = null, bool force = name = prefix + " " + name; } + if (_functionDefinition != null) + { + _functionDefinition.Name = name.AsString(); + } + _nameDescriptor = new PropertyDescriptor(name, PropertyFlag.Configurable); } diff --git a/Jint/Runtime/Interpreter/JintFunctionDefinition.cs b/Jint/Runtime/Interpreter/JintFunctionDefinition.cs index bc2283c7aa..c9bdf13ee0 100644 --- a/Jint/Runtime/Interpreter/JintFunctionDefinition.cs +++ b/Jint/Runtime/Interpreter/JintFunctionDefinition.cs @@ -17,7 +17,7 @@ internal sealed class JintFunctionDefinition private JintExpression? _bodyExpression; private JintStatementList? _bodyStatementList; - public readonly string? Name; + public string? Name; public readonly IFunction Function; public JintFunctionDefinition(IFunction function) From e017b1dfeb16b2db3ded8ca45ac80a3d08a507f3 Mon Sep 17 00:00:00 2001 From: scgm0 <2682963017@qq.com> Date: Sat, 6 Jan 2024 01:35:06 +0800 Subject: [PATCH 3/7] The toString() of 'class' and 'function' return SourceText --- Jint/Native/Function/Function.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Jint/Native/Function/Function.cs b/Jint/Native/Function/Function.cs index 242d28ac11..04900e68a4 100644 --- a/Jint/Native/Function/Function.cs +++ b/Jint/Native/Function/Function.cs @@ -381,6 +381,7 @@ public override string ToString() { return _sourceText; } + var nameValue = _nameDescriptor != null ? UnwrapJsValue(_nameDescriptor) : JsString.Empty; var name = ""; if (!nameValue.IsUndefined()) From 11656596bb23db5f20c4dc3e1ba12e3ab39278c5 Mon Sep 17 00:00:00 2001 From: scgm0 <2682963017@qq.com> Date: Thu, 8 Feb 2024 11:05:13 +0800 Subject: [PATCH 4/7] Fix methodDef.Closure._sourceText Regex --- Jint/Native/Function/ClassDefinition.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jint/Native/Function/ClassDefinition.cs b/Jint/Native/Function/ClassDefinition.cs index 0bc0a55517..45a9c434c8 100644 --- a/Jint/Native/Function/ClassDefinition.cs +++ b/Jint/Native/Function/ClassDefinition.cs @@ -366,7 +366,7 @@ public ClassStaticBlockFunction(StaticBlock staticBlock) : base(Nodes.StaticBloc methodDef.Closure.SetFunctionName(methodDef.Key); // TODO currently in the SourceText retrieved from Esprima, the method name is incorrect, so for now, use a regular replacement. #pragma warning disable MA0009 - methodDef.Closure._sourceText = new Regex("function").Replace(methodDef.Closure.ToString(), methodDef.Key.AsString(), 1); + methodDef.Closure._sourceText = new Regex("function").Replace(methodDef.Closure.ToString(), methodDef.Key.ToString(), 1); #pragma warning restore MA0009 return DefineMethodProperty(obj, methodDef.Key, methodDef.Closure, enumerable); } From cd2e56796a7d770ce4f81901243fef49b2975f40 Mon Sep 17 00:00:00 2001 From: scgm0 <2682963017@qq.com> Date: Thu, 8 Feb 2024 19:10:21 +0800 Subject: [PATCH 5/7] Using String Replacement Instead of Regular Replacement --- Jint/Native/Function/ClassDefinition.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Jint/Native/Function/ClassDefinition.cs b/Jint/Native/Function/ClassDefinition.cs index 45a9c434c8..13a8f2e2ba 100644 --- a/Jint/Native/Function/ClassDefinition.cs +++ b/Jint/Native/Function/ClassDefinition.cs @@ -364,10 +364,10 @@ public ClassStaticBlockFunction(StaticBlock staticBlock) : base(Nodes.StaticBloc { var methodDef = method.DefineMethod(obj); methodDef.Closure.SetFunctionName(methodDef.Key); - // TODO currently in the SourceText retrieved from Esprima, the method name is incorrect, so for now, use a regular replacement. -#pragma warning disable MA0009 - methodDef.Closure._sourceText = new Regex("function").Replace(methodDef.Closure.ToString(), methodDef.Key.ToString(), 1); -#pragma warning restore MA0009 + // TODO currently in the SourceText retrieved from Esprima, the method name is incorrect, so for now, use a string replacement. + var oldMethodName = methodDef.Closure.ToString(); + var index = oldMethodName.IndexOf("function", StringComparison.Ordinal); + methodDef.Closure._sourceText = index > -1 ? oldMethodName.Remove(index, "function".Length).Insert(index, methodDef.Key.ToString()) : oldMethodName; return DefineMethodProperty(obj, methodDef.Key, methodDef.Closure, enumerable); } From 40afaeff3ac1d42b8aebf05e949483308deac776 Mon Sep 17 00:00:00 2001 From: scgm0 <2682963017@qq.com> Date: Thu, 8 Feb 2024 21:01:22 +0800 Subject: [PATCH 6/7] Fix getter/setter and private method --- Jint/Native/Function/ClassDefinition.cs | 6 +++--- Jint/Native/Function/Function.cs | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Jint/Native/Function/ClassDefinition.cs b/Jint/Native/Function/ClassDefinition.cs index 13a8f2e2ba..cbc54bac41 100644 --- a/Jint/Native/Function/ClassDefinition.cs +++ b/Jint/Native/Function/ClassDefinition.cs @@ -365,9 +365,9 @@ public ClassStaticBlockFunction(StaticBlock staticBlock) : base(Nodes.StaticBloc var methodDef = method.DefineMethod(obj); methodDef.Closure.SetFunctionName(methodDef.Key); // TODO currently in the SourceText retrieved from Esprima, the method name is incorrect, so for now, use a string replacement. - var oldMethodName = methodDef.Closure.ToString(); - var index = oldMethodName.IndexOf("function", StringComparison.Ordinal); - methodDef.Closure._sourceText = index > -1 ? oldMethodName.Remove(index, "function".Length).Insert(index, methodDef.Key.ToString()) : oldMethodName; + var oldSourceText = methodDef.Closure.ToString(); + var index = oldSourceText.IndexOf("function", StringComparison.Ordinal); + methodDef.Closure._sourceText = index > -1 ? oldSourceText.Remove(index, 8).Insert(index, methodDef.Closure._functionDefinition.Name ?? string.Empty) : oldSourceText; return DefineMethodProperty(obj, methodDef.Key, methodDef.Closure, enumerable); } diff --git a/Jint/Native/Function/Function.cs b/Jint/Native/Function/Function.cs index 04900e68a4..f76f8853b9 100644 --- a/Jint/Native/Function/Function.cs +++ b/Jint/Native/Function/Function.cs @@ -207,6 +207,13 @@ internal void SetFunctionName(JsValue name, string? prefix = null, bool force = if (!string.IsNullOrWhiteSpace(prefix)) { name = prefix + " " + name; + if (prefix is "get" or "set") + { + // TODO currently in the SourceText retrieved from Esprima, the method name is incorrect, so for now, use a string replacement. + var oldSourceText = ToString(); + var index = oldSourceText.IndexOf("function", StringComparison.Ordinal); + _sourceText = index > -1 ? oldSourceText.Remove(index, 8).Insert(index, name.AsString()) : oldSourceText; + } } if (_functionDefinition != null) From 2c2fa8d22c53022e5f55284d85a9498e40881e1e Mon Sep 17 00:00:00 2001 From: scgm0 <2682963017@qq.com> Date: Fri, 9 Feb 2024 14:19:39 +0800 Subject: [PATCH 7/7] Update Test262Harness.settings.json --- .../Test262Harness.settings.json | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/Jint.Tests.Test262/Test262Harness.settings.json b/Jint.Tests.Test262/Test262Harness.settings.json index cdc1b1cf7b..37cc70ebf9 100644 --- a/Jint.Tests.Test262/Test262Harness.settings.json +++ b/Jint.Tests.Test262/Test262Harness.settings.json @@ -339,6 +339,53 @@ "language/statements/function/scope-param-elem-var-open.js", "language/statements/function/scope-param-rest-elem-var-close.js", "language/statements/function/scope-param-rest-elem-var-open.js", - "language/statements/with/cptn-abrupt-empty.js" + "language/statements/with/cptn-abrupt-empty.js", + + // need to wait for further updates from Esprima + "built-ins/Function/prototype/toString/arrow-function.js", + "built-ins/Function/prototype/toString/async-arrow-function.js", + "built-ins/Function/prototype/toString/async-function-declaration.js", + "built-ins/Function/prototype/toString/async-function-expression.js", + "built-ins/Function/prototype/toString/async-method-class-expression-static.js", + "built-ins/Function/prototype/toString/async-method-class-expression.js", + "built-ins/Function/prototype/toString/async-method-class-statement-static.js", + "built-ins/Function/prototype/toString/async-method-class-statement.js", + "built-ins/Function/prototype/toString/async-method-object.js", + "built-ins/Function/prototype/toString/AsyncFunction.js", + "built-ins/Function/prototype/toString/class-declaration-complex-heritage.js", + "built-ins/Function/prototype/toString/class-declaration-explicit-ctor.js", + "built-ins/Function/prototype/toString/class-declaration-implicit-ctor.js", + "built-ins/Function/prototype/toString/class-expression-explicit-ctor.js", + "built-ins/Function/prototype/toString/class-expression-implicit-ctor.js", + "built-ins/Function/prototype/toString/function-declaration-non-simple-parameter-list.js", + "built-ins/Function/prototype/toString/function-declaration.js", + "built-ins/Function/prototype/toString/function-expression.js", + "built-ins/Function/prototype/toString/Function.js", + "built-ins/Function/prototype/toString/generator-function-declaration.js", + "built-ins/Function/prototype/toString/generator-function-expression.js", + "built-ins/Function/prototype/toString/generator-method.js", + "built-ins/Function/prototype/toString/getter-class-expression-static.js", + "built-ins/Function/prototype/toString/getter-class-expression.js", + "built-ins/Function/prototype/toString/getter-class-statement-static.js", + "built-ins/Function/prototype/toString/getter-class-statement.js", + "built-ins/Function/prototype/toString/getter-object.js", + "built-ins/Function/prototype/toString/line-terminator-normalisation-CR-LF.js", + "built-ins/Function/prototype/toString/line-terminator-normalisation-CR.js", + "built-ins/Function/prototype/toString/line-terminator-normalisation-LF.js", + "built-ins/Function/prototype/toString/method-class-expression-static.js", + "built-ins/Function/prototype/toString/method-class-expression.js", + "built-ins/Function/prototype/toString/method-class-statement-static.js", + "built-ins/Function/prototype/toString/method-class-statement.js", + "built-ins/Function/prototype/toString/method-object.js", + "built-ins/Function/prototype/toString/private-method-class-expression.js", + "built-ins/Function/prototype/toString/private-method-class-statement.js", + "built-ins/Function/prototype/toString/private-static-method-class-expression.js", + "built-ins/Function/prototype/toString/private-static-method-class-statement.js", + "built-ins/Function/prototype/toString/setter-class-expression-static.js", + "built-ins/Function/prototype/toString/setter-class-expression.js", + "built-ins/Function/prototype/toString/setter-class-statement-static.js", + "built-ins/Function/prototype/toString/setter-class-statement.js", + "built-ins/Function/prototype/toString/setter-object.js", + "built-ins/Function/prototype/toString/unicode.js" ] } \ No newline at end of file