Răsfoiți Sursa

Latest Esprima beta changes (#595)

* Update to latest beta of Esprima

* Replace body with a valid statement

* Add ref to structs and in to readonly structs
Sam Lord 6 ani în urmă
părinte
comite
7b485ec8e0
36 a modificat fișierele cu 117 adăugiri și 130 ștergeri
  1. 1 0
      Jint.Benchmark/Jint.Benchmark.csproj
  2. 1 10
      Jint.Tests/Parser/JavascriptParserTests.cs
  3. 1 1
      Jint.Tests/Runtime/EngineTests.cs
  4. 13 9
      Jint/Engine.cs
  5. 1 1
      Jint/Jint.csproj
  6. 2 2
      Jint/Native/Function/EvalFunctionInstance.cs
  7. 2 2
      Jint/Native/Function/ScriptFunctionInstance.cs
  8. 1 1
      Jint/Native/JsValue.cs
  9. 30 52
      Jint/Native/Json/JsonParser.cs
  10. 1 1
      Jint/Runtime/Completion.cs
  11. 1 1
      Jint/Runtime/Debugger/DebugHandler.cs
  12. 1 1
      Jint/Runtime/Environments/DeclarativeEnvironmentRecord.cs
  13. 1 1
      Jint/Runtime/Interpreter/Expressions/BindingPatternAssignmentExpression.cs
  14. 3 3
      Jint/Runtime/Interpreter/Expressions/JintExpression.cs
  15. 12 1
      Jint/Runtime/Interpreter/JintFunctionDefinition.cs
  16. 8 7
      Jint/Runtime/Interpreter/JintStatementList.cs
  17. 0 2
      Jint/Runtime/Interpreter/Statements/JintBlockStatement.cs
  18. 1 1
      Jint/Runtime/Interpreter/Statements/JintBreakStatement.cs
  19. 2 1
      Jint/Runtime/Interpreter/Statements/JintContinueStatement.cs
  20. 1 1
      Jint/Runtime/Interpreter/Statements/JintDebuggerStatement.cs
  21. 2 2
      Jint/Runtime/Interpreter/Statements/JintDoWhileStatement.cs
  22. 1 1
      Jint/Runtime/Interpreter/Statements/JintEmptyStatement.cs
  23. 1 1
      Jint/Runtime/Interpreter/Statements/JintExpressionStatement.cs
  24. 3 3
      Jint/Runtime/Interpreter/Statements/JintForInStatement.cs
  25. 2 2
      Jint/Runtime/Interpreter/Statements/JintForStatement.cs
  26. 1 1
      Jint/Runtime/Interpreter/Statements/JintFunctionDeclarationStatement.cs
  27. 1 1
      Jint/Runtime/Interpreter/Statements/JintIfStatement.cs
  28. 1 1
      Jint/Runtime/Interpreter/Statements/JintLabeledStatement.cs
  29. 1 1
      Jint/Runtime/Interpreter/Statements/JintReturnStatement.cs
  30. 1 1
      Jint/Runtime/Interpreter/Statements/JintStatement.cs
  31. 8 7
      Jint/Runtime/Interpreter/Statements/JintSwitchBlock.cs
  32. 2 2
      Jint/Runtime/Interpreter/Statements/JintSwitchStatement.cs
  33. 1 1
      Jint/Runtime/Interpreter/Statements/JintVariableDeclaration.cs
  34. 2 2
      Jint/Runtime/Interpreter/Statements/JintWhileStatement.cs
  35. 5 4
      Jint/Runtime/JavaScriptException.cs
  36. 2 2
      Jint/Runtime/TypeConverter.cs

+ 1 - 0
Jint.Benchmark/Jint.Benchmark.csproj

@@ -22,6 +22,7 @@
     <PackageReference Include="BenchmarkDotNet" Version="0.11.2" />
     <ProjectReference Include="..\Jint\Jint.csproj" />
     <PackageReference Include="Jurassic" Version="3.0.0-alpha2" />
+    <PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
     <PackageReference Include="NiL.JS.NetCore" Version="2.5.1200" />
   </ItemGroup>
 </Project>

+ 1 - 10
Jint.Tests/Parser/JavascriptParserTests.cs

@@ -32,7 +32,6 @@ namespace Jint.Tests.Parser
             var program = new JavaScriptParser("this").ParseProgram();
             var body = program.Body;
 
-            Assert.NotNull(body);
             Assert.Single(body);
             Assert.Equal(Nodes.ThisExpression, body.First().As<ExpressionStatement>().Expression.Type);
         }
