mirror of
https://github.com/github/codeql.git
synced 2026-05-02 12:15:17 +02:00
refactor StaticInitializer into it's own class
This commit is contained in:
@@ -3219,7 +3219,7 @@ public class Parser {
|
||||
Expression superClass = this.parseClassSuper();
|
||||
Position bodyStartLoc = this.startLoc;
|
||||
boolean hadConstructor = false;
|
||||
List<Node> body = new ArrayList<>();
|
||||
List<MemberDefinition<?>> body = new ArrayList<>();
|
||||
this.expect(TokenType.braceL);
|
||||
while (!this.eat(TokenType.braceR)) {
|
||||
if (this.eat(TokenType.semi)) continue;
|
||||
|
||||
@@ -4,18 +4,18 @@ import java.util.List;
|
||||
|
||||
/** The body of a {@linkplain ClassDeclaration} or {@linkplain ClassExpression}. */
|
||||
public class ClassBody extends Node {
|
||||
private final List<Node> body; // either MemberDefinition or BlockStatement (static initialization blocks)
|
||||
private final List<MemberDefinition<?>> body;
|
||||
|
||||
public ClassBody(SourceLocation loc, List<Node> body) {
|
||||
public ClassBody(SourceLocation loc, List<MemberDefinition<?>> body) {
|
||||
super("ClassBody", loc);
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public List<Node> getBody() {
|
||||
public List<MemberDefinition<?>> getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public void addMember(Node md) {
|
||||
public void addMember(MemberDefinition<?> md) {
|
||||
body.add(md);
|
||||
}
|
||||
|
||||
|
||||
@@ -782,4 +782,9 @@ public class DefaultVisitor<C, R> implements Visitor<C, R> {
|
||||
public R visit(GeneratedCodeExpr nd, C c) {
|
||||
return visit((Expression) nd, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public R visit(StaticInitializer nd, C c) {
|
||||
return visit((MemberDefinition<Expression>) nd, c);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -897,6 +897,11 @@ public class NodeCopier implements Visitor<Void, INode> {
|
||||
|
||||
@Override
|
||||
public INode visit(GeneratedCodeExpr nd, Void c) {
|
||||
return new GeneratedCodeExpr(visit(nd.getLoc()), nd.getOpeningDelimiter(), nd.getClosingDelimiter(), nd.getBody());
|
||||
return new GeneratedCodeExpr(visit(nd.getLoc()), nd.getOpeningDelimiter(), nd.getClosingDelimiter(), nd.getBody());
|
||||
}
|
||||
|
||||
@Override
|
||||
public INode visit(StaticInitializer nd, Void c) {
|
||||
return new StaticInitializer(visit(nd.getLoc()), copy(nd.getBody()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.semmle.js.ast;
|
||||
|
||||
/**
|
||||
* A static initializer block in a class.
|
||||
* E.g.
|
||||
* ```TypeScript
|
||||
* class Foo {
|
||||
* static bar : number;
|
||||
* static {
|
||||
* Foo.bar = 42;
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
public class StaticInitializer extends MemberDefinition<Expression> {
|
||||
private final BlockStatement body;
|
||||
|
||||
public StaticInitializer(SourceLocation loc, BlockStatement body) {
|
||||
super("StaticInitializer", loc, DeclarationFlags.static_, null, null);
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the body of this static initializer.
|
||||
* @return The body of this static initializer.
|
||||
*/
|
||||
public BlockStatement getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConcrete() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <C, R> R accept(Visitor<C, R> v, C c) {
|
||||
return v.visit(this, c);
|
||||
}
|
||||
}
|
||||
@@ -315,4 +315,6 @@ public interface Visitor<C, R> {
|
||||
public R visit(XMLDotDotExpression nd, C c);
|
||||
|
||||
public R visit(GeneratedCodeExpr generatedCodeExpr, C c);
|
||||
|
||||
public R visit(StaticInitializer nd, C c);
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ import com.semmle.js.ast.SourceElement;
|
||||
import com.semmle.js.ast.SourceLocation;
|
||||
import com.semmle.js.ast.SpreadElement;
|
||||
import com.semmle.js.ast.Statement;
|
||||
import com.semmle.js.ast.StaticInitializer;
|
||||
import com.semmle.js.ast.Super;
|
||||
import com.semmle.js.ast.SwitchCase;
|
||||
import com.semmle.js.ast.SwitchStatement;
|
||||
@@ -1613,6 +1614,8 @@ public class ASTExtractor {
|
||||
int kind;
|
||||
if (nd instanceof MethodDefinition) {
|
||||
kind = getMethodKind((MethodDefinition) nd);
|
||||
} else if (nd instanceof StaticInitializer) {
|
||||
kind = 10;
|
||||
} else {
|
||||
kind = getFieldKind((FieldDefinition) nd);
|
||||
}
|
||||
@@ -1643,6 +1646,11 @@ public class ASTExtractor {
|
||||
}
|
||||
}
|
||||
|
||||
if (nd instanceof StaticInitializer) {
|
||||
StaticInitializer si = (StaticInitializer) nd;
|
||||
visit(si.getBody(), methkey, 3, IdContext.VAR_BIND);
|
||||
}
|
||||
|
||||
if (nd instanceof FieldDefinition) {
|
||||
FieldDefinition field = (FieldDefinition) nd;
|
||||
if (field.isParameterField() && constructorKey != null) {
|
||||
|
||||
@@ -65,6 +65,7 @@ import com.semmle.js.ast.SequenceExpression;
|
||||
import com.semmle.js.ast.SourceLocation;
|
||||
import com.semmle.js.ast.SpreadElement;
|
||||
import com.semmle.js.ast.Statement;
|
||||
import com.semmle.js.ast.StaticInitializer;
|
||||
import com.semmle.js.ast.Super;
|
||||
import com.semmle.js.ast.SwitchCase;
|
||||
import com.semmle.js.ast.SwitchStatement;
|
||||
@@ -454,7 +455,7 @@ public class CFGExtractor {
|
||||
|
||||
@Override
|
||||
public Node visit(ClassBody nd, Void v) {
|
||||
for (Node m : nd.getBody()) {
|
||||
for (MemberDefinition<?> m : nd.getBody()) {
|
||||
if (m instanceof MethodDefinition) {
|
||||
Node first = m.accept(this, v);
|
||||
if (first != null) return first;
|
||||
@@ -1163,11 +1164,8 @@ public class CFGExtractor {
|
||||
private Map<Expression, AClass> constructor2Class = new LinkedHashMap<>();
|
||||
|
||||
private Void visit(Node nd, AClass ac, SuccessorInfo i) {
|
||||
for (Node m : ac.getBody().getBody()) {
|
||||
if (m instanceof MemberDefinition) {
|
||||
MemberDefinition md = (MemberDefinition) m;
|
||||
if (md.isConstructor() && md.isConcrete()) constructor2Class.put(md.getValue(), ac);
|
||||
}
|
||||
for (MemberDefinition<?> md : ac.getBody().getBody()) {
|
||||
if (md.isConstructor() && md.isConcrete()) constructor2Class.put(md.getValue(), ac);
|
||||
}
|
||||
visitSequence(ac.getId(), ac.getSuperClass(), ac.getBody(), nd);
|
||||
writeSuccessors(nd, visitSequence(getStaticInitializers(ac.getBody()), getDecoratorsOfClass(ac), i.getAllSuccessors()));
|
||||
@@ -1207,18 +1205,15 @@ public class CFGExtractor {
|
||||
List<Node> staticDecorators = new ArrayList<>();
|
||||
List<Node> constructorParameterDecorators = new ArrayList<>();
|
||||
List<Node> classDecorators = (List<Node>)(List<?>)ac.getDecorators();
|
||||
for (Node memberNode : ac.getBody().getBody()) {
|
||||
if (memberNode instanceof MemberDefinition) {
|
||||
MemberDefinition<?> member = (MemberDefinition<?>) memberNode;
|
||||
if (!member.isConcrete()) continue;
|
||||
List<Node> decorators = getMemberDecorators(member);
|
||||
if (member.isConstructor()) {
|
||||
constructorParameterDecorators.addAll(decorators);
|
||||
} else if (member.isStatic()) {
|
||||
staticDecorators.addAll(decorators);
|
||||
} else {
|
||||
instanceDecorators.addAll(decorators);
|
||||
}
|
||||
for (MemberDefinition<?> member : ac.getBody().getBody()) {
|
||||
if (!member.isConcrete()) continue;
|
||||
List<Node> decorators = getMemberDecorators(member);
|
||||
if (member.isConstructor()) {
|
||||
constructorParameterDecorators.addAll(decorators);
|
||||
} else if (member.isStatic()) {
|
||||
staticDecorators.addAll(decorators);
|
||||
} else {
|
||||
instanceDecorators.addAll(decorators);
|
||||
}
|
||||
}
|
||||
List<Node> result = new ArrayList<>();
|
||||
@@ -1619,8 +1614,8 @@ public class CFGExtractor {
|
||||
|
||||
private List<MemberDefinition<?>> getMethods(ClassBody nd) {
|
||||
List<MemberDefinition<?>> mds = new ArrayList<>();
|
||||
for (Node md : nd.getBody()) {
|
||||
if (md instanceof MethodDefinition) mds.add((MemberDefinition<?>)md);
|
||||
for (MemberDefinition<?> md : nd.getBody()) {
|
||||
if (md instanceof MethodDefinition) mds.add(md);
|
||||
}
|
||||
return mds;
|
||||
}
|
||||
@@ -1630,18 +1625,16 @@ public class CFGExtractor {
|
||||
*/
|
||||
private List<Node> getStaticInitializers(ClassBody nd) {
|
||||
List<Node> nodes = new ArrayList<>();
|
||||
for (Node node : nd.getBody()) {
|
||||
for (MemberDefinition<?> node : nd.getBody()) {
|
||||
if (node instanceof FieldDefinition && ((FieldDefinition)node).isStatic()) nodes.add(node);
|
||||
if (node instanceof BlockStatement) nodes.add(node);
|
||||
if (node instanceof StaticInitializer) nodes.add(((StaticInitializer)node).getBody());
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
private List<FieldDefinition> getConcreteInstanceFields(ClassBody nd) {
|
||||
List<FieldDefinition> fds = new ArrayList<>();
|
||||
for (Node node : nd.getBody()) {
|
||||
if (!(node instanceof MemberDefinition)) continue;
|
||||
MemberDefinition<?> md = (MemberDefinition<?>)node;
|
||||
for (MemberDefinition<?> md : nd.getBody()) {
|
||||
if (md instanceof FieldDefinition && !md.isStatic() && md.isConcrete())
|
||||
fds.add((FieldDefinition) md);
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ import com.semmle.js.ast.SequenceExpression;
|
||||
import com.semmle.js.ast.SourceLocation;
|
||||
import com.semmle.js.ast.SpreadElement;
|
||||
import com.semmle.js.ast.Statement;
|
||||
import com.semmle.js.ast.StaticInitializer;
|
||||
import com.semmle.js.ast.Super;
|
||||
import com.semmle.js.ast.SwitchCase;
|
||||
import com.semmle.js.ast.SwitchStatement;
|
||||
@@ -155,6 +156,8 @@ import com.semmle.ts.ast.UnionTypeExpr;
|
||||
import com.semmle.util.collections.CollectionUtil;
|
||||
import com.semmle.util.data.IntList;
|
||||
|
||||
import jdk.internal.org.objectweb.asm.commons.StaticInitMerger;
|
||||
|
||||
/**
|
||||
* Utility class for converting a <a
|
||||
* href="https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API">TypeScript AST
|
||||
@@ -869,7 +872,8 @@ public class TypeScriptASTConverter {
|
||||
}
|
||||
|
||||
private Node convertStaticInitializerBlock(JsonObject node, SourceLocation loc) throws ParseError {
|
||||
return new BlockStatement(loc, convertChildren(node.get("body").getAsJsonObject(), "statements"));
|
||||
BlockStatement body = new BlockStatement(loc, convertChildren(node.get("body").getAsJsonObject(), "statements"));
|
||||
return new StaticInitializer(loc, body);
|
||||
}
|
||||
|
||||
private Node convertBlock(JsonObject node, SourceLocation loc) throws ParseError {
|
||||
|
||||
@@ -262,7 +262,9 @@ class ClassDefinition extends @class_definition, ClassOrInterface, AST::ValueNod
|
||||
/**
|
||||
* Gets a static initializer of this class, if any.
|
||||
*/
|
||||
BlockStmt getAStaticInitializerBlock() { result.getParent() = this }
|
||||
BlockStmt getAStaticInitializerBlock() {
|
||||
exists(StaticInitializer init | init.getDeclaringClass() = this | result = init.getBody())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1139,6 +1141,15 @@ class ParameterField extends FieldDeclaration, @parameter_field {
|
||||
override TypeAnnotation getTypeAnnotation() { result = getParameter().getTypeAnnotation() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A static initializer in a class.
|
||||
*/
|
||||
class StaticInitializer extends MemberDefinition, @static_initializer {
|
||||
BlockStmt getBody() { result.getParent() = this }
|
||||
|
||||
override Expr getNameExpr() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call signature declared in an interface.
|
||||
*
|
||||
|
||||
@@ -521,6 +521,7 @@ case @property.kind of
|
||||
| 7 = @enum_member
|
||||
| 8 = @proper_field
|
||||
| 9 = @parameter_field
|
||||
| 10 = @static_initializer
|
||||
;
|
||||
|
||||
@property_parent = @obj_expr | @object_pattern | @class_definition | @jsx_element | @interface_definition | @enum_declaration;
|
||||
|
||||
@@ -775,6 +775,7 @@ nodes
|
||||
| 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:185:5:187:5 | [ClassInitializedMember] static ... ; } | semmle.label | [ClassInitializedMember] 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 |
|
||||
@@ -782,6 +783,7 @@ nodes
|
||||
| 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:188:5:190:5 | [ClassInitializedMember] static ... ; } | semmle.label | [ClassInitializedMember] 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 |
|
||||
@@ -2295,10 +2297,10 @@ edges
|
||||
| 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:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:185:5:187:5 | [ClassInitializedMember] static ... ; } | semmle.label | 5 |
|
||||
| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:185:5:187:5 | [ClassInitializedMember] static ... ; } | semmle.order | 5 |
|
||||
| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:188:5:190:5 | [ClassInitializedMember] static ... ; } | semmle.label | 6 |
|
||||
| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:188:5:190:5 | [ClassInitializedMember] 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 |
|
||||
@@ -2325,6 +2327,8 @@ edges
|
||||
| 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:185:5:187:5 | [ClassInitializedMember] static ... ; } | tst.ts:185:5:187:5 | [BlockStmt] static ... ; } | semmle.label | 1 |
|
||||
| tst.ts:185:5:187:5 | [ClassInitializedMember] static ... ; } | tst.ts:185:5:187:5 | [BlockStmt] static ... ; } | 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 |
|
||||
@@ -2337,6 +2341,8 @@ edges
|
||||
| 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:188:5:190:5 | [ClassInitializedMember] static ... ; } | tst.ts:188:5:190:5 | [BlockStmt] static ... ; } | semmle.label | 1 |
|
||||
| tst.ts:188:5:190:5 | [ClassInitializedMember] static ... ; } | tst.ts:188:5:190:5 | [BlockStmt] static ... ; } | 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 |
|
||||
|
||||
Reference in New Issue
Block a user