diff --git a/javascript/extractor/src/com/semmle/jcorn/Parser.java b/javascript/extractor/src/com/semmle/jcorn/Parser.java index 5f7383813c6..cd790f90483 100644 --- a/javascript/extractor/src/com/semmle/jcorn/Parser.java +++ b/javascript/extractor/src/com/semmle/jcorn/Parser.java @@ -3219,7 +3219,7 @@ public class Parser { Expression superClass = this.parseClassSuper(); Position bodyStartLoc = this.startLoc; boolean hadConstructor = false; - List> body = new ArrayList>(); + List body = new ArrayList<>(); // TODO: The JS parser doesn't support static initializer blocks. this.expect(TokenType.braceL); while (!this.eat(TokenType.braceR)) { if (this.eat(TokenType.semi)) continue; diff --git a/javascript/extractor/src/com/semmle/js/ast/ClassBody.java b/javascript/extractor/src/com/semmle/js/ast/ClassBody.java index beb23ae3a3e..a99758a3701 100644 --- a/javascript/extractor/src/com/semmle/js/ast/ClassBody.java +++ b/javascript/extractor/src/com/semmle/js/ast/ClassBody.java @@ -4,23 +4,23 @@ import java.util.List; /** The body of a {@linkplain ClassDeclaration} or {@linkplain ClassExpression}. */ public class ClassBody extends Node { - private final List> body; + private final List body; // either MemberDefintion or BlockStatement (static initialization blocks) - public ClassBody(SourceLocation loc, List> body) { + public ClassBody(SourceLocation loc, List body) { super("ClassBody", loc); this.body = body; } - public List> getBody() { + public List getBody() { return body; } - public void addMember(MemberDefinition md) { + public void addMember(Node md) { body.add(md); } public MethodDefinition getConstructor() { - for (MemberDefinition md : body) if (md.isConstructor()) return (MethodDefinition) md; + for (Node md : body) if (md instanceof MethodDefinition && ((MethodDefinition)md).isConstructor()) return (MethodDefinition) md; return null; } diff --git a/javascript/extractor/src/com/semmle/js/extractor/CFGExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/CFGExtractor.java index 85dd13146fb..1316227de3e 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/CFGExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/CFGExtractor.java @@ -454,7 +454,7 @@ public class CFGExtractor { @Override public Node visit(ClassBody nd, Void v) { - for (MemberDefinition m : nd.getBody()) { + for (Node m : nd.getBody()) { if (m instanceof MethodDefinition) { Node first = m.accept(this, v); if (first != null) return first; @@ -1163,10 +1163,14 @@ public class CFGExtractor { private Map constructor2Class = new LinkedHashMap<>(); private Void visit(Node nd, AClass ac, SuccessorInfo i) { - for (MemberDefinition m : ac.getBody().getBody()) - if (m.isConstructor() && m.isConcrete()) constructor2Class.put(m.getValue(), ac); + for (Node m : ac.getBody().getBody()) { + if (m instanceof MemberDefinition) { + MemberDefinition md = (MemberDefinition) m; + if (md.isConstructor() && md.isConcrete()) constructor2Class.put(md.getValue(), ac); + } + } visitSequence(ac.getId(), ac.getSuperClass(), ac.getBody(), nd); - writeSuccessors(nd, visitSequence(getStaticFields(ac.getBody()), getDecoratorsOfClass(ac), i.getAllSuccessors())); + writeSuccessors(nd, visitSequence(getStaticInitializers(ac.getBody()), getDecoratorsOfClass(ac), i.getAllSuccessors())); return null; } @@ -1203,15 +1207,18 @@ public class CFGExtractor { List staticDecorators = new ArrayList<>(); List constructorParameterDecorators = new ArrayList<>(); List classDecorators = (List)(List)ac.getDecorators(); - for (MemberDefinition member : ac.getBody().getBody()) { - if (!member.isConcrete()) continue; - List decorators = getMemberDecorators(member); - if (member.isConstructor()) { - constructorParameterDecorators.addAll(decorators); - } else if (member.isStatic()) { - staticDecorators.addAll(decorators); - } else { - instanceDecorators.addAll(decorators); + for (Node memberNode : ac.getBody().getBody()) { + if (memberNode instanceof MemberDefinition) { + MemberDefinition member = (MemberDefinition) memberNode; + if (!member.isConcrete()) continue; + List decorators = getMemberDecorators(member); + if (member.isConstructor()) { + constructorParameterDecorators.addAll(decorators); + } else if (member.isStatic()) { + staticDecorators.addAll(decorators); + } else { + instanceDecorators.addAll(decorators); + } } } List result = new ArrayList<>(); @@ -1612,25 +1619,32 @@ public class CFGExtractor { private List> getMethods(ClassBody nd) { List> mds = new ArrayList<>(); - for (MemberDefinition md : nd.getBody()) { - if (md instanceof MethodDefinition) mds.add(md); + for (Node md : nd.getBody()) { + if (md instanceof MethodDefinition) mds.add((MemberDefinition)md); } return mds; } - private List> getStaticFields(ClassBody nd) { - List> mds = new ArrayList<>(); - for (MemberDefinition md : nd.getBody()) { - if (md instanceof FieldDefinition && md.isStatic()) mds.add(md); + /** + * Gets the static fields, and static initializer blocks, from `nd`. + */ + private List getStaticInitializers(ClassBody nd) { + List nodes = new ArrayList<>(); + for (Node node : nd.getBody()) { + if (node instanceof FieldDefinition && ((FieldDefinition)node).isStatic()) nodes.add(node); + if (node instanceof BlockStatement) nodes.add(node); } - return mds; + return nodes; } private List getConcreteInstanceFields(ClassBody nd) { List fds = new ArrayList<>(); - for (MemberDefinition md : nd.getBody()) + for (Node node : nd.getBody()) { + if (!(node instanceof MemberDefinition)) continue; + MemberDefinition md = (MemberDefinition)node; if (md instanceof FieldDefinition && !md.isStatic() && md.isConcrete()) fds.add((FieldDefinition) md); + } return fds; } diff --git a/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java b/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java index f8ad99915c9..448564cfbc7 100644 --- a/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java +++ b/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java @@ -632,6 +632,8 @@ public class TypeScriptASTConverter { return convertWithStatement(node, loc); case "YieldExpression": return convertYieldExpression(node, loc); + case "ClassStaticBlockDeclaration": + return convertStaticInitializerBlock(node, loc); default: throw new ParseError( "Unsupported TypeScript syntax " + kind, getSourceLocation(node).getStart()); @@ -866,6 +868,10 @@ public class TypeScriptASTConverter { } } + private Node convertStaticInitializerBlock(JsonObject node, SourceLocation loc) throws ParseError { + return new BlockStatement(loc, convertChildren(node.get("body").getAsJsonObject(), "statements")); + } + private Node convertBlock(JsonObject node, SourceLocation loc) throws ParseError { return new BlockStatement(loc, convertChildren(node, "statements")); } diff --git a/javascript/ql/test/library-tests/CFG/CFG.expected b/javascript/ql/test/library-tests/CFG/CFG.expected index a41f1c4999a..235b4f73183 100644 --- a/javascript/ql/test/library-tests/CFG/CFG.expected +++ b/javascript/ql/test/library-tests/CFG/CFG.expected @@ -770,7 +770,37 @@ | staticFieldsTS | 6 | D | 6 | new D() | | staticFieldsTS | 6 | instance | 6 | D | | staticFieldsTS | 6 | new D() | 6 | static ... ew D(); | -| staticFieldsTS | 6 | static ... ew D(); | 8 | exit node of | +| staticFieldsTS | 6 | static ... ew D(); | 9 | export ... ;\\n }\\n} | +| staticFieldsTS | 9 | E | 9 | constructor | +| staticFieldsTS | 9 | class E ... ;\\n }\\n} | 10 | f | +| staticFieldsTS | 9 | constructor | 9 | function in constructor() {} | +| staticFieldsTS | 9 | constructor() {} | 9 | class E ... ;\\n }\\n} | +| staticFieldsTS | 9 | entry node of () {} | 9 | {} | +| staticFieldsTS | 9 | export ... ;\\n }\\n} | 9 | E | +| staticFieldsTS | 9 | function in constructor() {} | 9 | constructor() {} | +| staticFieldsTS | 9 | {} | 9 | exit node of () {} | +| staticFieldsTS | 10 | f | 10 | false | +| staticFieldsTS | 10 | false | 10 | static ... false; | +| staticFieldsTS | 10 | static ... false; | 11 | static ... ();\\n } | +| staticFieldsTS | 11 | static ... ();\\n } | 12 | E.f = new C(); | +| staticFieldsTS | 12 | C | 12 | new C() | +| staticFieldsTS | 12 | E | 12 | f | +| staticFieldsTS | 12 | E.f | 12 | C | +| staticFieldsTS | 12 | E.f = new C() | 14 | g | +| staticFieldsTS | 12 | E.f = new C(); | 12 | E | +| staticFieldsTS | 12 | f | 12 | E.f | +| staticFieldsTS | 12 | new C() | 12 | E.f = new C() | +| staticFieldsTS | 14 | 1337 | 14 | static ... = 1337; | +| staticFieldsTS | 14 | g | 14 | 1337 | +| staticFieldsTS | 14 | static ... = 1337; | 15 | static ... ();\\n } | +| staticFieldsTS | 15 | static ... ();\\n } | 16 | E.g = new D(); | +| staticFieldsTS | 16 | D | 16 | new D() | +| staticFieldsTS | 16 | E | 16 | g | +| staticFieldsTS | 16 | E.g | 16 | D | +| staticFieldsTS | 16 | E.g = new D() | 18 | exit node of | +| staticFieldsTS | 16 | E.g = new D(); | 16 | E | +| staticFieldsTS | 16 | g | 16 | E.g | +| staticFieldsTS | 16 | new D() | 16 | E.g = new D() | | switch | 1 | entry node of | 14 | f | | switch | 1 | switch ... 19;\\n} | 2 | x | | switch | 2 | x | 6 | case\\n ... 19; | diff --git a/javascript/ql/test/library-tests/CFG/StaticInit.expected b/javascript/ql/test/library-tests/CFG/StaticInit.expected index 95e41584cdc..1da2f66503c 100644 --- a/javascript/ql/test/library-tests/CFG/StaticInit.expected +++ b/javascript/ql/test/library-tests/CFG/StaticInit.expected @@ -14,3 +14,5 @@ | staticFields.js:2:3:2:28 | static ... ew C(); | Field initializer occurs after its class is created | | staticFieldsTS.ts:2:3:2:31 | static ... ew C(); | Field initializer occurs after its class is created | | staticFieldsTS.ts:6:3:6:31 | static ... ew D(); | Field initializer occurs after its class is created | +| staticFieldsTS.ts:10:3:10:32 | static ... false; | Field initializer occurs after its class is created | +| staticFieldsTS.ts:14:3:14:30 | static ... = 1337; | Field initializer occurs after its class is created | diff --git a/javascript/ql/test/library-tests/CFG/staticFieldsTS.ts b/javascript/ql/test/library-tests/CFG/staticFieldsTS.ts index ca394de8265..77a17831958 100644 --- a/javascript/ql/test/library-tests/CFG/staticFieldsTS.ts +++ b/javascript/ql/test/library-tests/CFG/staticFieldsTS.ts @@ -5,3 +5,14 @@ class C { export class D { static instance: D = new D(); } + +export class E { + static f: C | boolean = false; + static { + E.f = new C(); + } + static g: D | number = 1337; + static { + E.g = new D(); + } +} \ No newline at end of file diff --git a/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected b/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected index 9f911cf8da2..5aca25ff803 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected +++ b/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected @@ -599,8 +599,8 @@ nodes | tst.ts:127:14:127:17 | [ThisExpr] this | semmle.label | [ThisExpr] this | | tst.ts:127:14:127:28 | [DotExpr] this.#someValue | semmle.label | [DotExpr] this.#someValue | | tst.ts:127:19:127:28 | [Label] #someValue | semmle.label | [Label] #someValue | -| tst.ts:132:1:178:1 | [NamespaceDeclaration] module ... ; } } | semmle.label | [NamespaceDeclaration] module ... ; } } | -| tst.ts:132:1:178:1 | [NamespaceDeclaration] module ... ; } } | semmle.order | 56 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | semmle.label | [NamespaceDeclaration] module ... } } | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | semmle.order | 56 | | tst.ts:132:8:132:11 | [VarDecl] TS44 | semmle.label | [VarDecl] TS44 | | tst.ts:133:3:138:3 | [FunctionDeclStmt] functio ... } } | semmle.label | [FunctionDeclStmt] functio ... } } | | tst.ts:133:12:133:14 | [VarDecl] foo | semmle.label | [VarDecl] foo | @@ -757,6 +757,37 @@ nodes | tst.ts:176:17:176:20 | [VarRef] data | semmle.label | [VarRef] data | | tst.ts:176:17:176:27 | [IndexExpr] data["foo"] | semmle.label | [IndexExpr] data["foo"] | | tst.ts:176:22:176:26 | [Literal] "foo" | semmle.label | [Literal] "foo" | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | semmle.label | [ClassDefinition,TypeDefinition] class F ... } | +| tst.ts:179:9:179:11 | [VarDecl] Foo | semmle.label | [VarDecl] Foo | +| tst.ts:179:13:179:12 | [BlockStmt] {} | semmle.label | [BlockStmt] {} | +| tst.ts:179:13:179:12 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | [ClassInitializedMember,ConstructorDefinition] constructor() {} | +| tst.ts:179:13:179:12 | [FunctionExpr] () {} | semmle.label | [FunctionExpr] () {} | +| tst.ts:179:13:179:12 | [Label] constructor | semmle.label | [Label] constructor | +| tst.ts:180:5:180:22 | [ClassInitializedMember,FieldDeclaration] static #count = 0; | semmle.label | [ClassInitializedMember,FieldDeclaration] static #count = 0; | +| tst.ts:180:12:180:17 | [Label] #count | semmle.label | [Label] #count | +| tst.ts:180:21:180:21 | [Literal] 0 | semmle.label | [Literal] 0 | +| tst.ts:182:5:184:5 | [ClassInitializedMember,GetterMethodDefinition] get cou ... ; } | semmle.label | [ClassInitializedMember,GetterMethodDefinition] get cou ... ; } | +| tst.ts:182:5:184:5 | [FunctionExpr] get cou ... ; } | semmle.label | [FunctionExpr] get cou ... ; } | +| tst.ts:182:9:182:13 | [Label] count | semmle.label | [Label] count | +| tst.ts:182:17:184:5 | [BlockStmt] { ... ; } | semmle.label | [BlockStmt] { ... ; } | +| tst.ts:183:9:183:26 | [ReturnStmt] return Foo.#count; | semmle.label | [ReturnStmt] return Foo.#count; | +| tst.ts:183:16:183:18 | [VarRef] Foo | semmle.label | [VarRef] Foo | +| tst.ts:183:16:183:25 | [DotExpr] Foo.#count | semmle.label | [DotExpr] Foo.#count | +| tst.ts:183:20:183:25 | [Label] #count | semmle.label | [Label] #count | +| tst.ts:185:5:187:5 | [BlockStmt] static ... ; } | semmle.label | [BlockStmt] static ... ; } | +| tst.ts:186:7:186:9 | [VarRef] Foo | semmle.label | [VarRef] Foo | +| tst.ts:186:7:186:16 | [DotExpr] Foo.#count | semmle.label | [DotExpr] Foo.#count | +| tst.ts:186:7:186:21 | [CompoundAssignExpr] Foo.#count += 3 | semmle.label | [CompoundAssignExpr] Foo.#count += 3 | +| tst.ts:186:7:186:22 | [ExprStmt] Foo.#count += 3; | semmle.label | [ExprStmt] Foo.#count += 3; | +| tst.ts:186:11:186:16 | [Label] #count | semmle.label | [Label] #count | +| tst.ts:186:21:186:21 | [Literal] 3 | semmle.label | [Literal] 3 | +| tst.ts:188:5:190:5 | [BlockStmt] static ... ; } | semmle.label | [BlockStmt] static ... ; } | +| tst.ts:189:7:189:29 | [DeclStmt] var count = ... | semmle.label | [DeclStmt] var count = ... | +| tst.ts:189:11:189:15 | [VarDecl] count | semmle.label | [VarDecl] count | +| tst.ts:189:11:189:28 | [VariableDeclarator] count = Foo.#count | semmle.label | [VariableDeclarator] count = Foo.#count | +| tst.ts:189:19:189:21 | [VarRef] Foo | semmle.label | [VarRef] Foo | +| tst.ts:189:19:189:28 | [DotExpr] Foo.#count | semmle.label | [DotExpr] Foo.#count | +| tst.ts:189:23:189:28 | [Label] #count | semmle.label | [Label] #count | | type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | | type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.order | 57 | | type_alias.ts:1:6:1:6 | [Identifier] B | semmle.label | [Identifier] B | @@ -1942,18 +1973,20 @@ edges | tst.ts:127:14:127:28 | [DotExpr] this.#someValue | tst.ts:127:14:127:17 | [ThisExpr] this | semmle.order | 1 | | tst.ts:127:14:127:28 | [DotExpr] this.#someValue | tst.ts:127:19:127:28 | [Label] #someValue | semmle.label | 2 | | tst.ts:127:14:127:28 | [DotExpr] this.#someValue | tst.ts:127:19:127:28 | [Label] #someValue | semmle.order | 2 | -| tst.ts:132:1:178:1 | [NamespaceDeclaration] module ... ; } } | tst.ts:132:8:132:11 | [VarDecl] TS44 | semmle.label | 1 | -| tst.ts:132:1:178:1 | [NamespaceDeclaration] module ... ; } } | tst.ts:132:8:132:11 | [VarDecl] TS44 | semmle.order | 1 | -| tst.ts:132:1:178:1 | [NamespaceDeclaration] module ... ; } } | tst.ts:133:3:138:3 | [FunctionDeclStmt] functio ... } } | semmle.label | 2 | -| tst.ts:132:1:178:1 | [NamespaceDeclaration] module ... ; } } | tst.ts:133:3:138:3 | [FunctionDeclStmt] functio ... } } | semmle.order | 2 | -| tst.ts:132:1:178:1 | [NamespaceDeclaration] module ... ; } } | tst.ts:140:3:142:47 | [TypeAliasDeclaration,TypeDefinition] type Sh ... mber }; | semmle.label | 3 | -| tst.ts:132:1:178:1 | [NamespaceDeclaration] module ... ; } } | tst.ts:140:3:142:47 | [TypeAliasDeclaration,TypeDefinition] type Sh ... mber }; | semmle.order | 3 | -| tst.ts:132:1:178:1 | [NamespaceDeclaration] module ... ; } } | tst.ts:144:3:149:3 | [FunctionDeclStmt] functio ... ; } } | semmle.label | 4 | -| tst.ts:132:1:178:1 | [NamespaceDeclaration] module ... ; } } | tst.ts:144:3:149:3 | [FunctionDeclStmt] functio ... ; } } | semmle.order | 4 | -| tst.ts:132:1:178:1 | [NamespaceDeclaration] module ... ; } } | tst.ts:151:3:162:3 | [FunctionDeclStmt] functio ... 2]; } | semmle.label | 5 | -| tst.ts:132:1:178:1 | [NamespaceDeclaration] module ... ; } } | tst.ts:151:3:162:3 | [FunctionDeclStmt] functio ... 2]; } | semmle.order | 5 | -| tst.ts:132:1:178:1 | [NamespaceDeclaration] module ... ; } } | tst.ts:164:3:177:3 | [FunctionDeclStmt] functio ... "]; } | semmle.label | 6 | -| tst.ts:132:1:178:1 | [NamespaceDeclaration] module ... ; } } | tst.ts:164:3:177:3 | [FunctionDeclStmt] functio ... "]; } | semmle.order | 6 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:132:8:132:11 | [VarDecl] TS44 | semmle.label | 1 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:132:8:132:11 | [VarDecl] TS44 | semmle.order | 1 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:133:3:138:3 | [FunctionDeclStmt] functio ... } } | semmle.label | 2 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:133:3:138:3 | [FunctionDeclStmt] functio ... } } | semmle.order | 2 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:140:3:142:47 | [TypeAliasDeclaration,TypeDefinition] type Sh ... mber }; | semmle.label | 3 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:140:3:142:47 | [TypeAliasDeclaration,TypeDefinition] type Sh ... mber }; | semmle.order | 3 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:144:3:149:3 | [FunctionDeclStmt] functio ... ; } } | semmle.label | 4 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:144:3:149:3 | [FunctionDeclStmt] functio ... ; } } | semmle.order | 4 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:151:3:162:3 | [FunctionDeclStmt] functio ... 2]; } | semmle.label | 5 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:151:3:162:3 | [FunctionDeclStmt] functio ... 2]; } | semmle.order | 5 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:164:3:177:3 | [FunctionDeclStmt] functio ... "]; } | semmle.label | 6 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:164:3:177:3 | [FunctionDeclStmt] functio ... "]; } | semmle.order | 6 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | semmle.label | 7 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | semmle.order | 7 | | tst.ts:133:3:138:3 | [FunctionDeclStmt] functio ... } } | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | | tst.ts:133:3:138:3 | [FunctionDeclStmt] functio ... } } | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | | tst.ts:133:3:138:3 | [FunctionDeclStmt] functio ... } } | tst.ts:133:12:133:14 | [VarDecl] foo | semmle.label | 0 | @@ -2254,6 +2287,66 @@ edges | tst.ts:176:17:176:27 | [IndexExpr] data["foo"] | tst.ts:176:17:176:20 | [VarRef] data | semmle.order | 1 | | tst.ts:176:17:176:27 | [IndexExpr] data["foo"] | tst.ts:176:22:176:26 | [Literal] "foo" | semmle.label | 2 | | tst.ts:176:17:176:27 | [IndexExpr] data["foo"] | tst.ts:176:22:176:26 | [Literal] "foo" | semmle.order | 2 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:179:9:179:11 | [VarDecl] Foo | semmle.label | 1 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:179:9:179:11 | [VarDecl] Foo | semmle.order | 1 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:179:13:179:12 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | 2 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:179:13:179:12 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.order | 2 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:180:5:180:22 | [ClassInitializedMember,FieldDeclaration] static #count = 0; | semmle.label | 3 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:180:5:180:22 | [ClassInitializedMember,FieldDeclaration] static #count = 0; | semmle.order | 3 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:182:5:184:5 | [ClassInitializedMember,GetterMethodDefinition] get cou ... ; } | semmle.label | 4 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:182:5:184:5 | [ClassInitializedMember,GetterMethodDefinition] get cou ... ; } | semmle.order | 4 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:185:5:187:5 | [BlockStmt] static ... ; } | semmle.label | 5 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:185:5:187:5 | [BlockStmt] static ... ; } | semmle.order | 5 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:188:5:190:5 | [BlockStmt] static ... ; } | semmle.label | 6 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:188:5:190:5 | [BlockStmt] static ... ; } | semmle.order | 6 | +| tst.ts:179:13:179:12 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:179:13:179:12 | [FunctionExpr] () {} | semmle.label | 2 | +| tst.ts:179:13:179:12 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:179:13:179:12 | [FunctionExpr] () {} | semmle.order | 2 | +| tst.ts:179:13:179:12 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:179:13:179:12 | [Label] constructor | semmle.label | 1 | +| tst.ts:179:13:179:12 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:179:13:179:12 | [Label] constructor | semmle.order | 1 | +| tst.ts:179:13:179:12 | [FunctionExpr] () {} | tst.ts:179:13:179:12 | [BlockStmt] {} | semmle.label | 5 | +| tst.ts:179:13:179:12 | [FunctionExpr] () {} | tst.ts:179:13:179:12 | [BlockStmt] {} | semmle.order | 5 | +| tst.ts:180:5:180:22 | [ClassInitializedMember,FieldDeclaration] static #count = 0; | tst.ts:180:12:180:17 | [Label] #count | semmle.label | 1 | +| tst.ts:180:5:180:22 | [ClassInitializedMember,FieldDeclaration] static #count = 0; | tst.ts:180:12:180:17 | [Label] #count | semmle.order | 1 | +| tst.ts:180:5:180:22 | [ClassInitializedMember,FieldDeclaration] static #count = 0; | tst.ts:180:21:180:21 | [Literal] 0 | semmle.label | 2 | +| tst.ts:180:5:180:22 | [ClassInitializedMember,FieldDeclaration] static #count = 0; | tst.ts:180:21:180:21 | [Literal] 0 | semmle.order | 2 | +| tst.ts:182:5:184:5 | [ClassInitializedMember,GetterMethodDefinition] get cou ... ; } | tst.ts:182:5:184:5 | [FunctionExpr] get cou ... ; } | semmle.label | 1 | +| tst.ts:182:5:184:5 | [ClassInitializedMember,GetterMethodDefinition] get cou ... ; } | tst.ts:182:5:184:5 | [FunctionExpr] get cou ... ; } | semmle.order | 1 | +| tst.ts:182:5:184:5 | [ClassInitializedMember,GetterMethodDefinition] get cou ... ; } | tst.ts:182:9:182:13 | [Label] count | semmle.label | 2 | +| tst.ts:182:5:184:5 | [ClassInitializedMember,GetterMethodDefinition] get cou ... ; } | tst.ts:182:9:182:13 | [Label] count | semmle.order | 2 | +| tst.ts:182:5:184:5 | [FunctionExpr] get cou ... ; } | tst.ts:182:17:184:5 | [BlockStmt] { ... ; } | semmle.label | 5 | +| tst.ts:182:5:184:5 | [FunctionExpr] get cou ... ; } | tst.ts:182:17:184:5 | [BlockStmt] { ... ; } | semmle.order | 5 | +| tst.ts:182:17:184:5 | [BlockStmt] { ... ; } | tst.ts:183:9:183:26 | [ReturnStmt] return Foo.#count; | semmle.label | 1 | +| tst.ts:182:17:184:5 | [BlockStmt] { ... ; } | tst.ts:183:9:183:26 | [ReturnStmt] return Foo.#count; | semmle.order | 1 | +| tst.ts:183:9:183:26 | [ReturnStmt] return Foo.#count; | tst.ts:183:16:183:25 | [DotExpr] Foo.#count | semmle.label | 1 | +| tst.ts:183:9:183:26 | [ReturnStmt] return Foo.#count; | tst.ts:183:16:183:25 | [DotExpr] Foo.#count | semmle.order | 1 | +| tst.ts:183:16:183:25 | [DotExpr] Foo.#count | tst.ts:183:16:183:18 | [VarRef] Foo | semmle.label | 1 | +| tst.ts:183:16:183:25 | [DotExpr] Foo.#count | tst.ts:183:16:183:18 | [VarRef] Foo | semmle.order | 1 | +| tst.ts:183:16:183:25 | [DotExpr] Foo.#count | tst.ts:183:20:183:25 | [Label] #count | semmle.label | 2 | +| tst.ts:183:16:183:25 | [DotExpr] Foo.#count | tst.ts:183:20:183:25 | [Label] #count | semmle.order | 2 | +| tst.ts:185:5:187:5 | [BlockStmt] static ... ; } | tst.ts:186:7:186:22 | [ExprStmt] Foo.#count += 3; | semmle.label | 1 | +| tst.ts:185:5:187:5 | [BlockStmt] static ... ; } | tst.ts:186:7:186:22 | [ExprStmt] Foo.#count += 3; | semmle.order | 1 | +| tst.ts:186:7:186:16 | [DotExpr] Foo.#count | tst.ts:186:7:186:9 | [VarRef] Foo | semmle.label | 1 | +| tst.ts:186:7:186:16 | [DotExpr] Foo.#count | tst.ts:186:7:186:9 | [VarRef] Foo | semmle.order | 1 | +| tst.ts:186:7:186:16 | [DotExpr] Foo.#count | tst.ts:186:11:186:16 | [Label] #count | semmle.label | 2 | +| tst.ts:186:7:186:16 | [DotExpr] Foo.#count | tst.ts:186:11:186:16 | [Label] #count | semmle.order | 2 | +| tst.ts:186:7:186:21 | [CompoundAssignExpr] Foo.#count += 3 | tst.ts:186:7:186:16 | [DotExpr] Foo.#count | semmle.label | 1 | +| tst.ts:186:7:186:21 | [CompoundAssignExpr] Foo.#count += 3 | tst.ts:186:7:186:16 | [DotExpr] Foo.#count | semmle.order | 1 | +| tst.ts:186:7:186:21 | [CompoundAssignExpr] Foo.#count += 3 | tst.ts:186:21:186:21 | [Literal] 3 | semmle.label | 2 | +| tst.ts:186:7:186:21 | [CompoundAssignExpr] Foo.#count += 3 | tst.ts:186:21:186:21 | [Literal] 3 | semmle.order | 2 | +| tst.ts:186:7:186:22 | [ExprStmt] Foo.#count += 3; | tst.ts:186:7:186:21 | [CompoundAssignExpr] Foo.#count += 3 | semmle.label | 1 | +| tst.ts:186:7:186:22 | [ExprStmt] Foo.#count += 3; | tst.ts:186:7:186:21 | [CompoundAssignExpr] Foo.#count += 3 | semmle.order | 1 | +| tst.ts:188:5:190:5 | [BlockStmt] static ... ; } | tst.ts:189:7:189:29 | [DeclStmt] var count = ... | semmle.label | 1 | +| tst.ts:188:5:190:5 | [BlockStmt] static ... ; } | tst.ts:189:7:189:29 | [DeclStmt] var count = ... | semmle.order | 1 | +| tst.ts:189:7:189:29 | [DeclStmt] var count = ... | tst.ts:189:11:189:28 | [VariableDeclarator] count = Foo.#count | semmle.label | 1 | +| tst.ts:189:7:189:29 | [DeclStmt] var count = ... | tst.ts:189:11:189:28 | [VariableDeclarator] count = Foo.#count | semmle.order | 1 | +| tst.ts:189:11:189:28 | [VariableDeclarator] count = Foo.#count | tst.ts:189:11:189:15 | [VarDecl] count | semmle.label | 1 | +| tst.ts:189:11:189:28 | [VariableDeclarator] count = Foo.#count | tst.ts:189:11:189:15 | [VarDecl] count | semmle.order | 1 | +| tst.ts:189:11:189:28 | [VariableDeclarator] count = Foo.#count | tst.ts:189:19:189:28 | [DotExpr] Foo.#count | semmle.label | 2 | +| tst.ts:189:11:189:28 | [VariableDeclarator] count = Foo.#count | tst.ts:189:19:189:28 | [DotExpr] Foo.#count | semmle.order | 2 | +| tst.ts:189:19:189:28 | [DotExpr] Foo.#count | tst.ts:189:19:189:21 | [VarRef] Foo | semmle.label | 1 | +| tst.ts:189:19:189:28 | [DotExpr] Foo.#count | tst.ts:189:19:189:21 | [VarRef] Foo | semmle.order | 1 | +| tst.ts:189:19:189:28 | [DotExpr] Foo.#count | tst.ts:189:23:189:28 | [Label] #count | semmle.label | 2 | +| tst.ts:189:19:189:28 | [DotExpr] Foo.#count | tst.ts:189:23:189:28 | [Label] #count | semmle.order | 2 | | type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | type_alias.ts:1:6:1:6 | [Identifier] B | semmle.label | 1 | | type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | type_alias.ts:1:6:1:6 | [Identifier] B | semmle.order | 1 | | type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | type_alias.ts:1:10:1:16 | [KeywordTypeExpr] boolean | semmle.label | 2 | diff --git a/javascript/ql/test/library-tests/TypeScript/Types/tests.expected b/javascript/ql/test/library-tests/TypeScript/Types/tests.expected index bee3610f28d..34f46ca29dc 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/tests.expected +++ b/javascript/ql/test/library-tests/TypeScript/Types/tests.expected @@ -247,6 +247,19 @@ getExprType | tst.ts:176:17:176:20 | data | Data | | tst.ts:176:17:176:27 | data["foo"] | boolean | | tst.ts:176:22:176:26 | "foo" | "foo" | +| tst.ts:179:9:179:11 | Foo | Foo | +| tst.ts:180:21:180:21 | 0 | 0 | +| tst.ts:182:5:184:5 | get cou ... ;\\n } | number | +| tst.ts:182:9:182:13 | count | number | +| tst.ts:183:16:183:18 | Foo | typeof Foo in tst.ts:132 | +| tst.ts:183:16:183:25 | Foo.#count | number | +| tst.ts:186:7:186:9 | Foo | typeof Foo in tst.ts:132 | +| tst.ts:186:7:186:16 | Foo.#count | number | +| tst.ts:186:7:186:21 | Foo.#count += 3 | number | +| tst.ts:186:21:186:21 | 3 | 3 | +| tst.ts:189:11:189:15 | count | number | +| tst.ts:189:19:189:21 | Foo | typeof Foo in tst.ts:132 | +| tst.ts:189:19:189:28 | Foo.#count | number | | type_alias.ts:3:5:3:5 | b | boolean | | type_alias.ts:7:5:7:5 | c | ValueOrArray | | type_alias.ts:14:9:14:32 | [proper ... ]: Json | any | @@ -309,6 +322,7 @@ getTypeDefinitionType | tst.ts:152:5:156:5 | interfa ... ;\\n } | Colors | | tst.ts:165:5:167:5 | interfa ... ;\\n } | Foo | | tst.ts:171:5:173:5 | interfa ... ;\\n } | Data | +| tst.ts:179:3:192:3 | class F ... \\n } | Foo | | type_alias.ts:1:1:1:17 | type B = boolean; | boolean | | type_alias.ts:5:1:5:50 | type Va ... ay>; | ValueOrArray | | type_alias.ts:9:1:15:13 | type Js ... Json[]; | Json | @@ -551,6 +565,7 @@ referenceDefinition | EnumWithOneMember | type_definitions.ts:18:26:18:31 | member | | Foo | tst.ts:116:3:129:3 | class F ... }\\n } | | Foo | tst.ts:165:5:167:5 | interfa ... ;\\n } | +| Foo | tst.ts:179:3:192:3 | class F ... \\n } | | HasArea | tst.ts:58:1:60:1 | interfa ... mber;\\n} | | I | type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} | | I | type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} | diff --git a/javascript/ql/test/library-tests/TypeScript/Types/tst.ts b/javascript/ql/test/library-tests/TypeScript/Types/tst.ts index aca96f28f25..0db050b2f49 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/tst.ts +++ b/javascript/ql/test/library-tests/TypeScript/Types/tst.ts @@ -175,4 +175,19 @@ module TS44 { const data: Data = {}; const baz = data["foo"]; } + + class Foo { + static #count = 0; + + get count() { + return Foo.#count; + } + static { + Foo.#count += 3; + } + static { + var count = Foo.#count; + } + + } } \ No newline at end of file