@@ -43,7 +42,6 @@ namespace Jint.Tests.Parser
             var program = new JavaScriptParser("null").ParseProgram();
             var body = program.Body;
 
-            Assert.NotNull(body);
             Assert.Single(body);
             Assert.Equal(Nodes.Literal, body.First().As<ExpressionStatement>().Expression.Type);
             Assert.Equal(null, body.First().As<ExpressionStatement>().Expression.As<Literal>().Value);
@@ -59,7 +57,6 @@ namespace Jint.Tests.Parser
             ").ParseProgram();
             var body = program.Body;
 
-            Assert.NotNull(body);
             Assert.Single(body);
             Assert.Equal(Nodes.Literal, body.First().As<ExpressionStatement>().Expression.Type);
             Assert.Equal(42d, body.First().As<ExpressionStatement>().Expression.As<Literal>().Value);
@@ -74,7 +71,6 @@ namespace Jint.Tests.Parser
             var program = new JavaScriptParser("(1 + 2 ) * 3").ParseProgram();
             var body = program.Body;
 
-            Assert.NotNull(body);
             Assert.Single(body);
             Assert.NotNull(binary = body.First().As<ExpressionStatement>().Expression.As<BinaryExpression>());
             Assert.Equal(3d, binary.Right.As<Literal>().Value);
@@ -111,7 +107,6 @@ namespace Jint.Tests.Parser
             var program = new JavaScriptParser(source).ParseProgram();
             var body = program.Body;
 
-            Assert.NotNull(body);
             Assert.Single(body);
             Assert.NotNull(literal = body.First().As<ExpressionStatement>().Expression.As<Literal>());
             Assert.Equal(Convert.ToDouble(expected), Convert.ToDouble(literal.Value));
@@ -131,7 +126,6 @@ namespace Jint.Tests.Parser
             var program = new JavaScriptParser(source).ParseProgram();
             var body = program.Body;
 
-            Assert.NotNull(body);
             Assert.Single(body);
             Assert.NotNull(literal = body.First().As<ExpressionStatement>().Expression.As<Literal>());
             Assert.Equal(expected, literal.Value);
@@ -172,10 +166,7 @@ namespace Jint.Tests.Parser
 
         public void ShouldInsertSemicolons(string source)
         {
-            var program = new JavaScriptParser(source).ParseProgram();
-            var body = program.Body;
-
-            Assert.NotNull(body);
+            new JavaScriptParser(source).ParseProgram();
         }
 
         [Fact]

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

@@ -1127,7 +1127,7 @@ namespace Jint.Tests.Runtime
             {
                 Assert.Equal(1, e.LineNumber);
                 Assert.Equal(9, e.Column);
-                Assert.Equal("jQuery.js", e.Source);
+                Assert.Equal("jQuery.js", e.SourceText);
             }
         }
         #region DateParsingAndStrings

+ 13 - 9
Jint/Engine.cs

@@ -255,7 +255,7 @@ namespace Jint
             }
 
             ClrTypeConverter = new DefaultTypeConverter(this);
-            BreakPoints = new List<BreakPoint>();
+            BreakPoints = new System.Collections.Generic.List<BreakPoint>();
             DebugHandler = new DebugHandler(this);
         }
 
@@ -301,7 +301,7 @@ namespace Jint
         public event DebugStepDelegate Step;
         public event BreakDelegate Break;
         internal DebugHandler DebugHandler { get; private set; }
