Ver código fonte

Upgrade to Esprima 3.0.0-beta-6 (#1268)

Marko Lahma 2 anos atrás
pai
commit
2196309316

+ 3 - 3
Jint.Benchmark/EngineConstructionBenchmark.cs

@@ -11,8 +11,8 @@ namespace Jint.Benchmark
 
         public EngineConstructionBenchmark()
         {
-            var parser = new JavaScriptParser("return [].length + ''.length");
-            _program = parser.ParseScript();
+            var parser = new JavaScriptParser();
+            _program = parser.ParseScript("return [].length + ''.length");
         }
 
         [Benchmark]
@@ -22,4 +22,4 @@ namespace Jint.Benchmark
             return engine.Evaluate(_program).AsNumber();
         }
     }
-}
+}

+ 2 - 2
Jint.Repl/Program.cs

@@ -30,7 +30,7 @@ namespace Jint.Repl
                 }
 
                 var script = File.ReadAllText(filename);
-                engine.Evaluate(script);
+                engine.Evaluate(script, "repl");
                 return;
             }
 
@@ -45,7 +45,7 @@ namespace Jint.Repl
             Console.WriteLine();
 
             var defaultColor = Console.ForegroundColor;
-            var parserOptions = new ParserOptions("repl")
+            var parserOptions = new ParserOptions
             {
                 Tolerant = true,
                 AdaptRegexp = true

+ 2 - 2
Jint.Tests.Test262/Test262ModuleLoader.cs

@@ -37,13 +37,13 @@ internal sealed class Test262ModuleLoader : IModuleLoader
                 code = stream.ReadToEnd();
             }
 
-            var parserOptions = new ParserOptions(resolved.Uri?.LocalPath!)
+            var parserOptions = new ParserOptions
             {
                 AdaptRegexp = true,
                 Tolerant = true
             };
 
-            module = new JavaScriptParser(code, parserOptions).ParseModule();
+            module = new JavaScriptParser(parserOptions).ParseModule(code, source: resolved.Uri?.LocalPath!);
         }
         catch (ParserException ex)
         {

+ 4 - 4
Jint.Tests.Test262/Test262Test.cs

@@ -18,7 +18,7 @@ public abstract partial class Test262Test
             cfg.EnableModules(new Test262ModuleLoader(State.Test262Stream.Options.FileSystem, relativePath));
         });
 
-        if (file.Flags.Contains("raw"))
+        if (file.Flags.IndexOf("raw") != -1)
         {
             // nothing should be loaded
             return engine;
@@ -39,8 +39,8 @@ public abstract partial class Test262Test
                 }
 
                 var options = new ParserOptions { AdaptRegexp = true, Tolerant = false };
-                var parser = new JavaScriptParser(args.At(0).AsString(), options);
-                var script = parser.ParseScript();
+                var parser = new JavaScriptParser(options);
+                var script = parser.ParseScript(args.At(0).AsString());
 
                 return engine.Evaluate(script);
             }), true, true, true));
@@ -87,7 +87,7 @@ public abstract partial class Test262Test
         }
         else
         {
-            engine.Execute(new JavaScriptParser(file.Program, new ParserOptions(file.FileName)).ParseScript());
+            engine.Execute(new JavaScriptParser().ParseScript(file.Program, source: file.FileName));
         }
     }
 

+ 1 - 1
Jint.Tests.Test262/TestHarness.cs

@@ -12,7 +12,7 @@ public partial class TestHarness
         foreach (var file in State.HarnessFiles)
         {
             var source = file.Program;
-            State.Sources[Path.GetFileName(file.FileName)] = new JavaScriptParser(source, new ParserOptions(file.FileName)).ParseScript();
+            State.Sources[Path.GetFileName(file.FileName)] = new JavaScriptParser().ParseScript(source, source: file.FileName);
         }
 
         return Task.CompletedTask;

+ 15 - 15
Jint.Tests/Parser/JavascriptParserTests.cs

