refactor StaticInitializer into it's own class

This commit is contained in:
Erik Krogh Kristensen
2021-09-03 10:15:36 +02:00
parent 23e28ae5d4
commit e3ed6c2523
12 changed files with 112 additions and 37 deletions

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -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()));
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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) {

View File

@@ -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);
}