-        public List<BreakPoint> BreakPoints { get; private set; }
+        public System.Collections.Generic.List<BreakPoint> BreakPoints { get; private set; }
 
         internal StepMode? InvokeStepEvent(DebugInformation info)
         {
@@ -429,8 +429,8 @@ namespace Jint
             {
                 DeclarationBindingInstantiation(
                     DeclarationBindingType.GlobalCode,
-                    program.HoistingScope.FunctionDeclarations,
-                    program.HoistingScope.VariableDeclarations,
+                    ref program.HoistingScope.FunctionDeclarations,
+                    ref program.HoistingScope.VariableDeclarations,
                     functionInstance: null,
                     arguments: null);
 
@@ -762,8 +762,8 @@ namespace Jint
         //  http://www.ecma-international.org/ecma-262/5.1/#sec-10.5
         internal bool DeclarationBindingInstantiation(
             DeclarationBindingType declarationBindingType,
-            List<FunctionDeclaration> functionDeclarations,
-            List<VariableDeclaration> variableDeclarations,
+            ref Esprima.Ast.List<FunctionDeclaration> functionDeclarations,
+            ref Esprima.Ast.List<VariableDeclaration> variableDeclarations,
             FunctionInstance functionInstance,
             JsValue[] arguments)
         {
@@ -808,7 +808,7 @@ namespace Jint
 
             if (functionDeclarations.Count > 0)
             {
-                AddFunctionDeclarations(functionDeclarations, env, configurableBindings, strict);
+                AddFunctionDeclarations(ref functionDeclarations, env, configurableBindings, strict);
             }
 
             if (variableDeclarations.Count == 0)
@@ -819,7 +819,7 @@ namespace Jint
             // process all variable declarations in the current parser scope
             if (!ReferenceEquals(der, null))
             {
-                der.AddVariableDeclarations(variableDeclarations);
+                der.AddVariableDeclarations(ref variableDeclarations);
             }
             else
             {
@@ -847,7 +847,11 @@ namespace Jint
             return canReleaseArgumentsInstance;
         }
 
-        private void AddFunctionDeclarations(List<FunctionDeclaration> functionDeclarations, EnvironmentRecord env, bool configurableBindings, bool strict)
+        private void AddFunctionDeclarations(
+            ref Esprima.Ast.List<FunctionDeclaration> functionDeclarations,
+            EnvironmentRecord env,
+            bool configurableBindings,
+            bool strict)
         {
             var functionDeclarationsCount = functionDeclarations.Count;
             for (var i = 0; i < functionDeclarationsCount; i++)

+ 1 - 1
Jint/Jint.csproj

@@ -7,6 +7,6 @@
     <LangVersion>latest</LangVersion>
   </PropertyGroup>
   <ItemGroup>
-    <PackageReference Include="Esprima" Version="1.0.0-beta-1070" />
+    <PackageReference Include="Esprima" Version="1.0.0-beta-1178" />
   </ItemGroup>
 </Project>

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

@@ -58,8 +58,8 @@ namespace Jint.Native.Function
 
                             bool argumentInstanceRented = Engine.DeclarationBindingInstantiation(
                                 DeclarationBindingType.EvalCode,
-                                program.HoistingScope.FunctionDeclarations,
-                                program.HoistingScope.VariableDeclarations,
+                                ref program.HoistingScope.FunctionDeclarations,
+                                ref program.HoistingScope.VariableDeclarations,
                                 functionInstance: this, 
                                 arguments);
 

+ 2 - 2
Jint/Native/Function/ScriptFunctionInstance.cs

@@ -98,8 +98,8 @@ namespace Jint.Native.Function
                 {
                     var argumentInstanceRented = _engine.DeclarationBindingInstantiation(
                         DeclarationBindingType.FunctionCode,
-                        _function._hoistingScope.FunctionDeclarations,
-                        _function._hoistingScope.VariableDeclarations,
+                        ref _function._hoistingScope.FunctionDeclarations,
+                        ref _function._hoistingScope.VariableDeclarations,
                         functionInstance: this,
                         arguments);
 

+ 1 - 1
Jint/Native/JsValue.cs

@@ -222,7 +222,7 @@ namespace Jint.Native
             }
 
             // TODO not implemented
-            return new Completion(CompletionType.Normal, Native.Undefined.Instance, null);
+            return new Completion(CompletionType.Normal, Native.Undefined.Instance, null, default);
         }
 
         [Pure]

+ 30 - 52
Jint/Native/Json/JsonParser.cs

@@ -484,21 +484,17 @@ namespace Jint.Native.Json
 
         private Token CollectToken()
         {
-            _location = new Location
-                {
-                    Start = new Position
-                        {
-                            Line = _lineNumber,
-                            Column = _index - _lineStart
-                        }
-                };
+            var start = new Position(
+                line: _lineNumber,
+                column: _index - _lineStart);
 
             Token token = Advance();
-            _location.End = new Position
-                {
-                    Line = _lineNumber,
-                    Column = _index - _lineStart
-                };
+
+            var end = new Position(
+                line: _lineNumber,
+                column: _index - _lineStart);
+
+            _location = new Location(start, end, _source);
 
             if (token.Type != Tokens.EOF)
             {
@@ -559,23 +555,18 @@ namespace Jint.Native.Json
         {
             if (_extra.Range != null)
             {
-                node.Range = new int[] {_state.MarkerStack.Pop(), _index};
+                node.Range = new Range(_state.MarkerStack.Pop(), _index);
             }
             if (_extra.Loc.HasValue)
             {
-                node.Location = new Location
-                    {
-                        Start = new Position
-                            {
-                                Line = _state.MarkerStack.Pop(),
-                                Column = _state.MarkerStack.Pop()
-                            },
-                        End = new Position
-                            {
-                                Line = _lineNumber,
-                                Column = _index - _lineStart
-                            }
-                    };
+                node.Location = new Location(
+                    start: new Position(
+                        line: _state.MarkerStack.Pop(),
+                        column: _state.MarkerStack.Pop()),
+                    end: new Position(
+                        line: _lineNumber,
+                        column: _index - _lineStart),
+                    source: _source);
                 PostProcess(node);
             }
             return node;
@@ -624,29 +615,16 @@ namespace Jint.Native.Json
 
         private void ThrowError(Token token, string messageFormat, params object[] arguments)
         {
-            ParserException exception;
             string msg = System.String.Format(messageFormat, arguments);
-
-            if (token.LineNumber.HasValue)
-            {
-                exception = new ParserException("Line " + token.LineNumber + ": " + msg)
-                    {
-                        Index = token.Range[0],
-                        LineNumber = token.LineNumber.Value,
-                        Column = token.Range[0] - _lineStart + 1
-                    };
-            }
-            else
-            {
-                exception = new ParserException("Line " + _lineNumber + ": " + msg)
-                    {
-                        Index = _index,
-                        LineNumber = _lineNumber,
-                        Column = _index - _lineStart + 1
-                    };
-            }
-
-            exception.Description = msg;
+            int lineNumber = token.LineNumber ?? _lineNumber;
+
+            var error = new ParseError(
+                    description: msg,
+                    source: _source,
+                    index: token.Range[0],
+                    position: new Position(token.LineNumber ?? _lineNumber, token.Range[0] - _lineStart + 1));
+            var exception = new ParserException("Line " + lineNumber  + ": " + msg, error);
+            
             throw exception;
         }
 
@@ -694,7 +672,7 @@ namespace Jint.Native.Json
 
         private ObjectInstance ParseJsonArray()
         {
-            var elements = new List<JsValue>();
+            var elements = new System.Collections.Generic.List<JsValue>();
 
             Expect("[");
 
@@ -848,7 +826,7 @@ namespace Jint.Native.Json
             {
                 if (options.Tokens)
                 {
-                    _extra.Tokens = new List<Token>();
+                    _extra.Tokens = new System.Collections.Generic.List<Token>();
                 }
 
             }
@@ -879,7 +857,7 @@ namespace Jint.Native.Json
             public int? Loc;
             public int[] Range;
 
-            public List<Token> Tokens;
+            public System.Collections.Generic.List<Token> Tokens;
         }
 
         private enum Tokens

+ 1 - 1
Jint/Runtime/Completion.cs

@@ -18,7 +18,7 @@ namespace Jint.Runtime
     /// </summary>
     public readonly struct Completion
     {
-        public Completion(CompletionType type, JsValue value, string identifier, Location location = null)
+        public Completion(CompletionType type, JsValue value, string identifier, Location location)
         {
             Type = type;
             Value = value;

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

@@ -44,7 +44,7 @@ namespace Jint.Runtime.Debugger
             if (identifier != null)
             {
                 var stack = identifier.Name + "(";
-                var paramStrings = new List<string>();
+                var paramStrings = new System.Collections.Generic.List<string>();
 
                 foreach (var argument in callExpression.Arguments)
                 {

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

@@ -384,7 +384,7 @@ using Jint.Native.Function;
             return defaultValue;
         }
 
-        internal void AddVariableDeclarations(List<VariableDeclaration> variableDeclarations)
+        internal void AddVariableDeclarations(ref Esprima.Ast.List<VariableDeclaration> variableDeclarations)
         {
             var variableDeclarationsCount = variableDeclarations.Count;
             for (var i = 0; i < variableDeclarationsCount; i++)

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

@@ -111,7 +111,7 @@ namespace Jint.Runtime.Interpreter.Expressions
                     }
                     ProcessPatterns(engine, bindingPattern, value);
                 }
-                else if (left is ArrayPatternElement arrayPatternElement)
+                else if (left is IArrayPatternElement arrayPatternElement)
                 {
                     if (arrayPatternElement is RestElement restElement)
                     {

+ 3 - 3
Jint/Runtime/Interpreter/Expressions/JintExpression.cs

@@ -344,7 +344,7 @@ namespace Jint.Runtime.Interpreter.Expressions
 
         protected JsValue[] BuildArgumentsWithSpreads(JintExpression[] jintExpressions)
         {
-            var args = new List<JsValue>(jintExpressions.Length);
+            var args = new System.Collections.Generic.List<JsValue>(jintExpressions.Length);
             for (var i = 0; i < jintExpressions.Length; i++)
             {
                 var jintExpression = jintExpressions[i];
@@ -380,11 +380,11 @@ namespace Jint.Runtime.Interpreter.Expressions
 
         private sealed class ArraySpreadProtocol : IteratorProtocol
         {
-            private readonly List<JsValue> _instance;
+            private readonly System.Collections.Generic.List<JsValue> _instance;
 
             public ArraySpreadProtocol(
                 Engine engine,
-                List<JsValue> instance,
+                System.Collections.Generic.List<JsValue> instance,
                 IIterator iterator) : base(engine, iterator, 0)
             {
                 _instance = instance;

+ 12 - 1
Jint/Runtime/Interpreter/JintFunctionDefinition.cs

@@ -22,7 +22,18 @@ namespace Jint.Runtime.Interpreter
             _name = !string.IsNullOrEmpty(function.Id?.Name) ? function.Id.Name : null;
             _strict = function.Strict;
             _parameterNames = GetParameterNames(function);
-            _body = JintStatement.Build(engine, function.Body);
+
+            Statement bodyStatement;
+            if (function.Expression)
+            {
+                bodyStatement = new ReturnStatement((Expression) function.Body);
+            }
+            else
+            {
+                bodyStatement = (BlockStatement) function.Body;
+            }
+
+            _body = JintStatement.Build(engine, bodyStatement);
         }
 
         private string[] GetParameterNames(IFunction functionDeclaration)

+ 8 - 7
Jint/Runtime/Interpreter/JintStatementList.cs

@@ -15,12 +15,12 @@ namespace Jint.Runtime.Interpreter
 
         private readonly Engine _engine;
         private readonly Statement _statement;
-        private readonly List<StatementListItem> _statements;
+        private readonly Esprima.Ast.List<StatementListItem> _statements;
 
         private Pair[] _jintStatements;
         private bool _initialized;
 
-        public JintStatementList(Engine engine, Statement statement, List<StatementListItem> statements)
+        public JintStatementList(Engine engine, Statement statement, Esprima.Ast.List<StatementListItem> statements)
         {
             _engine = engine;
             _statement = statement;
@@ -59,7 +59,7 @@ namespace Jint.Runtime.Interpreter
             }
 
             JintStatement s = null;
-            var c = new Completion(CompletionType.Normal, null, null);
+            var c = new Completion(CompletionType.Normal, null, null, _engine._lastSyntaxNode?.Location ?? default);
             Completion sl = c;
             try
             {
@@ -85,7 +85,8 @@ namespace Jint.Runtime.Interpreter
             }
             catch (JavaScriptException v)
             {
-                var completion = new Completion(CompletionType.Throw, v.Error, null, v.Location ?? s?.Location);
+                var location = v.Location == default ? s.Location : v.Location;
+                var completion = new Completion(CompletionType.Throw, v.Error, null, location);
                 return completion;
             }
             catch (TypeErrorException e)
@@ -94,7 +95,7 @@ namespace Jint.Runtime.Interpreter
                 {
                     e.Message
                 });
-                return new Completion(CompletionType.Throw, error, null, s?.Location);
+                return new Completion(CompletionType.Throw, error, null, s.Location);
             }
             catch (RangeErrorException e)
             {
@@ -102,9 +103,9 @@ namespace Jint.Runtime.Interpreter
                 {
                     e.Message
                 });
-                c = new Completion(CompletionType.Throw, error, null, s?.Location);
+                c = new Completion(CompletionType.Throw, error, null, s.Location);
             }
-            return new Completion(c.Type, c.GetValueOrDefault(), c.Identifier);
+            return new Completion(c.Type, c.GetValueOrDefault(), c.Identifier, c.Location);
         }
 
         internal Completion? FastResolve()

+ 0 - 2
Jint/Runtime/Interpreter/Statements/JintBlockStatement.cs

@@ -16,7 +16,5 @@ namespace Jint.Runtime.Interpreter.Statements
         {
             return _statementList.Execute();
         }
-
-        public override Location Location => null;
     }
 }

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

@@ -16,7 +16,7 @@ namespace Jint.Runtime.Interpreter.Statements
 
         protected override Completion ExecuteInternal()
         {
-            return new Completion(CompletionType.Break, null, _label);
+            return new Completion(CompletionType.Break, null, _label, Location);
         }
     }
 }

+ 2 - 1
Jint/Runtime/Interpreter/Statements/JintContinueStatement.cs

@@ -1,3 +1,4 @@
+using Esprima;
 using Esprima.Ast;
 
 namespace Jint.Runtime.Interpreter.Statements
@@ -16,7 +17,7 @@ namespace Jint.Runtime.Interpreter.Statements
 
         protected override Completion ExecuteInternal()
         {
-            return new Completion(CompletionType.Continue, null, _labelName);
+            return new Completion(CompletionType.Continue, null, _labelName, Location);
         }
     }
 }

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

@@ -20,7 +20,7 @@ namespace Jint.Runtime.Interpreter.Statements
                 System.Diagnostics.Debugger.Break();
             }
 
-            return new Completion(CompletionType.Normal, null, null);
+            return new Completion(CompletionType.Normal, null, null, Location);
         }
     }
 }

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

