diff --git a/src/Esprima/JavascriptParser.cs b/src/Esprima/JavascriptParser.cs index fe5170d7..2f90e88c 100644 --- a/src/Esprima/JavascriptParser.cs +++ b/src/Esprima/JavascriptParser.cs @@ -678,6 +678,14 @@ private Expression ParsePrimaryExpression() { expr = ParseImportCall(); } + else if (MatchImportMeta()) + { + if (!_context.IsModule) + { + TolerateUnexpectedToken(_lookahead, Messages.CannotUseImportMetaOutsideAModule); + } + expr = ParseImportMeta(); + } else { return ThrowUnexpectedToken(NextToken()); @@ -1486,7 +1494,48 @@ private Import ParseImportCall() { var node = CreateNode(); ExpectKeyword("import"); - return this.Finalize(node, new Import()); + return Finalize(node, new Import()); + } + + private bool MatchImportMeta() + { + var match = MatchKeyword("import"); + if (match) + { + var state = _scanner.SaveState(); + _scanner.ScanComments(); + var dot = _scanner.Lex(); + if (dot.Type == TokenType.Punctuator && Equals(dot.Value, ".")) + { + _scanner.ScanComments(); + var meta = _scanner.Lex(); + match = meta.Type == TokenType.Identifier && Equals(meta.Value, "meta"); + if (match) + { + if (meta.End - meta.Start != "meta".Length) + { + TolerateUnexpectedToken(meta, Messages.InvalidEscapedReservedWord); + } + } + } + else + { + match = false; + } + _scanner.RestoreState(state); + } + + return match; + } + + private MetaProperty ParseImportMeta() + { + var node = CreateNode(); + var id = ParseIdentifierName(); // 'import', already ensured by matchImportMeta + Expect("."); + var property = ParseIdentifierName(); // 'meta', already ensured by matchImportMeta + _context.IsAssignmentTarget = false; + return Finalize(node, new MetaProperty(id, property)); } private Expression ParseLeftHandSideExpressionAllowCall() @@ -1573,8 +1622,8 @@ private Expression ParseLeftHandSideExpressionAllowCall() } else if (Match(".") || optional) { - this._context.IsBindingElement = false; - this._context.IsAssignmentTarget = !optional; + _context.IsBindingElement = false; + _context.IsAssignmentTarget = !optional; if (!optional) { Expect("."); @@ -1688,7 +1737,7 @@ private Expression ParseUpdateExpression() Expression expr; var startToken = _lookahead; - if (Match("++") || this.Match("--")) + if (Match("++") || Match("--")) { var node = StartNode(startToken); var token = NextToken(); @@ -2321,6 +2370,10 @@ private Statement ParseStatementListItem() { statement = ParseExpressionStatement(); } + else if (MatchImportMeta()) + { + statement = ParseStatement(); + } else { if (!_context.IsModule) @@ -3979,7 +4032,7 @@ private FunctionExpression ParseGetterMethod() { TolerateError(Messages.BadGetterArity); } - var method = this.ParsePropertyMethod(formalParameters); + var method = ParsePropertyMethod(formalParameters); _context.AllowYield = previousAllowYield; return Finalize(node, new FunctionExpression(null, NodeList.From(ref formalParameters.Parameters), method, generator: isGenerator, _context.Strict, async: false)); diff --git a/src/Esprima/Messages.cs b/src/Esprima/Messages.cs index 9ecda7fd..b7c178e6 100644 --- a/src/Esprima/Messages.cs +++ b/src/Esprima/Messages.cs @@ -7,6 +7,7 @@ public static class Messages public const string BadGetterArity = "Getter must not have any formal parameters"; public const string BadSetterArity = "Setter must have exactly one formal parameter"; public const string BadSetterRestParameter = "Setter function argument must not be a rest parameter"; + public const string CannotUseImportMetaOutsideAModule = "Cannot use 'import.meta' outside a module"; public const string ConstructorIsAsync = "Class constructor may not be an async method"; public const string ConstructorSpecialMethod = "Class constructor may not be an accessor"; public const string DeclarationMissingInitializer = "Missing initializer in {0} declaration"; diff --git a/test/Esprima.Tests/Fixtures.cs b/test/Esprima.Tests/Fixtures.cs index 90d319cd..96338636 100644 --- a/test/Esprima.Tests/Fixtures.cs +++ b/test/Esprima.Tests/Fixtures.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; using System.Reflection; +using System.Runtime.Serialization.Json; using Esprima.Ast; using Esprima.Utils; using Newtonsoft.Json.Linq; @@ -34,7 +35,7 @@ private static string ParseAndFormat(SourceType sourceType, string source, Parse ); } - public bool CompareTrees(string actual, string expected) + private static void CompareTrees(string actual, string expected, string path) { var actualJObject = JObject.Parse(actual); var expectedJObject = JObject.Parse(expected); @@ -49,8 +50,8 @@ public bool CompareTrees(string actual, string expected) { var actualString = actualJObject.ToString(); var expectedString = expectedJObject.ToString(); + Assert.Equal(expectedString, actualString); } - return areEqual; } [Theory] @@ -134,7 +135,7 @@ public void ExecuteTestCase(string fixture) options.Tolerant = true; var actual = ParseAndFormat(sourceType, script, options); - Assert.True(CompareTrees(actual, expected), jsFilePath); + CompareTrees(actual, expected, jsFilePath); } else { diff --git a/test/Esprima.Tests/Fixtures/es2020/import.meta/assignment.module.js b/test/Esprima.Tests/Fixtures/es2020/import.meta/assignment.module.js new file mode 100644 index 00000000..cbff3c97 --- /dev/null +++ b/test/Esprima.Tests/Fixtures/es2020/import.meta/assignment.module.js @@ -0,0 +1 @@ +import.meta.foo = 'bar'; diff --git a/test/Esprima.Tests/Fixtures/es2020/import.meta/assignment.module.tree.json b/test/Esprima.Tests/Fixtures/es2020/import.meta/assignment.module.tree.json new file mode 100644 index 00000000..c2fe577d --- /dev/null +++ b/test/Esprima.Tests/Fixtures/es2020/import.meta/assignment.module.tree.json @@ -0,0 +1,310 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "computed": false, + "object": { + "type": "MetaProperty", + "meta": { + "type": "Identifier", + "name": "import", + "range": [ + 0, + 6 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 6 + } + } + }, + "property": { + "type": "Identifier", + "name": "meta", + "range": [ + 7, + 11 + ], + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 11 + } + } + }, + "range": [ + 0, + 11 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 11 + } + } + }, + "property": { + "type": "Identifier", + "name": "foo", + "range": [ + 12, + 15 + ], + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 1, + "column": 15 + } + } + }, + "optional": false, + "range": [ + 0, + 15 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 15 + } + } + }, + "right": { + "type": "Literal", + "value": "bar", + "raw": "'bar'", + "range": [ + 18, + 23 + ], + "loc": { + "start": { + "line": 1, + "column": 18 + }, + "end": { + "line": 1, + "column": 23 + } + } + }, + "range": [ + 0, + 23 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 23 + } + } + }, + "range": [ + 0, + 24 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 24 + } + } + } + ], + "sourceType": "module", + "range": [ + 0, + 24 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 24 + } + }, + "tokens": [ + { + "type": "Keyword", + "value": "import", + "range": [ + 0, + 6 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 6 + } + } + }, + { + "type": "Punctuator", + "value": ".", + "range": [ + 6, + 7 + ], + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 7 + } + } + }, + { + "type": "Identifier", + "value": "meta", + "range": [ + 7, + 11 + ], + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 11 + } + } + }, + { + "type": "Punctuator", + "value": ".", + "range": [ + 11, + 12 + ], + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 12 + } + } + }, + { + "type": "Identifier", + "value": "foo", + "range": [ + 12, + 15 + ], + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 1, + "column": 15 + } + } + }, + { + "type": "Punctuator", + "value": "=", + "range": [ + 16, + 17 + ], + "loc": { + "start": { + "line": 1, + "column": 16 + }, + "end": { + "line": 1, + "column": 17 + } + } + }, + { + "type": "String", + "value": "'bar'", + "range": [ + 18, + 23 + ], + "loc": { + "start": { + "line": 1, + "column": 18 + }, + "end": { + "line": 1, + "column": 23 + } + } + }, + { + "type": "Punctuator", + "value": ";", + "range": [ + 23, + 24 + ], + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 24 + } + } + } + ] +} diff --git a/test/Esprima.Tests/Fixtures/es2020/import.meta/log.failure.json b/test/Esprima.Tests/Fixtures/es2020/import.meta/log.failure.json new file mode 100644 index 00000000..a0cf4125 --- /dev/null +++ b/test/Esprima.Tests/Fixtures/es2020/import.meta/log.failure.json @@ -0,0 +1 @@ +{"index":12,"lineNumber":1,"column":13,"message":"Error: Line 1: Cannot use 'import.meta' outside a module","description":"Cannot use 'import.meta' outside a module"} \ No newline at end of file diff --git a/test/Esprima.Tests/Fixtures/es2020/import.meta/log.js b/test/Esprima.Tests/Fixtures/es2020/import.meta/log.js new file mode 100644 index 00000000..58220625 --- /dev/null +++ b/test/Esprima.Tests/Fixtures/es2020/import.meta/log.js @@ -0,0 +1 @@ +console.log(import.meta); \ No newline at end of file diff --git a/test/Esprima.Tests/Fixtures/es2020/import.meta/log.module.js b/test/Esprima.Tests/Fixtures/es2020/import.meta/log.module.js new file mode 100644 index 00000000..e7313a09 --- /dev/null +++ b/test/Esprima.Tests/Fixtures/es2020/import.meta/log.module.js @@ -0,0 +1 @@ +console.log(import.meta); diff --git a/test/Esprima.Tests/Fixtures/es2020/import.meta/log.module.tree.json b/test/Esprima.Tests/Fixtures/es2020/import.meta/log.module.tree.json new file mode 100644 index 00000000..617e4360 --- /dev/null +++ b/test/Esprima.Tests/Fixtures/es2020/import.meta/log.module.tree.json @@ -0,0 +1,329 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "computed": false, + "object": { + "type": "Identifier", + "name": "console", + "range": [ + 0, + 7 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 7 + } + } + }, + "property": { + "type": "Identifier", + "name": "log", + "range": [ + 8, + 11 + ], + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 1, + "column": 11 + } + } + }, + "optional": false, + "range": [ + 0, + 11 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 11 + } + } + }, + "arguments": [ + { + "type": "MetaProperty", + "meta": { + "type": "Identifier", + "name": "import", + "range": [ + 12, + 18 + ], + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 1, + "column": 18 + } + } + }, + "property": { + "type": "Identifier", + "name": "meta", + "range": [ + 19, + 23 + ], + "loc": { + "start": { + "line": 1, + "column": 19 + }, + "end": { + "line": 1, + "column": 23 + } + } + }, + "range": [ + 12, + 23 + ], + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 1, + "column": 23 + } + } + } + ], + "optional": false, + "range": [ + 0, + 24 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 24 + } + } + }, + "range": [ + 0, + 25 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 25 + } + } + } + ], + "sourceType": "module", + "range": [ + 0, + 25 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 25 + } + }, + "tokens": [ + { + "type": "Identifier", + "value": "console", + "range": [ + 0, + 7 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 7 + } + } + }, + { + "type": "Punctuator", + "value": ".", + "range": [ + 7, + 8 + ], + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 8 + } + } + }, + { + "type": "Identifier", + "value": "log", + "range": [ + 8, + 11 + ], + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 1, + "column": 11 + } + } + }, + { + "type": "Punctuator", + "value": "(", + "range": [ + 11, + 12 + ], + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 12 + } + } + }, + { + "type": "Keyword", + "value": "import", + "range": [ + 12, + 18 + ], + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 1, + "column": 18 + } + } + }, + { + "type": "Punctuator", + "value": ".", + "range": [ + 18, + 19 + ], + "loc": { + "start": { + "line": 1, + "column": 18 + }, + "end": { + "line": 1, + "column": 19 + } + } + }, + { + "type": "Identifier", + "value": "meta", + "range": [ + 19, + 23 + ], + "loc": { + "start": { + "line": 1, + "column": 19 + }, + "end": { + "line": 1, + "column": 23 + } + } + }, + { + "type": "Punctuator", + "value": ")", + "range": [ + 23, + 24 + ], + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 24 + } + } + }, + { + "type": "Punctuator", + "value": ";", + "range": [ + 24, + 25 + ], + "loc": { + "start": { + "line": 1, + "column": 24 + }, + "end": { + "line": 1, + "column": 25 + } + } + } + ] +} diff --git a/test/Esprima.Tests/Fixtures/es2020/import.meta/unicode-escape-import.module.failure.json b/test/Esprima.Tests/Fixtures/es2020/import.meta/unicode-escape-import.module.failure.json new file mode 100644 index 00000000..4518e8dd --- /dev/null +++ b/test/Esprima.Tests/Fixtures/es2020/import.meta/unicode-escape-import.module.failure.json @@ -0,0 +1 @@ +{"index":0,"lineNumber":1,"column":1,"message":"Error: Line 1: Keyword must not contain escaped characters","description":"Keyword must not contain escaped characters"} \ No newline at end of file diff --git a/test/Esprima.Tests/Fixtures/es2020/import.meta/unicode-escape-import.module.js b/test/Esprima.Tests/Fixtures/es2020/import.meta/unicode-escape-import.module.js new file mode 100644 index 00000000..dba6d495 --- /dev/null +++ b/test/Esprima.Tests/Fixtures/es2020/import.meta/unicode-escape-import.module.js @@ -0,0 +1 @@ +im\u0070ort.meta; \ No newline at end of file diff --git a/test/Esprima.Tests/Fixtures/es2020/import.meta/unicode-escape-meta.module.failure.json b/test/Esprima.Tests/Fixtures/es2020/import.meta/unicode-escape-meta.module.failure.json new file mode 100644 index 00000000..e4db394f --- /dev/null +++ b/test/Esprima.Tests/Fixtures/es2020/import.meta/unicode-escape-meta.module.failure.json @@ -0,0 +1 @@ +{"index":7,"lineNumber":1,"column":8,"message":"Error: Line 1: Keyword must not contain escaped characters","description":"Keyword must not contain escaped characters"} \ No newline at end of file diff --git a/test/Esprima.Tests/Fixtures/es2020/import.meta/unicode-escape-meta.module.js b/test/Esprima.Tests/Fixtures/es2020/import.meta/unicode-escape-meta.module.js new file mode 100644 index 00000000..3eaf2c9d --- /dev/null +++ b/test/Esprima.Tests/Fixtures/es2020/import.meta/unicode-escape-meta.module.js @@ -0,0 +1 @@ +import.m\u0065ta; \ No newline at end of file diff --git a/test/Esprima.Tests/Fixtures/es2020/import.meta/url.module.js b/test/Esprima.Tests/Fixtures/es2020/import.meta/url.module.js new file mode 100644 index 00000000..6bf78c51 --- /dev/null +++ b/test/Esprima.Tests/Fixtures/es2020/import.meta/url.module.js @@ -0,0 +1 @@ +new URL(import.meta.url).searchParams.get('someURLInfo'); \ No newline at end of file diff --git a/test/Esprima.Tests/Fixtures/es2020/import.meta/url.module.tree.json b/test/Esprima.Tests/Fixtures/es2020/import.meta/url.module.tree.json new file mode 100644 index 00000000..2dd12fec --- /dev/null +++ b/test/Esprima.Tests/Fixtures/es2020/import.meta/url.module.tree.json @@ -0,0 +1,585 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "computed": false, + "object": { + "type": "MemberExpression", + "computed": false, + "object": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "URL", + "range": [ + 4, + 7 + ], + "loc": { + "start": { + "line": 1, + "column": 4 + }, + "end": { + "line": 1, + "column": 7 + } + } + }, + "arguments": [ + { + "type": "MemberExpression", + "computed": false, + "object": { + "type": "MetaProperty", + "meta": { + "type": "Identifier", + "name": "import", + "range": [ + 8, + 14 + ], + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 1, + "column": 14 + } + } + }, + "property": { + "type": "Identifier", + "name": "meta", + "range": [ + 15, + 19 + ], + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 19 + } + } + }, + "range": [ + 8, + 19 + ], + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 1, + "column": 19 + } + } + }, + "property": { + "type": "Identifier", + "name": "url", + "range": [ + 20, + 23 + ], + "loc": { + "start": { + "line": 1, + "column": 20 + }, + "end": { + "line": 1, + "column": 23 + } + } + }, + "optional": false, + "range": [ + 8, + 23 + ], + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 1, + "column": 23 + } + } + } + ], + "range": [ + 0, + 24 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 24 + } + } + }, + "property": { + "type": "Identifier", + "name": "searchParams", + "range": [ + 25, + 37 + ], + "loc": { + "start": { + "line": 1, + "column": 25 + }, + "end": { + "line": 1, + "column": 37 + } + } + }, + "optional": false, + "range": [ + 0, + 37 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 37 + } + } + }, + "property": { + "type": "Identifier", + "name": "get", + "range": [ + 38, + 41 + ], + "loc": { + "start": { + "line": 1, + "column": 38 + }, + "end": { + "line": 1, + "column": 41 + } + } + }, + "optional": false, + "range": [ + 0, + 41 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 41 + } + } + }, + "arguments": [ + { + "type": "Literal", + "value": "someURLInfo", + "raw": "'someURLInfo'", + "range": [ + 42, + 55 + ], + "loc": { + "start": { + "line": 1, + "column": 42 + }, + "end": { + "line": 1, + "column": 55 + } + } + } + ], + "optional": false, + "range": [ + 0, + 56 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 56 + } + } + }, + "range": [ + 0, + 57 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 57 + } + } + } + ], + "sourceType": "module", + "range": [ + 0, + 57 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 57 + } + }, + "tokens": [ + { + "type": "Keyword", + "value": "new", + "range": [ + 0, + 3 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + { + "type": "Identifier", + "value": "URL", + "range": [ + 4, + 7 + ], + "loc": { + "start": { + "line": 1, + "column": 4 + }, + "end": { + "line": 1, + "column": 7 + } + } + }, + { + "type": "Punctuator", + "value": "(", + "range": [ + 7, + 8 + ], + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 8 + } + } + }, + { + "type": "Keyword", + "value": "import", + "range": [ + 8, + 14 + ], + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 1, + "column": 14 + } + } + }, + { + "type": "Punctuator", + "value": ".", + "range": [ + 14, + 15 + ], + "loc": { + "start": { + "line": 1, + "column": 14 + }, + "end": { + "line": 1, + "column": 15 + } + } + }, + { + "type": "Identifier", + "value": "meta", + "range": [ + 15, + 19 + ], + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 19 + } + } + }, + { + "type": "Punctuator", + "value": ".", + "range": [ + 19, + 20 + ], + "loc": { + "start": { + "line": 1, + "column": 19 + }, + "end": { + "line": 1, + "column": 20 + } + } + }, + { + "type": "Identifier", + "value": "url", + "range": [ + 20, + 23 + ], + "loc": { + "start": { + "line": 1, + "column": 20 + }, + "end": { + "line": 1, + "column": 23 + } + } + }, + { + "type": "Punctuator", + "value": ")", + "range": [ + 23, + 24 + ], + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 24 + } + } + }, + { + "type": "Punctuator", + "value": ".", + "range": [ + 24, + 25 + ], + "loc": { + "start": { + "line": 1, + "column": 24 + }, + "end": { + "line": 1, + "column": 25 + } + } + }, + { + "type": "Identifier", + "value": "searchParams", + "range": [ + 25, + 37 + ], + "loc": { + "start": { + "line": 1, + "column": 25 + }, + "end": { + "line": 1, + "column": 37 + } + } + }, + { + "type": "Punctuator", + "value": ".", + "range": [ + 37, + 38 + ], + "loc": { + "start": { + "line": 1, + "column": 37 + }, + "end": { + "line": 1, + "column": 38 + } + } + }, + { + "type": "Identifier", + "value": "get", + "range": [ + 38, + 41 + ], + "loc": { + "start": { + "line": 1, + "column": 38 + }, + "end": { + "line": 1, + "column": 41 + } + } + }, + { + "type": "Punctuator", + "value": "(", + "range": [ + 41, + 42 + ], + "loc": { + "start": { + "line": 1, + "column": 41 + }, + "end": { + "line": 1, + "column": 42 + } + } + }, + { + "type": "String", + "value": "'someURLInfo'", + "range": [ + 42, + 55 + ], + "loc": { + "start": { + "line": 1, + "column": 42 + }, + "end": { + "line": 1, + "column": 55 + } + } + }, + { + "type": "Punctuator", + "value": ")", + "range": [ + 55, + 56 + ], + "loc": { + "start": { + "line": 1, + "column": 55 + }, + "end": { + "line": 1, + "column": 56 + } + } + }, + { + "type": "Punctuator", + "value": ";", + "range": [ + 56, + 57 + ], + "loc": { + "start": { + "line": 1, + "column": 56 + }, + "end": { + "line": 1, + "column": 57 + } + } + } + ] +}