diff --git a/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java b/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java index e34d552b777..7b68106bb3f 100644 --- a/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java +++ b/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java @@ -1552,8 +1552,13 @@ public class TypeScriptASTConverter { } private Node convertJsxAttribute(JsonObject node, SourceLocation loc) throws ParseError { + JsonObject nameNode = node.get("name").getAsJsonObject(); + if (nameNode.get("name") != null) { + // it's a namespaced attribute + nameNode = nameNode.get("name").getAsJsonObject(); + } return new JSXAttribute( - loc, convertJSXName(convertChild(node, "name")), convertChild(node, "initializer")); + loc, convertJSXName(((Expression)convertNode(nameNode, null))), convertChild(node, "initializer")); // 2 } private Node convertJsxClosingElement(JsonObject node, SourceLocation loc) throws ParseError { diff --git a/javascript/ql/test/library-tests/JSX/printAst.expected b/javascript/ql/test/library-tests/JSX/printAst.expected index 11bf254a890..a34e194cca8 100644 --- a/javascript/ql/test/library-tests/JSX/printAst.expected +++ b/javascript/ql/test/library-tests/JSX/printAst.expected @@ -3,10 +3,14 @@ nodes | file://:0:0:0:0 | (Attributes) | semmle.label | (Attributes) | | file://:0:0:0:0 | (Attributes) | semmle.label | (Attributes) | | file://:0:0:0:0 | (Attributes) | semmle.label | (Attributes) | +| file://:0:0:0:0 | (Attributes) | semmle.label | (Attributes) | +| file://:0:0:0:0 | (Attributes) | semmle.label | (Attributes) | | file://:0:0:0:0 | (Body) | semmle.label | (Body) | | file://:0:0:0:0 | (Body) | semmle.label | (Body) | | file://:0:0:0:0 | (Body) | semmle.label | (Body) | | file://:0:0:0:0 | (Body) | semmle.label | (Body) | +| file://:0:0:0:0 | (Body) | semmle.label | (Body) | +| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | tst.js:1:1:1:32 | [DeclStmt] var href = ... | semmle.label | [DeclStmt] var href = ... | | tst.js:1:1:1:32 | [DeclStmt] var href = ... | semmle.order | 1 | | tst.js:1:5:1:8 | [VarDecl] href | semmle.label | [VarDecl] href | @@ -119,6 +123,42 @@ nodes | tstest.tsx:7:33:7:38 | [JsxElement] | semmle.label | [JsxElement] | | tstest.tsx:7:34:7:36 | [VarRef] Foo | semmle.label | [VarRef] Foo | | tstest.tsx:7:40:7:49 | [Literal] more text | semmle.label | [Literal] more text | +| tstest.tsx:10:1:10:30 | [DeclStmt] const x = ... | semmle.label | [DeclStmt] const x = ... | +| tstest.tsx:10:1:10:30 | [DeclStmt] const x = ... | semmle.order | 15 | +| tstest.tsx:10:7:10:7 | [VarDecl] x | semmle.label | [VarDecl] x | +| tstest.tsx:10:7:10:29 | [VariableDeclarator] x = | semmle.label | [VariableDeclarator] x = | +| tstest.tsx:10:11:10:29 | [JsxElement] | semmle.label | [JsxElement] | +| tstest.tsx:10:12:10:14 | [VarRef] Bar | semmle.label | [VarRef] Bar | +| tstest.tsx:10:16:10:26 | [JsxAttribute] a:b="hello" | semmle.label | [JsxAttribute] a:b="hello" | +| tstest.tsx:10:18:10:18 | [Label] b | semmle.label | [Label] b | +| tstest.tsx:10:20:10:26 | [Literal] "hello" | semmle.label | [Literal] "hello" | +| tstest.tsx:11:1:11:32 | [DeclStmt] const y = ... | semmle.label | [DeclStmt] const y = ... | +| tstest.tsx:11:1:11:32 | [DeclStmt] const y = ... | semmle.order | 16 | +| tstest.tsx:11:7:11:7 | [VarDecl] y | semmle.label | [VarDecl] y | +| tstest.tsx:11:7:11:31 | [VariableDeclarator] y = | semmle.label | [VariableDeclarator] y = | +| tstest.tsx:11:11:11:31 | [JsxElement] | semmle.label | [JsxElement] | +| tstest.tsx:11:12:11:14 | [VarRef] Bar | semmle.label | [VarRef] Bar | +| tstest.tsx:11:16:11:28 | [JsxAttribute] a : b="hello" | semmle.label | [JsxAttribute] a : b="hello" | +| tstest.tsx:11:20:11:20 | [Label] b | semmle.label | [Label] b | +| tstest.tsx:11:22:11:28 | [Literal] "hello" | semmle.label | [Literal] "hello" | +| tstest.tsx:13:1:15:1 | [InterfaceDeclaration,TypeDefinition] interfa ... ring; } | semmle.label | [InterfaceDeclaration,TypeDefinition] interfa ... ring; } | +| tstest.tsx:13:1:15:1 | [InterfaceDeclaration,TypeDefinition] interfa ... ring; } | semmle.order | 17 | +| tstest.tsx:13:11:13:18 | [Identifier] BarProps | semmle.label | [Identifier] BarProps | +| tstest.tsx:14:5:14:9 | [Literal] "a:b" | semmle.label | [Literal] "a:b" | +| tstest.tsx:14:5:14:18 | [FieldDeclaration] "a:b": string; | semmle.label | [FieldDeclaration] "a:b": string; | +| tstest.tsx:14:12:14:17 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string | +| tstest.tsx:17:1:19:1 | [FunctionDeclStmt] functio ... div>; } | semmle.label | [FunctionDeclStmt] functio ... div>; } | +| tstest.tsx:17:1:19:1 | [FunctionDeclStmt] functio ... div>; } | semmle.order | 18 | +| tstest.tsx:17:10:17:12 | [VarDecl] Bar | semmle.label | [VarDecl] Bar | +| tstest.tsx:17:14:17:18 | [SimpleParameter] props | semmle.label | [SimpleParameter] props | +| tstest.tsx:17:21:17:28 | [LocalTypeAccess] BarProps | semmle.label | [LocalTypeAccess] BarProps | +| tstest.tsx:17:31:19:1 | [BlockStmt] { r ... div>; } | semmle.label | [BlockStmt] { r ... div>; } | +| tstest.tsx:18:5:18:37 | [ReturnStmt] return ... ; | semmle.label | [ReturnStmt] return ... ; | +| tstest.tsx:18:12:18:36 | [JsxElement]
{p ... }
| semmle.label | [JsxElement]
{p ... }
| +| tstest.tsx:18:13:18:15 | [Label] div | semmle.label | [Label] div | +| tstest.tsx:18:18:18:22 | [VarRef] props | semmle.label | [VarRef] props | +| tstest.tsx:18:18:18:29 | [IndexExpr] props["a:b"] | semmle.label | [IndexExpr] props["a:b"] | +| tstest.tsx:18:24:18:28 | [Literal] "a:b" | semmle.label | [Literal] "a:b" | edges | file://:0:0:0:0 | (Attributes) | tst.js:3:4:3:14 | [JsxAttribute] href={href} | semmle.label | 0 | | file://:0:0:0:0 | (Attributes) | tst.js:3:4:3:14 | [JsxAttribute] href={href} | semmle.order | 0 | @@ -136,6 +176,10 @@ edges | file://:0:0:0:0 | (Attributes) | tstest.tsx:3:32:3:45 | [JsxAttribute] {...linkTypes} | semmle.order | 2 | | file://:0:0:0:0 | (Attributes) | tstest.tsx:4:25:4:33 | [JsxAttribute] foo="bar" | semmle.label | 0 | | file://:0:0:0:0 | (Attributes) | tstest.tsx:4:25:4:33 | [JsxAttribute] foo="bar" | semmle.order | 0 | +| file://:0:0:0:0 | (Attributes) | tstest.tsx:10:16:10:26 | [JsxAttribute] a:b="hello" | semmle.label | 0 | +| file://:0:0:0:0 | (Attributes) | tstest.tsx:10:16:10:26 | [JsxAttribute] a:b="hello" | semmle.order | 0 | +| file://:0:0:0:0 | (Attributes) | tstest.tsx:11:16:11:28 | [JsxAttribute] a : b="hello" | semmle.label | 0 | +| file://:0:0:0:0 | (Attributes) | tstest.tsx:11:16:11:28 | [JsxAttribute] a : b="hello" | semmle.order | 0 | | file://:0:0:0:0 | (Body) | tst.js:3:47:3:54 | [Literal] Link to | semmle.label | 0 | | file://:0:0:0:0 | (Body) | tst.js:3:47:3:54 | [Literal] Link to | semmle.order | 0 | | file://:0:0:0:0 | (Body) | tst.js:3:56:3:59 | [VarRef] href | semmle.label | 1 | @@ -164,6 +208,10 @@ edges | file://:0:0:0:0 | (Body) | tstest.tsx:7:33:7:38 | [JsxElement] | semmle.order | 1 | | file://:0:0:0:0 | (Body) | tstest.tsx:7:40:7:49 | [Literal] more text | semmle.label | 2 | | file://:0:0:0:0 | (Body) | tstest.tsx:7:40:7:49 | [Literal] more text | semmle.order | 2 | +| file://:0:0:0:0 | (Body) | tstest.tsx:18:18:18:29 | [IndexExpr] props["a:b"] | semmle.label | 0 | +| file://:0:0:0:0 | (Body) | tstest.tsx:18:18:18:29 | [IndexExpr] props["a:b"] | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | tstest.tsx:17:14:17:18 | [SimpleParameter] props | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | tstest.tsx:17:14:17:18 | [SimpleParameter] props | semmle.order | 0 | | tst.js:1:1:1:32 | [DeclStmt] var href = ... | tst.js:1:5:1:31 | [VariableDeclarator] href = ... le.com" | semmle.label | 1 | | tst.js:1:1:1:32 | [DeclStmt] var href = ... | tst.js:1:5:1:31 | [VariableDeclarator] href = ... le.com" | semmle.order | 1 | | tst.js:1:5:1:31 | [VariableDeclarator] href = ... le.com" | tst.js:1:5:1:8 | [VarDecl] href | semmle.label | 1 | @@ -304,5 +352,61 @@ edges | tstest.tsx:7:16:7:52 | [JsxFragment] <> frag ... ext | file://:0:0:0:0 | (Body) | semmle.order | 1 | | tstest.tsx:7:33:7:38 | [JsxElement] | tstest.tsx:7:34:7:36 | [VarRef] Foo | semmle.label | 0 | | tstest.tsx:7:33:7:38 | [JsxElement] | tstest.tsx:7:34:7:36 | [VarRef] Foo | semmle.order | 0 | +| tstest.tsx:10:1:10:30 | [DeclStmt] const x = ... | tstest.tsx:10:7:10:29 | [VariableDeclarator] x = | semmle.label | 1 | +| tstest.tsx:10:1:10:30 | [DeclStmt] const x = ... | tstest.tsx:10:7:10:29 | [VariableDeclarator] x = | semmle.order | 1 | +| tstest.tsx:10:7:10:29 | [VariableDeclarator] x = | tstest.tsx:10:7:10:7 | [VarDecl] x | semmle.label | 1 | +| tstest.tsx:10:7:10:29 | [VariableDeclarator] x = | tstest.tsx:10:7:10:7 | [VarDecl] x | semmle.order | 1 | +| tstest.tsx:10:7:10:29 | [VariableDeclarator] x = | tstest.tsx:10:11:10:29 | [JsxElement] | semmle.label | 2 | +| tstest.tsx:10:7:10:29 | [VariableDeclarator] x = | tstest.tsx:10:11:10:29 | [JsxElement] | semmle.order | 2 | +| tstest.tsx:10:11:10:29 | [JsxElement] | file://:0:0:0:0 | (Attributes) | semmle.label | 2 | +| tstest.tsx:10:11:10:29 | [JsxElement] | file://:0:0:0:0 | (Attributes) | semmle.order | 2 | +| tstest.tsx:10:11:10:29 | [JsxElement] | tstest.tsx:10:12:10:14 | [VarRef] Bar | semmle.label | 0 | +| tstest.tsx:10:11:10:29 | [JsxElement] | tstest.tsx:10:12:10:14 | [VarRef] Bar | semmle.order | 0 | +| tstest.tsx:10:16:10:26 | [JsxAttribute] a:b="hello" | tstest.tsx:10:18:10:18 | [Label] b | semmle.label | 1 | +| tstest.tsx:10:16:10:26 | [JsxAttribute] a:b="hello" | tstest.tsx:10:18:10:18 | [Label] b | semmle.order | 1 | +| tstest.tsx:10:16:10:26 | [JsxAttribute] a:b="hello" | tstest.tsx:10:20:10:26 | [Literal] "hello" | semmle.label | 2 | +| tstest.tsx:10:16:10:26 | [JsxAttribute] a:b="hello" | tstest.tsx:10:20:10:26 | [Literal] "hello" | semmle.order | 2 | +| tstest.tsx:11:1:11:32 | [DeclStmt] const y = ... | tstest.tsx:11:7:11:31 | [VariableDeclarator] y = | semmle.label | 1 | +| tstest.tsx:11:1:11:32 | [DeclStmt] const y = ... | tstest.tsx:11:7:11:31 | [VariableDeclarator] y = | semmle.order | 1 | +| tstest.tsx:11:7:11:31 | [VariableDeclarator] y = | tstest.tsx:11:7:11:7 | [VarDecl] y | semmle.label | 1 | +| tstest.tsx:11:7:11:31 | [VariableDeclarator] y = | tstest.tsx:11:7:11:7 | [VarDecl] y | semmle.order | 1 | +| tstest.tsx:11:7:11:31 | [VariableDeclarator] y = | tstest.tsx:11:11:11:31 | [JsxElement] | semmle.label | 2 | +| tstest.tsx:11:7:11:31 | [VariableDeclarator] y = | tstest.tsx:11:11:11:31 | [JsxElement] | semmle.order | 2 | +| tstest.tsx:11:11:11:31 | [JsxElement] | file://:0:0:0:0 | (Attributes) | semmle.label | 2 | +| tstest.tsx:11:11:11:31 | [JsxElement] | file://:0:0:0:0 | (Attributes) | semmle.order | 2 | +| tstest.tsx:11:11:11:31 | [JsxElement] | tstest.tsx:11:12:11:14 | [VarRef] Bar | semmle.label | 0 | +| tstest.tsx:11:11:11:31 | [JsxElement] | tstest.tsx:11:12:11:14 | [VarRef] Bar | semmle.order | 0 | +| tstest.tsx:11:16:11:28 | [JsxAttribute] a : b="hello" | tstest.tsx:11:20:11:20 | [Label] b | semmle.label | 1 | +| tstest.tsx:11:16:11:28 | [JsxAttribute] a : b="hello" | tstest.tsx:11:20:11:20 | [Label] b | semmle.order | 1 | +| tstest.tsx:11:16:11:28 | [JsxAttribute] a : b="hello" | tstest.tsx:11:22:11:28 | [Literal] "hello" | semmle.label | 2 | +| tstest.tsx:11:16:11:28 | [JsxAttribute] a : b="hello" | tstest.tsx:11:22:11:28 | [Literal] "hello" | semmle.order | 2 | +| tstest.tsx:13:1:15:1 | [InterfaceDeclaration,TypeDefinition] interfa ... ring; } | tstest.tsx:13:11:13:18 | [Identifier] BarProps | semmle.label | 1 | +| tstest.tsx:13:1:15:1 | [InterfaceDeclaration,TypeDefinition] interfa ... ring; } | tstest.tsx:13:11:13:18 | [Identifier] BarProps | semmle.order | 1 | +| tstest.tsx:13:1:15:1 | [InterfaceDeclaration,TypeDefinition] interfa ... ring; } | tstest.tsx:14:5:14:18 | [FieldDeclaration] "a:b": string; | semmle.label | 2 | +| tstest.tsx:13:1:15:1 | [InterfaceDeclaration,TypeDefinition] interfa ... ring; } | tstest.tsx:14:5:14:18 | [FieldDeclaration] "a:b": string; | semmle.order | 2 | +| tstest.tsx:14:5:14:18 | [FieldDeclaration] "a:b": string; | tstest.tsx:14:5:14:9 | [Literal] "a:b" | semmle.label | 1 | +| tstest.tsx:14:5:14:18 | [FieldDeclaration] "a:b": string; | tstest.tsx:14:5:14:9 | [Literal] "a:b" | semmle.order | 1 | +| tstest.tsx:14:5:14:18 | [FieldDeclaration] "a:b": string; | tstest.tsx:14:12:14:17 | [KeywordTypeExpr] string | semmle.label | 2 | +| tstest.tsx:14:5:14:18 | [FieldDeclaration] "a:b": string; | tstest.tsx:14:12:14:17 | [KeywordTypeExpr] string | semmle.order | 2 | +| tstest.tsx:17:1:19:1 | [FunctionDeclStmt] functio ... div>; } | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| tstest.tsx:17:1:19:1 | [FunctionDeclStmt] functio ... div>; } | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| tstest.tsx:17:1:19:1 | [FunctionDeclStmt] functio ... div>; } | tstest.tsx:17:10:17:12 | [VarDecl] Bar | semmle.label | 0 | +| tstest.tsx:17:1:19:1 | [FunctionDeclStmt] functio ... div>; } | tstest.tsx:17:10:17:12 | [VarDecl] Bar | semmle.order | 0 | +| tstest.tsx:17:1:19:1 | [FunctionDeclStmt] functio ... div>; } | tstest.tsx:17:31:19:1 | [BlockStmt] { r ... div>; } | semmle.label | 5 | +| tstest.tsx:17:1:19:1 | [FunctionDeclStmt] functio ... div>; } | tstest.tsx:17:31:19:1 | [BlockStmt] { r ... div>; } | semmle.order | 5 | +| tstest.tsx:17:14:17:18 | [SimpleParameter] props | tstest.tsx:17:21:17:28 | [LocalTypeAccess] BarProps | semmle.label | -2 | +| tstest.tsx:17:14:17:18 | [SimpleParameter] props | tstest.tsx:17:21:17:28 | [LocalTypeAccess] BarProps | semmle.order | -2 | +| tstest.tsx:17:31:19:1 | [BlockStmt] { r ... div>; } | tstest.tsx:18:5:18:37 | [ReturnStmt] return ... ; | semmle.label | 1 | +| tstest.tsx:17:31:19:1 | [BlockStmt] { r ... div>; } | tstest.tsx:18:5:18:37 | [ReturnStmt] return ... ; | semmle.order | 1 | +| tstest.tsx:18:5:18:37 | [ReturnStmt] return ... ; | tstest.tsx:18:12:18:36 | [JsxElement]
{p ... }
| semmle.label | 1 | +| tstest.tsx:18:5:18:37 | [ReturnStmt] return ... ; | tstest.tsx:18:12:18:36 | [JsxElement]
{p ... }
| semmle.order | 1 | +| tstest.tsx:18:12:18:36 | [JsxElement]
{p ... }
| file://:0:0:0:0 | (Body) | semmle.label | 1 | +| tstest.tsx:18:12:18:36 | [JsxElement]
{p ... }
| file://:0:0:0:0 | (Body) | semmle.order | 1 | +| tstest.tsx:18:12:18:36 | [JsxElement]
{p ... }
| tstest.tsx:18:13:18:15 | [Label] div | semmle.label | 0 | +| tstest.tsx:18:12:18:36 | [JsxElement]
{p ... }
| tstest.tsx:18:13:18:15 | [Label] div | semmle.order | 0 | +| tstest.tsx:18:18:18:29 | [IndexExpr] props["a:b"] | tstest.tsx:18:18:18:22 | [VarRef] props | semmle.label | 1 | +| tstest.tsx:18:18:18:29 | [IndexExpr] props["a:b"] | tstest.tsx:18:18:18:22 | [VarRef] props | semmle.order | 1 | +| tstest.tsx:18:18:18:29 | [IndexExpr] props["a:b"] | tstest.tsx:18:24:18:28 | [Literal] "a:b" | semmle.label | 2 | +| tstest.tsx:18:18:18:29 | [IndexExpr] props["a:b"] | tstest.tsx:18:24:18:28 | [Literal] "a:b" | semmle.order | 2 | graphProperties | semmle.graphKind | tree | diff --git a/javascript/ql/test/library-tests/JSX/tests.expected b/javascript/ql/test/library-tests/JSX/tests.expected index 974d5608802..50b00601fbe 100644 --- a/javascript/ql/test/library-tests/JSX/tests.expected +++ b/javascript/ql/test/library-tests/JSX/tests.expected @@ -3,6 +3,7 @@ htmlElements | tst.js:6:1:6:10 | | | tstest.tsx:3:1:3:106 | | | tstest.tsx:6:1:6:10 | | +| tstest.tsx:18:12:18:36 |
{p ... }
| jsxElementAttribute | tst.js:3:1:3:106 |
| 0 | tst.js:3:4:3:14 | href={href} | | tst.js:3:1:3:106 | | 1 | tst.js:3:16:3:30 | target="_blank" | @@ -12,6 +13,8 @@ jsxElementAttribute | tstest.tsx:3:1:3:106 | | 1 | tstest.tsx:3:16:3:30 | target="_blank" | | tstest.tsx:3:1:3:106 | | 2 | tstest.tsx:3:32:3:45 | {...linkTypes} | | tstest.tsx:4:1:4:35 | | 0 | tstest.tsx:4:25:4:33 | foo="bar" | +| tstest.tsx:10:11:10:29 | | 0 | tstest.tsx:10:16:10:26 | a:b="hello" | +| tstest.tsx:11:11:11:31 | | 0 | tstest.tsx:11:16:11:28 | a : b="hello" | jsxElementAttributeName | tst.js:3:1:3:106 | | 0 | href | | tst.js:3:1:3:106 | | 1 | target | @@ -19,6 +22,8 @@ jsxElementAttributeName | tstest.tsx:3:1:3:106 | | 0 | href | | tstest.tsx:3:1:3:106 | | 1 | target | | tstest.tsx:4:1:4:35 | | 0 | foo | +| tstest.tsx:10:11:10:29 | | 0 | b | +| tstest.tsx:11:11:11:31 | | 0 | b | jsxElementBody | tst.js:3:1:3:106 | | 0 | tst.js:3:47:3:54 | Link to | | tst.js:3:1:3:106 | | 1 | tst.js:3:56:3:59 | href | @@ -28,6 +33,7 @@ jsxElementBody | tstest.tsx:3:1:3:106 | | 1 | tstest.tsx:3:56:3:59 | href | | tstest.tsx:3:1:3:106 | | 2 | tstest.tsx:3:61:3:62 | . | | tstest.tsx:3:1:3:106 | | 3 | tstest.tsx:3:63:3:102 | {/*TODO ... text*/} | +| tstest.tsx:18:12:18:36 |
{p ... }
| 0 | tstest.tsx:18:18:18:29 | props["a:b"] | jsxElementName | tst.js:3:1:3:106 |
| tst.js:3:2:3:2 | a | a | | tst.js:4:1:4:35 | | tst.js:4:2:4:23 | MyCompo ... ncyLink | MyComponents.FancyLink | @@ -39,6 +45,9 @@ jsxElementName | tstest.tsx:5:1:5:6 | | tstest.tsx:5:2:5:4 | Foo | Foo | | tstest.tsx:6:1:6:10 | | tstest.tsx:6:2:6:8 | Foo-Bar | Foo-Bar | | tstest.tsx:7:33:7:38 | | tstest.tsx:7:34:7:36 | Foo | Foo | +| tstest.tsx:10:11:10:29 | | tstest.tsx:10:12:10:14 | Bar | Bar | +| tstest.tsx:11:11:11:31 | | tstest.tsx:11:12:11:14 | Bar | Bar | +| tstest.tsx:18:12:18:36 |
{p ... }
| tstest.tsx:18:13:18:15 | div | div | jsxFragments | tst.js:7:16:7:52 | <> frag ... ext | 0 | tst.js:7:18:7:32 | fragment text | | tst.js:7:16:7:52 | <> frag ... ext | 1 | tst.js:7:33:7:38 | | diff --git a/javascript/ql/test/library-tests/JSX/tstest.tsx b/javascript/ql/test/library-tests/JSX/tstest.tsx index c1011712e19..966d6ced2fd 100644 --- a/javascript/ql/test/library-tests/JSX/tstest.tsx +++ b/javascript/ql/test/library-tests/JSX/tstest.tsx @@ -5,3 +5,15 @@ var linkTypes = { rel: "noopener noreferrer" }; ; // interpreted as a custom component because of capitalisation ; // interpreted as an HTML element because of the dash var fragment = <> fragment text more text + +// Both of these are equivalent: +const x = ; +const y = ; + +interface BarProps { + "a:b": string; +} + +function Bar(props: BarProps) { + return
{props["a:b"]}
; +} \ No newline at end of file