@@ -37,7 +37,7 @@ namespace Jint.Runtime.Interpreter.Statements
                 {
                     if (completion.Type == CompletionType.Break && (completion.Identifier == null || completion.Identifier == _labelSetName))
                     {
-                        return new Completion(CompletionType.Normal, v, null);
+                        return new Completion(CompletionType.Normal, v, null, Location);
                     }
 
                     if (completion.Type != CompletionType.Normal)
@@ -49,7 +49,7 @@ namespace Jint.Runtime.Interpreter.Statements
                 iterating = TypeConverter.ToBoolean(_test.GetValue());
             } while (iterating);
 
-            return new Completion(CompletionType.Normal, v, null);
+            return new Completion(CompletionType.Normal, v, null, Location);
         }
     }
 }

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

@@ -10,7 +10,7 @@ namespace Jint.Runtime.Interpreter.Statements
 
         protected override Completion ExecuteInternal()
         {
-            return new Completion(CompletionType.Normal, null, null);
+            return new Completion(CompletionType.Normal, null, null, Location);
         }
     }
 }

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

@@ -15,7 +15,7 @@ namespace Jint.Runtime.Interpreter.Statements
         protected override Completion ExecuteInternal()
         {
             var value = _expression.GetValue();
-            return new Completion(CompletionType.Normal, value, null);
+            return new Completion(CompletionType.Normal, value, null, Location);
         }
     }
 }

