ast-based constant folding
This commit is contained in:
parent
bc4939db97
commit
27a8fff714
|
@ -27,6 +27,7 @@ import com.ibm.wala.cast.tree.CAstEntity;
|
||||||
import com.ibm.wala.cast.tree.CAstNode;
|
import com.ibm.wala.cast.tree.CAstNode;
|
||||||
import com.ibm.wala.cast.tree.impl.CAstImpl;
|
import com.ibm.wala.cast.tree.impl.CAstImpl;
|
||||||
import com.ibm.wala.cast.tree.rewrite.CAstBasicRewriter;
|
import com.ibm.wala.cast.tree.rewrite.CAstBasicRewriter;
|
||||||
|
import com.ibm.wala.cast.tree.rewrite.CAstBasicRewriter.NonCopyingContext;
|
||||||
import com.ibm.wala.cast.util.CAstPattern;
|
import com.ibm.wala.cast.util.CAstPattern;
|
||||||
import com.ibm.wala.cast.util.CAstPattern.Segments;
|
import com.ibm.wala.cast.util.CAstPattern.Segments;
|
||||||
import com.ibm.wala.cfg.AbstractCFG;
|
import com.ibm.wala.cfg.AbstractCFG;
|
||||||
|
@ -183,12 +184,12 @@ public class ArgumentSpecialization {
|
||||||
if (v != null) {
|
if (v != null) {
|
||||||
final JavaScriptLoader myloader = (JavaScriptLoader) method.getDeclaringClass().getClassLoader();
|
final JavaScriptLoader myloader = (JavaScriptLoader) method.getDeclaringClass().getClassLoader();
|
||||||
|
|
||||||
class FixedArgumentsRewriter extends CAstBasicRewriter {
|
class FixedArgumentsRewriter extends CAstBasicRewriter<NonCopyingContext> {
|
||||||
private final CAstEntity e;
|
private final CAstEntity e;
|
||||||
private final Map<String, CAstNode> argRefs = HashMapFactory.make();
|
private final Map<String, CAstNode> argRefs = HashMapFactory.make();
|
||||||
|
|
||||||
public FixedArgumentsRewriter(CAst Ast) {
|
public FixedArgumentsRewriter(CAst Ast) {
|
||||||
super(Ast, false);
|
super(Ast, new NonCopyingContext(), false);
|
||||||
this.e = m.getEntity();
|
this.e = m.getEntity();
|
||||||
for(Segments s : CAstPattern.findAll(destructuredAccessPattern, m.getEntity())) {
|
for(Segments s : CAstPattern.findAll(destructuredAccessPattern, m.getEntity())) {
|
||||||
argRefs.put(s.getSingle("name").getValue().toString(), s.getSingle("value"));
|
argRefs.put(s.getSingle("name").getValue().toString(), s.getSingle("value"));
|
||||||
|
|
|
@ -0,0 +1,192 @@
|
||||||
|
package com.ibm.wala.cast.test;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.tree.CAst;
|
||||||
|
import com.ibm.wala.cast.tree.CAstAnnotation;
|
||||||
|
import com.ibm.wala.cast.tree.CAstControlFlowMap;
|
||||||
|
import com.ibm.wala.cast.tree.CAstEntity;
|
||||||
|
import com.ibm.wala.cast.tree.CAstNode;
|
||||||
|
import com.ibm.wala.cast.tree.CAstNodeTypeMap;
|
||||||
|
import com.ibm.wala.cast.tree.CAstQualifier;
|
||||||
|
import com.ibm.wala.cast.tree.CAstSourcePositionMap;
|
||||||
|
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
||||||
|
import com.ibm.wala.cast.tree.CAstType;
|
||||||
|
import com.ibm.wala.cast.tree.impl.CAstImpl;
|
||||||
|
import com.ibm.wala.cast.tree.impl.CAstOperator;
|
||||||
|
import com.ibm.wala.cast.tree.rewrite.AstConstantFolder;
|
||||||
|
import com.ibm.wala.cast.util.AstConstantCollector;
|
||||||
|
import com.ibm.wala.cast.util.CAstPattern;
|
||||||
|
import com.ibm.wala.cast.util.CAstPattern.Segments;
|
||||||
|
import com.ibm.wala.util.collections.EmptyIterator;
|
||||||
|
|
||||||
|
public class TestConstantCollector {
|
||||||
|
|
||||||
|
private CAst ast = new CAstImpl();
|
||||||
|
|
||||||
|
private static CAstEntity fakeEntity(CAstNode root) {
|
||||||
|
return new CAstEntity() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getKind() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSignature() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getArgumentNames() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CAstNode[] getArgumentDefaults() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getArgumentCount() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<CAstNode, Collection<CAstEntity>> getAllScopedEntities() {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<CAstEntity> getScopedEntities(CAstNode construct) {
|
||||||
|
return EmptyIterator.instance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CAstNode getAST() {
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CAstControlFlowMap getControlFlow() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CAstSourcePositionMap getSourceMap() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Position getPosition() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CAstNodeTypeMap getNodeTypeMap() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<CAstQualifier> getQualifiers() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CAstType getType() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<CAstAnnotation> getAnnotations() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private CAstNode root1 =
|
||||||
|
ast.makeNode(CAstNode.BLOCK_STMT,
|
||||||
|
ast.makeNode(CAstNode.ASSIGN,
|
||||||
|
ast.makeNode(CAstNode.VAR,
|
||||||
|
ast.makeConstant("var1")),
|
||||||
|
ast.makeConstant(15)));
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSegmentsRoot1() {
|
||||||
|
Collection<Segments> x = CAstPattern.findAll(AstConstantCollector.simpleValuePattern, fakeEntity(root1));
|
||||||
|
assert x.size() == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRoot1() {
|
||||||
|
Map<String,Object> x = AstConstantCollector.collectConstants(fakeEntity(root1));
|
||||||
|
assert x.size() == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CAstNode root2 =
|
||||||
|
ast.makeNode(CAstNode.BLOCK_STMT,
|
||||||
|
ast.makeNode(CAstNode.ASSIGN,
|
||||||
|
ast.makeNode(CAstNode.VAR,
|
||||||
|
ast.makeConstant("var1")),
|
||||||
|
ast.makeConstant(15)),
|
||||||
|
ast.makeNode(CAstNode.ASSIGN,
|
||||||
|
ast.makeNode(CAstNode.VAR,
|
||||||
|
ast.makeConstant("var1")),
|
||||||
|
ast.makeConstant(14)));
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSegmentsRoot2() {
|
||||||
|
Collection<Segments> x = CAstPattern.findAll(AstConstantCollector.simpleValuePattern, fakeEntity(root2));
|
||||||
|
assert x.size() == 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRoot2() {
|
||||||
|
Map<String,Object> x = AstConstantCollector.collectConstants(fakeEntity(root2));
|
||||||
|
assert x.size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CAstNode root3 =
|
||||||
|
ast.makeNode(CAstNode.BLOCK_EXPR,
|
||||||
|
ast.makeNode(CAstNode.ASSIGN,
|
||||||
|
ast.makeNode(CAstNode.VAR,
|
||||||
|
ast.makeConstant("var1")),
|
||||||
|
ast.makeConstant(15)),
|
||||||
|
ast.makeNode(CAstNode.BINARY_EXPR,
|
||||||
|
CAstOperator.OP_ADD,
|
||||||
|
ast.makeConstant(10),
|
||||||
|
ast.makeNode(CAstNode.VAR, ast.makeConstant("var1"))));
|
||||||
|
|
||||||
|
public static final CAstPattern toCodePattern3 = CAstPattern.parse("BINARY_EXPR(*,\"10\",\"15\")");
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRoot3() {
|
||||||
|
CAstEntity ce = fakeEntity(root3);
|
||||||
|
CAstEntity nce = AstConstantFolder.fold(ce);
|
||||||
|
Collection<Segments> matches = CAstPattern.findAll(toCodePattern3, nce);
|
||||||
|
assert matches.size() == 1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4604,7 +4604,7 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
|
||||||
nodeMap.put(Pair.make(root, c.key()), expr);
|
nodeMap.put(Pair.make(root, c.key()), expr);
|
||||||
return expr;
|
return expr;
|
||||||
} else {
|
} else {
|
||||||
return super.copyNodesHackForEclipse(root, cfg, c, nodeMap);
|
return super.copyNodes(root, cfg, c, nodeMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).rewrite(included);
|
}).rewrite(included);
|
||||||
|
|
|
@ -17,12 +17,13 @@ import com.ibm.wala.cast.tree.CAstControlFlowMap;
|
||||||
import com.ibm.wala.cast.tree.CAstNode;
|
import com.ibm.wala.cast.tree.CAstNode;
|
||||||
import com.ibm.wala.cast.tree.impl.CAstOperator;
|
import com.ibm.wala.cast.tree.impl.CAstOperator;
|
||||||
import com.ibm.wala.cast.tree.rewrite.CAstBasicRewriter;
|
import com.ibm.wala.cast.tree.rewrite.CAstBasicRewriter;
|
||||||
|
import com.ibm.wala.cast.tree.rewrite.CAstBasicRewriter.NonCopyingContext;
|
||||||
import com.ibm.wala.util.collections.Pair;
|
import com.ibm.wala.util.collections.Pair;
|
||||||
|
|
||||||
public abstract class ConstantFoldingRewriter extends CAstBasicRewriter {
|
public abstract class ConstantFoldingRewriter extends CAstBasicRewriter<NonCopyingContext> {
|
||||||
|
|
||||||
protected ConstantFoldingRewriter(CAst Ast) {
|
protected ConstantFoldingRewriter(CAst Ast) {
|
||||||
super(Ast, true);
|
super(Ast, new NonCopyingContext(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract Object eval(CAstOperator op, Object lhs, Object rhs);
|
protected abstract Object eval(CAstOperator op, Object lhs, Object rhs);
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
package com.ibm.wala.cast.tree.rewrite;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.tree.CAstControlFlowMap;
|
||||||
|
import com.ibm.wala.cast.tree.CAstEntity;
|
||||||
|
import com.ibm.wala.cast.tree.CAstNode;
|
||||||
|
import com.ibm.wala.cast.tree.CAstNodeTypeMap;
|
||||||
|
import com.ibm.wala.cast.tree.CAstSourcePositionMap;
|
||||||
|
import com.ibm.wala.cast.tree.impl.CAstImpl;
|
||||||
|
import com.ibm.wala.cast.tree.impl.DelegatingEntity;
|
||||||
|
import com.ibm.wala.cast.tree.rewrite.CAstBasicRewriter.NonCopyingContext;
|
||||||
|
import com.ibm.wala.cast.tree.rewrite.CAstRewriter.Rewrite;
|
||||||
|
import com.ibm.wala.cast.util.AstConstantCollector;
|
||||||
|
import com.ibm.wala.util.collections.EmptyIterator;
|
||||||
|
import com.ibm.wala.util.collections.HashSetFactory;
|
||||||
|
import com.ibm.wala.util.collections.Pair;
|
||||||
|
|
||||||
|
public class AstConstantFolder {
|
||||||
|
static class AssignSkipContext extends NonCopyingContext {
|
||||||
|
private Set<CAstNode> skip = HashSetFactory.make();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CAstEntity fold(CAstEntity ce) {
|
||||||
|
Map<String,Object> constants = AstConstantCollector.collectConstants(ce);
|
||||||
|
if (constants.isEmpty()) {
|
||||||
|
return ce;
|
||||||
|
} else {
|
||||||
|
Rewrite nce = new CAstCloner(new CAstImpl(), new AssignSkipContext(), true) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CAstNode copyNodes(CAstNode root, CAstControlFlowMap cfg, NonCopyingContext c,
|
||||||
|
Map<Pair<CAstNode, NoKey>, CAstNode> nodeMap) {
|
||||||
|
|
||||||
|
if (root.getKind() == CAstNode.ASSIGN) {
|
||||||
|
((AssignSkipContext)c).skip.add(root.getChild(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (root.getKind() == CAstNode.VAR && constants.containsKey(root.getChild(0).getValue()) && ! ((AssignSkipContext)c).skip.contains(root)) {
|
||||||
|
return Ast.makeConstant(constants.get(root.getChild(0).getValue()));
|
||||||
|
} else {
|
||||||
|
return super.copyNodes(root, cfg, c, nodeMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}.rewrite(ce.getAST(), ce.getControlFlow(), ce.getSourceMap(), ce.getNodeTypeMap(), ce.getAllScopedEntities());
|
||||||
|
return new DelegatingEntity(ce) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CAstNode getAST() {
|
||||||
|
return nce.newRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CAstControlFlowMap getControlFlow() {
|
||||||
|
return nce.newCfg();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CAstSourcePositionMap getSourceMap() {
|
||||||
|
return nce.newPos();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CAstNodeTypeMap getNodeTypeMap() {
|
||||||
|
return nce.newTypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<CAstNode, Collection<CAstEntity>> getAllScopedEntities() {
|
||||||
|
return nce.newChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<CAstEntity> getScopedEntities(CAstNode construct) {
|
||||||
|
Collection<CAstEntity> children = nce.newChildren().get(construct);
|
||||||
|
return children==null? EmptyIterator.instance(): children.iterator();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,8 +23,8 @@ import com.ibm.wala.util.debug.Assertions;
|
||||||
* abstract base class for {@link CAstRewriter}s that do no cloning of nodes
|
* abstract base class for {@link CAstRewriter}s that do no cloning of nodes
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class CAstBasicRewriter
|
public abstract class CAstBasicRewriter<T extends CAstBasicRewriter.NonCopyingContext>
|
||||||
extends CAstRewriter<CAstBasicRewriter.NonCopyingContext,
|
extends CAstRewriter<T,
|
||||||
CAstBasicRewriter.NoKey>
|
CAstBasicRewriter.NoKey>
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -69,11 +69,11 @@ public abstract class CAstBasicRewriter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CAstBasicRewriter(CAst Ast, boolean recursive) {
|
protected CAstBasicRewriter(CAst Ast, T context, boolean recursive) {
|
||||||
super(Ast, recursive, new NonCopyingContext());
|
super(Ast, recursive, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected abstract CAstNode copyNodes(CAstNode root, final CAstControlFlowMap cfg, NonCopyingContext context, Map<Pair<CAstNode,NoKey>, CAstNode> nodeMap);
|
protected abstract CAstNode copyNodes(CAstNode root, final CAstControlFlowMap cfg, T context, Map<Pair<CAstNode,NoKey>, CAstNode> nodeMap);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,25 +22,22 @@ import com.ibm.wala.cast.tree.CAstSourcePositionMap;
|
||||||
import com.ibm.wala.cast.tree.impl.CAstOperator;
|
import com.ibm.wala.cast.tree.impl.CAstOperator;
|
||||||
import com.ibm.wala.util.collections.Pair;
|
import com.ibm.wala.util.collections.Pair;
|
||||||
|
|
||||||
public class CAstCloner extends CAstBasicRewriter {
|
public class CAstCloner extends CAstBasicRewriter<CAstBasicRewriter.NonCopyingContext> {
|
||||||
|
|
||||||
public CAstCloner(CAst Ast, boolean recursive) {
|
public CAstCloner(CAst Ast, boolean recursive) {
|
||||||
super(Ast, recursive);
|
this(Ast, new NonCopyingContext(), recursive);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CAstCloner(CAst Ast) {
|
public CAstCloner(CAst Ast) {
|
||||||
this(Ast, false);
|
this(Ast, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected CAstCloner(CAst Ast, NonCopyingContext context, boolean recursive) {
|
||||||
protected CAstNode copyNodes(CAstNode root, final CAstControlFlowMap cfg, NonCopyingContext c, Map<Pair<CAstNode,NoKey>, CAstNode> nodeMap) {
|
super(Ast, context, recursive);
|
||||||
return copyNodesHackForEclipse(root, cfg, c, nodeMap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* what is the hack here? --MS
|
protected CAstNode copyNodes(CAstNode root, final CAstControlFlowMap cfg, NonCopyingContext c, Map<Pair<CAstNode,NoKey>, CAstNode> nodeMap) {
|
||||||
*/
|
|
||||||
protected CAstNode copyNodesHackForEclipse(CAstNode root, final CAstControlFlowMap cfg, NonCopyingContext c, Map<Pair<CAstNode,NoKey>, CAstNode> nodeMap) {
|
|
||||||
final Pair<CAstNode, NoKey> pairKey = Pair.make(root, c.key());
|
final Pair<CAstNode, NoKey> pairKey = Pair.make(root, c.key());
|
||||||
if (root instanceof CAstOperator) {
|
if (root instanceof CAstOperator) {
|
||||||
nodeMap.put(pairKey, root);
|
nodeMap.put(pairKey, root);
|
||||||
|
|
|
@ -361,7 +361,7 @@ public abstract class CAstRewriter<C extends CAstRewriter.RewriteContext<K>, K e
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CAstControlFlowMap newCfg() {
|
public CAstControlFlowMap newCfg() {
|
||||||
if (theCfg == null)
|
if (theCfg == null && cfg != null)
|
||||||
theCfg = copyFlow(nodes, cfg, newPos());
|
theCfg = copyFlow(nodes, cfg, newPos());
|
||||||
return theCfg;
|
return theCfg;
|
||||||
}
|
}
|
||||||
|
@ -375,7 +375,7 @@ public abstract class CAstRewriter<C extends CAstRewriter.RewriteContext<K>, K e
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CAstNodeTypeMap newTypes() {
|
public CAstNodeTypeMap newTypes() {
|
||||||
if (theTypes == null)
|
if (theTypes == null && types != null)
|
||||||
theTypes = copyTypes(nodes, types);
|
theTypes = copyTypes(nodes, types);
|
||||||
return theTypes;
|
return theTypes;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.ibm.wala.cast.util;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.tree.CAstEntity;
|
||||||
|
import com.ibm.wala.cast.tree.CAstNode;
|
||||||
|
import com.ibm.wala.cast.util.CAstPattern.Segments;
|
||||||
|
import com.ibm.wala.util.collections.HashMapFactory;
|
||||||
|
import com.ibm.wala.util.collections.HashSetFactory;
|
||||||
|
|
||||||
|
public class AstConstantCollector {
|
||||||
|
|
||||||
|
public static final CAstPattern simplePreUpdatePattern = CAstPattern.parse("ASSIGN_PRE_OP(VAR(<name>CONSTANT()),**)");
|
||||||
|
|
||||||
|
public static final CAstPattern simplePostUpdatePattern = CAstPattern.parse("ASSIGN_POST_OP(VAR(<name>CONSTANT()),**)");
|
||||||
|
|
||||||
|
public static final CAstPattern simpleValuePattern = CAstPattern.parse("ASSIGN(VAR(<name>CONSTANT()),<value>*)");
|
||||||
|
|
||||||
|
public static Map<String,Object> collectConstants(CAstEntity function, Map<String,Object> values) {
|
||||||
|
if (function.getAST() != null) {
|
||||||
|
Set<String> bad = HashSetFactory.make();
|
||||||
|
for(Segments s : CAstPattern.findAll(simplePreUpdatePattern, function)) {
|
||||||
|
bad.add((String) s.getSingle("name").getValue());
|
||||||
|
}
|
||||||
|
for(Segments s : CAstPattern.findAll(simplePostUpdatePattern, function)) {
|
||||||
|
bad.add((String) s.getSingle("name").getValue());
|
||||||
|
}
|
||||||
|
for(Segments s : CAstPattern.findAll(simpleValuePattern, function)) {
|
||||||
|
String var = (String) s.getSingle("name").getValue();
|
||||||
|
if (s.getSingle("value").getKind() != CAstNode.CONSTANT) {
|
||||||
|
bad.add(var);
|
||||||
|
} else {
|
||||||
|
Object val = s.getSingle("value").getValue();
|
||||||
|
if (! bad.contains(var)) {
|
||||||
|
if (values.containsKey(var)) {
|
||||||
|
if (!values.get(var).equals(val)) {
|
||||||
|
values.remove(var);
|
||||||
|
bad.add(var);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
values.put(var, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Collection<CAstEntity> ces : function.getAllScopedEntities().values()) {
|
||||||
|
for(CAstEntity ce : ces) {
|
||||||
|
collectConstants(ce, values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String,Object> collectConstants(CAstEntity function) {
|
||||||
|
Map<String,Object> values = HashMapFactory.make();
|
||||||
|
collectConstants(function, values);
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
}
|
|
@ -408,6 +408,13 @@ public class CAstPattern {
|
||||||
visit(top, c, this);
|
visit(top, c, this);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean doVisit(CAstNode n, Context context, CAstVisitor<Context> visitor) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Parser {
|
private static class Parser {
|
||||||
|
|
|
@ -3,6 +3,5 @@ source.. = src/,\
|
||||||
output.. = bin/test
|
output.. = bin/test
|
||||||
bin.includes = META-INF/,\
|
bin.includes = META-INF/,\
|
||||||
.,\
|
.,\
|
||||||
plugin.xml,\
|
plugin.properties
|
||||||
plugin.properties
|
|
||||||
javacProjectSettings = true
|
javacProjectSettings = true
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<?eclipse version="3.2"?>
|
|
||||||
<!DOCTYPE plugin>
|
|
||||||
<plugin>
|
|
||||||
<extension id="HeadlessWALA"
|
|
||||||
point="org.eclipse.core.runtime.applications">
|
|
||||||
<application>
|
|
||||||
<run class="com.ibm.wala.eclipse.headless.Main"/>
|
|
||||||
</application>
|
|
||||||
</extension>
|
|
||||||
</plugin>
|
|
|
@ -118,7 +118,7 @@ public class AnalysisScope {
|
||||||
*/
|
*/
|
||||||
private SetOfClasses exclusions;
|
private SetOfClasses exclusions;
|
||||||
|
|
||||||
final protected LinkedHashMap<Atom, ClassLoaderReference> loadersByName = new LinkedHashMap<>();
|
public final LinkedHashMap<Atom, ClassLoaderReference> loadersByName = new LinkedHashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Special class loader for array instances
|
* Special class loader for array instances
|
||||||
|
|
Loading…
Reference in New Issue