@@ -9,7 +9,7 @@ namespace Jint.Tests.Parser
         [Fact]
         public void ShouldParseThis()
         {
-            var program = new JavaScriptParser("this").ParseScript();
+            var program = new JavaScriptParser().ParseScript("this");
             var body = program.Body;
 
             Assert.Single(body);
@@ -19,7 +19,7 @@ namespace Jint.Tests.Parser
         [Fact]
         public void ShouldParseNull()
         {
-            var program = new JavaScriptParser("null").ParseScript();
+            var program = new JavaScriptParser().ParseScript("null");
             var body = program.Body;
 
             Assert.Single(body);
@@ -31,10 +31,10 @@ namespace Jint.Tests.Parser
         [Fact]
         public void ShouldParseNumeric()
         {
-            var program = new JavaScriptParser(
-                @"
+            var code = @"
                 42
-            ").ParseScript();
+            ";
+            var program = new JavaScriptParser().ParseScript(code);
             var body = program.Body;
 
             Assert.Single(body);
@@ -48,7 +48,7 @@ namespace Jint.Tests.Parser
         {
             BinaryExpression binary;
 
-            var program = new JavaScriptParser("(1 + 2 ) * 3").ParseScript();
+            var program = new JavaScriptParser().ParseScript("(1 + 2 ) * 3");
             var body = program.Body;
 
             Assert.Single(body);
@@ -80,11 +80,11 @@ namespace Jint.Tests.Parser
         [InlineData(10, "0012")]
         [InlineData(1.189008226412092e+38, "0x5973772948c653ac1971f1576e03c4d4")]
         [InlineData(18446744073709552000d, "0xffffffffffffffff")]
-        public void ShouldParseNumericLiterals(object expected, string source)
+        public void ShouldParseNumericLiterals(object expected, string code)
         {
             Literal literal;
 
-            var program = new JavaScriptParser(source).ParseScript();
+            var program = new JavaScriptParser().ParseScript(code);
             var body = program.Body;
 
             Assert.Single(body);
@@ -99,11 +99,11 @@ namespace Jint.Tests.Parser
         [InlineData("\x61", @"'\x61'")]
         [InlineData("Hello\nworld", @"'Hello\nworld'")]
         [InlineData("Hello\\\nworld", @"'Hello\\\nworld'")]
-        public void ShouldParseStringLiterals(string expected, string source)
+        public void ShouldParseStringLiterals(string expected, string code)
         {
             Literal literal;
 
-            var program = new JavaScriptParser(source).ParseScript();
+            var program = new JavaScriptParser().ParseScript(code);
             var body = program.Body;
 
             Assert.Single(body);
@@ -144,19 +144,19 @@ namespace Jint.Tests.Parser
         [InlineData(@"{ throw error/* Multiline
                       Comment */error; }")]
 
-        public void ShouldInsertSemicolons(string source)
+        public void ShouldInsertSemicolons(string code)
         {
-            new JavaScriptParser(source).ParseScript();
+            new JavaScriptParser().ParseScript(code);
         }
 
         [Fact]
         public void ShouldProvideLocationForMultiLinesStringLiterals()
         {
-            var source = @"'\
+            const string Code = @"'\
 \
 '
 ";
-            var program = new JavaScriptParser(source, new ParserOptions()).ParseScript();
+            var program = new JavaScriptParser(new ParserOptions()).ParseScript(Code);
             var expr = program.Body.First().As<ExpressionStatement>().Expression;
             Assert.Equal(1, expr.Location.Start.Line);
             Assert.Equal(0, expr.Location.Start.Column);
@@ -178,7 +178,7 @@ namespace Jint.Tests.Parser
         [InlineData("-.-")]
         public void ShouldThrowParserExceptionForInvalidCode(string code)
         {
-            Assert.Throws<ParserException>(() => new JavaScriptParser(code).ParseScript());
+            Assert.Throws<ParserException>(() => new JavaScriptParser().ParseScript(code));
         }
     }
 }

+ 3 - 3
Jint.Tests/Runtime/Debugger/BreakPointTests.cs

@@ -167,15 +167,15 @@ test(z);";
 
             // We need to specify the source to the parser.
             // And we need locations too (Jint specifies that in its default options)
-            engine.Execute(script1, new ParserOptions("script1"));
+            engine.Execute(script1, "script1");
             Assert.False(didBreak);
 
-            engine.Execute(script2, new ParserOptions("script2"));
+            engine.Execute(script2, "script2");
             Assert.False(didBreak);
 
             // Note that it's actually script3 that executes the function in script2
             // and triggers the breakpoint
-            engine.Execute(script3, new ParserOptions("script3"));
+            engine.Execute(script3, "script3");
             Assert.True(didBreak);
         }
 

+ 1 - 1
Jint.Tests/Runtime/EngineTests.cs

@@ -1044,7 +1044,7 @@ namespace Jint.Tests.Runtime
             var engine = new Engine();
             try
             {
-                engine.Evaluate("1.2+ new", new ParserOptions(source: "jQuery.js"));
+                engine.Evaluate("1.2+ new", "jQuery.js");
             }
             catch (ParserException e)
             {

+ 17 - 16
Jint.Tests/Runtime/ErrorTests.cs

@@ -65,9 +65,9 @@ var a = function(v) {
 var b = function(v) {
   return a(v);
 }
-            ", new ParserOptions("custom.js"));
+            ", "custom.js");
 
-            var e = Assert.Throws<JavaScriptException>(() => engine.Execute("var x = b(7);", new ParserOptions("main.js")));
+            var e = Assert.Throws<JavaScriptException>(() => engine.Execute("var x = b(7);", "main.js"));
             Assert.Equal("Cannot read property 'yyy' of undefined", e.Message);
             Assert.Equal(3, e.Location.Start.Line);
             Assert.Equal(15, e.Location.Start.Column);
@@ -92,9 +92,9 @@ var a = function(v) {
 var b = function(v) {
   return a(v);
 }
-            ", new ParserOptions("custom.js"));
+            ", "custom.js");
 
-            var e = Assert.Throws<JavaScriptException>(() => engine.Execute("var x = b(7);", new ParserOptions("main.js")));
+            var e = Assert.Throws<JavaScriptException>(() => engine.Execute("var x = b(7);", "main.js"));
             Assert.Equal("Error thrown from script", e.Message);
             Assert.Equal(3, e.Location.Start.Line);
             Assert.Equal(8, e.Location.Start.Column);
@@ -119,9 +119,9 @@ var a = function(v) {
 var b = function(v) {
   return a(v);
 }
-            ", new ParserOptions("custom.js"));
+            ", "custom.js");
 
-            var e = engine.Evaluate(@"b(7)", new ParserOptions("main.js")).AsString();
+            var e = engine.Evaluate(@"b(7)", "main.js").AsString();
 
             var stack = e;
             EqualIgnoringNewLineDifferences(@"   at a (v) custom.js:3:10
@@ -146,9 +146,9 @@ var a = function(v) {
 var b = function(v) {
   return a(v);
 }
-            ", new ParserOptions("custom.js"));
+            ", "custom.js");
 
-            var e = engine.Evaluate(@"b(7)", new ParserOptions("main.js")).AsString();
+            var e = engine.Evaluate(@"b(7)", "main.js").AsString();
 
             var stack = e;
             EqualIgnoringNewLineDifferences(@"   at a (v) custom.js:4:11
@@ -174,9 +174,9 @@ var a = function(v) {
 var b = function(v) {
   return a(v);
 }
-            ", new ParserOptions("custom.js"));
+            ", "custom.js");
 
-            var e = engine.Evaluate(@"b(7)", new ParserOptions("main.js")).AsString();
+            var e = engine.Evaluate(@"b(7)", "main.js").AsString();
 
             var stack = e;
             EqualIgnoringNewLineDifferences(@"   at a (v) custom.js:4:13
@@ -293,12 +293,12 @@ var x = b(7);";
     return item;
 })(getItem);";
 
-            var parserOptions = new ParserOptions("get-item.js")
+            var parserOptions = new ParserOptions
             {
                 AdaptRegexp = true,
                 Tolerant = true
             };
-            var ex = Assert.Throws<JavaScriptException>(() => engine.Execute(script, parserOptions));
+            var ex = Assert.Throws<JavaScriptException>(() => engine.Execute(script, "get-item.js", parserOptions));
 
             const string expected = @"Error: Cannot read property '5' of null
    at getItem (items, itemIndex) get-item.js:2:22
@@ -382,9 +382,9 @@ try {
         [Fact]
         public void CallStackWorksWithRecursiveCalls()
         {
-            static ParserOptions CreateParserOptions(string filePath)
+            static ParserOptions CreateParserOptions()
             {
-                return new ParserOptions(filePath)
+                return new ParserOptions
                 {
                     AdaptRegexp = true,
                     Tolerant = true
@@ -405,12 +405,13 @@ executeFile(""second-file.js"");",
 nuм -= 3;",
                         _ => throw new FileNotFoundException($"File '{path}' not exist.", path)
                     };
-                    engine.Execute(content, CreateParserOptions(path));
+                    engine.Execute(content, path, CreateParserOptions());
                 }));
                 engine.Execute(
                     @"var num = 5;
 executeFile(""first-file.js"");",
-                    CreateParserOptions("main-file.js")
+                    "main-file.js",
+                    CreateParserOptions()
                 );
             });
 

+ 2 - 2
Jint.Tests/Runtime/NullPropagation.cs

@@ -135,9 +135,9 @@ this.is_notnullfield_not_null = this.NotNullField !== null;
 this.has_emptyfield_not_null = this.EmptyField !== null;
 ";
 
-            var wrapperScript = string.Format(@"function ExecutePatchScript(docInner){{ (function(doc){{ {0} }}).apply(docInner); }};", script);
+            var wrapperScript = $@"function ExecutePatchScript(docInner){{ (function(doc){{ {script} }}).apply(docInner); }};";
 
-            engine.Execute(wrapperScript, new ParserOptions("main.js"));
+            engine.Execute(wrapperScript, "main.js");
 
             engine.Invoke("ExecutePatchScript", jsObject);
 

+ 30 - 14
Jint/Engine.cs

@@ -23,11 +23,7 @@ namespace Jint
 {
     public sealed partial class Engine : IDisposable
     {
-        private static readonly ParserOptions DefaultParserOptions = new("<anonymous>")
-        {
-            AdaptRegexp = true,
-            Tolerant = true
-        };
+        private readonly JavaScriptParser _defaultParser = new(ParserOptions.Default);
 
         private readonly ExecutionContextStack _executionContexts;
         private JsValue _completionValue = JsValue.Undefined;
@@ -242,22 +238,42 @@ namespace Jint
             CallStack.Clear();
         }
 
-        public JsValue Evaluate(string source)
-            => Evaluate(source, DefaultParserOptions);
+        public JsValue Evaluate(string code)
+            => Evaluate(code, "<anonymous>", ParserOptions.Default);
+
+        public JsValue Evaluate(string code, string source)
+            => Evaluate(code, source, ParserOptions.Default);
+
+        public JsValue Evaluate(string code, ParserOptions parserOptions)
+            => Evaluate(code, "<anonymous>", parserOptions);
+
+        public JsValue Evaluate(string code, string source, ParserOptions parserOptions)
+        {
+            var parser = ReferenceEquals(ParserOptions.Default, parserOptions)
+                ? _defaultParser
+                : new JavaScriptParser(parserOptions);
 
-        public JsValue Evaluate(string source, ParserOptions parserOptions)
-            => Evaluate(new JavaScriptParser(source, parserOptions).ParseScript());
+            var script = parser.ParseScript(code, source);
+
+            return Evaluate(script);
+        }
 
         public JsValue Evaluate(Script script)
             => Execute(script)._completionValue;
 
-        public Engine Execute(string source)
-            => Execute(source, DefaultParserOptions);
+        public Engine Execute(string code, string? source = null)
+            => Execute(code, source ?? "<anonymous>", ParserOptions.Default);
 
-        public Engine Execute(string source, ParserOptions parserOptions)
+        public Engine Execute(string code, ParserOptions parserOptions)
+            => Execute(code, "<anonymous>", parserOptions);
+
+        public Engine Execute(string code, string source, ParserOptions parserOptions)
         {
-            var parser = new JavaScriptParser(source, parserOptions);
-            var script = parser.ParseScript();
+            var parser = ReferenceEquals(ParserOptions.Default, parserOptions)
+                ? _defaultParser
+                : new JavaScriptParser(parserOptions);
+
+            var script = parser.ParseScript(code, source);
 
             return Execute(script);
         }

+ 1 - 1
Jint/Jint.csproj

@@ -11,7 +11,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Esprima" Version="3.0.0-beta-5" />
+    <PackageReference Include="Esprima" Version="3.0.0-beta-6" />
     <PackageReference Include="IsExternalInit" Version="1.0.2" PrivateAssets="all" />
     <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="all" />
     <PackageReference Include="Nullable" Version="1.3.0" PrivateAssets="all" />

+ 4 - 4
Jint/ModuleBuilder.cs

@@ -19,7 +19,7 @@ public sealed class ModuleBuilder
     {
         _engine = engine;
         _specifier = specifier;
-        _options = new ParserOptions(specifier);
+        _options = new ParserOptions();
     }
 
     public ModuleBuilder AddSource(string code)
@@ -109,11 +109,11 @@ public sealed class ModuleBuilder
             return new Module(NodeList.Create(Array.Empty<Statement>()));
         }
 
-        var javaScriptParser = new JavaScriptParser(_sourceRaw.Count == 1 ? _sourceRaw[0] : string.Join(Environment.NewLine, _sourceRaw), _options);
-
+        var javaScriptParser = new JavaScriptParser(_options);
         try
         {
-            return javaScriptParser.ParseModule();
+            var source = _sourceRaw.Count == 1 ? _sourceRaw[0] : string.Join(Environment.NewLine, _sourceRaw);
+            return javaScriptParser.ParseModule(source, _specifier);
         }
         catch (ParserException ex)
         {

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

@@ -23,8 +23,7 @@ namespace Jint.Native.Function
             // generate missing constructor AST only once
             static MethodDefinition CreateConstructorMethodDefinition(string source)
             {
-                var parser = new JavaScriptParser(source);
-                var script = parser.ParseScript();
+                var script = new JavaScriptParser().ParseScript(source);
                 var classDeclaration = (ClassDeclaration) script.Body[0];
                 return (MethodDefinition) classDeclaration.Body.Body[0];
             }

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

@@ -9,8 +9,9 @@ namespace Jint.Native.Function
 {
     public sealed class EvalFunctionInstance : FunctionInstance
     {
-        private static readonly ParserOptions ParserOptions = new ParserOptions { Tolerant = false };
-        private static readonly JsString _functionName = new JsString("eval");
+        private static readonly JsString _functionName = new("eval");
+
+        private readonly JavaScriptParser _parser = new(new ParserOptions { Tolerant = false });
 
         public EvalFunctionInstance(
             Engine engine,
@@ -66,11 +67,10 @@ namespace Jint.Native.Function
                 }
             }
 
-            var parser = new JavaScriptParser(x.ToString(), ParserOptions);
             Script? script = null;
             try
             {
-                script = parser.ParseScript(strictCaller);
+                script = _parser.ParseScript(x.ToString(), strict: strictCaller);
             }
             catch (ParserException e)
             {

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

@@ -13,10 +13,11 @@ namespace Jint.Native.Function
     /// </summary>
     public sealed class FunctionConstructor : FunctionInstance, IConstructor
     {
-        private static readonly ParserOptions ParserOptions = new ParserOptions { Tolerant = false };
         private static readonly JsString _functionName = new JsString("Function");
         private static readonly JsString _functionNameAnonymous = new JsString("anonymous");
 
+        private readonly JavaScriptParser _parser = new(new ParserOptions { Tolerant = false });
+
         internal FunctionConstructor(
             Engine engine,
             Realm realm,
@@ -174,8 +175,7 @@ namespace Jint.Native.Function
                     }
                 }
 
-                var parser = new JavaScriptParser(functionExpression, ParserOptions);
-                function = (IFunction) parser.ParseScript().Body[0];
+                function = (IFunction) _parser.ParseScript(functionExpression).Body[0];
             }
             catch (ParserException ex)
             {

+ 2 - 5
Jint/Native/ShadowRealm/ShadowRealmInstance.cs

@@ -17,8 +17,7 @@ namespace Jint.Native.ShadowRealm;
 /// </summary>
 public sealed class ShadowRealmInstance : ObjectInstance
 {
-    private static readonly ParserOptions ParserOptions = new() { Tolerant = false };
-
+    private readonly JavaScriptParser _parser = new(new ParserOptions { Tolerant = false });
     internal readonly Realm _shadowRealm;
     internal readonly ExecutionContext _executionContext;
 
@@ -49,12 +48,10 @@ public sealed class ShadowRealmInstance : ObjectInstance
 
         _engine._host.EnsureCanCompileStrings(callerRealm, evalRealm);
 
-        var parser = new JavaScriptParser(sourceText, ParserOptions);
-
         Script script;
         try
         {
-            script = parser.ParseScript();
+            script = _parser.ParseScript(sourceText);
         }
         catch (ParserException e)
         {

+ 3 - 3
Jint/Runtime/Debugger/DebugHandler.cs

@@ -110,11 +110,11 @@ namespace Jint.Runtime.Debugger
         /// <inheritdoc cref="Evaluate(Script)" />
         public JsValue Evaluate(string source, ParserOptions? options = null)
         {
-            options ??= new ParserOptions("evaluation");
-            var parser = new JavaScriptParser(source, options);
+            options ??= new ParserOptions();
+            var parser = new JavaScriptParser(options);
             try
             {
-                var script = parser.ParseScript();
+                var script = parser.ParseScript(source, "evaluation");
                 return Evaluate(script);
             }
             catch (ParserException ex)

+ 1 - 2
Jint/Runtime/Modules/DefaultModuleLoader.cs

@@ -128,8 +128,7 @@ public sealed class DefaultModuleLoader : IModuleLoader
         Module module;
         try
         {
-            var parserOptions = new ParserOptions(resolved.Uri.LocalPath);
-            module = new JavaScriptParser(code, parserOptions).ParseModule();
+            module = new JavaScriptParser().ParseModule(code, source: resolved.Uri.LocalPath);
         }
         catch (ParserException ex)
         {