+ 3 - 3
Jint/Runtime/Interpreter/Statements/JintForInStatement.cs

@@ -41,7 +41,7 @@ namespace Jint.Runtime.Interpreter.Statements
             var experValue = _right.GetValue();
             if (experValue.IsNullOrUndefined())
             {
-                return new Completion(CompletionType.Normal, null, null);
+                return new Completion(CompletionType.Normal, null, null, Location);
             }
 
             var obj = TypeConverter.ToObject(_engine, experValue);
@@ -89,7 +89,7 @@ namespace Jint.Runtime.Interpreter.Statements
 
                     if (stmt.Type == CompletionType.Break)
                     {
-                        return new Completion(CompletionType.Normal, v, null);
+                        return new Completion(CompletionType.Normal, v, null, Location);
                     }
 
                     if (stmt.Type != CompletionType.Continue)
@@ -104,7 +104,7 @@ namespace Jint.Runtime.Interpreter.Statements
                 cursor = cursor.Prototype;
             }
 
-            return new Completion(CompletionType.Normal, v, null);
+            return new Completion(CompletionType.Normal, v, null, Location);
         }
     }
 }

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

@@ -54,7 +54,7 @@ namespace Jint.Runtime.Interpreter.Statements
                 {
                     if (!TypeConverter.ToBoolean(_test.GetValue()))
                     {
-                        return new Completion(CompletionType.Normal, v, null);
+                        return new Completion(CompletionType.Normal, v, null, Location);
                     }
                 }
 
