Fixed bugs in the front end handling esoteric cases of weird control
flow. added support for JavaScript projects read from Eclipse that are based on HTML files as well as JavaScript files
This commit is contained in:
parent
de6b644e8c
commit
beab92e359
|
@ -15,5 +15,6 @@ Require-Bundle: com.ibm.wala.cast.js.rhino;bundle-version="1.0.0",
|
|||
org.junit;bundle-version="4.0.0"
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.ibm.wala.cast.js.rhino.test,
|
||||
Export-Package: com.ibm.wala.cast.js.rhino.callgraph.fieldbased.test,
|
||||
com.ibm.wala.cast.js.rhino.test,
|
||||
com.ibm.wala.cast.js.test
|
||||
|
|
|
@ -74,7 +74,12 @@ public class TestSimpleCallGraphShapeRhino extends TestSimpleCallGraphShape {
|
|||
public void testNonLoopBreakLabel() throws IllegalArgumentException, IOException, CancelException, WalaException {
|
||||
JSCallGraphBuilderUtil.makeScriptCG("tests", "non_loop_break.js");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testForInName() throws IllegalArgumentException, IOException, CancelException, WalaException {
|
||||
JSCallGraphBuilderUtil.makeScriptCG("tests", "for_in_name.js");
|
||||
}
|
||||
|
||||
@Test(expected = WalaException.class)
|
||||
public void testParseError() throws IllegalArgumentException, IOException, CancelException, WalaException {
|
||||
PropagationCallGraphBuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "portal-example-simple.html");
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
</listAttribute>
|
||||
<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
|
||||
<mapAttribute key="org.eclipse.debug.core.preferred_launchers">
|
||||
<mapEntry key="[debug]" value="org.eclipse.jdt.junit.launchconfig"/>
|
||||
<mapEntry key="[run]" value="org.eclipse.jdt.junit.launchconfig"/>
|
||||
</mapAttribute>
|
||||
<stringAttribute key="org.eclipse.debug.ui.ATTR_CAPTURE_IN_FILE" value="/tmp/console.txt"/>
|
||||
|
|
|
@ -294,7 +294,7 @@ public class RhinoToAstTranslator {
|
|||
}
|
||||
|
||||
private CAstNode handleNew(WalkContext context, String globalName, CAstNode arguments[]) {
|
||||
return handleNew(context, readName(context, globalName), arguments);
|
||||
return handleNew(context, readName(context, null, globalName), arguments);
|
||||
}
|
||||
|
||||
private CAstNode handleNew(WalkContext context, CAstNode value, CAstNode arguments[]) {
|
||||
|
@ -557,9 +557,13 @@ public class RhinoToAstTranslator {
|
|||
return n;
|
||||
}
|
||||
|
||||
private CAstNode readName(WalkContext context, String name) {
|
||||
private CAstNode readName(WalkContext context, AstNode node, String name) {
|
||||
CAstNode cn = makeVarRef(name);
|
||||
context.cfg().map(cn, cn);
|
||||
if (node != null) {
|
||||
context.cfg().map(node, cn);
|
||||
} else {
|
||||
context.cfg().map(cn, cn);
|
||||
}
|
||||
CAstNode target = context.getCatchTarget();
|
||||
if (target != null) {
|
||||
context.cfg().add(cn, target, JavaScriptTypes.ReferenceError);
|
||||
|
@ -729,14 +733,16 @@ public class RhinoToAstTranslator {
|
|||
public CAstNode visitContinueStatement(ContinueStatement node,
|
||||
WalkContext arg) {
|
||||
CAstNode continueStmt;
|
||||
Node target;
|
||||
if (node.getLabel() != null) {
|
||||
continueStmt = Ast.makeNode(CAstNode.GOTO, Ast.makeConstant(node.getLabel().getIdentifier()));
|
||||
target = arg.getContinueFor(node.getLabel().getIdentifier());
|
||||
} else {
|
||||
continueStmt = Ast.makeNode(CAstNode.GOTO);
|
||||
target = arg.getContinueFor(null);
|
||||
}
|
||||
|
||||
arg.cfg().map(node, continueStmt);
|
||||
|
||||
Node target = node.getTarget();
|
||||
arg.cfg().add(node, target, null);
|
||||
|
||||
return continueStmt;
|
||||
|
@ -805,15 +811,15 @@ public class RhinoToAstTranslator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public CAstNode visitForInLoop(ForInLoop node, WalkContext arg) {
|
||||
String tempName = "for in loop temp";
|
||||
|
||||
public CAstNode visitForInLoop(ForInLoop node, WalkContext arg) {
|
||||
// set up
|
||||
AstNode object = node.getIteratedObject();
|
||||
CAstNode loopTemp =
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(tempName)),
|
||||
visit(object, arg));
|
||||
|
||||
CAstNode object = visit(node.getIteratedObject(), arg);
|
||||
String tempName = "for in loop temp";
|
||||
CAstNode[] loopHeader = new CAstNode[]{
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(tempName))),
|
||||
Ast.makeNode(CAstNode.ASSIGN, Ast.makeNode(CAstNode.VAR, Ast.makeConstant(tempName)), object)
|
||||
};
|
||||
|
||||
CAstNode initNode;
|
||||
AstNode var = node.getIterator();
|
||||
assert var instanceof Name || var instanceof VariableDeclaration || var instanceof LetNode : var.getClass() + " " + var;
|
||||
|
@ -844,7 +850,7 @@ public class RhinoToAstTranslator {
|
|||
} else {
|
||||
arg.addNameDecl(
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(init.getTarget().getString())),
|
||||
readName(arg, "$$undefined")));
|
||||
readName(arg, null, "$$undefined")));
|
||||
|
||||
initNode =
|
||||
Ast.makeNode(CAstNode.ASSIGN,
|
||||
|
@ -858,15 +864,21 @@ public class RhinoToAstTranslator {
|
|||
CAstNode breakLabel = visit(breakStmt, arg);
|
||||
AstNode contStmt = makeEmptyLabelStmt("contLabel");
|
||||
CAstNode contLabel = visit(contStmt, arg);
|
||||
// TODO: Figure out why this is needed to make the correlation extraction tests pass
|
||||
// TODO: remove this silly label
|
||||
AstNode garbageStmt = makeEmptyLabelStmt("garbageLabel");
|
||||
CAstNode garbageLabel = visit(garbageStmt, arg);
|
||||
WalkContext loopContext = makeLoopContext(node, arg, breakStmt, contStmt);
|
||||
CAstNode body = Ast.makeNode(CAstNode.BLOCK_STMT,
|
||||
initNode,
|
||||
visit(node.getBody(), loopContext),
|
||||
contLabel);
|
||||
garbageLabel);
|
||||
|
||||
CAstNode loop = Ast.makeNode(CAstNode.LOCAL_SCOPE,
|
||||
Ast.makeNode(CAstNode.BLOCK_STMT,
|
||||
loopTemp,
|
||||
loopHeader[0],
|
||||
loopHeader[1],
|
||||
contLabel,
|
||||
Ast.makeNode(CAstNode.LOOP,
|
||||
Ast.makeNode(CAstNode.EACH_ELEMENT_HAS_NEXT,
|
||||
Ast.makeNode(CAstNode.VAR, Ast.makeConstant(tempName))),
|
||||
|
@ -885,9 +897,10 @@ public class RhinoToAstTranslator {
|
|||
|
||||
WalkContext loopContext = makeLoopContext(node, arg, breakStmt, contStmt);
|
||||
|
||||
CAstNode loop = Ast.makeNode(CAstNode.BLOCK_STMT,
|
||||
CAstNode loop;
|
||||
CAstNode top = Ast.makeNode(CAstNode.BLOCK_STMT,
|
||||
visit(node.getInitializer(), arg),
|
||||
Ast.makeNode(CAstNode.LOOP,
|
||||
loop = Ast.makeNode(CAstNode.LOOP,
|
||||
visit(node.getCondition(), arg),
|
||||
Ast.makeNode(CAstNode.BLOCK_STMT,
|
||||
visit(node.getBody(), loopContext),
|
||||
|
@ -895,7 +908,7 @@ public class RhinoToAstTranslator {
|
|||
visit(node.getIncrement(), arg))),
|
||||
breakLabel);
|
||||
arg.cfg().map(node, loop);
|
||||
return loop;
|
||||
return top;
|
||||
}
|
||||
|
||||
private CAstNode[] gatherCallArguments(Node call, WalkContext context) {
|
||||
|
@ -912,7 +925,7 @@ public class RhinoToAstTranslator {
|
|||
public CAstNode visitFunctionCall(FunctionCall n, WalkContext context) {
|
||||
if (!isPrimitiveCall(context, n)) {
|
||||
AstNode callee = n.getTarget();
|
||||
int thisBaseVarNum = ++baseVarNum;
|
||||
int thisBaseVarNum = ++tempVarNum;
|
||||
WalkContext child = new MemberDestructuringContext(context, callee, thisBaseVarNum);
|
||||
CAstNode fun = visit(callee, child);
|
||||
|
||||
|
@ -1107,7 +1120,7 @@ public class RhinoToAstTranslator {
|
|||
|
||||
@Override
|
||||
public CAstNode visitName(Name n, WalkContext context) {
|
||||
return readName(context, n.getString());
|
||||
return readName(context, n, n.getString());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1345,7 +1358,7 @@ public class RhinoToAstTranslator {
|
|||
noteSourcePosition(
|
||||
arg,
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(init.getTarget().getString())),
|
||||
readName(arg, "$$undefined")),
|
||||
readName(arg, null, "$$undefined")),
|
||||
node));
|
||||
|
||||
if (init.getInitializer() == null) {
|
||||
|
@ -1380,11 +1393,10 @@ public class RhinoToAstTranslator {
|
|||
WalkContext loopContext = makeLoopContext(node, arg, breakStmt, contStmt);
|
||||
|
||||
CAstNode loop = Ast.makeNode(CAstNode.BLOCK_STMT,
|
||||
contLabel,
|
||||
Ast.makeNode(CAstNode.LOOP,
|
||||
visit(node.getCondition(), arg),
|
||||
Ast.makeNode(CAstNode.BLOCK_STMT,
|
||||
visit(node.getBody(), loopContext),
|
||||
contLabel)),
|
||||
visit(node.getBody(), loopContext)),
|
||||
breakLabel);
|
||||
|
||||
arg.cfg().map(node, loop);
|
||||
|
@ -2337,7 +2349,7 @@ private CAstNode[] walkChildren(final Node n, WalkContext context) {
|
|||
|
||||
final private Reader sourceReader;
|
||||
|
||||
private int baseVarNum = 0;
|
||||
private int tempVarNum = 0;
|
||||
|
||||
private final DoLoopTranslator doLoopTranslator;
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
var f = function for_in_with_assign(b) {
|
||||
var a,d,n,e;
|
||||
n=1;
|
||||
for(e=arguments.length;n<e;n+=1)
|
||||
for(a in d=arguments[n],d)
|
||||
Object.prototype.hasOwnProperty.call(d,a)&&(b[a]=d[a]);
|
||||
return b;
|
||||
}
|
||||
|
||||
f(new Object());
|
|
@ -0,0 +1,74 @@
|
|||
var f = function(arrangedSSIDs,accessPointSpecs,exactLocation)
|
||||
{
|
||||
for (var i=0; i < accessPointSpecs.length; i++)
|
||||
{
|
||||
var definedSSID = accessPointSpecs[i].SSID;
|
||||
var definedMAC = accessPointSpecs[i].MAC;
|
||||
|
||||
if (arrangedSSIDs[definedSSID])
|
||||
{
|
||||
if (definedMAC)
|
||||
{
|
||||
if (arrangedSSIDs[definedSSID][definedMAC])
|
||||
{
|
||||
arrangedSSIDs[definedSSID][definedMAC].checked = true;
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
arrangedSSIDs[definedSSID].checked = true;
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (exactLocation)
|
||||
{
|
||||
for (var key in arrangedSSIDs)
|
||||
{
|
||||
var SSID = arrangedSSIDs[key];
|
||||
if (!SSID.checked)
|
||||
{
|
||||
var checkedMACs = false;
|
||||
for (var MAC in SSID)
|
||||
{
|
||||
checkedMACs = true;
|
||||
var obj = SSID[MAC];
|
||||
if (!obj.checked) return false;
|
||||
}
|
||||
|
||||
if (!checkedMACs) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
var g = function(transactionId) {
|
||||
var obj,http,i;
|
||||
try
|
||||
{
|
||||
http = new XMLHttpRequest();
|
||||
obj = { conn:http, tId:transactionId, xhr: true };
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
for(i=0; i<this._msxml_progid.length; ++i){
|
||||
try
|
||||
{
|
||||
http = new ActiveXObject(this._msxml_progid[i]);
|
||||
obj = { conn:http, tId:transactionId, xhr: true };
|
||||
break;
|
||||
}
|
||||
catch(e1){}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
f();
|
||||
g();
|
|
@ -16,6 +16,7 @@ import java.io.IOException;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.ComparisonFailure;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -50,20 +51,27 @@ public abstract class TestForInBodyExtraction {
|
|||
|
||||
public void testRewriter(String testName, String in, String out) {
|
||||
File tmp = null;
|
||||
String expected = null;
|
||||
String actual = null;
|
||||
try {
|
||||
tmp = File.createTempFile("test", ".js");
|
||||
FileUtil.writeFile(tmp, in);
|
||||
CAstImpl ast = new CAstImpl();
|
||||
String actual = new CAstDumper().dump(new ClosureExtractor(ast, ForInBodyExtractionPolicy.FACTORY).rewrite(parseJS(tmp, ast)));
|
||||
actual = new CAstDumper().dump(new ClosureExtractor(ast, ForInBodyExtractionPolicy.FACTORY).rewrite(parseJS(tmp, ast)));
|
||||
actual = eraseGeneratedNames(actual);
|
||||
|
||||
FileUtil.writeFile(tmp, out);
|
||||
String expected = new CAstDumper().dump(parseJS(tmp, ast));
|
||||
expected = new CAstDumper().dump(parseJS(tmp, ast));
|
||||
expected = eraseGeneratedNames(expected);
|
||||
|
||||
Assert.assertEquals(testName, expected, actual);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ComparisonFailure e) {
|
||||
System.err.println("Comparison Failure in " + testName + "!");
|
||||
System.err.println(expected);
|
||||
System.err.println(actual);
|
||||
throw e;
|
||||
} finally {
|
||||
if(tmp != null && tmp.exists())
|
||||
tmp.delete();
|
||||
|
|
|
@ -671,6 +671,11 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
|||
JSCallGraphBuilderUtil.makeScriptCG("tests", "dead_catch.js");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUglyLoopCrash() throws IllegalArgumentException, IOException, CancelException, WalaException {
|
||||
JSCallGraphBuilderUtil.makeScriptCG("tests", "ssa-crash.js");
|
||||
}
|
||||
|
||||
@Ignore("need a bug fix")
|
||||
@Test
|
||||
public void testTryFinallyCrash() throws IllegalArgumentException, IOException, CancelException, WalaException {
|
||||
|
|
|
@ -69,6 +69,7 @@ import com.ibm.wala.shrikeBT.IUnaryOpInstruction;
|
|||
import com.ibm.wala.shrikeBT.ShiftInstruction;
|
||||
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSAGetCaughtExceptionInstruction;
|
||||
import com.ibm.wala.ssa.SSAGotoInstruction;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAInstructionFactory;
|
||||
import com.ibm.wala.ssa.SSAMonitorInstruction;
|
||||
|
@ -603,7 +604,7 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
|
|||
return "PreBB" + number + ":" + firstIndex + ".." + lastIndex;
|
||||
}
|
||||
|
||||
List<SSAInstruction> instructions() {
|
||||
private List<SSAInstruction> instructions() {
|
||||
return instructions;
|
||||
}
|
||||
|
||||
|
@ -1062,6 +1063,9 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
|
|||
if (currentBlock.instructions().size() == 0) {
|
||||
currentBlock.setFirstIndex(inst);
|
||||
} else {
|
||||
for(SSAInstruction priorInst : currentBlock.instructions()) {
|
||||
assert ! (priorInst instanceof SSAGotoInstruction);
|
||||
}
|
||||
assert !(n instanceof SSAGetCaughtExceptionInstruction);
|
||||
}
|
||||
|
||||
|
@ -1114,13 +1118,34 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
|
|||
}
|
||||
}
|
||||
|
||||
AstCFG(CAstEntity n, IncipientCFG icfg, SymbolTable symtab) {
|
||||
private boolean checkBlockBoundaries(IncipientCFG icfg) {
|
||||
MutableIntSet boundaries = IntSetUtil.make();
|
||||
for(PreBasicBlock b : icfg) {
|
||||
if (b.getFirstInstructionIndex() >= 0) {
|
||||
if (boundaries.contains(b.getFirstInstructionIndex())) {
|
||||
return false;
|
||||
}
|
||||
boundaries.add(b.getFirstInstructionIndex());
|
||||
}
|
||||
if (b.getLastInstructionIndex() >= 0 && b.getLastInstructionIndex() != b.getFirstInstructionIndex()) {
|
||||
if (boundaries.contains(b.getLastInstructionIndex())) {
|
||||
return false;
|
||||
}
|
||||
boundaries.add(b.getLastInstructionIndex());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
AstCFG(CAstEntity n, IncipientCFG icfg, SymbolTable symtab, SSAInstructionFactory insts) {
|
||||
super(null);
|
||||
|
||||
Set<PreBasicBlock> liveBlocks = DFS.getReachableNodes(icfg, Collections.singleton(icfg.entryBlock));
|
||||
List<PreBasicBlock> blocks = icfg.blocks;
|
||||
boolean hasDeadBlocks = blocks.size() > liveBlocks.size();
|
||||
|
||||
assert checkBlockBoundaries(icfg);
|
||||
|
||||
this.symtab = symtab;
|
||||
functionName = n.getName();
|
||||
instructionToBlockMap = new int[liveBlocks.size()];
|
||||
|
@ -1149,11 +1174,15 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
|
|||
});
|
||||
}
|
||||
|
||||
int instruction = 0;
|
||||
for (int i = 0, blockNumber = 0; i < blocks.size(); i++) {
|
||||
PreBasicBlock pb = blocks.get(i);
|
||||
PreBasicBlock block = blocks.get(i);
|
||||
block.setGraphNodeId(-1);
|
||||
if (liveBlocks.contains(pb)) {
|
||||
if (liveBlocks.contains(block)) {
|
||||
if (block.getFirstInstructionIndex() >= 0) {
|
||||
block.setFirstIndex(instruction);
|
||||
block.setLastIndex((instruction += block.instructions().size()) - 1);
|
||||
}
|
||||
instructionToBlockMap[blockNumber] = block.getLastInstructionIndex();
|
||||
|
||||
this.addNode(block);
|
||||
|
@ -1209,7 +1238,14 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
|
|||
if (liveBlocks.contains(blocks.get(i))) {
|
||||
List<SSAInstruction> bi = blocks.get(i).instructions();
|
||||
for (int j = 0; j < bi.size(); j++) {
|
||||
instructions[x++] = bi.get(j);
|
||||
SSAInstruction inst = bi.get(j);
|
||||
if (inst instanceof SSAGetCaughtExceptionInstruction) {
|
||||
SSAGetCaughtExceptionInstruction ci = (SSAGetCaughtExceptionInstruction) inst;
|
||||
if (ci.getBasicBlockNumber() != blocks.get(i).getNumber()) {
|
||||
inst = insts.GetCaughtExceptionInstruction(blocks.get(i).getNumber(), ci.getException());
|
||||
}
|
||||
}
|
||||
instructions[x++] = inst;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3107,7 +3143,7 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
|
|||
// create code entry stuff for this entity
|
||||
SymbolTable symtab = ((AbstractScope) functionContext.currentScope()).getUnderlyingSymtab();
|
||||
Map<IBasicBlock,TypeReference[]> catchTypes = functionContext.getCatchTypes();
|
||||
AstCFG cfg = new AstCFG(n, functionContext.cfg(), symtab);
|
||||
AstCFG cfg = new AstCFG(n, functionContext.cfg(), symtab, insts);
|
||||
Position[] line = functionContext.cfg().getLinePositionMap();
|
||||
boolean katch = functionContext.cfg().hasCatchBlock();
|
||||
boolean monitor = functionContext.cfg().hasMonitorOp();
|
||||
|
@ -3526,13 +3562,13 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
|
|||
WalkContext context = (WalkContext) c;
|
||||
if (!context.cfg().isDeadBlock(context.cfg().getCurrentBlock())) {
|
||||
context.cfg().addPreNode(n, context.getUnwindState());
|
||||
context.cfg().addInstruction(insts.GotoInstruction());
|
||||
context.cfg().newBlock(false);
|
||||
context.cfg().addPreEdge(n, context.getControlFlow().getTarget(n, null), false);
|
||||
context.cfg().addInstruction(insts.GotoInstruction());
|
||||
if (context.getControlFlow().getTarget(n, null) == null) {
|
||||
assert context.getControlFlow().getTarget(n, null) != null : context.getControlFlow() + " does not map " + n + " ("
|
||||
+ context.getSourceMap().getPosition(n) + ")";
|
||||
}
|
||||
context.cfg().addPreEdge(n, context.getControlFlow().getTarget(n, null), false);
|
||||
context.cfg().newBlock(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -185,7 +185,7 @@ public abstract class CAstAbstractModuleLoader extends CAstAbstractLoader {
|
|||
* in topLevelEntities
|
||||
*/
|
||||
private void translateModuleToCAst(Module module, CAst ast, Set<Pair<CAstEntity, ModuleEntry>> topLevelEntities) {
|
||||
for (Iterator<ModuleEntry> mes = module.getEntries(); mes.hasNext();) {
|
||||
for (Iterator<? extends ModuleEntry> mes = module.getEntries(); mes.hasNext();) {
|
||||
translateModuleEntryToCAst(mes.next(), ast, topLevelEntities);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,8 +43,8 @@ public abstract class DirectoryTreeModule implements Module {
|
|||
|
||||
protected abstract boolean includeFile(File file);
|
||||
|
||||
private Set<ModuleEntry> getEntriesRecursive(File dir) {
|
||||
Set<ModuleEntry> result = HashSetFactory.make();
|
||||
private Set<FileModule> getEntriesRecursive(File dir) {
|
||||
Set<FileModule> result = HashSetFactory.make();
|
||||
File[] files = dir.listFiles();
|
||||
if (files != null) {
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
|
@ -67,7 +67,7 @@ public abstract class DirectoryTreeModule implements Module {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Iterator<ModuleEntry> getEntries() {
|
||||
public Iterator<FileModule> getEntries() {
|
||||
return getEntriesRecursive(root).iterator();
|
||||
}
|
||||
|
||||
|
|
|
@ -23,5 +23,5 @@ public interface Module {
|
|||
/**
|
||||
* @return an Iterator of the ModuleEntries in this Module.
|
||||
*/
|
||||
Iterator<ModuleEntry> getEntries();
|
||||
Iterator<? extends ModuleEntry> getEntries();
|
||||
}
|
||||
|
|
|
@ -16,3 +16,4 @@ Require-Bundle: com.ibm.wala.core;bundle-version="1.1.3",
|
|||
org.junit;bundle-version="4.0.0"
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-Activator: com.ibm.wala.ide.jsdt.tests.Activator
|
||||
Export-Package: com.ibm.wala.ide.jsdt.tests
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.pde.ui.JunitLaunchConfig">
|
||||
<booleanAttribute key="append.args" value="true"/>
|
||||
<booleanAttribute key="askclear" value="false"/>
|
||||
<booleanAttribute key="automaticAdd" value="true"/>
|
||||
<booleanAttribute key="automaticValidate" value="false"/>
|
||||
<stringAttribute key="bootstrap" value=""/>
|
||||
<stringAttribute key="checked" value="[NONE]"/>
|
||||
<booleanAttribute key="clearConfig" value="true"/>
|
||||
<booleanAttribute key="clearws" value="true"/>
|
||||
<booleanAttribute key="clearwslog" value="false"/>
|
||||
<stringAttribute key="configLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/pde-junit"/>
|
||||
<booleanAttribute key="default" value="true"/>
|
||||
<booleanAttribute key="includeOptional" value="true"/>
|
||||
<stringAttribute key="location" value="${workspace_loc}/../junit-workspace"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/com.ibm.wala.ide.jsdt.tests/src/com/ibm/wala/ide/jsdt/tests/WLProjectWebScopeTest.java"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="1"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.debug.ui.ATTR_CAPTURE_IN_FILE" value="/tmp/jswebcgtest.txt"/>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>
|
||||
<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.ibm.wala.ide.jsdt.tests.WLProjectWebScopeTest"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.ibm.wala.ide.jsdt.tests"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms40m -XX:MaxPermSize=512m -Xmx2048m -Xdock:icon=../Resources/Eclipse.icns -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts"/>
|
||||
<stringAttribute key="pde.version" value="3.3"/>
|
||||
<stringAttribute key="product" value="org.eclipse.sdk.ide"/>
|
||||
<booleanAttribute key="run_in_ui_thread" value="true"/>
|
||||
<booleanAttribute key="show_selected_only" value="false"/>
|
||||
<booleanAttribute key="tracing" value="false"/>
|
||||
<booleanAttribute key="useCustomFeatures" value="false"/>
|
||||
<booleanAttribute key="useDefaultConfig" value="true"/>
|
||||
<booleanAttribute key="useDefaultConfigArea" value="false"/>
|
||||
<booleanAttribute key="useProduct" value="true"/>
|
||||
</launchConfiguration>
|
File diff suppressed because one or more lines are too long
|
@ -36,7 +36,7 @@ import com.ibm.wala.ipa.callgraph.CallGraph;
|
|||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
public class AbstractJSProjectScopeTest {
|
||||
public abstract class AbstractJSProjectScopeTest {
|
||||
|
||||
protected final ZippedProjectData project;
|
||||
|
||||
|
@ -55,12 +55,16 @@ public class AbstractJSProjectScopeTest {
|
|||
public void testProjectScope() throws IOException, CoreException {
|
||||
IJavaScriptProject p = JavaScriptHeadlessUtil.getJavaScriptProjectFromWorkspace(project.projectName);
|
||||
JSCallGraphUtil.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
||||
AnalysisScope s = JavaScriptEclipseProjectPath.make(p).toAnalysisScope(new CAstAnalysisScope(JSCallGraphUtil.makeLoaders(), Collections.singleton(JavaScriptLoader.JS)));
|
||||
AnalysisScope s = makeProjectPath(p).toAnalysisScope(new CAstAnalysisScope(JSCallGraphUtil.makeLoaders(), Collections.singleton(JavaScriptLoader.JS)));
|
||||
System.err.println(s);
|
||||
Assert.assertTrue("cannot make scope", s != null);
|
||||
Assert.assertFalse("cannot find files", s.getModules(JavaScriptTypes.jsLoader).isEmpty());
|
||||
}
|
||||
|
||||
protected JavaScriptEclipseProjectPath makeProjectPath(IJavaScriptProject p) throws IOException, CoreException {
|
||||
return JavaScriptEclipseProjectPath.make(p);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParsing() throws IOException, CoreException {
|
||||
Set<ModuleEntry> mes = JsdtUtil.getJavaScriptCodeFromProject(project.projectName);
|
||||
|
@ -77,7 +81,7 @@ public class AbstractJSProjectScopeTest {
|
|||
@Test
|
||||
public void testEngine() throws IOException, CoreException, IllegalArgumentException, CancelException {
|
||||
IJavaScriptProject p = JavaScriptHeadlessUtil.getJavaScriptProjectFromWorkspace(project.projectName);
|
||||
EclipseJavaScriptAnalysisEngine e = new EclipseJavaScriptAnalysisEngine(p);
|
||||
EclipseJavaScriptAnalysisEngine e = makeAnalysisEngine(p);
|
||||
JSCallGraphUtil.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
||||
e.buildAnalysisScope();
|
||||
IClassHierarchy cha = e.getClassHierarchy();
|
||||
|
@ -85,16 +89,8 @@ public class AbstractJSProjectScopeTest {
|
|||
Assert.assertTrue(cha != null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFieldBasedCG() throws IOException, CoreException, IllegalArgumentException, CancelException {
|
||||
IJavaScriptProject p = JavaScriptHeadlessUtil.getJavaScriptProjectFromWorkspace(project.projectName);
|
||||
EclipseJavaScriptAnalysisEngine e = new EclipseJavaScriptAnalysisEngine(p);
|
||||
JSCallGraphUtil.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
||||
e.buildAnalysisScope();
|
||||
CallGraph CG = e.getFieldBasedCallGraph();
|
||||
System.err.println(CG);
|
||||
Assert.assertTrue(CG.getNumberOfNodes() > 0);
|
||||
Assert.assertTrue(CG != null);
|
||||
protected EclipseJavaScriptAnalysisEngine makeAnalysisEngine(IJavaScriptProject p) throws IOException, CoreException {
|
||||
return new EclipseJavaScriptAnalysisEngine(p);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.ibm.wala.ide.jsdt.tests;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.wst.jsdt.core.IJavaScriptProject;
|
||||
|
||||
import com.ibm.wala.cast.js.client.EclipseJavaScriptAnalysisEngine;
|
||||
import com.ibm.wala.cast.js.client.EclipseWebAnalysisEngine;
|
||||
import com.ibm.wala.ide.util.EclipseWebProjectPath;
|
||||
import com.ibm.wala.ide.util.JavaScriptEclipseProjectPath;
|
||||
|
||||
public class WLProjectWebScopeTest extends WLProjectScopeTest {
|
||||
|
||||
@Override
|
||||
protected JavaScriptEclipseProjectPath makeProjectPath(IJavaScriptProject p) throws IOException, CoreException {
|
||||
return new EclipseWebProjectPath(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EclipseJavaScriptAnalysisEngine makeAnalysisEngine(IJavaScriptProject p) throws IOException, CoreException {
|
||||
return new EclipseWebAnalysisEngine(p);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.ibm.wala.cast.js.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.wst.jsdt.core.IJavaScriptProject;
|
||||
|
||||
import com.ibm.wala.cast.ipa.callgraph.CAstAnalysisScope;
|
||||
import com.ibm.wala.cast.js.html.WebPageLoaderFactory;
|
||||
import com.ibm.wala.cast.js.loader.JavaScriptLoader;
|
||||
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
|
||||
import com.ibm.wala.classLoader.ClassLoaderFactory;
|
||||
import com.ibm.wala.ide.util.EclipseWebProjectPath;
|
||||
import com.ibm.wala.ide.util.JavaScriptEclipseProjectPath;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.ipa.callgraph.impl.SetOfClasses;
|
||||
|
||||
public class EclipseWebAnalysisEngine extends EclipseJavaScriptAnalysisEngine {
|
||||
|
||||
public EclipseWebAnalysisEngine(IJavaScriptProject project) throws IOException, CoreException {
|
||||
super(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassLoaderFactory makeClassLoaderFactory(SetOfClasses exclusions) {
|
||||
return new WebPageLoaderFactory(new CAstRhinoTranslatorFactory());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AnalysisScope makeAnalysisScope() {
|
||||
return new CAstAnalysisScope(new WebPageLoaderFactory(new CAstRhinoTranslatorFactory()), Collections.singleton(JavaScriptLoader.JS));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JavaScriptEclipseProjectPath createProjectPath(IJavaScriptProject project) throws IOException, CoreException {
|
||||
return new EclipseWebProjectPath(project);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.ibm.wala.ide.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.wst.jsdt.core.IJavaScriptProject;
|
||||
|
||||
import com.ibm.wala.cast.ir.translator.TranslatorToCAst.Error;
|
||||
import com.ibm.wala.cast.js.html.MappedSourceModule;
|
||||
import com.ibm.wala.cast.js.html.WebUtil;
|
||||
import com.ibm.wala.classLoader.FileModule;
|
||||
import com.ibm.wala.classLoader.Module;
|
||||
import com.ibm.wala.ide.classloader.EclipseSourceDirectoryTreeModule;
|
||||
import com.ibm.wala.util.collections.MapUtil;
|
||||
|
||||
public class EclipseWebProjectPath extends JavaScriptEclipseProjectPath {
|
||||
|
||||
public EclipseWebProjectPath(IJavaScriptProject p) throws IOException, CoreException {
|
||||
super(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void resolveSourcePathEntry(com.ibm.wala.ide.util.EclipseProjectPath.ILoader loader, boolean includeSource, boolean cpeFromMainProject, IPath p, IPath o, String fileExtension) {
|
||||
List<Module> s = MapUtil.findOrCreateList(modules, loader);
|
||||
Iterator<FileModule> htmlPages = new EclipseSourceDirectoryTreeModule(p, "html").getEntries();
|
||||
while (htmlPages.hasNext()) {
|
||||
FileModule htmlPage = htmlPages.next();
|
||||
Set<MappedSourceModule> scripts;
|
||||
String urlString = "file://" + htmlPage.getAbsolutePath();
|
||||
try {
|
||||
scripts = WebUtil.extractScriptFromHTML(new URL(urlString)).fst;
|
||||
s.addAll(scripts);
|
||||
} catch (MalformedURLException e1) {
|
||||
assert false : "internal error constructing URL " + urlString;
|
||||
} catch (Error e1) {
|
||||
System.err.print("skipping " + htmlPage.getAbsolutePath() + ": " + e1.warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,12 @@
|
|||
package com.ibm.wala.ide.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
@ -20,8 +25,18 @@ import org.eclipse.wst.jsdt.core.IJavaScriptProject;
|
|||
import org.eclipse.wst.jsdt.core.JavaScriptCore;
|
||||
import org.eclipse.wst.jsdt.core.JavaScriptModelException;
|
||||
|
||||
import com.ibm.wala.cast.ir.translator.TranslatorToCAst.Error;
|
||||
import com.ibm.wala.cast.js.html.MappedSourceModule;
|
||||
import com.ibm.wala.cast.js.html.WebUtil;
|
||||
import com.ibm.wala.cast.js.types.JavaScriptTypes;
|
||||
import com.ibm.wala.cast.loader.CAstAbstractLoader;
|
||||
import com.ibm.wala.classLoader.FileModule;
|
||||
import com.ibm.wala.classLoader.Module;
|
||||
import com.ibm.wala.classLoader.SourceModule;
|
||||
import com.ibm.wala.classLoader.SourceURLModule;
|
||||
import com.ibm.wala.ide.classloader.EclipseSourceDirectoryTreeModule;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.util.collections.MapUtil;
|
||||
|
||||
public class JavaScriptEclipseProjectPath extends EclipseProjectPath<IIncludePathEntry, IJavaScriptProject> {
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ public class JsdtUtil {
|
|||
List<Module> modules = s.getModules(JavaScriptTypes.jsLoader);
|
||||
Set<ModuleEntry> mes = HashSetFactory.make();
|
||||
for(Module m : modules) {
|
||||
for(Iterator<ModuleEntry> mm = m.getEntries(); mm.hasNext(); ) {
|
||||
for(Iterator<? extends ModuleEntry> mm = m.getEntries(); mm.hasNext(); ) {
|
||||
mes.add(mm.next());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue