Skip to content

Commit f1f21b4

Browse files
committed
Merged ES6Class into FunctionStyleClass
1 parent 008dd3f commit f1f21b4

File tree

2 files changed

+147
-79
lines changed

2 files changed

+147
-79
lines changed

javascript/ql/lib/semmle/javascript/dataflow/Nodes.qll

Lines changed: 56 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,81 +1214,6 @@ module ClassNode {
12141214
DataFlow::Node getADecorator() { none() }
12151215
}
12161216

1217-
/**
1218-
* An ES6 class as a `ClassNode` instance.
1219-
*/
1220-
private class ES6Class extends Range, DataFlow::ValueNode {
1221-
override ClassDefinition astNode;
1222-
1223-
override string getName() { result = astNode.getName() }
1224-
1225-
override string describe() { result = astNode.describe() }
1226-
1227-
override FunctionNode getConstructor() { result = astNode.getConstructor().getBody().flow() }
1228-
1229-
override FunctionNode getInstanceMember(string name, MemberKind kind) {
1230-
exists(MethodDeclaration method |
1231-
method = astNode.getMethod(name) and
1232-
not method.isStatic() and
1233-
kind = MemberKind::of(method) and
1234-
result = method.getBody().flow()
1235-
)
1236-
or
1237-
kind = MemberKind::method() and
1238-
result = this.getConstructor().getReceiver().getAPropertySource(name)
1239-
}
1240-
1241-
override FunctionNode getAnInstanceMember(MemberKind kind) {
1242-
exists(MethodDeclaration method |
1243-
method = astNode.getAMethod() and
1244-
not method.isStatic() and
1245-
kind = MemberKind::of(method) and
1246-
result = method.getBody().flow()
1247-
)
1248-
or
1249-
kind = MemberKind::method() and
1250-
result = this.getConstructor().getReceiver().getAPropertySource()
1251-
}
1252-
1253-
override FunctionNode getStaticMember(string name, MemberKind kind) {
1254-
exists(MethodDeclaration method |
1255-
method = astNode.getMethod(name) and
1256-
method.isStatic() and
1257-
kind = MemberKind::of(method) and
1258-
result = method.getBody().flow()
1259-
)
1260-
or
1261-
kind.isMethod() and
1262-
result = this.getAPropertySource(name)
1263-
}
1264-
1265-
override FunctionNode getAStaticMember(MemberKind kind) {
1266-
exists(MethodDeclaration method |
1267-
method = astNode.getAMethod() and
1268-
method.isStatic() and
1269-
kind = MemberKind::of(method) and
1270-
result = method.getBody().flow()
1271-
)
1272-
or
1273-
kind.isMethod() and
1274-
result = this.getAPropertySource()
1275-
}
1276-
1277-
override DataFlow::Node getASuperClassNode() { result = astNode.getSuperClass().flow() }
1278-
1279-
override TypeAnnotation getFieldTypeAnnotation(string fieldName) {
1280-
exists(FieldDeclaration field |
1281-
field.getDeclaringClass() = astNode and
1282-
fieldName = field.getName() and
1283-
result = field.getTypeAnnotation()
1284-
)
1285-
}
1286-
1287-
override DataFlow::Node getADecorator() {
1288-
result = astNode.getADecorator().getExpression().flow()
1289-
}
1290-
}
1291-
12921217
private DataFlow::PropRef getAPrototypeReferenceInFile(string name, File f) {
12931218
result.getBase() = AccessPath::getAReferenceOrAssignmentTo(name) and
12941219
result.getPropertyName() = "prototype" and
@@ -1313,12 +1238,16 @@ module ClassNode {
13131238

13141239
/**
13151240
* A function definition, targeted by a `new`-call or with prototype manipulation, seen as a `ClassNode` instance.
1241+
* Or An ES6 class as a `ClassNode` instance.
13161242
*/
13171243
class FunctionStyleClass extends Range, DataFlow::ValueNode {
1318-
override Function astNode;
1244+
override AST::ValueNode astNode;
13191245
AbstractFunction function;
13201246

13211247
FunctionStyleClass() {
1248+
astNode instanceof ClassDefinition
1249+
or
1250+
astNode instanceof Function and
13221251
function.getFunction() = astNode and
13231252
(
13241253
exists(getAFunctionValueWithPrototype(function))
@@ -1333,11 +1262,17 @@ module ClassNode {
13331262
)
13341263
}
13351264

1336-
override string getName() { result = astNode.getName() }
1265+
override string getName() {
1266+
result = [astNode.(Function).getName(), astNode.(ClassDefinition).getName()]
1267+
}
13371268

1338-
override string describe() { result = astNode.describe() }
1269+
override string describe() {
1270+
result = [astNode.(Function).describe(), astNode.(ClassDefinition).describe()]
1271+
}
13391272

1340-
override FunctionNode getConstructor() { result = this }
1273+
override FunctionNode getConstructor() {
1274+
result = this or result = astNode.(ClassDefinition).getConstructor().getBody().flow()
1275+
}
13411276

13421277
private PropertyAccessor getAnAccessor(MemberKind kind) {
13431278
result.getObjectExpr() = this.getAPrototypeReference().asExpr() and
@@ -1362,6 +1297,13 @@ module ClassNode {
13621297
accessor.getName() = name and
13631298
result = accessor.getInit().flow()
13641299
)
1300+
or
1301+
exists(MethodDeclaration method |
1302+
method = astNode.(ClassDefinition).getMethod(name) and
1303+
not method.isStatic() and
1304+
kind = MemberKind::of(method) and
1305+
result = method.getBody().flow()
1306+
)
13651307
}
13661308

13671309
override FunctionNode getAnInstanceMember(MemberKind kind) {
@@ -1375,14 +1317,35 @@ module ClassNode {
13751317
accessor = this.getAnAccessor(kind) and
13761318
result = accessor.getInit().flow()
13771319
)
1320+
or
1321+
exists(MethodDeclaration method |
1322+
method = astNode.(ClassDefinition).getAMethod() and
1323+
not method.isStatic() and
1324+
kind = MemberKind::of(method) and
1325+
result = method.getBody().flow()
1326+
)
13781327
}
13791328

13801329
override FunctionNode getStaticMember(string name, MemberKind kind) {
1330+
exists(MethodDeclaration method |
1331+
method = astNode.(ClassDefinition).getMethod(name) and
1332+
method.isStatic() and
1333+
kind = MemberKind::of(method) and
1334+
result = method.getBody().flow()
1335+
)
1336+
or
13811337
kind.isMethod() and
13821338
result = this.getAPropertySource(name)
13831339
}
13841340

13851341
override FunctionNode getAStaticMember(MemberKind kind) {
1342+
exists(MethodDeclaration method |
1343+
method = astNode.(ClassDefinition).getAMethod() and
1344+
method.isStatic() and
1345+
kind = MemberKind::of(method) and
1346+
result = method.getBody().flow()
1347+
)
1348+
or
13861349
kind.isMethod() and
13871350
result = this.getAPropertySource()
13881351
}
@@ -1431,6 +1394,20 @@ module ClassNode {
14311394
this = inheritsCall.getArgument(0).getALocalSource() and
14321395
result = inheritsCall.getArgument(1)
14331396
)
1397+
or
1398+
result = astNode.(ClassDefinition).getSuperClass().flow()
1399+
}
1400+
1401+
override TypeAnnotation getFieldTypeAnnotation(string fieldName) {
1402+
exists(FieldDeclaration field |
1403+
field.getDeclaringClass() = astNode and
1404+
fieldName = field.getName() and
1405+
result = field.getTypeAnnotation()
1406+
)
1407+
}
1408+
1409+
override DataFlow::Node getADecorator() {
1410+
result = astNode.(ClassDefinition).getADecorator().getExpression().flow()
14341411
}
14351412
}
14361413
}

javascript/ql/test/library-tests/ClassNode/tests.expected

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,48 @@ fieldStep
44
| tst2.js:3:14:3:14 | x | tst2.js:12:12:12:17 | this.x |
55
getAReceiverNode
66
| fields.ts:1:1:3:1 | class B ... mber;\\n} | fields.ts:1:12:1:11 | this |
7+
| fields.ts:1:1:3:1 | class B ... mber;\\n} | tst.js:17:19:17:18 | this |
8+
| fields.ts:1:1:3:1 | class B ... mber;\\n} | tst.js:21:19:21:18 | this |
9+
| fields.ts:1:1:3:1 | class B ... mber;\\n} | tst.js:25:13:25:12 | this |
10+
| fields.ts:1:1:3:1 | class B ... mber;\\n} | tst.js:26:13:26:12 | this |
11+
| fields.ts:1:1:3:1 | class B ... mber;\\n} | tst.js:27:4:27:3 | this |
712
| fields.ts:5:1:13:1 | class F ... > {};\\n} | fields.ts:6:5:6:4 | this |
13+
| fields.ts:5:1:13:1 | class F ... > {};\\n} | tst.js:17:19:17:18 | this |
14+
| fields.ts:5:1:13:1 | class F ... > {};\\n} | tst.js:21:19:21:18 | this |
15+
| fields.ts:5:1:13:1 | class F ... > {};\\n} | tst.js:25:13:25:12 | this |
16+
| fields.ts:5:1:13:1 | class F ... > {};\\n} | tst.js:26:13:26:12 | this |
17+
| fields.ts:5:1:13:1 | class F ... > {};\\n} | tst.js:27:4:27:3 | this |
818
| namespace.js:3:15:3:31 | function Baz() {} | namespace.js:3:15:3:14 | this |
919
| namespace.js:3:15:3:31 | function Baz() {} | namespace.js:5:32:5:31 | this |
1020
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | tst2.js:2:14:2:13 | this |
1121
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | tst2.js:6:9:6:8 | this |
1222
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | tst2.js:11:13:11:12 | this |
23+
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | tst.js:17:19:17:18 | this |
24+
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | tst.js:21:19:21:18 | this |
25+
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | tst.js:25:13:25:12 | this |
26+
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | tst.js:26:13:26:12 | this |
27+
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | tst.js:27:4:27:3 | this |
1328
| tst2.js:16:1:20:1 | class D ... ;\\n }\\n} | tst2.js:17:14:17:13 | this |
29+
| tst2.js:16:1:20:1 | class D ... ;\\n }\\n} | tst.js:17:19:17:18 | this |
30+
| tst2.js:16:1:20:1 | class D ... ;\\n }\\n} | tst.js:21:19:21:18 | this |
31+
| tst2.js:16:1:20:1 | class D ... ;\\n }\\n} | tst.js:25:13:25:12 | this |
32+
| tst2.js:16:1:20:1 | class D ... ;\\n }\\n} | tst.js:26:13:26:12 | this |
33+
| tst2.js:16:1:20:1 | class D ... ;\\n }\\n} | tst.js:27:4:27:3 | this |
1434
| tst.js:3:1:10:1 | class A ... () {}\\n} | tst.js:3:9:3:8 | this |
1535
| tst.js:3:1:10:1 | class A ... () {}\\n} | tst.js:4:17:4:16 | this |
1636
| tst.js:3:1:10:1 | class A ... () {}\\n} | tst.js:7:6:7:5 | this |
1737
| tst.js:3:1:10:1 | class A ... () {}\\n} | tst.js:9:10:9:9 | this |
38+
| tst.js:3:1:10:1 | class A ... () {}\\n} | tst.js:17:19:17:18 | this |
39+
| tst.js:3:1:10:1 | class A ... () {}\\n} | tst.js:21:19:21:18 | this |
40+
| tst.js:3:1:10:1 | class A ... () {}\\n} | tst.js:25:13:25:12 | this |
41+
| tst.js:3:1:10:1 | class A ... () {}\\n} | tst.js:26:13:26:12 | this |
42+
| tst.js:3:1:10:1 | class A ... () {}\\n} | tst.js:27:4:27:3 | this |
1843
| tst.js:13:1:13:21 | class A ... ds A {} | tst.js:13:20:13:19 | this |
44+
| tst.js:13:1:13:21 | class A ... ds A {} | tst.js:17:19:17:18 | this |
45+
| tst.js:13:1:13:21 | class A ... ds A {} | tst.js:21:19:21:18 | this |
46+
| tst.js:13:1:13:21 | class A ... ds A {} | tst.js:25:13:25:12 | this |
47+
| tst.js:13:1:13:21 | class A ... ds A {} | tst.js:26:13:26:12 | this |
48+
| tst.js:13:1:13:21 | class A ... ds A {} | tst.js:27:4:27:3 | this |
1949
| tst.js:15:1:15:15 | function B() {} | tst.js:15:1:15:0 | this |
2050
| tst.js:15:1:15:15 | function B() {} | tst.js:17:19:17:18 | this |
2151
| tst.js:19:1:19:15 | function C() {} | tst.js:19:1:19:0 | this |
@@ -24,36 +54,97 @@ getAReceiverNode
2454
| tst.js:23:1:23:15 | function D() {} | tst.js:25:13:25:12 | this |
2555
| tst.js:23:1:23:15 | function D() {} | tst.js:26:13:26:12 | this |
2656
| tst.js:23:1:23:15 | function D() {} | tst.js:27:4:27:3 | this |
57+
| tst.js:30:1:34:1 | class S ... x) {}\\n} | tst.js:17:19:17:18 | this |
58+
| tst.js:30:1:34:1 | class S ... x) {}\\n} | tst.js:21:19:21:18 | this |
59+
| tst.js:30:1:34:1 | class S ... x) {}\\n} | tst.js:25:13:25:12 | this |
60+
| tst.js:30:1:34:1 | class S ... x) {}\\n} | tst.js:26:13:26:12 | this |
61+
| tst.js:30:1:34:1 | class S ... x) {}\\n} | tst.js:27:4:27:3 | this |
2762
| tst.js:30:1:34:1 | class S ... x) {}\\n} | tst.js:30:21:30:20 | this |
2863
getFieldTypeAnnotation
2964
| fields.ts:1:1:3:1 | class B ... mber;\\n} | baseField | fields.ts:2:16:2:21 | number |
3065
| fields.ts:5:1:13:1 | class F ... > {};\\n} | x | fields.ts:6:27:6:32 | number |
3166
| fields.ts:5:1:13:1 | class F ... > {};\\n} | y | fields.ts:6:46:6:51 | string |
3267
| fields.ts:5:1:13:1 | class F ... > {};\\n} | z | fields.ts:10:8:10:15 | string[] |
3368
instanceMember
69+
| fields.ts:1:1:3:1 | class B ... mber;\\n} | bar | method | tst.js:21:19:21:31 | function() {} | Base |
70+
| fields.ts:1:1:3:1 | class B ... mber;\\n} | foo | method | tst.js:17:19:17:31 | function() {} | Base |
71+
| fields.ts:1:1:3:1 | class B ... mber;\\n} | getter | getter | tst.js:25:13:25:17 | () {} | Base |
72+
| fields.ts:1:1:3:1 | class B ... mber;\\n} | m | method | tst.js:27:4:27:8 | () {} | Base |
73+
| fields.ts:1:1:3:1 | class B ... mber;\\n} | setter | setter | tst.js:26:13:26:18 | (x) {} | Base |
74+
| fields.ts:5:1:13:1 | class F ... > {};\\n} | bar | method | tst.js:21:19:21:31 | function() {} | Foo |
75+
| fields.ts:5:1:13:1 | class F ... > {};\\n} | foo | method | tst.js:17:19:17:31 | function() {} | Foo |
76+
| fields.ts:5:1:13:1 | class F ... > {};\\n} | getter | getter | tst.js:25:13:25:17 | () {} | Foo |
3477
| fields.ts:5:1:13:1 | class F ... > {};\\n} | m | method | fields.ts:12:16:12:32 | (x: string) => {} | Foo |
78+
| fields.ts:5:1:13:1 | class F ... > {};\\n} | m | method | tst.js:27:4:27:8 | () {} | Foo |
79+
| fields.ts:5:1:13:1 | class F ... > {};\\n} | setter | setter | tst.js:26:13:26:18 | (x) {} | Foo |
3580
| namespace.js:3:15:3:31 | function Baz() {} | method | method | namespace.js:5:32:5:44 | function() {} | Baz |
81+
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | bar | method | tst.js:21:19:21:31 | function() {} | C |
82+
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | foo | method | tst.js:17:19:17:31 | function() {} | C |
3683
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | getter | getter | tst2.js:11:13:13:3 | () {\\n ... .x;\\n } | C |
84+
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | getter | getter | tst.js:25:13:25:17 | () {} | C |
85+
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | m | method | tst.js:27:4:27:8 | () {} | C |
3786
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | method | method | tst2.js:6:9:9:3 | () {\\n ... .x;\\n } | C |
87+
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | setter | setter | tst.js:26:13:26:18 | (x) {} | C |
88+
| tst2.js:16:1:20:1 | class D ... ;\\n }\\n} | bar | method | tst.js:21:19:21:31 | function() {} | D |
3889
| tst2.js:16:1:20:1 | class D ... ;\\n }\\n} | f | method | tst2.js:18:14:18:22 | (x) => {} | D |
90+
| tst2.js:16:1:20:1 | class D ... ;\\n }\\n} | foo | method | tst.js:17:19:17:31 | function() {} | D |
91+
| tst2.js:16:1:20:1 | class D ... ;\\n }\\n} | getter | getter | tst.js:25:13:25:17 | () {} | D |
92+
| tst2.js:16:1:20:1 | class D ... ;\\n }\\n} | m | method | tst.js:27:4:27:8 | () {} | D |
93+
| tst2.js:16:1:20:1 | class D ... ;\\n }\\n} | setter | setter | tst.js:26:13:26:18 | (x) {} | D |
3994
| tst.js:3:1:10:1 | class A ... () {}\\n} | bar | method | tst.js:7:6:7:10 | () {} | A |
95+
| tst.js:3:1:10:1 | class A ... () {}\\n} | bar | method | tst.js:21:19:21:31 | function() {} | A |
4096
| tst.js:3:1:10:1 | class A ... () {}\\n} | baz | getter | tst.js:9:10:9:14 | () {} | A |
97+
| tst.js:3:1:10:1 | class A ... () {}\\n} | foo | method | tst.js:17:19:17:31 | function() {} | A |
98+
| tst.js:3:1:10:1 | class A ... () {}\\n} | getter | getter | tst.js:25:13:25:17 | () {} | A |
4199
| tst.js:3:1:10:1 | class A ... () {}\\n} | instanceMethod | method | tst.js:4:17:4:21 | () {} | A |
100+
| tst.js:3:1:10:1 | class A ... () {}\\n} | m | method | tst.js:27:4:27:8 | () {} | A |
101+
| tst.js:3:1:10:1 | class A ... () {}\\n} | setter | setter | tst.js:26:13:26:18 | (x) {} | A |
102+
| tst.js:13:1:13:21 | class A ... ds A {} | bar | method | tst.js:21:19:21:31 | function() {} | A2 |
103+
| tst.js:13:1:13:21 | class A ... ds A {} | foo | method | tst.js:17:19:17:31 | function() {} | A2 |
104+
| tst.js:13:1:13:21 | class A ... ds A {} | getter | getter | tst.js:25:13:25:17 | () {} | A2 |
105+
| tst.js:13:1:13:21 | class A ... ds A {} | m | method | tst.js:27:4:27:8 | () {} | A2 |
106+
| tst.js:13:1:13:21 | class A ... ds A {} | setter | setter | tst.js:26:13:26:18 | (x) {} | A2 |
42107
| tst.js:15:1:15:15 | function B() {} | foo | method | tst.js:17:19:17:31 | function() {} | B |
43108
| tst.js:19:1:19:15 | function C() {} | bar | method | tst.js:21:19:21:31 | function() {} | C |
44109
| tst.js:23:1:23:15 | function D() {} | getter | getter | tst.js:25:13:25:17 | () {} | D |
45110
| tst.js:23:1:23:15 | function D() {} | m | method | tst.js:27:4:27:8 | () {} | D |
46111
| tst.js:23:1:23:15 | function D() {} | setter | setter | tst.js:26:13:26:18 | (x) {} | D |
112+
| tst.js:30:1:34:1 | class S ... x) {}\\n} | bar | method | tst.js:21:19:21:31 | function() {} | StaticMembers |
113+
| tst.js:30:1:34:1 | class S ... x) {}\\n} | foo | method | tst.js:17:19:17:31 | function() {} | StaticMembers |
114+
| tst.js:30:1:34:1 | class S ... x) {}\\n} | getter | getter | tst.js:25:13:25:17 | () {} | StaticMembers |
115+
| tst.js:30:1:34:1 | class S ... x) {}\\n} | m | method | tst.js:27:4:27:8 | () {} | StaticMembers |
116+
| tst.js:30:1:34:1 | class S ... x) {}\\n} | setter | setter | tst.js:26:13:26:18 | (x) {} | StaticMembers |
47117
instanceMethod
118+
| fields.ts:1:1:3:1 | class B ... mber;\\n} | bar | tst.js:21:19:21:31 | function() {} | Base |
119+
| fields.ts:1:1:3:1 | class B ... mber;\\n} | foo | tst.js:17:19:17:31 | function() {} | Base |
120+
| fields.ts:1:1:3:1 | class B ... mber;\\n} | m | tst.js:27:4:27:8 | () {} | Base |
121+
| fields.ts:5:1:13:1 | class F ... > {};\\n} | bar | tst.js:21:19:21:31 | function() {} | Foo |
122+
| fields.ts:5:1:13:1 | class F ... > {};\\n} | foo | tst.js:17:19:17:31 | function() {} | Foo |
48123
| fields.ts:5:1:13:1 | class F ... > {};\\n} | m | fields.ts:12:16:12:32 | (x: string) => {} | Foo |
124+
| fields.ts:5:1:13:1 | class F ... > {};\\n} | m | tst.js:27:4:27:8 | () {} | Foo |
49125
| namespace.js:3:15:3:31 | function Baz() {} | method | namespace.js:5:32:5:44 | function() {} | Baz |
126+
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | bar | tst.js:21:19:21:31 | function() {} | C |
127+
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | foo | tst.js:17:19:17:31 | function() {} | C |
128+
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | m | tst.js:27:4:27:8 | () {} | C |
50129
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | method | tst2.js:6:9:9:3 | () {\\n ... .x;\\n } | C |
130+
| tst2.js:16:1:20:1 | class D ... ;\\n }\\n} | bar | tst.js:21:19:21:31 | function() {} | D |
51131
| tst2.js:16:1:20:1 | class D ... ;\\n }\\n} | f | tst2.js:18:14:18:22 | (x) => {} | D |
132+
| tst2.js:16:1:20:1 | class D ... ;\\n }\\n} | foo | tst.js:17:19:17:31 | function() {} | D |
133+
| tst2.js:16:1:20:1 | class D ... ;\\n }\\n} | m | tst.js:27:4:27:8 | () {} | D |
52134
| tst.js:3:1:10:1 | class A ... () {}\\n} | bar | tst.js:7:6:7:10 | () {} | A |
135+
| tst.js:3:1:10:1 | class A ... () {}\\n} | bar | tst.js:21:19:21:31 | function() {} | A |
136+
| tst.js:3:1:10:1 | class A ... () {}\\n} | foo | tst.js:17:19:17:31 | function() {} | A |
53137
| tst.js:3:1:10:1 | class A ... () {}\\n} | instanceMethod | tst.js:4:17:4:21 | () {} | A |
138+
| tst.js:3:1:10:1 | class A ... () {}\\n} | m | tst.js:27:4:27:8 | () {} | A |
139+
| tst.js:13:1:13:21 | class A ... ds A {} | bar | tst.js:21:19:21:31 | function() {} | A2 |
140+
| tst.js:13:1:13:21 | class A ... ds A {} | foo | tst.js:17:19:17:31 | function() {} | A2 |
141+
| tst.js:13:1:13:21 | class A ... ds A {} | m | tst.js:27:4:27:8 | () {} | A2 |
54142
| tst.js:15:1:15:15 | function B() {} | foo | tst.js:17:19:17:31 | function() {} | B |
55143
| tst.js:19:1:19:15 | function C() {} | bar | tst.js:21:19:21:31 | function() {} | C |
56144
| tst.js:23:1:23:15 | function D() {} | m | tst.js:27:4:27:8 | () {} | D |
145+
| tst.js:30:1:34:1 | class S ... x) {}\\n} | bar | tst.js:21:19:21:31 | function() {} | StaticMembers |
146+
| tst.js:30:1:34:1 | class S ... x) {}\\n} | foo | tst.js:17:19:17:31 | function() {} | StaticMembers |
147+
| tst.js:30:1:34:1 | class S ... x) {}\\n} | m | tst.js:27:4:27:8 | () {} | StaticMembers |
57148
staticMember
58149
| tst.js:3:1:10:1 | class A ... () {}\\n} | staticMethod | method | tst.js:5:22:5:26 | () {} | A |
59150
| tst.js:30:1:34:1 | class S ... x) {}\\n} | getter | getter | tst.js:32:20:32:24 | () {} | StaticMembers |

0 commit comments

Comments
 (0)