@@ -67,7 +67,7 @@ namespace Jint.Runtime.Interpreter.Statements
                 var stmtType = stmt.Type;
                 if (stmtType == CompletionType.Break && (stmt.Identifier == null || stmt.Identifier == _statement?.LabelSet?.Name))
                 {
-                    return new Completion(CompletionType.Normal, stmt.Value, null);
+                    return new Completion(CompletionType.Normal, stmt.Value, null, Location);
                 }
 
                 if (stmtType != CompletionType.Continue || ((stmt.Identifier != null) && stmt.Identifier != _statement?.LabelSet?.Name))

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

@@ -10,7 +10,7 @@ namespace Jint.Runtime.Interpreter.Statements
 
         protected override Completion ExecuteInternal()
         {
-            return new Completion(CompletionType.Normal, null, null);
+            return new Completion(CompletionType.Normal, null, null, Location);
         }
     }
 }

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

@@ -29,7 +29,7 @@ namespace Jint.Runtime.Interpreter.Statements
             }
             else
             {
-                return new Completion(CompletionType.Normal, null, null);
+                return new Completion(CompletionType.Normal, null, null, Location);
             }
 
             return result;

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

@@ -22,7 +22,7 @@ namespace Jint.Runtime.Interpreter.Statements
             if (result.Type == CompletionType.Break && result.Identifier == _labelName)
             {
                 var value = result.Value;
-                return new Completion(CompletionType.Normal, value, null);
+                return new Completion(CompletionType.Normal, value, null, Location);
             }
 
             return result;

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

@@ -21,7 +21,7 @@ namespace Jint.Runtime.Interpreter.Statements
         protected override Completion ExecuteInternal()
         {
             var jsValue = _argument?.GetValue() ?? Undefined.Instance;
-            return new Completion(CompletionType.Return, jsValue, null);
+            return new Completion(CompletionType.Return, jsValue, null, Location);
         }
     }
 }

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

@@ -131,7 +131,7 @@ namespace Jint.Runtime.Interpreter.Statements
                 var jsValue = JintLiteralExpression.ConvertToJsValue(l);
                 if (jsValue != null)
                 {
-                    return new Completion(CompletionType.Return, jsValue, null);
+                    return new Completion(CompletionType.Return, jsValue, null, rs.Location);
                 }
             }
 

+ 8 - 7
Jint/Runtime/Interpreter/Statements/JintSwitchBlock.cs

@@ -1,4 +1,5 @@
 using System.Collections.Generic;
+using Esprima;
 using Esprima.Ast;
 using Jint.Native;
 using Jint.Runtime.Interpreter.Expressions;
@@ -8,11 +9,11 @@ namespace Jint.Runtime.Interpreter.Statements
     internal sealed class JintSwitchBlock
     {
         private readonly Engine _engine;
-        private readonly List<SwitchCase> _switchBlock;
+        private readonly Esprima.Ast.List<SwitchCase> _switchBlock;
         private JintSwitchCase[] _jintSwitchBlock;
         private bool _initialized;
 
-        public JintSwitchBlock(Engine engine, List<SwitchCase> switchBlock)
+        public JintSwitchBlock(Engine engine, in Esprima.Ast.List<SwitchCase> switchBlock)
         {
             _engine = engine;
             _switchBlock = switchBlock;
@@ -36,6 +37,7 @@ namespace Jint.Runtime.Interpreter.Statements
             }
 
             JsValue v = Undefined.Instance;
+            Location l = _engine._lastSyntaxNode.Location;
             JintSwitchCase defaultCase = null;
             bool hit = false;
 
@@ -63,6 +65,7 @@ namespace Jint.Runtime.Interpreter.Statements
                         return r;
                     }
 
+                    l = r.Location;
                     v = r.Value ?? Undefined.Instance;
                 }
             }
@@ -76,10 +79,11 @@ namespace Jint.Runtime.Interpreter.Statements
                     return r;
                 }
 
+                l = r.Location;
                 v = r.Value ?? Undefined.Instance;
             }
 
-            return new Completion(CompletionType.Normal, v, null);
+            return new Completion(CompletionType.Normal, v, null, l);
         }
 
         private sealed class JintSwitchCase
@@ -89,10 +93,7 @@ namespace Jint.Runtime.Interpreter.Statements
 
             public JintSwitchCase(Engine engine, SwitchCase switchCase)
             {
-                if (switchCase.Consequent != null)
-                {
-                    Consequent = new JintStatementList(engine, null, switchCase.Consequent);
-                }
+                Consequent = new JintStatementList(engine, null, switchCase.Consequent);
 
                 if (switchCase.Test != null)
                 {

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

@@ -13,7 +13,7 @@ namespace Jint.Runtime.Interpreter.Statements
 
         public JintSwitchStatement(Engine engine, SwitchStatement statement) : base(engine, statement)
         {
-            _switchBlock = new JintSwitchBlock(engine, _statement.Cases);
+            _switchBlock = new JintSwitchBlock(engine, in _statement.Cases);
             _discriminant = JintExpression.Build(engine, _statement.Discriminant);
         }
 
@@ -23,7 +23,7 @@ namespace Jint.Runtime.Interpreter.Statements
             var r = _switchBlock.Execute(jsValue);
             if (r.Type == CompletionType.Break && r.Identifier == _statement.LabelSet?.Name)
             {
-                return new Completion(CompletionType.Normal, r.Value, null);
+                return new Completion(CompletionType.Normal, r.Value, null, Location);
             }
 
             return r;

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

@@ -7,7 +7,7 @@ namespace Jint.Runtime.Interpreter.Statements
 {
     internal sealed class JintVariableDeclaration : JintStatement<VariableDeclaration>
     {
-        private static readonly Completion VoidCompletion = new Completion(CompletionType.Normal, Undefined.Instance, null);
+        private static readonly Completion VoidCompletion = new Completion(CompletionType.Normal, Undefined.Instance, null, default);
 
         private ResolvedDeclaration[] _declarations;
 

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

@@ -28,7 +28,7 @@ namespace Jint.Runtime.Interpreter.Statements
                 var jsValue = _test.GetValue();
                 if (!TypeConverter.ToBoolean(jsValue))
                 {
-                    return new Completion(CompletionType.Normal, v, null);
+                    return new Completion(CompletionType.Normal, v, null, Location);
                 }
 
                 var completion = _body.Execute();
@@ -42,7 +42,7 @@ namespace Jint.Runtime.Interpreter.Statements
                 {
                     if (completion.Type == CompletionType.Break && (completion.Identifier == null || completion.Identifier == _labelSetName))
                     {
-                        return new Completion(CompletionType.Normal, v, null);
+                        return new Completion(CompletionType.Normal, v, null, Location);
                     }
 
                     if (completion.Type != CompletionType.Normal)

+ 5 - 4
Jint/Runtime/JavaScriptException.cs

@@ -34,9 +34,10 @@ namespace Jint.Runtime
             Error = error;
         }
 
-        public JavaScriptException SetCallstack(Engine engine, Location location = null)
+        public JavaScriptException SetCallstack(Engine engine, Location? location = null)
         {
-            Location = location;
+            Location = location ?? default;
+
             using (var sb = StringBuilderPool.Rent())
             {
                 foreach (var cse in engine.CallStack)
@@ -120,8 +121,8 @@ namespace Jint.Runtime
 
         public Location Location { get; set; }
 
-        public int LineNumber => Location?.Start.Line ?? 0;
+        public int LineNumber => Location.Start.Line;
 
-        public int Column => Location?.Start.Column ?? 0;
+        public int Column => Location.Start.Column;
     }
 }

+ 2 - 2
Jint/Runtime/TypeConverter.cs

@@ -496,7 +496,7 @@ namespace Jint.Runtime
 
         public static IEnumerable<Tuple<MethodBase, JsValue[]>> FindBestMatch<T>(T[] methods, Func<T, bool, JsValue[]> argumentProvider) where T : MethodBase
         {
-            List<Tuple<T, JsValue[]>> matchingByParameterCount = null;
+            System.Collections.Generic.List<Tuple<T, JsValue[]>> matchingByParameterCount = null;
             foreach (var m in methods)
             {
                 bool hasParams = false;
@@ -519,7 +519,7 @@ namespace Jint.Runtime
                         yield break;
                     }
 
-                    matchingByParameterCount = matchingByParameterCount ?? new List<Tuple<T, JsValue[]>>();
+                    matchingByParameterCount = matchingByParameterCount ?? new System.Collections.Generic.List<Tuple<T, JsValue[]>>();
                     matchingByParameterCount.Add(new Tuple<T, JsValue[]>(m, arguments));
                 }
             }