Merge branch 'github_master' into internal_merge
This commit is contained in:
commit
bb2c45803c
|
@ -10,3 +10,4 @@ com.ibm.wala.core.testdata/@dot/
|
||||||
com.ibm.wala.core.testdata/lib/
|
com.ibm.wala.core.testdata/lib/
|
||||||
com.ibm.wala.core/dat/wala.properties
|
com.ibm.wala.core/dat/wala.properties
|
||||||
com.ibm.wala.cast.js.html.nu_validator/lib/
|
com.ibm.wala.cast.js.html.nu_validator/lib/
|
||||||
|
com.ibm.wala.cast.java.test/testdata/
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
This is a mirror of the <a
|
This is the main source repository for WALA. For more details on WALA, see <a
|
||||||
href="http://wala.svn.sourceforge.net/viewvc/wala/">WALA SVN repository</a>. It
|
href="http://wala.sourceforge.net">the WALA home page</a>.
|
||||||
is maintained manually for now, but more official support may be added in the
|
|
||||||
future. For more details on WALA, see <a href="http://wala.sourceforge.net">the
|
|
||||||
WALA home page</a>.
|
|
||||||
|
|
|
@ -5,18 +5,18 @@ Bundle-SymbolicName: com.ibm.wala.cast.java.jdt.test
|
||||||
Bundle-Version: 1.0.0
|
Bundle-Version: 1.0.0
|
||||||
Bundle-Activator: com.ibm.wala.cast.java.jdt.test.Activator
|
Bundle-Activator: com.ibm.wala.cast.java.jdt.test.Activator
|
||||||
Bundle-Vendor: IBM
|
Bundle-Vendor: IBM
|
||||||
Require-Bundle: com.ibm.wala.cast;bundle-version="1.0.0",
|
Require-Bundle: com.ibm.wala.cast.java.test;bundle-version="1.0.0",
|
||||||
com.ibm.wala.cast.java;bundle-version="1.0.0",
|
|
||||||
com.ibm.wala.cast.java.test;bundle-version="1.0.0",
|
|
||||||
com.ibm.wala.cast.test;bundle-version="1.0.0",
|
com.ibm.wala.cast.test;bundle-version="1.0.0",
|
||||||
com.ibm.wala.core;bundle-version="1.1.3",
|
com.ibm.wala.ide.tests;bundle-version="1.1.3",
|
||||||
com.ibm.wala.core.tests;bundle-version="1.1.3",
|
com.ibm.wala.core.tests;bundle-version="1.1.3",
|
||||||
com.ibm.wala.cast.java.jdt;bundle-version="1.0.0",
|
com.ibm.wala.cast.java.jdt;bundle-version="1.0.0",
|
||||||
org.eclipse.core.runtime,
|
com.ibm.wala.cast.java;bundle-version="1.0.0",
|
||||||
|
com.ibm.wala.cast;bundle-version="1.0.0",
|
||||||
com.ibm.wala.ide;bundle-version="1.1.3",
|
com.ibm.wala.ide;bundle-version="1.1.3",
|
||||||
|
com.ibm.wala.core;bundle-version="1.1.3",
|
||||||
org.eclipse.core.resources;bundle-version="3.4.1",
|
org.eclipse.core.resources;bundle-version="3.4.1",
|
||||||
com.ibm.wala.ide.tests;bundle-version="1.1.3",
|
|
||||||
org.eclipse.jdt.core;bundle-version="3.4.2",
|
org.eclipse.jdt.core;bundle-version="3.4.2",
|
||||||
org.junit4;bundle-version="4.3.1"
|
org.junit4;bundle-version="4.8.1",
|
||||||
|
org.eclipse.core.runtime
|
||||||
Bundle-ActivationPolicy: lazy
|
Bundle-ActivationPolicy: lazy
|
||||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -24,11 +24,11 @@ import com.ibm.wala.cast.java.test.ide.IDEIRTestUtil;
|
||||||
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
|
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
|
||||||
import com.ibm.wala.core.tests.plugin.CoreTestsPlugin;
|
import com.ibm.wala.core.tests.plugin.CoreTestsPlugin;
|
||||||
import com.ibm.wala.ide.tests.util.EclipseTestUtil;
|
import com.ibm.wala.ide.tests.util.EclipseTestUtil;
|
||||||
|
import com.ibm.wala.ide.util.EclipseFileProvider;
|
||||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||||
import com.ibm.wala.ipa.callgraph.Entrypoint;
|
import com.ibm.wala.ipa.callgraph.Entrypoint;
|
||||||
import com.ibm.wala.ipa.callgraph.impl.Util;
|
import com.ibm.wala.ipa.callgraph.impl.Util;
|
||||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||||
import com.ibm.wala.util.io.FileProvider;
|
|
||||||
|
|
||||||
public class JDTJava15IRTests extends IRTests {
|
public class JDTJava15IRTests extends IRTests {
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ public class JDTJava15IRTests extends IRTests {
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
engine.setExclusionsFile(FileProvider
|
engine.setExclusionsFile((new EclipseFileProvider())
|
||||||
.getFileFromPlugin(CoreTestsPlugin.getDefault(), CallGraphTestUtil.REGRESSION_EXCLUSIONS).getAbsolutePath());
|
.getFileFromPlugin(CoreTestsPlugin.getDefault(), CallGraphTestUtil.REGRESSION_EXCLUSIONS).getAbsolutePath());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Assert.assertFalse("Cannot find exclusions file", true);
|
Assert.assertFalse("Cannot find exclusions file", true);
|
||||||
|
|
|
@ -54,11 +54,11 @@ import com.ibm.wala.cast.java.test.ide.IDEIRTestUtil;
|
||||||
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
|
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
|
||||||
import com.ibm.wala.core.tests.plugin.CoreTestsPlugin;
|
import com.ibm.wala.core.tests.plugin.CoreTestsPlugin;
|
||||||
import com.ibm.wala.ide.tests.util.EclipseTestUtil;
|
import com.ibm.wala.ide.tests.util.EclipseTestUtil;
|
||||||
|
import com.ibm.wala.ide.util.EclipseFileProvider;
|
||||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||||
import com.ibm.wala.ipa.callgraph.Entrypoint;
|
import com.ibm.wala.ipa.callgraph.Entrypoint;
|
||||||
import com.ibm.wala.ipa.callgraph.impl.Util;
|
import com.ibm.wala.ipa.callgraph.impl.Util;
|
||||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||||
import com.ibm.wala.util.io.FileProvider;
|
|
||||||
|
|
||||||
public class JDTJavaIRTests extends JavaIRTests {
|
public class JDTJavaIRTests extends JavaIRTests {
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ public class JDTJavaIRTests extends JavaIRTests {
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
engine.setExclusionsFile(FileProvider
|
engine.setExclusionsFile((new EclipseFileProvider())
|
||||||
.getFileFromPlugin(CoreTestsPlugin.getDefault(), CallGraphTestUtil.REGRESSION_EXCLUSIONS).getAbsolutePath());
|
.getFileFromPlugin(CoreTestsPlugin.getDefault(), CallGraphTestUtil.REGRESSION_EXCLUSIONS).getAbsolutePath());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Assert.assertFalse("Cannot find exclusions file", true);
|
Assert.assertFalse("Cannot find exclusions file", true);
|
||||||
|
|
|
@ -128,10 +128,11 @@ import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
|
||||||
import org.eclipse.jdt.core.dom.WhileStatement;
|
import org.eclipse.jdt.core.dom.WhileStatement;
|
||||||
|
|
||||||
import com.ibm.wala.cast.ir.translator.AstTranslator.InternalCAstSymbol;
|
import com.ibm.wala.cast.ir.translator.AstTranslator.InternalCAstSymbol;
|
||||||
|
import com.ibm.wala.cast.ir.translator.TranslatorToCAst;
|
||||||
|
import com.ibm.wala.cast.ir.translator.TranslatorToCAst.DoLoopTranslator;
|
||||||
import com.ibm.wala.cast.java.loader.JavaSourceLoaderImpl;
|
import com.ibm.wala.cast.java.loader.JavaSourceLoaderImpl;
|
||||||
import com.ibm.wala.cast.java.loader.Util;
|
import com.ibm.wala.cast.java.loader.Util;
|
||||||
import com.ibm.wala.cast.java.translator.JavaProcedureEntity;
|
import com.ibm.wala.cast.java.translator.JavaProcedureEntity;
|
||||||
import com.ibm.wala.cast.java.translator.TranslatorToCAst;
|
|
||||||
import com.ibm.wala.cast.tree.CAst;
|
import com.ibm.wala.cast.tree.CAst;
|
||||||
import com.ibm.wala.cast.tree.CAstControlFlowMap;
|
import com.ibm.wala.cast.tree.CAstControlFlowMap;
|
||||||
import com.ibm.wala.cast.tree.CAstEntity;
|
import com.ibm.wala.cast.tree.CAstEntity;
|
||||||
|
@ -175,7 +176,7 @@ import com.ibm.wala.util.debug.Assertions;
|
||||||
// * enums (probably in simplename or something. but using resolveConstantExpressionValue() possible)
|
// * enums (probably in simplename or something. but using resolveConstantExpressionValue() possible)
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class JDTJava2CAstTranslator implements TranslatorToCAst {
|
public class JDTJava2CAstTranslator {
|
||||||
protected final CAst fFactory = new CAstImpl();
|
protected final CAst fFactory = new CAstImpl();
|
||||||
|
|
||||||
// ///////////////////////////////////////////
|
// ///////////////////////////////////////////
|
||||||
|
@ -203,6 +204,8 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
|
||||||
|
|
||||||
protected ITypeBinding OutOfMemoryError;
|
protected ITypeBinding OutOfMemoryError;
|
||||||
|
|
||||||
|
protected DoLoopTranslator doLoopTranslator;
|
||||||
|
|
||||||
private String fullPath;
|
private String fullPath;
|
||||||
|
|
||||||
private CompilationUnit cu;
|
private CompilationUnit cu;
|
||||||
|
@ -211,20 +214,7 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
|
||||||
// COMPILATION UNITS & TYPES
|
// COMPILATION UNITS & TYPES
|
||||||
//
|
//
|
||||||
|
|
||||||
public JDTJava2CAstTranslator(JavaSourceLoaderImpl sourceLoader) {
|
public JDTJava2CAstTranslator(JavaSourceLoaderImpl sourceLoader, CompilationUnit astRoot, String fullPath, boolean replicateForDoLoops) {
|
||||||
this.fSourceLoader = sourceLoader;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CAstEntity translate(Object astRoot, String fullPath) {
|
|
||||||
this.cu = (CompilationUnit) astRoot;
|
|
||||||
|
|
||||||
this.fullPath = fullPath;
|
|
||||||
ast = cu.getAST();
|
|
||||||
|
|
||||||
// FIXME: we might need one AST (-> "Object" class) for all files.
|
|
||||||
fIdentityMapper = new JDTIdentityMapper(fSourceLoader.getReference(), ast);
|
|
||||||
fTypeDict = new JDTTypeDictionary(ast, fIdentityMapper);
|
|
||||||
|
|
||||||
fDivByZeroExcType = FakeExceptionTypeBinding.arithmetic;
|
fDivByZeroExcType = FakeExceptionTypeBinding.arithmetic;
|
||||||
fNullPointerExcType = FakeExceptionTypeBinding.nullPointer;
|
fNullPointerExcType = FakeExceptionTypeBinding.nullPointer;
|
||||||
fClassCastExcType = FakeExceptionTypeBinding.classCast;
|
fClassCastExcType = FakeExceptionTypeBinding.classCast;
|
||||||
|
@ -232,12 +222,27 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
|
||||||
ExceptionInInitializerError = FakeExceptionTypeBinding.initException;
|
ExceptionInInitializerError = FakeExceptionTypeBinding.initException;
|
||||||
OutOfMemoryError = FakeExceptionTypeBinding.outOfMemory;
|
OutOfMemoryError = FakeExceptionTypeBinding.outOfMemory;
|
||||||
|
|
||||||
|
this.fSourceLoader = sourceLoader;
|
||||||
|
this.cu = astRoot;
|
||||||
|
|
||||||
|
this.fullPath = fullPath;
|
||||||
|
ast = cu.getAST();
|
||||||
|
|
||||||
|
this.doLoopTranslator = new DoLoopTranslator(replicateForDoLoops, fFactory);
|
||||||
|
|
||||||
|
// FIXME: we might need one AST (-> "Object" class) for all files.
|
||||||
|
fIdentityMapper = new JDTIdentityMapper(fSourceLoader.getReference(), ast);
|
||||||
|
fTypeDict = new JDTTypeDictionary(ast, fIdentityMapper);
|
||||||
|
|
||||||
fRuntimeExcType = ast.resolveWellKnownType("java.lang.RuntimeException");
|
fRuntimeExcType = ast.resolveWellKnownType("java.lang.RuntimeException");
|
||||||
assert fRuntimeExcType != null;
|
assert fRuntimeExcType != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CAstEntity translateToCAst() {
|
||||||
|
|
||||||
List<CAstEntity> declEntities = new ArrayList<CAstEntity>();
|
List<CAstEntity> declEntities = new ArrayList<CAstEntity>();
|
||||||
|
|
||||||
for (Iterator iter = cu.types().iterator(); iter.hasNext();) {
|
for (Iterator<CAstEntity> iter = cu.types().iterator(); iter.hasNext();) {
|
||||||
AbstractTypeDeclaration decl = (AbstractTypeDeclaration) iter.next();
|
AbstractTypeDeclaration decl = (AbstractTypeDeclaration) iter.next();
|
||||||
// can be of type AnnotationTypeDeclaration, EnumDeclaration, TypeDeclaration
|
// can be of type AnnotationTypeDeclaration, EnumDeclaration, TypeDeclaration
|
||||||
declEntities.add(visit(decl, new RootContext()));
|
declEntities.add(visit(decl, new RootContext()));
|
||||||
|
@ -2095,7 +2100,6 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
|
||||||
// ////////////////
|
// ////////////////
|
||||||
|
|
||||||
private CAstNode visit(LabeledStatement n, WalkContext context) {
|
private CAstNode visit(LabeledStatement n, WalkContext context) {
|
||||||
ASTNode breakTarget = makeBreakOrContinueTarget(n, n.getLabel().getIdentifier());
|
|
||||||
|
|
||||||
// find the first non-block statement ant set-up the label map (useful for breaking many fors)
|
// find the first non-block statement ant set-up the label map (useful for breaking many fors)
|
||||||
ASTNode stmt = n.getBody();
|
ASTNode stmt = n.getBody();
|
||||||
|
@ -2108,10 +2112,12 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
|
||||||
|
|
||||||
CAstNode result;
|
CAstNode result;
|
||||||
if (!(n.getBody() instanceof EmptyStatement)) {
|
if (!(n.getBody() instanceof EmptyStatement)) {
|
||||||
|
ASTNode breakTarget = makeBreakOrContinueTarget(n, n.getLabel().getIdentifier());
|
||||||
|
CAstNode breakNode = visitNode(breakTarget, context);
|
||||||
WalkContext child = new BreakContext(context, n.getLabel().getIdentifier(), breakTarget);
|
WalkContext child = new BreakContext(context, n.getLabel().getIdentifier(), breakTarget);
|
||||||
|
|
||||||
result = makeNode(context, fFactory, n, CAstNode.BLOCK_STMT, makeNode(context, fFactory, n, CAstNode.LABEL_STMT, fFactory
|
result = makeNode(context, fFactory, n, CAstNode.BLOCK_STMT, makeNode(context, fFactory, n, CAstNode.LABEL_STMT, fFactory
|
||||||
.makeConstant(n.getLabel().getIdentifier()), visitNode(n.getBody(), child)), visitNode(breakTarget, context));
|
.makeConstant(n.getLabel().getIdentifier()), visitNode(n.getBody(), child)), breakNode);
|
||||||
} else {
|
} else {
|
||||||
result = makeNode(context, fFactory, n, CAstNode.LABEL_STMT, fFactory.makeConstant(n.getLabel().getIdentifier()), visitNode(n
|
result = makeNode(context, fFactory, n, CAstNode.LABEL_STMT, fFactory.makeConstant(n.getLabel().getIdentifier()), visitNode(n
|
||||||
.getBody(), context));
|
.getBody(), context));
|
||||||
|
@ -2163,7 +2169,10 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
|
||||||
Statement body = n.getBody();
|
Statement body = n.getBody();
|
||||||
|
|
||||||
ASTNode breakTarget = makeBreakOrContinueTarget(n, "breakLabel" + n.getStartPosition());
|
ASTNode breakTarget = makeBreakOrContinueTarget(n, "breakLabel" + n.getStartPosition());
|
||||||
|
CAstNode breakNode = visitNode(breakTarget, context);
|
||||||
|
|
||||||
ASTNode continueTarget = makeBreakOrContinueTarget(n, "continueLabel" + n.getStartPosition());
|
ASTNode continueTarget = makeBreakOrContinueTarget(n, "continueLabel" + n.getStartPosition());
|
||||||
|
CAstNode continueNode = visitNode(continueTarget, context);
|
||||||
|
|
||||||
String loopLabel = (String) context.getLabelMap().get(n);
|
String loopLabel = (String) context.getLabelMap().get(n);
|
||||||
LoopContext lc = new LoopContext(context, loopLabel, breakTarget, continueTarget);
|
LoopContext lc = new LoopContext(context, loopLabel, breakTarget, continueTarget);
|
||||||
|
@ -2172,8 +2181,8 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
|
||||||
* The following loop is created sligtly differently than in jscore. It doesn't have a specific target for continue.
|
* The following loop is created sligtly differently than in jscore. It doesn't have a specific target for continue.
|
||||||
*/
|
*/
|
||||||
return makeNode(context, fFactory, n, CAstNode.BLOCK_STMT, makeNode(context, fFactory, n, CAstNode.LOOP, visitNode(cond,
|
return makeNode(context, fFactory, n, CAstNode.BLOCK_STMT, makeNode(context, fFactory, n, CAstNode.LOOP, visitNode(cond,
|
||||||
context), makeNode(context, fFactory, n, CAstNode.BLOCK_STMT, visitNode(body, lc), visitNode(continueTarget, context))),
|
context), makeNode(context, fFactory, n, CAstNode.BLOCK_STMT, visitNode(body, lc), continueNode)),
|
||||||
visitNode(breakTarget, context));
|
breakNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CAstNode getSwitchCaseConstant(SwitchCase n, WalkContext context) {
|
private CAstNode getSwitchCaseConstant(SwitchCase n, WalkContext context) {
|
||||||
|
@ -2282,22 +2291,21 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
|
||||||
}
|
}
|
||||||
|
|
||||||
private CAstNode visit(DoStatement n, WalkContext context) {
|
private CAstNode visit(DoStatement n, WalkContext context) {
|
||||||
ASTNode header = ast.newEmptyStatement();
|
|
||||||
ASTNode breakTarget = makeBreakOrContinueTarget(n, "breakLabel" + n.getStartPosition());
|
|
||||||
ASTNode continueTarget = makeBreakOrContinueTarget(n, "continue" + "Label" + n.getStartPosition());
|
|
||||||
|
|
||||||
CAstNode loopGoto = makeNode(context, fFactory, n, CAstNode.IFGOTO, visitNode(n.getExpression(), context));
|
|
||||||
|
|
||||||
context.cfg().map(loopGoto, loopGoto);
|
|
||||||
context.cfg().add(loopGoto, header, Boolean.TRUE);
|
|
||||||
|
|
||||||
String loopLabel = (String) context.getLabelMap().get(n); // set by visit(LabeledStatement)
|
String loopLabel = (String) context.getLabelMap().get(n); // set by visit(LabeledStatement)
|
||||||
WalkContext loopContext = new LoopContext(context, loopLabel, breakTarget, continueTarget);
|
String token = loopLabel==null? "at_" + n.getStartPosition(): loopLabel;
|
||||||
|
|
||||||
|
ASTNode breakTarget = makeBreakOrContinueTarget(n, "breakLabel_" + token);
|
||||||
|
CAstNode breakNode = visitNode(breakTarget, context);
|
||||||
|
|
||||||
|
ASTNode continueTarget = makeBreakOrContinueTarget(n, "continueLabel_" + token);
|
||||||
CAstNode continueNode = visitNode(continueTarget, context);
|
CAstNode continueNode = visitNode(continueTarget, context);
|
||||||
|
|
||||||
return makeNode(context, fFactory, n, CAstNode.BLOCK_STMT, visitNode(header, context), makeNode(context, fFactory, n,
|
CAstNode loopTest = visitNode(n.getExpression(), context);
|
||||||
CAstNode.BLOCK_STMT, visitNode(n.getBody(), loopContext), continueNode), loopGoto, visitNode(breakTarget, context));
|
|
||||||
|
WalkContext loopContext = new LoopContext(context, loopLabel, breakTarget, continueTarget);
|
||||||
|
CAstNode loopBody = visitNode(n.getBody(), loopContext);
|
||||||
|
|
||||||
|
return doLoopTranslator.translateDoLoop(loopTest, loopBody, continueNode, breakNode, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2861,7 +2869,6 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CAstSourcePositionMap.Position getPosition() {
|
public CAstSourcePositionMap.Position getPosition() {
|
||||||
Assertions.UNREACHABLE("CompilationUnitEntity.getPosition()");
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2889,24 +2896,12 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
|
||||||
* Contains things needed by in the visit() of some nodes to process the nodes. For example, pos() contains the source position
|
* Contains things needed by in the visit() of some nodes to process the nodes. For example, pos() contains the source position
|
||||||
* mapping which each node registers
|
* mapping which each node registers
|
||||||
*/
|
*/
|
||||||
public static interface WalkContext {
|
public static interface WalkContext extends TranslatorToCAst.WalkContext<WalkContext, ASTNode> {
|
||||||
// LEFTOUT: plenty of stuff
|
|
||||||
public CAstControlFlowRecorder cfg();
|
|
||||||
|
|
||||||
public void addScopedEntity(CAstNode newNode, CAstEntity visit);
|
|
||||||
|
|
||||||
public Collection<Pair<ITypeBinding, Object>> getCatchTargets(ITypeBinding type);
|
public Collection<Pair<ITypeBinding, Object>> getCatchTargets(ITypeBinding type);
|
||||||
|
|
||||||
public CAstSourcePositionRecorder pos();
|
|
||||||
|
|
||||||
public CAstNodeTypeMapRecorder getNodeTypeMap();
|
|
||||||
|
|
||||||
public Map<ASTNode, String> getLabelMap();
|
public Map<ASTNode, String> getLabelMap();
|
||||||
|
|
||||||
public ASTNode getContinueFor(String label);
|
|
||||||
|
|
||||||
public ASTNode getBreakFor(String label);
|
|
||||||
|
|
||||||
public boolean needLValue();
|
public boolean needLValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2914,45 +2909,20 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
|
||||||
* Default context functions. When one context doesn't handle something, it the next one up does. For example, there is only one
|
* Default context functions. When one context doesn't handle something, it the next one up does. For example, there is only one
|
||||||
* source pos. mapping per MethodContext, so loop contexts delegate it up.
|
* source pos. mapping per MethodContext, so loop contexts delegate it up.
|
||||||
*/
|
*/
|
||||||
public static class DelegatingContext implements WalkContext {
|
public static class DelegatingContext extends TranslatorToCAst.DelegatingContext<WalkContext, ASTNode> implements WalkContext {
|
||||||
protected WalkContext parent;
|
|
||||||
|
|
||||||
public DelegatingContext(WalkContext parent) {
|
public DelegatingContext(WalkContext parent) {
|
||||||
this.parent = parent;
|
super(parent);
|
||||||
}
|
|
||||||
|
|
||||||
public CAstControlFlowRecorder cfg() {
|
|
||||||
return parent.cfg();
|
|
||||||
}
|
|
||||||
|
|
||||||
public CAstSourcePositionRecorder pos() {
|
|
||||||
return parent.pos();
|
|
||||||
}
|
|
||||||
|
|
||||||
public CAstNodeTypeMapRecorder getNodeTypeMap() {
|
|
||||||
return parent.getNodeTypeMap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<Pair<ITypeBinding, Object>> getCatchTargets(ITypeBinding type) {
|
public Collection<Pair<ITypeBinding, Object>> getCatchTargets(ITypeBinding type) {
|
||||||
return parent.getCatchTargets(type);
|
return parent.getCatchTargets(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addScopedEntity(CAstNode newNode, CAstEntity visit) {
|
|
||||||
parent.addScopedEntity(newNode, visit);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<ASTNode, String> getLabelMap() {
|
public Map<ASTNode, String> getLabelMap() {
|
||||||
return parent.getLabelMap();
|
return parent.getLabelMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ASTNode getContinueFor(String label) {
|
|
||||||
return parent.getContinueFor(label);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ASTNode getBreakFor(String label) {
|
|
||||||
return parent.getBreakFor(label);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean needLValue() {
|
public boolean needLValue() {
|
||||||
return parent.needLValue();
|
return parent.needLValue();
|
||||||
}
|
}
|
||||||
|
@ -2961,26 +2931,7 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
|
||||||
/*
|
/*
|
||||||
* Root context. Doesn't do anything.
|
* Root context. Doesn't do anything.
|
||||||
*/
|
*/
|
||||||
public static class RootContext implements WalkContext {
|
public static class RootContext extends TranslatorToCAst.RootContext<WalkContext, ASTNode> implements WalkContext {
|
||||||
public void addScopedEntity(CAstNode newNode, CAstEntity visit) {
|
|
||||||
Assertions.UNREACHABLE("Rootcontext.addScopedEntity()");
|
|
||||||
}
|
|
||||||
|
|
||||||
public CAstControlFlowRecorder cfg() {
|
|
||||||
Assertions.UNREACHABLE("RootContext.cfg()");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CAstSourcePositionRecorder pos() {
|
|
||||||
Assertions.UNREACHABLE("RootContext.pos()");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CAstNodeTypeMapRecorder getNodeTypeMap() {
|
|
||||||
Assertions.UNREACHABLE("RootContext.getNodeTypeMap()");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<Pair<ITypeBinding, Object>> getCatchTargets(ITypeBinding type) {
|
public Collection<Pair<ITypeBinding, Object>> getCatchTargets(ITypeBinding type) {
|
||||||
Assertions.UNREACHABLE("RootContext.getCatchTargets()");
|
Assertions.UNREACHABLE("RootContext.getCatchTargets()");
|
||||||
return null;
|
return null;
|
||||||
|
@ -2991,16 +2942,6 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ASTNode getBreakFor(String label) {
|
|
||||||
Assertions.UNREACHABLE("RootContext.getBreakFor()");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ASTNode getContinueFor(String label) {
|
|
||||||
Assertions.UNREACHABLE("RootContext.getContinueFor()");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean needLValue() {
|
public boolean needLValue() {
|
||||||
Assertions.UNREACHABLE("Rootcontext.needLValue()");
|
Assertions.UNREACHABLE("Rootcontext.needLValue()");
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -115,8 +115,6 @@ public class JDTSourceModuleTranslator implements SourceModuleTranslator {
|
||||||
public void loadAllSources(Set<ModuleEntry> modules) {
|
public void loadAllSources(Set<ModuleEntry> modules) {
|
||||||
// TODO: we might need one AST (-> "Object" class) for all files.
|
// TODO: we might need one AST (-> "Object" class) for all files.
|
||||||
// TODO: group by project and send 'em in
|
// TODO: group by project and send 'em in
|
||||||
JDTJava2CAstTranslator jdt2cast = makeCAstTranslator();
|
|
||||||
final Java2IRTranslator java2ir = makeIRTranslator(jdt2cast);
|
|
||||||
|
|
||||||
System.out.println(modules);
|
System.out.println(modules);
|
||||||
|
|
||||||
|
@ -143,7 +141,9 @@ public class JDTSourceModuleTranslator implements SourceModuleTranslator {
|
||||||
public void acceptAST(ICompilationUnit source, CompilationUnit ast) {
|
public void acceptAST(ICompilationUnit source, CompilationUnit ast) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
java2ir.translate(proj.getValue().get(source), ast, source.getUnderlyingResource().getLocation().toOSString());
|
JDTJava2CAstTranslator jdt2cast = makeCAstTranslator(ast, source.getUnderlyingResource().getLocation().toOSString());
|
||||||
|
final Java2IRTranslator java2ir = makeIRTranslator();
|
||||||
|
java2ir.translate(proj.getValue().get(source), jdt2cast.translateToCAst());
|
||||||
} catch (JavaModelException e) {
|
} catch (JavaModelException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -165,12 +165,12 @@ public class JDTSourceModuleTranslator implements SourceModuleTranslator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Java2IRTranslator makeIRTranslator(JDTJava2CAstTranslator jdt2cast) {
|
protected Java2IRTranslator makeIRTranslator() {
|
||||||
return new Java2IRTranslator(jdt2cast, sourceLoader);
|
return new Java2IRTranslator(sourceLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected JDTJava2CAstTranslator makeCAstTranslator() {
|
protected JDTJava2CAstTranslator makeCAstTranslator(CompilationUnit cu, String fullPath) {
|
||||||
return new JDTJava2CAstTranslator(sourceLoader);
|
return new JDTJava2CAstTranslator(sourceLoader, cu, fullPath, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<classpath>
|
<classpath>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
|
|
||||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||||
<classpathentry kind="src" path="source"/>
|
<classpathentry kind="src" path="source"/>
|
||||||
<classpathentry kind="lib" path="/com.ibm.wala.cast.java.polyglot/lib/polyglot.jar"/>
|
<classpathentry kind="lib" path="/com.ibm.wala.cast.java.polyglot/lib/polyglot.jar"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
#Thu Feb 03 10:12:26 EST 2011
|
#Mon Jul 02 13:01:58 EDT 2012
|
||||||
eclipse.preferences.version=1
|
eclipse.preferences.version=1
|
||||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
|
|
||||||
org.eclipse.jdt.core.compiler.compliance=1.5
|
|
||||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
|
||||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
|
||||||
org.eclipse.jdt.core.compiler.source=1.5
|
|
||||||
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
|
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
|
||||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
|
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<launchConfiguration type="org.eclipse.jdt.junit.launchconfig">
|
<launchConfiguration type="org.eclipse.jdt.junit.launchconfig">
|
||||||
<stringAttribute key="bad_container_name" value="/com.ibm.wala.cast.java.polyglottest/launchers"/>
|
<stringAttribute key="bad_container_name" value="/com.ibm.wala.cast.java.polyglottest/launchers"/>
|
||||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||||
|
@ -13,5 +13,6 @@
|
||||||
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
|
<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.cast.java.test.PolyglotJavaIRTests"/>
|
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.ibm.wala.cast.java.test.PolyglotJavaIRTests"/>
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.ibm.wala.cast.java.polyglot.test"/>
|
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.ibm.wala.cast.java.polyglot.test"/>
|
||||||
|
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea -Xmx512M"/>
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:com.ibm.wala.cast.java.test.data}"/>
|
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:com.ibm.wala.cast.java.test.data}"/>
|
||||||
</launchConfiguration>
|
</launchConfiguration>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<classpath>
|
<classpath>
|
||||||
<classpathentry kind="src" path="source"/>
|
<classpathentry kind="src" path="source"/>
|
||||||
<classpathentry exported="true" kind="lib" path="lib/polyglot.jar"/>
|
<classpathentry kind="lib" path="lib/polyglot.jar"/>
|
||||||
<classpathentry exported="true" kind="lib" path="lib/java_cup.jar"/>
|
<classpathentry kind="lib" path="lib/java_cup.jar"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
#Mon Apr 13 15:38:50 EDT 2009
|
#Mon Apr 16 10:59:09 EDT 2012
|
||||||
eclipse.preferences.version=1
|
eclipse.preferences.version=1
|
||||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
|
|
||||||
org.eclipse.jdt.core.compiler.compliance=1.5
|
|
||||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
|
||||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
|
||||||
org.eclipse.jdt.core.compiler.source=1.5
|
|
||||||
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
|
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
|
||||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
|
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
|
||||||
|
|
|
@ -25,7 +25,8 @@ import com.ibm.wala.classLoader.BinaryDirectoryTreeModule;
|
||||||
import com.ibm.wala.classLoader.ClassLoaderFactory;
|
import com.ibm.wala.classLoader.ClassLoaderFactory;
|
||||||
import com.ibm.wala.classLoader.Module;
|
import com.ibm.wala.classLoader.Module;
|
||||||
import com.ibm.wala.classLoader.SourceDirectoryTreeModule;
|
import com.ibm.wala.classLoader.SourceDirectoryTreeModule;
|
||||||
import com.ibm.wala.core.plugin.CorePlugin;
|
import com.ibm.wala.ide.plugin.CorePlugin;
|
||||||
|
import com.ibm.wala.ide.util.EclipseFileProvider;
|
||||||
import com.ibm.wala.ide.util.EclipseProjectPath;
|
import com.ibm.wala.ide.util.EclipseProjectPath;
|
||||||
import com.ibm.wala.ide.util.EclipseProjectPath.Loader;
|
import com.ibm.wala.ide.util.EclipseProjectPath.Loader;
|
||||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||||
|
@ -64,7 +65,7 @@ public class EclipseProjectSourceAnalysisEngine extends EclipseProjectAnalysisEn
|
||||||
super(project);
|
super(project);
|
||||||
this.fileExt = fileExt;
|
this.fileExt = fileExt;
|
||||||
try {
|
try {
|
||||||
setExclusionsFile(FileProvider.getFileFromPlugin(CorePlugin.getDefault(), "J2SEClassHierarchyExclusions.txt")
|
setExclusionsFile((new EclipseFileProvider()).getFileFromPlugin(CorePlugin.getDefault(), "J2SEClassHierarchyExclusions.txt")
|
||||||
.getAbsolutePath());
|
.getAbsolutePath());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Assertions.UNREACHABLE("Cannot find exclusions file");
|
Assertions.UNREACHABLE("Cannot find exclusions file");
|
||||||
|
|
|
@ -51,16 +51,18 @@ public class IRGoal extends SourceGoal_c /* PORT1.7 removed 'implements EndGoal'
|
||||||
ExtensionInfo extInfo= job.extensionInfo();
|
ExtensionInfo extInfo= job.extensionInfo();
|
||||||
|
|
||||||
fTranslator= new Java2IRTranslator(
|
fTranslator= new Java2IRTranslator(
|
||||||
|
fSourceLoader,
|
||||||
|
((IRTranslatorExtension)extInfo).getCAstRewriterFactory());
|
||||||
|
ModuleSource src = (ModuleSource) job.source();
|
||||||
|
fTranslator.translate(
|
||||||
|
src.getModule(),
|
||||||
new PolyglotJava2CAstTranslator(
|
new PolyglotJava2CAstTranslator(
|
||||||
|
job.ast(),
|
||||||
fSourceLoader.getReference(),
|
fSourceLoader.getReference(),
|
||||||
extInfo.nodeFactory(),
|
extInfo.nodeFactory(),
|
||||||
extInfo.typeSystem(),
|
extInfo.typeSystem(),
|
||||||
new PolyglotIdentityMapper(fSourceLoader.getReference()),
|
new PolyglotIdentityMapper(fSourceLoader.getReference()),
|
||||||
((IRTranslatorExtension)extInfo).getReplicateForDoLoops()),
|
((IRTranslatorExtension)extInfo).getReplicateForDoLoops()).translateToCAst());
|
||||||
fSourceLoader,
|
|
||||||
((IRTranslatorExtension)extInfo).getCAstRewriterFactory());
|
|
||||||
ModuleSource src = (ModuleSource) job.source();
|
|
||||||
fTranslator.translate(src.getModule(),job.ast(), src.name());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
|
@ -34,6 +35,7 @@ import polyglot.ast.ArrayTypeNode;
|
||||||
import polyglot.ast.Assert;
|
import polyglot.ast.Assert;
|
||||||
import polyglot.ast.Assign;
|
import polyglot.ast.Assign;
|
||||||
import polyglot.ast.Binary;
|
import polyglot.ast.Binary;
|
||||||
|
import polyglot.ast.Binary.Operator;
|
||||||
import polyglot.ast.Block;
|
import polyglot.ast.Block;
|
||||||
import polyglot.ast.BooleanLit;
|
import polyglot.ast.BooleanLit;
|
||||||
import polyglot.ast.Branch;
|
import polyglot.ast.Branch;
|
||||||
|
@ -49,6 +51,7 @@ import polyglot.ast.ClassLit;
|
||||||
import polyglot.ast.ClassMember;
|
import polyglot.ast.ClassMember;
|
||||||
import polyglot.ast.Conditional;
|
import polyglot.ast.Conditional;
|
||||||
import polyglot.ast.ConstructorCall;
|
import polyglot.ast.ConstructorCall;
|
||||||
|
import polyglot.ast.ConstructorCall.Kind;
|
||||||
import polyglot.ast.ConstructorDecl;
|
import polyglot.ast.ConstructorDecl;
|
||||||
import polyglot.ast.Do;
|
import polyglot.ast.Do;
|
||||||
import polyglot.ast.Empty;
|
import polyglot.ast.Empty;
|
||||||
|
@ -94,8 +97,6 @@ import polyglot.ast.TopLevelDecl;
|
||||||
import polyglot.ast.Try;
|
import polyglot.ast.Try;
|
||||||
import polyglot.ast.Unary;
|
import polyglot.ast.Unary;
|
||||||
import polyglot.ast.While;
|
import polyglot.ast.While;
|
||||||
import polyglot.ast.Binary.Operator;
|
|
||||||
import polyglot.ast.ConstructorCall.Kind;
|
|
||||||
import polyglot.types.ArrayType;
|
import polyglot.types.ArrayType;
|
||||||
import polyglot.types.ClassType;
|
import polyglot.types.ClassType;
|
||||||
import polyglot.types.CodeInstance;
|
import polyglot.types.CodeInstance;
|
||||||
|
@ -117,9 +118,11 @@ import polyglot.types.Types;
|
||||||
import polyglot.util.Position;
|
import polyglot.util.Position;
|
||||||
|
|
||||||
import com.ibm.wala.cast.ir.translator.AstTranslator.InternalCAstSymbol;
|
import com.ibm.wala.cast.ir.translator.AstTranslator.InternalCAstSymbol;
|
||||||
|
import com.ibm.wala.cast.ir.translator.TranslatorToCAst;
|
||||||
|
import com.ibm.wala.cast.ir.translator.TranslatorToCAst.DoLoopTranslator;
|
||||||
|
import com.ibm.wala.cast.ir.translator.TranslatorToCAst.WalkContext;
|
||||||
import com.ibm.wala.cast.java.loader.Util;
|
import com.ibm.wala.cast.java.loader.Util;
|
||||||
import com.ibm.wala.cast.java.translator.JavaProcedureEntity;
|
import com.ibm.wala.cast.java.translator.JavaProcedureEntity;
|
||||||
import com.ibm.wala.cast.java.translator.TranslatorToCAst;
|
|
||||||
import com.ibm.wala.cast.java.types.JavaType;
|
import com.ibm.wala.cast.java.types.JavaType;
|
||||||
import com.ibm.wala.cast.tree.CAst;
|
import com.ibm.wala.cast.tree.CAst;
|
||||||
import com.ibm.wala.cast.tree.CAstControlFlowMap;
|
import com.ibm.wala.cast.tree.CAstControlFlowMap;
|
||||||
|
@ -132,12 +135,10 @@ import com.ibm.wala.cast.tree.CAstSymbol;
|
||||||
import com.ibm.wala.cast.tree.CAstType;
|
import com.ibm.wala.cast.tree.CAstType;
|
||||||
import com.ibm.wala.cast.tree.CAstTypeDictionary;
|
import com.ibm.wala.cast.tree.CAstTypeDictionary;
|
||||||
import com.ibm.wala.cast.tree.impl.AbstractSourcePosition;
|
import com.ibm.wala.cast.tree.impl.AbstractSourcePosition;
|
||||||
import com.ibm.wala.cast.tree.impl.CAstCloner;
|
|
||||||
import com.ibm.wala.cast.tree.impl.CAstControlFlowRecorder;
|
import com.ibm.wala.cast.tree.impl.CAstControlFlowRecorder;
|
||||||
import com.ibm.wala.cast.tree.impl.CAstImpl;
|
import com.ibm.wala.cast.tree.impl.CAstImpl;
|
||||||
import com.ibm.wala.cast.tree.impl.CAstNodeTypeMapRecorder;
|
import com.ibm.wala.cast.tree.impl.CAstNodeTypeMapRecorder;
|
||||||
import com.ibm.wala.cast.tree.impl.CAstOperator;
|
import com.ibm.wala.cast.tree.impl.CAstOperator;
|
||||||
import com.ibm.wala.cast.tree.impl.CAstRewriter;
|
|
||||||
import com.ibm.wala.cast.tree.impl.CAstSourcePositionRecorder;
|
import com.ibm.wala.cast.tree.impl.CAstSourcePositionRecorder;
|
||||||
import com.ibm.wala.cast.tree.impl.CAstSymbolImpl;
|
import com.ibm.wala.cast.tree.impl.CAstSymbolImpl;
|
||||||
import com.ibm.wala.classLoader.CallSiteReference;
|
import com.ibm.wala.classLoader.CallSiteReference;
|
||||||
|
@ -155,8 +156,7 @@ import com.ibm.wala.util.collections.IteratorPlusOne;
|
||||||
import com.ibm.wala.util.collections.Pair;
|
import com.ibm.wala.util.collections.Pair;
|
||||||
import com.ibm.wala.util.debug.Assertions;
|
import com.ibm.wala.util.debug.Assertions;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
public class PolyglotJava2CAstTranslator {
|
||||||
public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
|
|
||||||
protected final CAst fFactory = new CAstImpl();
|
protected final CAst fFactory = new CAstImpl();
|
||||||
|
|
||||||
protected final NodeFactory fNodeFactory;
|
protected final NodeFactory fNodeFactory;
|
||||||
|
@ -179,10 +179,12 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
|
||||||
|
|
||||||
protected PolyglotIdentityMapper fIdentityMapper;
|
protected PolyglotIdentityMapper fIdentityMapper;
|
||||||
|
|
||||||
protected boolean replicateForDoLoops = false;
|
protected final DoLoopTranslator doLoopTranslator;
|
||||||
|
|
||||||
protected final boolean DEBUG = true;
|
protected final boolean DEBUG = true;
|
||||||
|
|
||||||
|
private final Node ast;
|
||||||
|
|
||||||
final protected TranslatingVisitor getTranslator() {
|
final protected TranslatingVisitor getTranslator() {
|
||||||
if (fTranslator == null)
|
if (fTranslator == null)
|
||||||
fTranslator = createTranslator();
|
fTranslator = createTranslator();
|
||||||
|
@ -1133,42 +1135,17 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
|
||||||
String loopLabel = (String) wc.getLabelMap().get(d);
|
String loopLabel = (String) wc.getLabelMap().get(d);
|
||||||
|
|
||||||
CAstNode continueNode = walkNodes(continueTarget, wc);
|
CAstNode continueNode = walkNodes(continueTarget, wc);
|
||||||
CAstNode breakBody = walkNodes(breakTarget, wc);
|
CAstNode breakNode = walkNodes(breakTarget, wc);
|
||||||
|
|
||||||
|
|
||||||
WalkContext lc = new LoopContext(wc, loopLabel, breakTarget, continueTarget);
|
WalkContext lc = new LoopContext(wc, loopLabel, breakTarget, continueTarget);
|
||||||
|
CAstNode loopExpr = walkNodes(d.cond(), wc);
|
||||||
CAstNode loopBody = walkNodes(d.body(), lc);
|
CAstNode loopBody = walkNodes(d.body(), lc);
|
||||||
|
|
||||||
if (replicateForDoLoops) {
|
return doLoopTranslator.translateDoLoop(loopExpr, loopBody, continueNode, breakNode, wc);
|
||||||
CAstRewriter.Rewrite x = (new CAstCloner(fFactory, false)).copy(loopBody, wc.cfg(), wc.pos(), wc.getNodeTypeMap(), null);
|
|
||||||
CAstNode otherBody = x.newRoot();
|
|
||||||
|
|
||||||
wc.cfg().addAll(x.newCfg());
|
|
||||||
wc.pos().addAll(x.newPos());
|
|
||||||
wc.getNodeTypeMap().addAll(x.newTypes());
|
|
||||||
|
|
||||||
return makeNode(wc, fFactory, d, CAstNode.BLOCK_STMT,
|
|
||||||
loopBody,
|
|
||||||
makeNode(wc, fFactory, d, CAstNode.LOOP,
|
|
||||||
walkNodes(d.cond(), wc),
|
|
||||||
makeNode(wc, fFactory, d, CAstNode.BLOCK_STMT, otherBody, continueNode)),
|
|
||||||
breakBody);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Node header = fNodeFactory.Empty(Position.COMPILER_GENERATED);
|
|
||||||
|
|
||||||
CAstNode loopGoto = makeNode(wc, fFactory, d, CAstNode.IFGOTO, walkNodes(d.cond(), wc));
|
|
||||||
|
|
||||||
wc.cfg().map(loopGoto, loopGoto);
|
|
||||||
wc.cfg().add(loopGoto, header, Boolean.TRUE);
|
|
||||||
|
|
||||||
return makeNode(wc, fFactory, d, CAstNode.BLOCK_STMT,
|
|
||||||
walkNodes(header, wc),
|
|
||||||
makeNode(wc, fFactory, d, CAstNode.BLOCK_STMT, loopBody, continueNode),
|
|
||||||
loopGoto,
|
|
||||||
breakBody);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public CAstNode visit(For f, WalkContext wc) {
|
public CAstNode visit(For f, WalkContext wc) {
|
||||||
Node breakTarget = makeBreakTarget(f);
|
Node breakTarget = makeBreakTarget(f);
|
||||||
Node continueTarget = makeContinueTarget(f);
|
Node continueTarget = makeContinueTarget(f);
|
||||||
|
@ -1434,7 +1411,6 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CAstSourcePositionMap.Position getPosition() {
|
public CAstSourcePositionMap.Position getPosition() {
|
||||||
Assertions.UNREACHABLE("CompilationUnitEntity.getPosition()");
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1529,12 +1505,8 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
|
||||||
protected abstract static class CodeBodyEntity implements CAstEntity {
|
protected abstract static class CodeBodyEntity implements CAstEntity {
|
||||||
private final Map<CAstNode, Collection<CAstEntity>> fEntities;
|
private final Map<CAstNode, Collection<CAstEntity>> fEntities;
|
||||||
|
|
||||||
public CodeBodyEntity(Map<CAstNode, CAstEntity> entities) {
|
public CodeBodyEntity(Map<CAstNode, Collection<CAstEntity>> entities) {
|
||||||
fEntities = new LinkedHashMap<CAstNode, Collection<CAstEntity>>();
|
fEntities = new LinkedHashMap<CAstNode, Collection<CAstEntity>>(entities);
|
||||||
for (Iterator<CAstNode> keys = entities.keySet().iterator(); keys.hasNext();) {
|
|
||||||
CAstNode key = keys.next();
|
|
||||||
fEntities.put(key, Collections.singleton(entities.get(key)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<CAstNode, Collection<CAstEntity>> getAllScopedEntities() {
|
public Map<CAstNode, Collection<CAstEntity>> getAllScopedEntities() {
|
||||||
|
@ -1674,7 +1646,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
|
||||||
private final String[] argumentNames;
|
private final String[] argumentNames;
|
||||||
|
|
||||||
public ProcedureEntity(CAstNode pdast, TypeSystem system, CodeInstance pd, Type declaringType, String[] argumentNames,
|
public ProcedureEntity(CAstNode pdast, TypeSystem system, CodeInstance pd, Type declaringType, String[] argumentNames,
|
||||||
Map<CAstNode, CAstEntity> entities, MethodContext mc) {
|
Map<CAstNode, Collection<CAstEntity>> entities, MethodContext mc) {
|
||||||
super(entities);
|
super(entities);
|
||||||
fPdast = pdast;
|
fPdast = pdast;
|
||||||
fSystem = system;
|
fSystem = system;
|
||||||
|
@ -1685,7 +1657,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProcedureEntity(CAstNode pdast, TypeSystem system, CodeInstance pd, String[] argumentNames,
|
public ProcedureEntity(CAstNode pdast, TypeSystem system, CodeInstance pd, String[] argumentNames,
|
||||||
Map<CAstNode, CAstEntity> entities, MethodContext mc) {
|
Map<CAstNode, Collection<CAstEntity>> entities, MethodContext mc) {
|
||||||
//PORT1.7 used to be this(pdast, system, pd, ((MemberInstance) pd).container(), argumentNames, entities, mc);
|
//PORT1.7 used to be this(pdast, system, pd, ((MemberInstance) pd).container(), argumentNames, entities, mc);
|
||||||
this(pdast, system, pd, ((MemberDef) pd.def()).container().get(), argumentNames, entities, mc);
|
this(pdast, system, pd, ((MemberDef) pd.def()).container().get(), argumentNames, entities, mc);
|
||||||
}
|
}
|
||||||
|
@ -1916,21 +1888,9 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface WalkContext {
|
public interface WalkContext extends TranslatorToCAst.WalkContext<WalkContext, Node> {
|
||||||
void addScopedEntity(CAstNode node, CAstEntity e);
|
|
||||||
|
|
||||||
CAstControlFlowRecorder cfg();
|
|
||||||
|
|
||||||
CAstSourcePositionRecorder pos();
|
|
||||||
|
|
||||||
CAstNodeTypeMapRecorder getNodeTypeMap();
|
|
||||||
|
|
||||||
Collection<Pair<Type, Object>> getCatchTargets(Type label);
|
Collection<Pair<Type, Object>> getCatchTargets(Type label);
|
||||||
|
|
||||||
Node getContinueFor(String label);
|
|
||||||
|
|
||||||
Node getBreakFor(String label);
|
|
||||||
|
|
||||||
Node getFinally();
|
Node getFinally();
|
||||||
|
|
||||||
CodeInstance getEnclosingMethod();
|
CodeInstance getEnclosingMethod();
|
||||||
|
@ -1948,49 +1908,15 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
|
||||||
boolean needLVal();
|
boolean needLVal();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static class DelegatingContext implements WalkContext {
|
protected static class DelegatingContext extends TranslatorToCAst.DelegatingContext<WalkContext, Node> implements WalkContext {
|
||||||
private final WalkContext parent;
|
|
||||||
|
|
||||||
public WalkContext getParent() {
|
|
||||||
return parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected DelegatingContext(WalkContext parent) {
|
protected DelegatingContext(WalkContext parent) {
|
||||||
this.parent = parent;
|
super(parent);
|
||||||
}
|
|
||||||
|
|
||||||
public void addScopedEntity(CAstNode node, CAstEntity e) {
|
|
||||||
parent.addScopedEntity(node, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// public Map/*<CAstNode,CAstEntity>*/ getScopedEntities() {
|
|
||||||
// return parent.getScopedEntities();
|
|
||||||
// }
|
|
||||||
|
|
||||||
public CAstControlFlowRecorder cfg() {
|
|
||||||
return parent.cfg();
|
|
||||||
}
|
|
||||||
|
|
||||||
public CAstSourcePositionRecorder pos() {
|
|
||||||
return parent.pos();
|
|
||||||
}
|
|
||||||
|
|
||||||
public CAstNodeTypeMapRecorder getNodeTypeMap() {
|
|
||||||
return parent.getNodeTypeMap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<Pair<Type, Object>> getCatchTargets(Type label) {
|
public Collection<Pair<Type, Object>> getCatchTargets(Type label) {
|
||||||
return parent.getCatchTargets(label);
|
return parent.getCatchTargets(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Node getContinueFor(String label) {
|
|
||||||
return parent.getContinueFor(label);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Node getBreakFor(String label) {
|
|
||||||
return parent.getBreakFor(label);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Node getFinally() {
|
public Node getFinally() {
|
||||||
return parent.getFinally();
|
return parent.getFinally();
|
||||||
}
|
}
|
||||||
|
@ -2121,9 +2047,9 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
|
||||||
|
|
||||||
private final Map<Node, String> labelMap = HashMapFactory.make(2);
|
private final Map<Node, String> labelMap = HashMapFactory.make(2);
|
||||||
|
|
||||||
private final Map<CAstNode, CAstEntity> fEntities;
|
private final Map<CAstNode, Collection<CAstEntity>> fEntities;
|
||||||
|
|
||||||
public CodeBodyContext(WalkContext parent, Map<CAstNode, CAstEntity> entities) {
|
public CodeBodyContext(WalkContext parent, Map<CAstNode, Collection<CAstEntity>> entities) {
|
||||||
super(parent);
|
super(parent);
|
||||||
fEntities = entities;
|
fEntities = entities;
|
||||||
}
|
}
|
||||||
|
@ -2141,10 +2067,11 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addScopedEntity(CAstNode node, CAstEntity entity) {
|
public void addScopedEntity(CAstNode node, CAstEntity entity) {
|
||||||
fEntities.put(node, entity);
|
if (! fEntities.containsKey(node)) { fEntities.put(node, new HashSet<CAstEntity>(1)); }
|
||||||
|
fEntities.get(node).add(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map/* <CAstNode,CAstEntity> */<CAstNode, CAstEntity> getScopedEntities() {
|
public Map<CAstNode, Collection<CAstEntity>> getScopedEntities() {
|
||||||
return fEntities;
|
return fEntities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2160,7 +2087,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
|
||||||
public class MethodContext extends CodeBodyContext {
|
public class MethodContext extends CodeBodyContext {
|
||||||
final CodeInstance fPI;
|
final CodeInstance fPI;
|
||||||
|
|
||||||
public MethodContext(CodeInstance pi, Map<CAstNode, CAstEntity> entities, WalkContext parent) {
|
public MethodContext(CodeInstance pi, Map<CAstNode, Collection<CAstEntity>> entities, WalkContext parent) {
|
||||||
super(parent, entities);
|
super(parent, entities);
|
||||||
fPI = pi;
|
fPI = pi;
|
||||||
}
|
}
|
||||||
|
@ -2188,8 +2115,8 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
|
||||||
this.tryNode = tryNode;
|
this.tryNode = tryNode;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
|
||||||
for (Iterator catchIter = tryNode.catchBlocks().iterator(); catchIter.hasNext();) {
|
for (Iterator<Catch> catchIter = tryNode.catchBlocks().iterator(); catchIter.hasNext();) {
|
||||||
Catch c = (Catch) catchIter.next();
|
Catch c = catchIter.next();
|
||||||
Pair<Type,Object> p = Pair.make(c.catchType(), (Object)c);
|
Pair<Type,Object> p = Pair.make(c.catchType(), (Object)c);
|
||||||
|
|
||||||
fCatchNodes.add(p);
|
fCatchNodes.add(p);
|
||||||
|
@ -2217,7 +2144,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catchNodes.addAll(getParent().getCatchTargets(label));
|
catchNodes.addAll(parent.getCatchTargets(label));
|
||||||
return catchNodes;
|
return catchNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2230,53 +2157,23 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static class RootContext implements WalkContext {
|
protected static class RootContext extends TranslatorToCAst.RootContext<WalkContext, Node> implements WalkContext {
|
||||||
final CAstTypeDictionary fTypeDict;
|
final CAstTypeDictionary fTypeDict;
|
||||||
|
|
||||||
public RootContext(CAstTypeDictionary typeDict) {
|
public RootContext(CAstTypeDictionary typeDict) {
|
||||||
fTypeDict = typeDict;
|
fTypeDict = typeDict;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addScopedEntity(CAstNode node, CAstEntity e) {
|
|
||||||
Assertions.UNREACHABLE("Attempt to call addScopedEntity() on a RootContext.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public CAstControlFlowRecorder cfg() {
|
|
||||||
Assertions.UNREACHABLE("RootContext.cfg()");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<Pair<Type, Object>> getCatchTargets(Type label) {
|
public Collection<Pair<Type, Object>> getCatchTargets(Type label) {
|
||||||
Assertions.UNREACHABLE("RootContext.getCatchTargets()");
|
Assertions.UNREACHABLE("RootContext.getCatchTargets()");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CAstNodeTypeMapRecorder getNodeTypeMap() {
|
|
||||||
Assertions.UNREACHABLE("RootContext.getNodeTypeMap()");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Node getFinally() {
|
public Node getFinally() {
|
||||||
Assertions.UNREACHABLE("RootContext.getFinally()");
|
Assertions.UNREACHABLE("RootContext.getFinally()");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CAstSourcePositionRecorder pos() {
|
|
||||||
// No AST, so no AST map
|
|
||||||
Assertions.UNREACHABLE("RootContext.pos()");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Node getContinueFor(String label) {
|
|
||||||
Assertions.UNREACHABLE("RootContext.getContinueFor()");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Node getBreakFor(String label) {
|
|
||||||
Assertions.UNREACHABLE("RootContext.getBreakFor()");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CodeInstance getEnclosingMethod() {
|
public CodeInstance getEnclosingMethod() {
|
||||||
Assertions.UNREACHABLE("RootContext.getEnclosingMethod()");
|
Assertions.UNREACHABLE("RootContext.getEnclosingMethod()");
|
||||||
return null;
|
return null;
|
||||||
|
@ -2360,12 +2257,13 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public PolyglotJava2CAstTranslator(ClassLoaderReference clr, NodeFactory nf, TypeSystem ts, PolyglotIdentityMapper identityMapper, boolean replicateForDoLoops) {
|
public PolyglotJava2CAstTranslator(Node ast, ClassLoaderReference clr, NodeFactory nf, TypeSystem ts, PolyglotIdentityMapper identityMapper, boolean replicateForDoLoops) {
|
||||||
|
this.ast = ast;
|
||||||
fClassLoaderRef = clr;
|
fClassLoaderRef = clr;
|
||||||
fTypeSystem = ts;
|
fTypeSystem = ts;
|
||||||
fNodeFactory = nf;
|
fNodeFactory = nf;
|
||||||
fIdentityMapper = identityMapper;
|
fIdentityMapper = identityMapper;
|
||||||
this.replicateForDoLoops = replicateForDoLoops;
|
doLoopTranslator = new DoLoopTranslator(replicateForDoLoops, fFactory);
|
||||||
fNPEType = fTypeSystem.NullPointerException();
|
fNPEType = fTypeSystem.NullPointerException();
|
||||||
fCCEType = fTypeSystem.ClassCastException();
|
fCCEType = fTypeSystem.ClassCastException();
|
||||||
fREType = fTypeSystem.RuntimeException();
|
fREType = fTypeSystem.RuntimeException();
|
||||||
|
@ -2530,8 +2428,8 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
|
||||||
return cn;
|
return cn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CAstEntity translate(Object ast, String fileName) {
|
public CAstEntity translateToCAst() {
|
||||||
return walkEntity((Node) ast, new RootContext(getTypeDict()));
|
return walkEntity(ast, new RootContext(getTypeDict()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2623,7 +2521,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
|
||||||
InitializerDef initDef = fTypeSystem.initializerDef(n.position(), Types.ref(classType), Flags.STATIC);
|
InitializerDef initDef = fTypeSystem.initializerDef(n.position(), Types.ref(classType), Flags.STATIC);
|
||||||
InitializerInstance initInstance = fTypeSystem.createInitializerInstance(n.position(), Types.ref(initDef));
|
InitializerInstance initInstance = fTypeSystem.createInitializerInstance(n.position(), Types.ref(initDef));
|
||||||
|
|
||||||
Map<CAstNode, CAstEntity> childEntities = HashMapFactory.make();
|
Map<CAstNode, Collection<CAstEntity>> childEntities = HashMapFactory.make();
|
||||||
final MethodContext mc = new MethodContext(initInstance, childEntities, classContext);
|
final MethodContext mc = new MethodContext(initInstance, childEntities, classContext);
|
||||||
|
|
||||||
List inits = classContext.getStaticInitializers();
|
List inits = classContext.getStaticInitializers();
|
||||||
|
@ -2644,7 +2542,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
|
||||||
for (Iterator iter = superConstructors.iterator(); iter.hasNext();) {
|
for (Iterator iter = superConstructors.iterator(); iter.hasNext();) {
|
||||||
ConstructorInstance superCtor = (ConstructorInstance) iter.next();
|
ConstructorInstance superCtor = (ConstructorInstance) iter.next();
|
||||||
|
|
||||||
Map<CAstNode, CAstEntity> childEntities = HashMapFactory.make();
|
Map<CAstNode, Collection<CAstEntity>> childEntities = HashMapFactory.make();
|
||||||
final MethodContext mc = new MethodContext(superCtor, childEntities, classContext);
|
final MethodContext mc = new MethodContext(superCtor, childEntities, classContext);
|
||||||
|
|
||||||
String[] fakeArguments = new String[superCtor.formalTypes().size() + 1];
|
String[] fakeArguments = new String[superCtor.formalTypes().size() + 1];
|
||||||
|
@ -2713,7 +2611,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
|
||||||
return new ClassEntity(classContext, memberEntities, anonType, anonTypeName, n.position());
|
return new ClassEntity(classContext, memberEntities, anonType, anonTypeName, n.position());
|
||||||
} else if (rootNode instanceof ProcedureDecl) {
|
} else if (rootNode instanceof ProcedureDecl) {
|
||||||
final ProcedureDecl pd = (ProcedureDecl) rootNode;
|
final ProcedureDecl pd = (ProcedureDecl) rootNode;
|
||||||
final Map<CAstNode, CAstEntity> memberEntities = new LinkedHashMap<CAstNode, CAstEntity>();
|
final Map<CAstNode, Collection<CAstEntity>> memberEntities = HashMapFactory.make();
|
||||||
final MethodContext mc = new MethodContext(pd.procedureInstance().asInstance(), memberEntities, context);
|
final MethodContext mc = new MethodContext(pd.procedureInstance().asInstance(), memberEntities, context);
|
||||||
|
|
||||||
CAstNode pdAST = null;
|
CAstNode pdAST = null;
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
/p
|
||||||
|
/A.class
|
||||||
|
/AnonymousClass.class
|
||||||
|
/AnonymousClass.java
|
||||||
|
/AnonymousClass$1.class
|
||||||
|
/AnonymousClass$1FooImpl.class
|
||||||
|
/AnonymousClass$2.class
|
||||||
|
/AnonymousClass$Foo.class
|
||||||
|
/Array1.class
|
||||||
|
/Array1.java
|
||||||
|
/ArrayLiteral1.class
|
||||||
|
/ArrayLiteral1.java
|
||||||
|
/ArrayLiteral2.class
|
||||||
|
/ArrayLiteral2.java
|
||||||
|
/B.class
|
||||||
|
/BadLanguageExceptionEx1.class
|
||||||
|
/BadLanguageExceptionF1.class
|
||||||
|
/Bar.class
|
||||||
|
/Base.class
|
||||||
|
/Breaks.class
|
||||||
|
/Breaks.java
|
||||||
|
/Breaks$1.class
|
||||||
|
/Breaks$Ref.class
|
||||||
|
/CastFromNull.class
|
||||||
|
/CastFromNull.java
|
||||||
|
/Casts.class
|
||||||
|
/Casts.java
|
||||||
|
/Derived.class
|
||||||
|
/Exception1.class
|
||||||
|
/Exception1.java
|
||||||
|
/Exception2.class
|
||||||
|
/Exception2.java
|
||||||
|
/Finally1.class
|
||||||
|
/Finally1.java
|
||||||
|
/FooEx1.class
|
||||||
|
/FooEx2.class
|
||||||
|
/FooF1.class
|
||||||
|
/FooIT1.class
|
||||||
|
/FooQ.class
|
||||||
|
/IFoo.class
|
||||||
|
/Inheritance1.class
|
||||||
|
/Inheritance1.java
|
||||||
|
/InheritedField.class
|
||||||
|
/InheritedField.java
|
||||||
|
/InnerClass.class
|
||||||
|
/InnerClass.java
|
||||||
|
/InnerClass$WhatsIt.class
|
||||||
|
/InnerClass$WhatsIt$NotAgain.class
|
||||||
|
/InnerClass$WhatsThat.class
|
||||||
|
/InnerClassA.class
|
||||||
|
/InnerClassA.java
|
||||||
|
/InnerClassA$AA.class
|
||||||
|
/InnerClassA$AB.class
|
||||||
|
/InnerClassA$AB$ABA.class
|
||||||
|
/InnerClassA$AB$ABA$ABAA.class
|
||||||
|
/InnerClassA$AB$ABA$ABAB.class
|
||||||
|
/InnerClassA$AB$ABSubA.class
|
||||||
|
/InnerClassA$AB$ABSubA$ABSubAA.class
|
||||||
|
/InnerClassSuper.class
|
||||||
|
/InnerClassSuper.java
|
||||||
|
/InnerClassSuper$SuperOuter.class
|
||||||
|
/InterfaceTest1.class
|
||||||
|
/InterfaceTest1.java
|
||||||
|
/IntWrapper.class
|
||||||
|
/LocalClass.class
|
||||||
|
/LocalClass.java
|
||||||
|
/LocalClass$1Foo.class
|
||||||
|
/LocalClass$2Foo.class
|
||||||
|
/MiniaturList.class
|
||||||
|
/MiniaturList.java
|
||||||
|
/MiniaturSliceBug.class
|
||||||
|
/MiniaturSliceBug.java
|
||||||
|
/Monitor.class
|
||||||
|
/Monitor.java
|
||||||
|
/NullArrayInit.class
|
||||||
|
/NullArrayInit.java
|
||||||
|
/PrimitiveWrapper.class
|
||||||
|
/QualifiedStatic.class
|
||||||
|
/QualifiedStatic.java
|
||||||
|
/R.class
|
||||||
|
/Scoping1.class
|
||||||
|
/Scoping1.java
|
||||||
|
/Scoping2.class
|
||||||
|
/Scoping2.java
|
||||||
|
/Scoping2$1.class
|
||||||
|
/Simple1.class
|
||||||
|
/Simple1.java
|
||||||
|
/StaticInitializers.class
|
||||||
|
/StaticInitializers.java
|
||||||
|
/StaticInitializers$X.class
|
||||||
|
/StaticNesting.class
|
||||||
|
/StaticNesting.java
|
||||||
|
/StaticNesting$WhatsIt.class
|
||||||
|
/Sub.class
|
||||||
|
/Sub$SubInner.class
|
||||||
|
/Switch1.class
|
||||||
|
/Switch1.java
|
||||||
|
/Thread1.class
|
||||||
|
/Thread1.java
|
||||||
|
/TwoClasses.class
|
||||||
|
/TwoClasses.java
|
||||||
|
/WhileTest1.class
|
||||||
|
/WhileTest1.java
|
|
@ -48,6 +48,25 @@
|
||||||
|
|
||||||
<target name="getSources" depends="fetchJLex" />
|
<target name="getSources" depends="fetchJLex" />
|
||||||
|
|
||||||
|
<target name="testdatadir" depends="init,testdata.exists" unless="testdatadir.present">
|
||||||
|
<mkdir dir="${basedir}/../com.ibm.wala.cast.java.test/testdata"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="testdata.exists" depends="init">
|
||||||
|
<available file="${basedir}/../com.ibm.wala.cast.java.test/testdata"
|
||||||
|
type="dir"
|
||||||
|
property="testdatadir.present"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="compile" depends="getSources">
|
||||||
|
<javac srcdir="${basedir}/src"
|
||||||
|
destdir="${basedir}/bin"
|
||||||
|
excludes="**/Activator.java"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="jar" depends="compile,testdatadir">
|
||||||
|
<jar destfile="${basedir}/../com.ibm.wala.cast.java.test/testdata/test_project.zip" basedir="${basedir}"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
<target name="init" depends="properties">
|
<target name="init" depends="properties">
|
||||||
<condition property="pluginTemp" value="${buildTempFolder}/plugins">
|
<condition property="pluginTemp" value="${buildTempFolder}/plugins">
|
||||||
|
|
|
@ -186,7 +186,7 @@ public class SynchronizedBlockDuplicator extends
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CAstNode copyNodes(CAstNode n, RewriteContext<UnwindKey> c, Map<Pair<CAstNode, UnwindKey>, CAstNode> nodeMap) {
|
protected CAstNode copyNodes(CAstNode n, final CAstControlFlowMap cfg, RewriteContext<UnwindKey> c, Map<Pair<CAstNode, UnwindKey>, CAstNode> nodeMap) {
|
||||||
String varName;
|
String varName;
|
||||||
// don't copy operators or constants (presumably since they are immutable?)
|
// don't copy operators or constants (presumably since they are immutable?)
|
||||||
if (n instanceof CAstOperator) {
|
if (n instanceof CAstOperator) {
|
||||||
|
@ -204,15 +204,15 @@ public class SynchronizedBlockDuplicator extends
|
||||||
Ast.makeNode(CAstNode.VAR, Ast.makeConstant(varName)));
|
Ast.makeNode(CAstNode.VAR, Ast.makeConstant(varName)));
|
||||||
|
|
||||||
// the new if conditional
|
// the new if conditional
|
||||||
return Ast.makeNode(CAstNode.IF_STMT, test, copyNodes(n, new SyncContext(true, n, c), nodeMap),
|
return Ast.makeNode(CAstNode.IF_STMT, test, copyNodes(n, cfg, new SyncContext(true, n, c), nodeMap),
|
||||||
copyNodes(n, new SyncContext(false, n, c), nodeMap));
|
copyNodes(n, cfg, new SyncContext(false, n, c), nodeMap));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// invoke copyNodes() on the children with context c, ensuring, e.g., that
|
// invoke copyNodes() on the children with context c, ensuring, e.g., that
|
||||||
// the body of a synchronized block gets cloned
|
// the body of a synchronized block gets cloned
|
||||||
CAstNode[] newChildren = new CAstNode[n.getChildCount()];
|
CAstNode[] newChildren = new CAstNode[n.getChildCount()];
|
||||||
for (int i = 0; i < newChildren.length; i++)
|
for (int i = 0; i < newChildren.length; i++)
|
||||||
newChildren[i] = copyNodes(n.getChild(i), c, nodeMap);
|
newChildren[i] = copyNodes(n.getChild(i), cfg, c, nodeMap);
|
||||||
|
|
||||||
CAstNode newN = Ast.makeNode(n.getKind(), newChildren);
|
CAstNode newN = Ast.makeNode(n.getKind(), newChildren);
|
||||||
|
|
||||||
|
|
|
@ -272,7 +272,7 @@ public class AstJavaSSAPropagationCallGraphBuilder extends AstSSAPropagationCall
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitJavaInvoke(AstJavaInvokeInstruction instruction) {
|
public void visitJavaInvoke(AstJavaInvokeInstruction instruction) {
|
||||||
visitInvokeInternal(instruction);
|
visitInvokeInternal(instruction, new DefaultInvariantComputer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,21 +10,26 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
package com.ibm.wala.cast.java.ipa.callgraph;
|
package com.ibm.wala.cast.java.ipa.callgraph;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.ibm.wala.cast.ipa.callgraph.ScopeMappingInstanceKeys;
|
import com.ibm.wala.cast.ipa.callgraph.ScopeMappingInstanceKeys;
|
||||||
|
import com.ibm.wala.cast.ipa.callgraph.ScopeMappingInstanceKeys.ScopeMappingInstanceKey;
|
||||||
import com.ibm.wala.cast.ir.translator.AstTranslator;
|
import com.ibm.wala.cast.ir.translator.AstTranslator;
|
||||||
import com.ibm.wala.cast.java.loader.JavaSourceLoaderImpl.JavaClass;
|
import com.ibm.wala.cast.java.loader.JavaSourceLoaderImpl.JavaClass;
|
||||||
import com.ibm.wala.cast.loader.AstMethod;
|
import com.ibm.wala.cast.loader.AstMethod;
|
||||||
import com.ibm.wala.cast.loader.AstMethod.LexicalParent;
|
import com.ibm.wala.cast.loader.AstMethod.LexicalParent;
|
||||||
import com.ibm.wala.classLoader.IClass;
|
import com.ibm.wala.classLoader.IClass;
|
||||||
import com.ibm.wala.classLoader.IMethod;
|
import com.ibm.wala.classLoader.IMethod;
|
||||||
|
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKeyFactory;
|
import com.ibm.wala.ipa.callgraph.propagation.InstanceKeyFactory;
|
||||||
import com.ibm.wala.ipa.callgraph.propagation.PropagationCallGraphBuilder;
|
import com.ibm.wala.ipa.callgraph.propagation.PropagationCallGraphBuilder;
|
||||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||||
import com.ibm.wala.util.collections.HashSetFactory;
|
import com.ibm.wala.util.collections.HashSetFactory;
|
||||||
|
import com.ibm.wala.util.collections.Pair;
|
||||||
|
|
||||||
public class JavaScopeMappingInstanceKeys extends ScopeMappingInstanceKeys {
|
public class JavaScopeMappingInstanceKeys extends ScopeMappingInstanceKeys {
|
||||||
|
|
||||||
|
@ -75,4 +80,11 @@ public class JavaScopeMappingInstanceKeys extends ScopeMappingInstanceKeys {
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Collection<CGNode> getConstructorCallers(ScopeMappingInstanceKey smik, Pair<String, String> name) {
|
||||||
|
// for Java, the creator node is exactly what we want
|
||||||
|
return Collections.singleton(smik.getCreator());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ package com.ibm.wala.cast.java.translator;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.ir.translator.TranslatorToCAst;
|
||||||
import com.ibm.wala.cast.java.loader.JavaSourceLoaderImpl;
|
import com.ibm.wala.cast.java.loader.JavaSourceLoaderImpl;
|
||||||
import com.ibm.wala.cast.tree.CAst;
|
import com.ibm.wala.cast.tree.CAst;
|
||||||
import com.ibm.wala.cast.tree.CAstEntity;
|
import com.ibm.wala.cast.tree.CAstEntity;
|
||||||
|
@ -29,34 +30,29 @@ public class Java2IRTranslator {
|
||||||
|
|
||||||
protected final JavaSourceLoaderImpl fLoader;
|
protected final JavaSourceLoaderImpl fLoader;
|
||||||
|
|
||||||
protected final TranslatorToCAst fSourceTranslator;
|
|
||||||
|
|
||||||
CAstRewriterFactory castRewriterFactory = null;
|
CAstRewriterFactory castRewriterFactory = null;
|
||||||
|
|
||||||
public Java2IRTranslator(TranslatorToCAst sourceTranslator, JavaSourceLoaderImpl srcLoader) {
|
public Java2IRTranslator(JavaSourceLoaderImpl srcLoader) {
|
||||||
this(sourceTranslator, srcLoader, false);
|
this(srcLoader, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Java2IRTranslator(TranslatorToCAst sourceTranslator, JavaSourceLoaderImpl srcLoader, boolean debug) {
|
public Java2IRTranslator(JavaSourceLoaderImpl srcLoader, boolean debug) {
|
||||||
this(sourceTranslator, srcLoader, null, debug);
|
this(srcLoader, null, debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Java2IRTranslator(TranslatorToCAst sourceTranslator, JavaSourceLoaderImpl srcLoader,
|
public Java2IRTranslator(JavaSourceLoaderImpl srcLoader,
|
||||||
CAstRewriterFactory castRewriterFactory) {
|
CAstRewriterFactory castRewriterFactory) {
|
||||||
this(sourceTranslator, srcLoader, castRewriterFactory, false);
|
this(srcLoader, castRewriterFactory, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Java2IRTranslator(TranslatorToCAst sourceTranslator, JavaSourceLoaderImpl srcLoader,
|
public Java2IRTranslator(JavaSourceLoaderImpl srcLoader,
|
||||||
CAstRewriterFactory castRewriterFactory, boolean debug) {
|
CAstRewriterFactory castRewriterFactory, boolean debug) {
|
||||||
DEBUG = debug;
|
DEBUG = debug;
|
||||||
fLoader = srcLoader;
|
fLoader = srcLoader;
|
||||||
fSourceTranslator = sourceTranslator;
|
|
||||||
this.castRewriterFactory = castRewriterFactory;
|
this.castRewriterFactory = castRewriterFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void translate(ModuleEntry module, Object ast, String N) {
|
public void translate(ModuleEntry module, CAstEntity ce) {
|
||||||
CAstEntity ce = fSourceTranslator.translate(ast, N);
|
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
PrintWriter printWriter = new PrintWriter(System.out);
|
PrintWriter printWriter = new PrintWriter(System.out);
|
||||||
CAstPrinter.printTo(ce, printWriter);
|
CAstPrinter.printTo(ce, printWriter);
|
||||||
|
|
|
@ -304,26 +304,24 @@ public class JavaCAst2IRTranslator extends AstTranslator {
|
||||||
return ((JavaSourceLoaderImpl) loader).defineType(type, type.getType().getName(), parentType) != null;
|
return ((JavaSourceLoaderImpl) loader).defineType(type, type.getType().getName(), parentType) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void leaveThis(CAstNode n, Context c, CAstVisitor visitor) {
|
protected void leaveThis(CAstNode n, WalkContext c, CAstVisitor<WalkContext> visitor) {
|
||||||
if (n.getChildCount() == 0) {
|
if (n.getChildCount() == 0) {
|
||||||
super.leaveThis(n, c, visitor);
|
super.leaveThis(n, c, visitor);
|
||||||
} else {
|
} else {
|
||||||
WalkContext wc = (WalkContext) c;
|
int result = c.currentScope().allocateTempValue();
|
||||||
int result = wc.currentScope().allocateTempValue();
|
c.setValue(n, result);
|
||||||
setValue(n, result);
|
c.cfg().addInstruction(new EnclosingObjectReference(result, (TypeReference) n.getChild(0).getValue()));
|
||||||
wc.cfg().addInstruction(new EnclosingObjectReference(result, (TypeReference) n.getChild(0).getValue()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean visitCast(CAstNode n, Context c, CAstVisitor visitor) {
|
protected boolean visitCast(CAstNode n, WalkContext context, CAstVisitor<WalkContext> visitor) {
|
||||||
WalkContext context = (WalkContext)c;
|
|
||||||
int result = context.currentScope().allocateTempValue();
|
int result = context.currentScope().allocateTempValue();
|
||||||
setValue(n, result);
|
context.setValue(n, result);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
protected void leaveCast(CAstNode n, Context c, CAstVisitor visitor) {
|
|
||||||
WalkContext context = (WalkContext)c;
|
protected void leaveCast(CAstNode n, WalkContext context, CAstVisitor<WalkContext> visitor) {
|
||||||
int result = getValue(n);
|
int result = context.getValue(n);
|
||||||
CAstType toType = (CAstType) n.getChild(0).getValue();
|
CAstType toType = (CAstType) n.getChild(0).getValue();
|
||||||
TypeReference toRef = makeType(toType);
|
TypeReference toRef = makeType(toType);
|
||||||
|
|
||||||
|
@ -334,7 +332,7 @@ public class JavaCAst2IRTranslator extends AstTranslator {
|
||||||
context.cfg().addInstruction(
|
context.cfg().addInstruction(
|
||||||
insts.ConversionInstruction(
|
insts.ConversionInstruction(
|
||||||
result,
|
result,
|
||||||
getValue(n.getChild(1)),
|
context.getValue(n.getChild(1)),
|
||||||
fromRef,
|
fromRef,
|
||||||
toRef,
|
toRef,
|
||||||
false));
|
false));
|
||||||
|
@ -343,43 +341,42 @@ public class JavaCAst2IRTranslator extends AstTranslator {
|
||||||
context.cfg().addInstruction(
|
context.cfg().addInstruction(
|
||||||
insts.CheckCastInstruction(
|
insts.CheckCastInstruction(
|
||||||
result,
|
result,
|
||||||
getValue(n.getChild(1)),
|
context.getValue(n.getChild(1)),
|
||||||
toRef,
|
toRef,
|
||||||
true));
|
true));
|
||||||
|
|
||||||
processExceptions(n, context);
|
processExceptions(n, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected boolean visitInstanceOf(CAstNode n, Context c, CAstVisitor visitor) {
|
|
||||||
WalkContext context = (WalkContext)c;
|
protected boolean visitInstanceOf(CAstNode n, WalkContext context, CAstVisitor<WalkContext> visitor) {
|
||||||
int result = context.currentScope().allocateTempValue();
|
int result = context.currentScope().allocateTempValue();
|
||||||
setValue(n, result);
|
context.setValue(n, result);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
protected void leaveInstanceOf(CAstNode n, Context c, CAstVisitor visitor) {
|
|
||||||
WalkContext context = (WalkContext)c;
|
protected void leaveInstanceOf(CAstNode n, WalkContext context, CAstVisitor<WalkContext> visitor) {
|
||||||
int result = getValue(n);
|
int result = context.getValue(n);
|
||||||
CAstType type = (CAstType) n.getChild(0).getValue();
|
CAstType type = (CAstType) n.getChild(0).getValue();
|
||||||
|
|
||||||
TypeReference ref = makeType( type );
|
TypeReference ref = makeType( type );
|
||||||
context.cfg().addInstruction(
|
context.cfg().addInstruction(
|
||||||
insts.InstanceofInstruction(
|
insts.InstanceofInstruction(
|
||||||
result,
|
result,
|
||||||
getValue(n.getChild(1)),
|
context.getValue(n.getChild(1)),
|
||||||
ref));
|
ref));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean doVisit(CAstNode n, Context context, CAstVisitor visitor) {
|
protected boolean doVisit(CAstNode n, WalkContext wc, CAstVisitor<WalkContext> visitor) {
|
||||||
WalkContext wc = (WalkContext) context;
|
|
||||||
if (n.getKind() == CAstNode.MONITOR_ENTER) {
|
if (n.getKind() == CAstNode.MONITOR_ENTER) {
|
||||||
visitor.visit(n.getChild(0), wc, visitor);
|
visitor.visit(n.getChild(0), wc, visitor);
|
||||||
wc.cfg().addInstruction(insts.MonitorInstruction(getValue(n.getChild(0)), true));
|
wc.cfg().addInstruction(insts.MonitorInstruction(wc.getValue(n.getChild(0)), true));
|
||||||
processExceptions(n, wc);
|
processExceptions(n, wc);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else if (n.getKind() == CAstNode.MONITOR_EXIT) {
|
} else if (n.getKind() == CAstNode.MONITOR_EXIT) {
|
||||||
visitor.visit(n.getChild(0), wc, visitor);
|
visitor.visit(n.getChild(0), wc, visitor);
|
||||||
wc.cfg().addInstruction(insts.MonitorInstruction(getValue(n.getChild(0)), false));
|
wc.cfg().addInstruction(insts.MonitorInstruction(wc.getValue(n.getChild(0)), false));
|
||||||
processExceptions(n, wc);
|
processExceptions(n, wc);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -387,4 +384,6 @@ processExceptions(n, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* IBM Corporation - initial API and implementation
|
|
||||||
*****************************************************************************/
|
|
||||||
package com.ibm.wala.cast.java.translator;
|
|
||||||
|
|
||||||
import com.ibm.wala.cast.tree.CAstEntity;
|
|
||||||
|
|
||||||
public interface TranslatorToCAst {
|
|
||||||
|
|
||||||
public CAstEntity translate(Object astRoot, String unitName);
|
|
||||||
|
|
||||||
}
|
|
|
@ -2,8 +2,8 @@
|
||||||
<classpath>
|
<classpath>
|
||||||
<classpathentry kind="src" path="src"/>
|
<classpathentry kind="src" path="src"/>
|
||||||
<classpathentry kind="src" path="tests"/>
|
<classpathentry kind="src" path="tests"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
|
||||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
|
||||||
<classpathentry kind="lib" path="lib/htmlparser-1.3.1.jar"/>
|
<classpathentry kind="lib" path="lib/htmlparser-1.3.1.jar"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|
|
@ -8,5 +8,7 @@ Require-Bundle: com.ibm.wala.cast.js;bundle-version="1.0.0",
|
||||||
com.ibm.wala.cast.js.rhino.test;bundle-version="1.0.0",
|
com.ibm.wala.cast.js.rhino.test;bundle-version="1.0.0",
|
||||||
com.ibm.wala.cast.js.test;bundle-version="1.0.0",
|
com.ibm.wala.cast.js.test;bundle-version="1.0.0",
|
||||||
com.ibm.wala.cast.test;bundle-version="1.0.0",
|
com.ibm.wala.cast.test;bundle-version="1.0.0",
|
||||||
|
com.ibm.wala.cast;bundle-version="1.0.0",
|
||||||
com.ibm.wala.core.tests;bundle-version="1.1.3",
|
com.ibm.wala.core.tests;bundle-version="1.1.3",
|
||||||
com.ibm.wala.core;bundle-version="1.1.3"
|
com.ibm.wala.core;bundle-version="1.1.3",
|
||||||
|
org.junit;bundle-version="4.8.1"
|
||||||
|
|
|
@ -14,6 +14,8 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.LineNumberReader;
|
import java.io.LineNumberReader;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.AbstractMap;
|
import java.util.AbstractMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -32,10 +34,21 @@ import org.xml.sax.SAXException;
|
||||||
import com.ibm.wala.cast.js.html.IHtmlCallback;
|
import com.ibm.wala.cast.js.html.IHtmlCallback;
|
||||||
import com.ibm.wala.cast.js.html.IHtmlParser;
|
import com.ibm.wala.cast.js.html.IHtmlParser;
|
||||||
import com.ibm.wala.cast.js.html.ITag;
|
import com.ibm.wala.cast.js.html.ITag;
|
||||||
|
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
||||||
|
import com.ibm.wala.cast.tree.impl.LineNumberPosition;
|
||||||
|
import com.ibm.wala.util.collections.Pair;
|
||||||
|
|
||||||
public class NuValidatorHtmlParser implements IHtmlParser {
|
public class NuValidatorHtmlParser implements IHtmlParser {
|
||||||
|
|
||||||
public void parse(final InputStream reader, final IHtmlCallback handler, String fileName) {
|
public void parse(final URL url, final InputStream reader, final IHtmlCallback handler, final String fileName) {
|
||||||
|
URL xx = null;
|
||||||
|
try {
|
||||||
|
xx = new URL("file://" + fileName);
|
||||||
|
} catch (MalformedURLException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
final URL localFileName = xx;
|
||||||
|
|
||||||
HtmlParser parser = new HtmlParser();
|
HtmlParser parser = new HtmlParser();
|
||||||
parser.setXmlPolicy(XmlViolationPolicy.ALLOW);
|
parser.setXmlPolicy(XmlViolationPolicy.ALLOW);
|
||||||
parser.setContentHandler(new ContentHandler() {
|
parser.setContentHandler(new ContentHandler() {
|
||||||
|
@ -57,38 +70,46 @@ public class NuValidatorHtmlParser implements IHtmlParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startElement(String uri, final String localName, String qName, final Attributes atts) throws SAXException {
|
public void startElement(String uri, final String localName, String qName, final Attributes atts) throws SAXException {
|
||||||
final int line = locator.getLineNumber();
|
final Position line = new LineNumberPosition(url, localFileName, locator.getLineNumber());
|
||||||
tags.push(new ITag() {
|
tags.push(new ITag() {
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return localName;
|
return localName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAttributeByName(String name) {
|
public Pair<String,Position> getAttributeByName(String name) {
|
||||||
return atts.getValue(name);
|
if (atts.getValue(name) != null) {
|
||||||
|
return Pair.make(atts.getValue(name), line);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getAllAttributes() {
|
public Map<String, Pair<String,Position>> getAllAttributes() {
|
||||||
return new AbstractMap<String,String>() {
|
return new AbstractMap<String,Pair<String,Position>>() {
|
||||||
private Set<Map.Entry<String,String>> es = null;
|
private Set<Map.Entry<String,Pair<String,Position>>> es = null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<java.util.Map.Entry<String, String>> entrySet() {
|
public Set<java.util.Map.Entry<String, Pair<String,Position>>> entrySet() {
|
||||||
if (es == null) {
|
if (es == null) {
|
||||||
es = new HashSet<Map.Entry<String,String>>();
|
es = new HashSet<Map.Entry<String,Pair<String,Position>>>();
|
||||||
for(int i = 0; i < atts.getLength(); i++) {
|
for(int i = 0; i < atts.getLength(); i++) {
|
||||||
final int index = i;
|
final int index = i;
|
||||||
es.add(new Map.Entry<String,String>() {
|
es.add(new Map.Entry<String,Pair<String,Position>>() {
|
||||||
|
|
||||||
public String getKey() {
|
public String getKey() {
|
||||||
return atts.getLocalName(index);
|
return atts.getLocalName(index).toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getValue() {
|
public Pair<String,Position> getValue() {
|
||||||
return atts.getValue(index);
|
if (atts.getValue(index) != null) {
|
||||||
|
return Pair.make(atts.getValue(index), line);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String setValue(String value) {
|
public Pair<String,Position> setValue(Pair<String,Position> value) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -99,10 +120,15 @@ public class NuValidatorHtmlParser implements IHtmlParser {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStartingLineNum() {
|
public Position getElementPosition() {
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Position getContentPosition() {
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
handler.handleStartTag(tags.peek());
|
handler.handleStartTag(tags.peek());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,11 +137,11 @@ public class NuValidatorHtmlParser implements IHtmlParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||||
handler.handleText(locator.getLineNumber() - countLines(ch, start, length), new String(ch, start, length));
|
handler.handleText(new LineNumberPosition(url, localFileName, locator.getLineNumber() - countLines(ch, start, length)), new String(ch, start, length));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
|
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
|
||||||
handler.handleText(locator.getLineNumber(), new String(ch, start, length));
|
handler.handleText(new LineNumberPosition(url, localFileName, locator.getLineNumber()), new String(ch, start, length));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startDocument() throws SAXException {
|
public void startDocument() throws SAXException {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<classpath>
|
<classpath>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||||
<classpathentry kind="src" path="harness-src"/>
|
<classpathentry kind="src" path="harness-src"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
/apollo-example.html
|
||||||
|
/crawl.html
|
||||||
|
/iframeTest2.html
|
||||||
|
/list.html
|
||||||
|
/nojs.html
|
||||||
|
/page1.html
|
||||||
|
/page11.html
|
||||||
|
/page11b.html
|
||||||
|
/page12.html
|
||||||
|
/page13.html
|
||||||
|
/page15.html
|
||||||
|
/page16.html
|
||||||
|
/page17.html
|
||||||
|
/page2.html
|
||||||
|
/page3.html
|
||||||
|
/page4.html
|
||||||
|
/windowx.html
|
|
@ -13,7 +13,8 @@ Require-Bundle: org.eclipse.core.runtime,
|
||||||
com.ibm.wala.cast.js.test;bundle-version="1.0.0",
|
com.ibm.wala.cast.js.test;bundle-version="1.0.0",
|
||||||
com.ibm.wala.cast.test;bundle-version="1.0.0",
|
com.ibm.wala.cast.test;bundle-version="1.0.0",
|
||||||
com.ibm.wala.core.tests;bundle-version="1.1.3",
|
com.ibm.wala.core.tests;bundle-version="1.1.3",
|
||||||
org.junit4;bundle-version="4.3.1"
|
org.junit4;bundle-version="4.3.1",
|
||||||
|
com.ibm.wala.ide;bundle-version="1.1.3"
|
||||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||||
Bundle-ActivationPolicy: lazy
|
Bundle-ActivationPolicy: lazy
|
||||||
Export-Package: com.ibm.wala.cast.js.test
|
Export-Package: com.ibm.wala.cast.js.test
|
||||||
|
|
|
@ -0,0 +1,206 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package com.ibm.wala.cast.js.rhino.test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.ir.translator.AstTranslator;
|
||||||
|
import com.ibm.wala.cast.js.ipa.callgraph.ForInContextSelector;
|
||||||
|
import com.ibm.wala.cast.js.ipa.callgraph.JSCFABuilder;
|
||||||
|
import com.ibm.wala.cast.js.ipa.callgraph.JavaScriptFunctionDotCallTargetSelector;
|
||||||
|
import com.ibm.wala.cast.js.ipa.callgraph.RecursionCheckContextSelector;
|
||||||
|
import com.ibm.wala.cast.js.ipa.callgraph.correlations.extraction.CorrelatedPairExtractorFactory;
|
||||||
|
import com.ibm.wala.cast.js.test.JSCallGraphBuilderUtil;
|
||||||
|
import com.ibm.wala.cast.js.test.JSCallGraphBuilderUtil.CGBuilderType;
|
||||||
|
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
|
||||||
|
import com.ibm.wala.ide.util.ProgressMaster;
|
||||||
|
import com.ibm.wala.ide.util.ProgressMonitorDelegate;
|
||||||
|
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||||
|
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||||
|
import com.ibm.wala.ipa.callgraph.CallGraphBuilderCancelException;
|
||||||
|
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||||
|
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||||
|
import com.ibm.wala.util.collections.Iterator2Iterable;
|
||||||
|
import com.ibm.wala.util.io.CommandLine;
|
||||||
|
import com.ibm.wala.util.io.FileProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class for building call graphs of HTML pages.
|
||||||
|
*
|
||||||
|
* @author mschaefer
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class HTMLCGBuilder {
|
||||||
|
public static final int DEFAULT_TIMEOUT = 120;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple struct-like type to hold results of call graph construction.
|
||||||
|
*
|
||||||
|
* @author mschaefer
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static class CGBuilderResult {
|
||||||
|
/** time it took to build the call graph; {@code -1} if timeout occurred */
|
||||||
|
public long construction_time;
|
||||||
|
|
||||||
|
/** builder responsible for building the call graph*/
|
||||||
|
public JSCFABuilder builder;
|
||||||
|
|
||||||
|
/** pointer analysis results; partial if {@link #construction_time} is {@code -1} */
|
||||||
|
public PointerAnalysis pa;
|
||||||
|
|
||||||
|
/** call graph; partial if {@link #construction_time} is {@code -1} */
|
||||||
|
public CallGraph cg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a call graph for an HTML page, optionally with a timeout.
|
||||||
|
*
|
||||||
|
* @param src
|
||||||
|
* the HTML page to analyse, can either be a path to a local file or a URL
|
||||||
|
* @param timeout
|
||||||
|
* analysis timeout in seconds, -1 means no timeout
|
||||||
|
* @param automated_extraction
|
||||||
|
* whether to automatically extract correlated pairs
|
||||||
|
* @throws IOException
|
||||||
|
* @throws ClassHierarchyException
|
||||||
|
*/
|
||||||
|
public static CGBuilderResult buildHTMLCG(String src, int timeout, boolean automated_extraction, CGBuilderType builderType)
|
||||||
|
throws ClassHierarchyException, IOException {
|
||||||
|
CGBuilderResult res = new CGBuilderResult();
|
||||||
|
URL url = null;
|
||||||
|
try {
|
||||||
|
url = toUrl(src);
|
||||||
|
} catch (MalformedURLException e1) {
|
||||||
|
Assert.fail("Could not find page to analyse: " + src);
|
||||||
|
}
|
||||||
|
com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
||||||
|
if(automated_extraction)
|
||||||
|
com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil.setPreprocessor(new CorrelatedPairExtractorFactory(new CAstRhinoTranslatorFactory(), url));
|
||||||
|
JSCFABuilder builder = null;
|
||||||
|
try {
|
||||||
|
builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url, builderType);
|
||||||
|
builder.setContextSelector(new ForInContextSelector(2, builder.getContextSelector()));
|
||||||
|
builder.setContextSelector(new ForInContextSelector(3, builder.getContextSelector()));
|
||||||
|
// TODO we need to find a better way to do this ContextSelector delegation;
|
||||||
|
// the code below belongs somewhere else!!!
|
||||||
|
// the bound of 4 is what is needed to pass our current framework tests
|
||||||
|
if (AstTranslator.NEW_LEXICAL) {
|
||||||
|
// builder.setContextSelector(new RecursionBoundContextSelector(builder.getContextSelector(), 4));
|
||||||
|
builder.setContextSelector(new RecursionCheckContextSelector(builder.getContextSelector()));
|
||||||
|
}
|
||||||
|
ProgressMaster master = ProgressMaster.make(new NullProgressMonitor());
|
||||||
|
if (timeout > 0) {
|
||||||
|
master.setMillisPerWorkItem(timeout * 1000);
|
||||||
|
master.beginTask("runSolver", 1);
|
||||||
|
}
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
CallGraph cg = timeout > 0 ? builder.makeCallGraph(builder.getOptions(),
|
||||||
|
ProgressMonitorDelegate.createProgressMonitorDelegate(master)) : builder.makeCallGraph(builder.getOptions());
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
master.done();
|
||||||
|
res.construction_time = (end - start);
|
||||||
|
res.cg = cg;
|
||||||
|
res.pa = builder.getPointerAnalysis();
|
||||||
|
res.builder = builder;
|
||||||
|
return res;
|
||||||
|
} catch (CallGraphBuilderCancelException e) {
|
||||||
|
res.construction_time = -1;
|
||||||
|
res.cg = e.getPartialCallGraph();
|
||||||
|
res.pa = e.getPartialPointerAnalysis();
|
||||||
|
res.builder = builder;
|
||||||
|
return res;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static URL toUrl(String src) throws MalformedURLException {
|
||||||
|
// first try interpreting as local file name, if that doesn't work just
|
||||||
|
// assume it's a URL
|
||||||
|
try {
|
||||||
|
File f = (new FileProvider()).getFileFromClassLoader(src, HTMLCGBuilder.class.getClassLoader());
|
||||||
|
URL url = f.toURI().toURL();
|
||||||
|
return url;
|
||||||
|
} catch (FileNotFoundException fnfe) {
|
||||||
|
return new URL(src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Usage: HTMLCGBuilder -src path_to_html_file -timeout timeout_in_seconds -reachable function_name
|
||||||
|
* timeout argument is optional and defaults to {@link #DEFAULT_TIMEOUT}.
|
||||||
|
* reachable argument is optional. if provided, and some reachable function name contains function_name,
|
||||||
|
* will print "REACHABLE"
|
||||||
|
* @throws IOException
|
||||||
|
* @throws ClassHierarchyException
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws ClassHierarchyException, IOException {
|
||||||
|
Properties parsedArgs = CommandLine.parse(args);
|
||||||
|
String src = parsedArgs.getProperty("src");
|
||||||
|
if (src == null) {
|
||||||
|
throw new IllegalArgumentException("-src argument is required");
|
||||||
|
}
|
||||||
|
int timeout;
|
||||||
|
if (parsedArgs.containsKey("timeout")) {
|
||||||
|
timeout = Integer.parseInt(parsedArgs.getProperty("timeout"));
|
||||||
|
} else {
|
||||||
|
timeout = DEFAULT_TIMEOUT;
|
||||||
|
}
|
||||||
|
String reachableName = null;
|
||||||
|
if (parsedArgs.containsKey("reachable")) {
|
||||||
|
reachableName = parsedArgs.getProperty("reachable");
|
||||||
|
}
|
||||||
|
|
||||||
|
String srcNode = null, dstNode = null;
|
||||||
|
if (parsedArgs.containsKey("edgeExists")) {
|
||||||
|
String[] nodes = parsedArgs.getProperty("edgeExists").split(":");
|
||||||
|
srcNode = nodes[0];
|
||||||
|
dstNode = nodes[1];
|
||||||
|
}
|
||||||
|
// suppress debug output
|
||||||
|
JavaScriptFunctionDotCallTargetSelector.WARN_ABOUT_IMPRECISE_CALLGRAPH = false;
|
||||||
|
CGBuilderResult res = buildHTMLCG(src, timeout, true, AstTranslator.NEW_LEXICAL ? CGBuilderType.ONE_CFA_PRECISE_LEXICAL : CGBuilderType.ZERO_ONE_CFA);
|
||||||
|
if(res.construction_time == -1)
|
||||||
|
System.out.println("TIMED OUT");
|
||||||
|
else
|
||||||
|
System.out.println("Call graph construction took " + res.construction_time/1000.0 + " seconds");
|
||||||
|
if (reachableName != null) {
|
||||||
|
for (CGNode node : res.cg) {
|
||||||
|
if (node.getMethod().getDeclaringClass().getName().toString().contains(reachableName)) {
|
||||||
|
System.out.println("REACHABLE");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (srcNode != null) {
|
||||||
|
for (CGNode node : res.cg) {
|
||||||
|
if (node.getMethod().getDeclaringClass().getName().toString().endsWith(srcNode)) {
|
||||||
|
for (CGNode callee : Iterator2Iterable.make(res.cg.getSuccNodes(node))) {
|
||||||
|
if (callee.getMethod().getDeclaringClass().getName().toString().endsWith(dstNode)) {
|
||||||
|
System.out.println("EDGE EXISTS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,7 +22,7 @@ public class TestAjaxsltCallGraphShapeRhino extends TestAjaxsltCallGraphShape {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
com.ibm.wala.cast.js.ipa.callgraph.Util.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.ibm.wala.cast.js.test;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil;
|
||||||
|
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
|
||||||
|
|
||||||
|
public class TestArgumentSensitivityRhino extends TestArgumentSensitivity {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
JSCallGraphUtil.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -15,10 +15,10 @@ import java.io.IOException;
|
||||||
|
|
||||||
import com.ibm.wala.cast.js.ipa.callgraph.correlations.CorrelationFinder;
|
import com.ibm.wala.cast.js.ipa.callgraph.correlations.CorrelationFinder;
|
||||||
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
|
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
|
||||||
|
import com.ibm.wala.cast.js.translator.RhinoToAstTranslator;
|
||||||
import com.ibm.wala.cast.tree.CAstEntity;
|
import com.ibm.wala.cast.tree.CAstEntity;
|
||||||
import com.ibm.wala.cast.tree.impl.CAstImpl;
|
import com.ibm.wala.cast.tree.impl.CAstImpl;
|
||||||
import com.ibm.wala.classLoader.SourceModule;
|
import com.ibm.wala.classLoader.SourceModule;
|
||||||
import org.mozilla.javascript.RhinoToAstTranslator;
|
|
||||||
|
|
||||||
public class TestCorrelatedPairExtractionRhino extends TestCorrelatedPairExtraction {
|
public class TestCorrelatedPairExtractionRhino extends TestCorrelatedPairExtraction {
|
||||||
protected CorrelationFinder makeCorrelationFinder() {
|
protected CorrelationFinder makeCorrelationFinder() {
|
||||||
|
@ -26,9 +26,8 @@ public class TestCorrelatedPairExtractionRhino extends TestCorrelatedPairExtract
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CAstEntity parseJS(CAstImpl ast, SourceModule module) throws IOException {
|
protected CAstEntity parseJS(CAstImpl ast, SourceModule module) throws IOException {
|
||||||
RhinoToAstTranslator.resetGensymCounters();
|
RhinoToAstTranslator translator = new RhinoToAstTranslator(ast, module, module.getName(), false);
|
||||||
RhinoToAstTranslator translator = new RhinoToAstTranslator(ast, module, module.getName());
|
CAstEntity entity = translator.translateToCAst();
|
||||||
CAstEntity entity = translator.translate();
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,17 +13,16 @@ package com.ibm.wala.cast.js.test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.mozilla.javascript.RhinoToAstTranslator;
|
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.js.translator.RhinoToAstTranslator;
|
||||||
import com.ibm.wala.cast.tree.CAstEntity;
|
import com.ibm.wala.cast.tree.CAstEntity;
|
||||||
import com.ibm.wala.cast.tree.impl.CAstImpl;
|
import com.ibm.wala.cast.tree.impl.CAstImpl;
|
||||||
import com.ibm.wala.classLoader.SourceModule;
|
import com.ibm.wala.classLoader.SourceModule;
|
||||||
|
|
||||||
public class TestForInBodyExtractionRhino extends TestForInBodyExtraction {
|
public class TestForInBodyExtractionRhino extends TestForInBodyExtraction {
|
||||||
protected CAstEntity parseJS(CAstImpl ast, SourceModule module) throws IOException {
|
protected CAstEntity parseJS(CAstImpl ast, SourceModule module) throws IOException {
|
||||||
RhinoToAstTranslator.resetGensymCounters();
|
RhinoToAstTranslator translator = new RhinoToAstTranslator(ast, module, module.getName(), false);
|
||||||
RhinoToAstTranslator translator = new RhinoToAstTranslator(ast, module, module.getName());
|
CAstEntity entity = translator.translateToCAst();
|
||||||
CAstEntity entity = translator.translate();
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ public class TestForInLoopHackRhino extends TestForInLoopHack {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
com.ibm.wala.cast.js.ipa.callgraph.Util.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.ibm.wala.cast.js.test;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil;
|
||||||
|
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
|
||||||
|
|
||||||
|
public class TestJQueryExamplesRhino extends TestJQueryExamples {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
justThisTest(TestJQueryExamplesRhino.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
JSCallGraphUtil.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -22,7 +22,7 @@ public class TestMediawikiCallGraphShapeRhino extends TestMediawikiCallGraphShap
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
com.ibm.wala.cast.js.ipa.callgraph.Util.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ public class TestMozillaBugPagesRhino extends TestMozillaBugPages {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
com.ibm.wala.cast.js.ipa.callgraph.Util.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,170 @@
|
||||||
|
package com.ibm.wala.cast.js.test;
|
||||||
|
|
||||||
|
import static com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil.makeHierarchy;
|
||||||
|
import static com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil.makeLoaders;
|
||||||
|
import static com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil.setTranslatorFactory;
|
||||||
|
import static com.ibm.wala.cast.js.test.JSCallGraphBuilderUtil.makeScriptScope;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.js.loader.JavaScriptLoaderFactory;
|
||||||
|
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
|
||||||
|
import com.ibm.wala.cast.loader.AstMethod;
|
||||||
|
import com.ibm.wala.cast.types.AstMethodReference;
|
||||||
|
import com.ibm.wala.cast.util.SourceBuffer;
|
||||||
|
import com.ibm.wala.classLoader.IClass;
|
||||||
|
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||||
|
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||||
|
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||||
|
import com.ibm.wala.util.CancelException;
|
||||||
|
import com.ibm.wala.util.collections.HashMapFactory;
|
||||||
|
|
||||||
|
public class TestRhinoSourceMap {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String[][] jquery_spec_testSource = new String[][]{
|
||||||
|
new String[]{
|
||||||
|
"Ltests/jquery_spec_test.js/anonymous__0/isEmptyDataObject",
|
||||||
|
"function isEmptyDataObject(obj) {\n" +
|
||||||
|
" for (var name in obj) {\n" +
|
||||||
|
" if (name !== \"toJSON\") {\n" +
|
||||||
|
" return false;\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
" return true;\n" +
|
||||||
|
" }"
|
||||||
|
},
|
||||||
|
new String[]{
|
||||||
|
"Ltests/jquery_spec_test.js/anonymous__0/anonymous__59/anonymous__62/anonymous__63/anonymous__64/anonymous__65",
|
||||||
|
"function anonymous__65() {\n" +
|
||||||
|
" returned = fn.apply(this, arguments);\n" +
|
||||||
|
" if (returned && jQuery.isFunction(returned.promise)) {\n" +
|
||||||
|
" returned.promise().then(newDefer.resolve, newDefer.reject);\n" +
|
||||||
|
" } else {\n" +
|
||||||
|
" newDefer[action](returned);\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }"
|
||||||
|
},
|
||||||
|
new String[]{
|
||||||
|
"Ltests/jquery_spec_test.js/anonymous__0/anonymous__386/anonymous__392",
|
||||||
|
"function anonymous__392(map) {\n" +
|
||||||
|
" if (map) {\n" +
|
||||||
|
" var tmp;\n" +
|
||||||
|
" if (state < 2) {\n" +
|
||||||
|
" for (tmp in map) {\n" +
|
||||||
|
" statusCode[tmp] = [ statusCode[tmp], map[tmp] ];\n" +
|
||||||
|
" }\n" +
|
||||||
|
" } else {\n" +
|
||||||
|
" tmp = map[jqXHR.status];\n" +
|
||||||
|
" jqXHR.then(tmp, tmp);\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
" return this;\n" +
|
||||||
|
" }"
|
||||||
|
},
|
||||||
|
new String[]{
|
||||||
|
"Ltests/jquery_spec_test.js/anonymous__0/getWindow",
|
||||||
|
"function getWindow(elem) {\n" +
|
||||||
|
" return jQuery.isWindow(elem) ? elem : elem.nodeType === 9 ? elem.defaultView || elem.parentWindow : false;\n" +
|
||||||
|
" }"
|
||||||
|
},
|
||||||
|
new String[]{
|
||||||
|
"Ltests/jquery_spec_test.js/anonymous__0/anonymous__1/anonymous__7",
|
||||||
|
"function anonymous__7(elems, name, selector) {\n" +
|
||||||
|
" var ret = this.constructor();\n" +
|
||||||
|
" if (jQuery.isArray(elems)) {\n" +
|
||||||
|
" push.apply(ret, elems);\n" +
|
||||||
|
" } else {\n" +
|
||||||
|
" jQuery.merge(ret, elems);\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ret.prevObject = this;\n" +
|
||||||
|
" ret.context = this.context;\n" +
|
||||||
|
" if (name === \"find\") {\n" +
|
||||||
|
" ret.selector = this.selector + (this.selector ? \" \" : \"\") + selector;\n" +
|
||||||
|
" } else if (name) {\n" +
|
||||||
|
" ret.selector = this.selector + \".\" + name + \"(\" + selector + \")\";\n" +
|
||||||
|
" }\n" +
|
||||||
|
" return ret;\n" +
|
||||||
|
" }"
|
||||||
|
},
|
||||||
|
new String[]{
|
||||||
|
"Ltests/jquery_spec_test.js/anonymous__0/anonymous__1/anonymous__17",
|
||||||
|
"function anonymous__17() {\n" +
|
||||||
|
" var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false;\n" +
|
||||||
|
" if (typeof target === \"boolean\") {\n" +
|
||||||
|
" deep = target;\n" +
|
||||||
|
" target = arguments[1] || {};\n" +
|
||||||
|
" i = 2;\n" +
|
||||||
|
" }\n" +
|
||||||
|
" if (typeof target !== \"object\" && !jQuery.isFunction(target)) {\n" +
|
||||||
|
" target = {};\n" +
|
||||||
|
" }\n" +
|
||||||
|
" if (length === i) {\n" +
|
||||||
|
" target = this;\n" +
|
||||||
|
" --i;\n" +
|
||||||
|
" }\n" +
|
||||||
|
" for (; i < length; i++) {\n" +
|
||||||
|
" if ((options = arguments[i]) != null) {\n" +
|
||||||
|
" for (name in options) {\n" +
|
||||||
|
" (function _forin_body_extra_1(name) { var src = target[name];\n" +
|
||||||
|
" var copy = options[name];\n" +
|
||||||
|
" if (target === copy) {\n" +
|
||||||
|
" return; //continue;\n" +
|
||||||
|
" }\n" +
|
||||||
|
" if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))) {\n" +
|
||||||
|
" if (copyIsArray) {\n" +
|
||||||
|
" copyIsArray = false;\n" +
|
||||||
|
" clone = src && jQuery.isArray(src) ? src : [];\n" +
|
||||||
|
" } else {\n" +
|
||||||
|
" clone = src && jQuery.isPlainObject(src) ? src : {};\n" +
|
||||||
|
" }\n" +
|
||||||
|
" target[name] = jQuery.extend(deep, clone, copy);\n" +
|
||||||
|
" } else if (copy !== undefined) {\n" +
|
||||||
|
" target[name] = copy;\n" +
|
||||||
|
" } })(name);\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
" return target;\n" +
|
||||||
|
" }"}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testJquerySpecTestSourceMappings() throws IllegalArgumentException, IOException, CancelException, ClassHierarchyException {
|
||||||
|
checkFunctionBodies("jquery_spec_test.js", jquery_spec_testSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkFunctionBodies(String fileName, String[][] assertions) throws IOException, ClassHierarchyException {
|
||||||
|
Map<String, String> sources = HashMapFactory.make();
|
||||||
|
for(String[] assertion : assertions) {
|
||||||
|
sources.put(assertion[0], assertion[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
JavaScriptLoaderFactory loaders = makeLoaders();
|
||||||
|
AnalysisScope scope = makeScriptScope("tests", fileName, loaders);
|
||||||
|
IClassHierarchy cha = makeHierarchy(scope, loaders);
|
||||||
|
for(IClass cls : cha) {
|
||||||
|
if (cls.getName().toString().contains(fileName)) {
|
||||||
|
AstMethod fun = (AstMethod)cls.getMethod(AstMethodReference.fnSelector);
|
||||||
|
//System.err.println(fun.getDeclaringClass().getName() + " " + fun.getSourcePosition());
|
||||||
|
SourceBuffer sb = new SourceBuffer(fun.getSourcePosition());
|
||||||
|
//System.err.println(sb);
|
||||||
|
if (sources.containsKey(fun.getDeclaringClass().getName().toString())) {
|
||||||
|
System.err.println("checking source of " + fun.getDeclaringClass().getName() + " at " + fun.getSourcePosition());
|
||||||
|
Assert.assertEquals(sources.get(fun.getDeclaringClass().getName().toString()), sb.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -28,12 +28,12 @@ public class TestSimpleCallGraphShapeRhino extends TestSimpleCallGraphShape {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
com.ibm.wala.cast.js.ipa.callgraph.Util.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test214631() throws IOException, IllegalArgumentException, CancelException {
|
public void test214631() throws IOException, IllegalArgumentException, CancelException {
|
||||||
JSCFABuilder b = Util.makeScriptCGBuilder("tests", "214631.js");
|
JSCFABuilder b = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "214631.js");
|
||||||
b.makeCallGraph(b.getOptions());
|
b.makeCallGraph(b.getOptions());
|
||||||
PointerAnalysis PA = b.getPointerAnalysis();
|
PointerAnalysis PA = b.getPointerAnalysis();
|
||||||
// just make sure this does not crash
|
// just make sure this does not crash
|
||||||
|
@ -42,22 +42,27 @@ public class TestSimpleCallGraphShapeRhino extends TestSimpleCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRewriterDoesNotChangeLablesBug() throws IOException, IllegalArgumentException, CancelException {
|
public void testRewriterDoesNotChangeLablesBug() throws IOException, IllegalArgumentException, CancelException {
|
||||||
Util.makeScriptCG("tests", "rewrite_does_not_change_lables_bug.js");
|
JSCallGraphBuilderUtil.makeScriptCG("tests", "rewrite_does_not_change_lables_bug.js");
|
||||||
// all we need is for it to finish building CG successfully.
|
// all we need is for it to finish building CG successfully.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRepr() throws IllegalArgumentException, IOException, CancelException {
|
public void testRepr() throws IllegalArgumentException, IOException, CancelException {
|
||||||
Util.makeScriptCG("tests", "repr.js");
|
JSCallGraphBuilderUtil.makeScriptCG("tests", "repr.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTranslateToCAstCrash1() throws IllegalArgumentException, IOException, CancelException {
|
public void testTranslateToCAstCrash1() throws IllegalArgumentException, IOException, CancelException {
|
||||||
Util.makeScriptCG("tests", "rhino_crash1.js");
|
JSCallGraphBuilderUtil.makeScriptCG("tests", "rhino_crash1.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTranslateToCAstCrash2() throws IllegalArgumentException, IOException, CancelException {
|
public void testTranslateToCAstCrash2() throws IllegalArgumentException, IOException, CancelException {
|
||||||
Util.makeScriptCG("tests", "rhino_crash2.js");
|
JSCallGraphBuilderUtil.makeScriptCG("tests", "rhino_crash2.js");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTranslateToCAstCrash3() throws IllegalArgumentException, IOException, CancelException {
|
||||||
|
JSCallGraphBuilderUtil.makeScriptCG("tests", "rhino_crash3.js");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ public abstract class TestSimplePageCallGraphShapeRhino extends TestSimplePageCa
|
||||||
|
|
||||||
@Test public void testPage3() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testPage3() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/page3.html");
|
URL url = getClass().getClassLoader().getResource("pages/page3.html");
|
||||||
CallGraph CG = Util.makeHTMLCG(url);
|
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
|
||||||
verifyGraphAssertions(CG, assertionsForPage3);
|
verifyGraphAssertions(CG, assertionsForPage3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ public abstract class TestSimplePageCallGraphShapeRhino extends TestSimplePageCa
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
com.ibm.wala.cast.js.ipa.callgraph.Util.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
||||||
WebUtil.setFactory(new IHtmlParserFactory() {
|
WebUtil.setFactory(new IHtmlParserFactory() {
|
||||||
public IHtmlParser getParser() {
|
public IHtmlParser getParser() {
|
||||||
return TestSimplePageCallGraphShapeRhino.this.getParser();
|
return TestSimplePageCallGraphShapeRhino.this.getParser();
|
||||||
|
|
|
@ -15,7 +15,7 @@ public class TestSimplePageCallGraphShapeRhinoJericho extends TestSimplePageCall
|
||||||
|
|
||||||
@Test public void testCrawl() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testCrawl() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/crawl.html");
|
URL url = getClass().getClassLoader().getResource("pages/crawl.html");
|
||||||
CallGraph CG = Util.makeHTMLCG(url);
|
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
|
||||||
verifyGraphAssertions(CG, null);
|
verifyGraphAssertions(CG, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.ir.ssa.AstIRFactory;
|
||||||
import com.ibm.wala.cast.js.html.DefaultSourceExtractor;
|
import com.ibm.wala.cast.js.html.DefaultSourceExtractor;
|
||||||
import com.ibm.wala.cast.js.html.DomLessSourceExtractor;
|
import com.ibm.wala.cast.js.html.DomLessSourceExtractor;
|
||||||
import com.ibm.wala.cast.js.html.IdentityUrlResolver;
|
import com.ibm.wala.cast.js.html.IdentityUrlResolver;
|
||||||
|
@ -14,7 +15,7 @@ import com.ibm.wala.cast.js.html.WebUtil;
|
||||||
import com.ibm.wala.cast.js.html.jericho.JerichoHtmlParser;
|
import com.ibm.wala.cast.js.html.jericho.JerichoHtmlParser;
|
||||||
import com.ibm.wala.cast.js.ipa.callgraph.JSCFABuilder;
|
import com.ibm.wala.cast.js.ipa.callgraph.JSCFABuilder;
|
||||||
import com.ibm.wala.cast.js.loader.JavaScriptLoader;
|
import com.ibm.wala.cast.js.loader.JavaScriptLoader;
|
||||||
import com.ibm.wala.cast.js.test.Util;
|
import com.ibm.wala.cast.js.test.JSCallGraphBuilderUtil;
|
||||||
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
|
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
|
||||||
import com.ibm.wala.classLoader.SourceFileModule;
|
import com.ibm.wala.classLoader.SourceFileModule;
|
||||||
import com.ibm.wala.classLoader.SourceModule;
|
import com.ibm.wala.classLoader.SourceModule;
|
||||||
|
@ -23,7 +24,7 @@ import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||||
import com.ibm.wala.util.CancelException;
|
import com.ibm.wala.util.CancelException;
|
||||||
|
|
||||||
public class JsViewerDriver extends Util {
|
public class JsViewerDriver extends JSCallGraphBuilderUtil {
|
||||||
public static void main(String args[]) throws ClassHierarchyException, IllegalArgumentException, IOException, CancelException {
|
public static void main(String args[]) throws ClassHierarchyException, IllegalArgumentException, IOException, CancelException {
|
||||||
|
|
||||||
if (args.length != 1){
|
if (args.length != 1){
|
||||||
|
@ -35,12 +36,12 @@ public class JsViewerDriver extends Util {
|
||||||
URL url = new URL(args[0]);
|
URL url = new URL(args[0]);
|
||||||
|
|
||||||
// computing CG + PA
|
// computing CG + PA
|
||||||
Util.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
JSCallGraphBuilderUtil.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
||||||
JavaScriptLoader.addBootstrapFile(WebUtil.preamble);
|
JavaScriptLoader.addBootstrapFile(WebUtil.preamble);
|
||||||
|
|
||||||
SourceModule[] sources = getSources(domless, url);
|
SourceModule[] sources = getSources(domless, url);
|
||||||
|
|
||||||
JSCFABuilder builder = makeCGBuilder(new WebPageLoaderFactory(translatorFactory), sources, false, true);
|
JSCFABuilder builder = makeCGBuilder(new WebPageLoaderFactory(translatorFactory), sources, CGBuilderType.ZERO_ONE_CFA, AstIRFactory.makeDefaultFactory());
|
||||||
builder.setBaseURL(url);
|
builder.setBaseURL(url);
|
||||||
|
|
||||||
CallGraph cg = builder.makeCallGraph(builder.getOptions());
|
CallGraph cg = builder.makeCallGraph(builder.getOptions());
|
||||||
|
|
|
@ -39,9 +39,9 @@
|
||||||
<target name="fetchRhino" depends="RhinoPresent" unless="rhino.present">
|
<target name="fetchRhino" depends="RhinoPresent" unless="rhino.present">
|
||||||
<delete dir="${temp.folder}"/>
|
<delete dir="${temp.folder}"/>
|
||||||
<mkdir dir="${temp.folder}"/>
|
<mkdir dir="${temp.folder}"/>
|
||||||
<get src="ftp://ftp.mozilla.org/pub/mozilla.org/js/rhino1_7R2.zip" dest="${temp.folder}/rhino1_7R2.zip" />
|
<get src="http://ftp.mozilla.org/pub/mozilla.org/js/rhino1_7R3.zip" dest="${temp.folder}/rhino1_7R3.zip" />
|
||||||
<unzip src="${temp.folder}/rhino1_7R2.zip" dest="${temp.folder}"/>
|
<unzip src="${temp.folder}/rhino1_7R3.zip" dest="${temp.folder}"/>
|
||||||
<copy file="${temp.folder}/rhino1_7R2/js.jar" tofile="${plugin.destination}/lib/js.jar" />
|
<copy file="${temp.folder}/rhino1_7R3/js.jar" tofile="${plugin.destination}/lib/js.jar" />
|
||||||
<delete dir="${temp.folder}"/>
|
<delete dir="${temp.folder}"/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
|
|
@ -14,14 +14,9 @@ import java.io.IOException;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.mozilla.javascript.RhinoToAstTranslator;
|
|
||||||
|
|
||||||
import com.ibm.wala.cast.ir.translator.TranslatorToCAst;
|
import com.ibm.wala.cast.ir.translator.TranslatorToCAst;
|
||||||
import com.ibm.wala.cast.js.translator.PropertyReadExpander.ExpanderKey;
|
|
||||||
import com.ibm.wala.cast.tree.CAst;
|
|
||||||
import com.ibm.wala.cast.tree.CAstEntity;
|
import com.ibm.wala.cast.tree.CAstEntity;
|
||||||
import com.ibm.wala.cast.tree.impl.CAstImpl;
|
import com.ibm.wala.cast.tree.impl.CAstImpl;
|
||||||
import com.ibm.wala.cast.tree.impl.CAstRewriter;
|
|
||||||
import com.ibm.wala.cast.tree.impl.CAstRewriter.CopyKey;
|
import com.ibm.wala.cast.tree.impl.CAstRewriter.CopyKey;
|
||||||
import com.ibm.wala.cast.tree.impl.CAstRewriter.RewriteContext;
|
import com.ibm.wala.cast.tree.impl.CAstRewriter.RewriteContext;
|
||||||
import com.ibm.wala.cast.tree.impl.CAstRewriterFactory;
|
import com.ibm.wala.cast.tree.impl.CAstRewriterFactory;
|
||||||
|
@ -31,14 +26,11 @@ import com.ibm.wala.classLoader.SourceModule;
|
||||||
public class CAstRhinoTranslator implements TranslatorToCAst {
|
public class CAstRhinoTranslator implements TranslatorToCAst {
|
||||||
private final List<CAstRewriterFactory> rewriters = new LinkedList<CAstRewriterFactory>();
|
private final List<CAstRewriterFactory> rewriters = new LinkedList<CAstRewriterFactory>();
|
||||||
private final SourceModule M;
|
private final SourceModule M;
|
||||||
|
private final boolean replicateForDoLoops;
|
||||||
|
|
||||||
public CAstRhinoTranslator(SourceModule M) {
|
public CAstRhinoTranslator(SourceModule M, boolean replicateForDoLoops) {
|
||||||
this.M = M;
|
this.M = M;
|
||||||
this.addRewriter(new CAstRewriterFactory<PropertyReadExpander.RewriteContext, ExpanderKey>() {
|
this.replicateForDoLoops = replicateForDoLoops;
|
||||||
public CAstRewriter<PropertyReadExpander.RewriteContext, ExpanderKey> createCAstRewriter(CAst ast) {
|
|
||||||
return new PropertyReadExpander(ast);
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <C extends RewriteContext<K>, K extends CopyKey<K>> void addRewriter(CAstRewriterFactory<C, K> factory, boolean prepend) {
|
public <C extends RewriteContext<K>, K extends CopyKey<K>> void addRewriter(CAstRewriterFactory<C, K> factory, boolean prepend) {
|
||||||
|
@ -57,9 +49,10 @@ public class CAstRhinoTranslator implements TranslatorToCAst {
|
||||||
}
|
}
|
||||||
|
|
||||||
CAstImpl Ast = new CAstImpl();
|
CAstImpl Ast = new CAstImpl();
|
||||||
CAstEntity entity = new RhinoToAstTranslator(Ast, M, N).translate();
|
CAstEntity entity = new RhinoToAstTranslator(Ast, M, N, replicateForDoLoops).translateToCAst();
|
||||||
for(CAstRewriterFactory rwf : rewriters)
|
for(CAstRewriterFactory rwf : rewriters)
|
||||||
entity = rwf.createCAstRewriter(Ast).rewrite(entity);
|
entity = rwf.createCAstRewriter(Ast).rewrite(entity);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import com.ibm.wala.classLoader.SourceModule;
|
||||||
public class CAstRhinoTranslatorFactory implements JavaScriptTranslatorFactory {
|
public class CAstRhinoTranslatorFactory implements JavaScriptTranslatorFactory {
|
||||||
|
|
||||||
public TranslatorToCAst make(CAst ast, SourceModule M) {
|
public TranslatorToCAst make(CAst ast, SourceModule M) {
|
||||||
return new CAstRhinoTranslator(M);
|
return new CAstRhinoTranslator(M, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,303 @@
|
||||||
|
package com.ibm.wala.cast.js.translator;
|
||||||
|
|
||||||
|
import org.mozilla.javascript.ast.ArrayComprehension;
|
||||||
|
import org.mozilla.javascript.ast.ArrayComprehensionLoop;
|
||||||
|
import org.mozilla.javascript.ast.ArrayLiteral;
|
||||||
|
import org.mozilla.javascript.ast.Assignment;
|
||||||
|
import org.mozilla.javascript.ast.AstNode;
|
||||||
|
import org.mozilla.javascript.ast.AstRoot;
|
||||||
|
import org.mozilla.javascript.ast.Block;
|
||||||
|
import org.mozilla.javascript.ast.BreakStatement;
|
||||||
|
import org.mozilla.javascript.ast.CatchClause;
|
||||||
|
import org.mozilla.javascript.ast.Comment;
|
||||||
|
import org.mozilla.javascript.ast.ConditionalExpression;
|
||||||
|
import org.mozilla.javascript.ast.ContinueStatement;
|
||||||
|
import org.mozilla.javascript.ast.DoLoop;
|
||||||
|
import org.mozilla.javascript.ast.ElementGet;
|
||||||
|
import org.mozilla.javascript.ast.EmptyExpression;
|
||||||
|
import org.mozilla.javascript.ast.ErrorNode;
|
||||||
|
import org.mozilla.javascript.ast.ExpressionStatement;
|
||||||
|
import org.mozilla.javascript.ast.ForInLoop;
|
||||||
|
import org.mozilla.javascript.ast.ForLoop;
|
||||||
|
import org.mozilla.javascript.ast.FunctionCall;
|
||||||
|
import org.mozilla.javascript.ast.FunctionNode;
|
||||||
|
import org.mozilla.javascript.ast.IfStatement;
|
||||||
|
import org.mozilla.javascript.ast.InfixExpression;
|
||||||
|
import org.mozilla.javascript.ast.Jump;
|
||||||
|
import org.mozilla.javascript.ast.KeywordLiteral;
|
||||||
|
import org.mozilla.javascript.ast.Label;
|
||||||
|
import org.mozilla.javascript.ast.LabeledStatement;
|
||||||
|
import org.mozilla.javascript.ast.LetNode;
|
||||||
|
import org.mozilla.javascript.ast.Name;
|
||||||
|
import org.mozilla.javascript.ast.NewExpression;
|
||||||
|
import org.mozilla.javascript.ast.NumberLiteral;
|
||||||
|
import org.mozilla.javascript.ast.ObjectLiteral;
|
||||||
|
import org.mozilla.javascript.ast.ObjectProperty;
|
||||||
|
import org.mozilla.javascript.ast.ParenthesizedExpression;
|
||||||
|
import org.mozilla.javascript.ast.PropertyGet;
|
||||||
|
import org.mozilla.javascript.ast.RegExpLiteral;
|
||||||
|
import org.mozilla.javascript.ast.ReturnStatement;
|
||||||
|
import org.mozilla.javascript.ast.Scope;
|
||||||
|
import org.mozilla.javascript.ast.ScriptNode;
|
||||||
|
import org.mozilla.javascript.ast.StringLiteral;
|
||||||
|
import org.mozilla.javascript.ast.SwitchCase;
|
||||||
|
import org.mozilla.javascript.ast.SwitchStatement;
|
||||||
|
import org.mozilla.javascript.ast.Symbol;
|
||||||
|
import org.mozilla.javascript.ast.ThrowStatement;
|
||||||
|
import org.mozilla.javascript.ast.TryStatement;
|
||||||
|
import org.mozilla.javascript.ast.UnaryExpression;
|
||||||
|
import org.mozilla.javascript.ast.VariableDeclaration;
|
||||||
|
import org.mozilla.javascript.ast.VariableInitializer;
|
||||||
|
import org.mozilla.javascript.ast.WhileLoop;
|
||||||
|
import org.mozilla.javascript.ast.WithStatement;
|
||||||
|
import org.mozilla.javascript.ast.XmlDotQuery;
|
||||||
|
import org.mozilla.javascript.ast.XmlElemRef;
|
||||||
|
import org.mozilla.javascript.ast.XmlExpression;
|
||||||
|
import org.mozilla.javascript.ast.XmlFragment;
|
||||||
|
import org.mozilla.javascript.ast.XmlLiteral;
|
||||||
|
import org.mozilla.javascript.ast.XmlMemberGet;
|
||||||
|
import org.mozilla.javascript.ast.XmlPropRef;
|
||||||
|
import org.mozilla.javascript.ast.XmlRef;
|
||||||
|
import org.mozilla.javascript.ast.XmlString;
|
||||||
|
import org.mozilla.javascript.ast.Yield;
|
||||||
|
|
||||||
|
public abstract class TypedNodeVisitor<R,A> {
|
||||||
|
|
||||||
|
public R visit(AstNode node, A arg) {
|
||||||
|
if (node instanceof ArrayComprehension) {
|
||||||
|
return visitArrayComprehension((ArrayComprehension) node, arg);
|
||||||
|
} else if (node instanceof WhileLoop) {
|
||||||
|
return visitWhileLoop((WhileLoop) node, arg);
|
||||||
|
} else if (node instanceof ArrayComprehensionLoop) {
|
||||||
|
return visitArrayComprehensionLoop((ArrayComprehensionLoop) node, arg);
|
||||||
|
} else if (node instanceof ArrayLiteral) {
|
||||||
|
return visitArrayLiteral((ArrayLiteral) node, arg);
|
||||||
|
} else if (node instanceof Assignment) {
|
||||||
|
return visitAssignment((Assignment) node, arg);
|
||||||
|
} else if (node instanceof AstRoot) {
|
||||||
|
return visitAstRoot((AstRoot) node, arg);
|
||||||
|
} else if (node instanceof Block) {
|
||||||
|
return visitBlock((Block) node, arg);
|
||||||
|
} else if (node instanceof BreakStatement) {
|
||||||
|
return visitBreakStatement((BreakStatement) node, arg);
|
||||||
|
} else if (node instanceof CatchClause) {
|
||||||
|
return visitCatchClause((CatchClause) node, arg);
|
||||||
|
} else if (node instanceof Comment) {
|
||||||
|
return visitComment((Comment) node, arg);
|
||||||
|
} else if (node instanceof ConditionalExpression) {
|
||||||
|
return visitConditionalExpression((ConditionalExpression) node, arg);
|
||||||
|
} else if (node instanceof ContinueStatement) {
|
||||||
|
return visitContinueStatement((ContinueStatement) node, arg);
|
||||||
|
} else if (node instanceof DoLoop) {
|
||||||
|
return visitDoLoop((DoLoop) node, arg);
|
||||||
|
} else if (node instanceof ElementGet) {
|
||||||
|
return visitElementGet((ElementGet) node, arg);
|
||||||
|
} else if (node instanceof EmptyExpression) {
|
||||||
|
return visitEmptyExpression((EmptyExpression) node, arg);
|
||||||
|
} else if (node instanceof ErrorNode) {
|
||||||
|
return visitErrorNode((ErrorNode) node, arg);
|
||||||
|
} else if (node instanceof ExpressionStatement) {
|
||||||
|
return visitExpressionStatement((ExpressionStatement) node, arg);
|
||||||
|
} else if (node instanceof ForInLoop) {
|
||||||
|
return visitForInLoop((ForInLoop) node, arg);
|
||||||
|
} else if (node instanceof ForLoop) {
|
||||||
|
return visitForLoop((ForLoop) node, arg);
|
||||||
|
} else if (node instanceof NewExpression) {
|
||||||
|
return visitNewExpression((NewExpression) node, arg);
|
||||||
|
} else if (node instanceof FunctionCall) {
|
||||||
|
return visitFunctionCall((FunctionCall) node, arg);
|
||||||
|
} else if (node instanceof FunctionNode) {
|
||||||
|
return visitFunctionNode((FunctionNode) node, arg);
|
||||||
|
} else if (node instanceof IfStatement) {
|
||||||
|
return visitIfStatement((IfStatement) node, arg);
|
||||||
|
} else if (node instanceof KeywordLiteral) {
|
||||||
|
return visitKeywordLiteral((KeywordLiteral) node, arg);
|
||||||
|
} else if (node instanceof Label) {
|
||||||
|
return visitLabel((Label) node, arg);
|
||||||
|
} else if (node instanceof LabeledStatement) {
|
||||||
|
return visitLabeledStatement((LabeledStatement) node, arg);
|
||||||
|
} else if (node instanceof LetNode) {
|
||||||
|
return visitLetNode((LetNode) node, arg);
|
||||||
|
} else if (node instanceof Name) {
|
||||||
|
return visitName((Name) node, arg);
|
||||||
|
} else if (node instanceof NumberLiteral) {
|
||||||
|
return visitNumberLiteral((NumberLiteral) node, arg);
|
||||||
|
} else if (node instanceof ObjectLiteral) {
|
||||||
|
return visitObjectLiteral((ObjectLiteral) node, arg);
|
||||||
|
} else if (node instanceof ObjectProperty) {
|
||||||
|
return visitObjectProperty((ObjectProperty) node, arg);
|
||||||
|
} else if (node instanceof ParenthesizedExpression) {
|
||||||
|
return visitParenthesizedExpression((ParenthesizedExpression) node, arg);
|
||||||
|
} else if (node instanceof PropertyGet) {
|
||||||
|
return visitPropertyGet((PropertyGet) node, arg);
|
||||||
|
} else if (node instanceof RegExpLiteral) {
|
||||||
|
return visitRegExpLiteral((RegExpLiteral) node, arg);
|
||||||
|
} else if (node instanceof ReturnStatement) {
|
||||||
|
return visitReturnStatement((ReturnStatement) node, arg);
|
||||||
|
} else if (node instanceof Scope) {
|
||||||
|
return visitScope((Scope) node, arg);
|
||||||
|
} else if (node instanceof ScriptNode) {
|
||||||
|
return visitScriptNode((ScriptNode) node, arg);
|
||||||
|
} else if (node instanceof StringLiteral) {
|
||||||
|
return visitStringLiteral((StringLiteral) node, arg);
|
||||||
|
} else if (node instanceof SwitchCase) {
|
||||||
|
return visitSwitchCase((SwitchCase) node, arg);
|
||||||
|
} else if (node instanceof SwitchStatement) {
|
||||||
|
return visitSwitchStatement((SwitchStatement) node, arg);
|
||||||
|
} else if (node instanceof ThrowStatement) {
|
||||||
|
return visitThrowStatement((ThrowStatement) node, arg);
|
||||||
|
} else if (node instanceof TryStatement) {
|
||||||
|
return visitTryStatement((TryStatement) node, arg);
|
||||||
|
} else if (node instanceof UnaryExpression) {
|
||||||
|
return visitUnaryExpression((UnaryExpression) node, arg);
|
||||||
|
} else if (node instanceof VariableDeclaration) {
|
||||||
|
return visitVariableDeclaration((VariableDeclaration) node, arg);
|
||||||
|
} else if (node instanceof VariableInitializer) {
|
||||||
|
return visitVariableInitializer((VariableInitializer) node, arg);
|
||||||
|
} else if (node instanceof WithStatement) {
|
||||||
|
return visitWithStatement((WithStatement) node, arg);
|
||||||
|
} else if (node instanceof XmlDotQuery) {
|
||||||
|
return visitXmlDotQuery((XmlDotQuery) node, arg);
|
||||||
|
} else if (node instanceof XmlElemRef) {
|
||||||
|
return visitXmlElemRef((XmlElemRef) node, arg);
|
||||||
|
} else if (node instanceof XmlExpression) {
|
||||||
|
return visitXmlExpression((XmlExpression) node, arg);
|
||||||
|
} else if (node instanceof XmlLiteral) {
|
||||||
|
return visitXmlLiteral((XmlLiteral) node, arg);
|
||||||
|
} else if (node instanceof XmlMemberGet) {
|
||||||
|
return visitXmlMemberGet((XmlMemberGet) node, arg);
|
||||||
|
} else if (node instanceof XmlPropRef) {
|
||||||
|
return visitXmlPropRef((XmlPropRef) node, arg);
|
||||||
|
} else if (node instanceof XmlString) {
|
||||||
|
return visitXmlString((XmlString) node, arg);
|
||||||
|
} else if (node instanceof Yield) {
|
||||||
|
return visitYield((Yield) node, arg);
|
||||||
|
} else if (node instanceof InfixExpression) {
|
||||||
|
return visitInfixExpression((InfixExpression) node, arg);
|
||||||
|
} else if (node instanceof Jump) {
|
||||||
|
return visitJump((Jump) node, arg);
|
||||||
|
} else {
|
||||||
|
throw new Error("unexpected node type " + node.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R visitArrayComprehension(ArrayComprehension node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitArrayComprehensionLoop(ArrayComprehensionLoop node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitArrayLiteral(ArrayLiteral node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitAssignment(Assignment node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitAstRoot(AstRoot node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitBlock(Block node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitBreakStatement(BreakStatement node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitCatchClause(CatchClause node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitComment(Comment node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitConditionalExpression(ConditionalExpression node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitContinueStatement(ContinueStatement node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitDoLoop(DoLoop node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitElementGet(ElementGet node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitEmptyExpression(EmptyExpression node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitErrorNode(ErrorNode node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitExpressionStatement(ExpressionStatement node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitForInLoop(ForInLoop node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitForLoop(ForLoop node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitFunctionCall(FunctionCall node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitFunctionNode(FunctionNode node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitIfStatement(IfStatement node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitInfixExpression(InfixExpression node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitJump(Jump node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitKeywordLiteral(KeywordLiteral node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitLabel(Label node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitLabeledStatement(LabeledStatement node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitLetNode(LetNode node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitName(Name node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitNewExpression(NewExpression node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitNumberLiteral(NumberLiteral node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitObjectLiteral(ObjectLiteral node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitObjectProperty(ObjectProperty node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitParenthesizedExpression(ParenthesizedExpression node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitPropertyGet(PropertyGet node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitRegExpLiteral(RegExpLiteral node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitReturnStatement(ReturnStatement node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitScope(Scope node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitScriptNode(ScriptNode node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitStringLiteral(StringLiteral node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitSwitchCase(SwitchCase node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitSwitchStatement(SwitchStatement node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitSymbol(Symbol node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitThrowStatement(ThrowStatement node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitTryStatement(TryStatement node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitUnaryExpression(UnaryExpression node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitVariableDeclaration(VariableDeclaration node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitVariableInitializer(VariableInitializer node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitWhileLoop(WhileLoop node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitWithStatement(WithStatement node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitXmlDotQuery(XmlDotQuery node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitXmlElemRef(XmlElemRef node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitXmlExpression(XmlExpression node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitXmlFragment(XmlFragment node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitXmlLiteral(XmlLiteral node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitXmlMemberGet(XmlMemberGet node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitXmlPropRef(XmlPropRef node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitXmlRef(XmlRef node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitXmlString(XmlString node, A arg) ;
|
||||||
|
|
||||||
|
public abstract R visitYield(Yield node, A arg) ;
|
||||||
|
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,16 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(document).ready(function(){
|
||||||
|
$("button").click(function(){
|
||||||
|
$(this).hide();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<button>Click me</button>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,28 @@
|
||||||
|
|
||||||
|
function a() {
|
||||||
|
if (arguments.length >= 1) {
|
||||||
|
arguments[0]();
|
||||||
|
if (arguments.length >= 2) {
|
||||||
|
arguments[1]();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function x() {
|
||||||
|
print("x");
|
||||||
|
}
|
||||||
|
|
||||||
|
function y() {
|
||||||
|
print("y");
|
||||||
|
}
|
||||||
|
|
||||||
|
function z() {
|
||||||
|
print("z");
|
||||||
|
}
|
||||||
|
|
||||||
|
function wrong() {
|
||||||
|
print("wrong");
|
||||||
|
}
|
||||||
|
|
||||||
|
a(x);
|
||||||
|
a(y, z, wrong);
|
|
@ -1,5 +1,6 @@
|
||||||
function f() {
|
function f() {
|
||||||
arguments[0].g();
|
for(var p in arguments)
|
||||||
|
arguments[p].g();
|
||||||
}
|
}
|
||||||
f.g = function g1() {};
|
f.g = function g1() {};
|
||||||
|
|
||||||
|
@ -12,4 +13,10 @@ var oo = {
|
||||||
g: function g3() { }
|
g: function g3() { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// at the IR level, this call has three arguments: (1) the function object for f, (2) o, (3), oo
|
||||||
|
// however, only the last one ends up in the arguments array
|
||||||
o.f(oo);
|
o.f(oo);
|
||||||
|
|
||||||
|
// make g1 and g2 reachable so we can check assertions
|
||||||
|
f.g();
|
||||||
|
o.g();
|
|
@ -0,0 +1,21 @@
|
||||||
|
function copyObjRec(to, from) {
|
||||||
|
|
||||||
|
for (var p in from) {
|
||||||
|
(function _forin_body(name) {
|
||||||
|
to[name] = from[name];
|
||||||
|
copyObjRec(to,from[name]);
|
||||||
|
})(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var obj = {
|
||||||
|
foo: function testForIn1() { return 7; },
|
||||||
|
bar: function testForIn2() { return "whatever"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.baz = obj;
|
||||||
|
|
||||||
|
var copy = new Object();
|
||||||
|
|
||||||
|
copyObjRec(copy, obj);
|
|
@ -0,0 +1,33 @@
|
||||||
|
var left = {
|
||||||
|
|
||||||
|
inner: function left_inner(x) {
|
||||||
|
return x+1;
|
||||||
|
},
|
||||||
|
|
||||||
|
outer: function left_outer(x) {
|
||||||
|
return this.inner(x+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
var right = {
|
||||||
|
|
||||||
|
inner: function right_inner(x) {
|
||||||
|
return Math.abs(x);
|
||||||
|
},
|
||||||
|
|
||||||
|
outer: function right_outer(x) {
|
||||||
|
return this.inner(-x);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
var x = 3;
|
||||||
|
if (x > Math.random()) {
|
||||||
|
x = left;
|
||||||
|
} else {
|
||||||
|
x = right;
|
||||||
|
}
|
||||||
|
|
||||||
|
x.outer(7);
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
|
|
||||||
|
|
||||||
function() {
|
(function(x) {
|
||||||
switch(0) {
|
switch(x) {
|
||||||
case Ext.Date:
|
case Ext.Date:
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
return -1;
|
||||||
|
})(0);
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,10 @@
|
||||||
|
function foo(x) {
|
||||||
|
function bar() {
|
||||||
|
x = function i_am_reachable() {}
|
||||||
|
}
|
||||||
|
bar();
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
var y = foo(null);
|
||||||
|
y();
|
|
@ -44,3 +44,7 @@ var foo = strObj.toLowerCase();
|
||||||
var whatnot = [ , , , 7, numObj, arg2, strObj ];
|
var whatnot = [ , , , 7, numObj, arg2, strObj ];
|
||||||
|
|
||||||
whatnot[ 5 ].otherMethod( 7 );
|
whatnot[ 5 ].otherMethod( 7 );
|
||||||
|
|
||||||
|
delete arg2.bar();
|
||||||
|
delete whatnot[ 5 ];
|
||||||
|
delete arg2;
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
function f() {
|
||||||
|
switch (0) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
oParsedResponse || 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
f();
|
|
@ -0,0 +1,10 @@
|
||||||
|
function f() {
|
||||||
|
switch (0) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
oParsedResponse || 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
f();
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
function foo() {
|
||||||
|
function baz() {
|
||||||
|
return function f1() {};
|
||||||
|
}
|
||||||
|
function boo() {
|
||||||
|
baz = function biz() { return function i_am_reachable() {}; }
|
||||||
|
}
|
||||||
|
boo();
|
||||||
|
return baz();
|
||||||
|
}
|
||||||
|
|
||||||
|
var x = foo();
|
||||||
|
x();
|
|
@ -11,6 +11,11 @@
|
||||||
|
|
||||||
package com.ibm.wala.cast.js.test;
|
package com.ibm.wala.cast.js.test;
|
||||||
|
|
||||||
|
import static com.ibm.wala.cast.tree.CAstNode.ASSIGN;
|
||||||
|
import static com.ibm.wala.cast.tree.CAstNode.BLOCK_EXPR;
|
||||||
|
import static com.ibm.wala.cast.tree.CAstNode.BLOCK_STMT;
|
||||||
|
import static com.ibm.wala.cast.tree.CAstNode.EMPTY;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -38,6 +43,7 @@ import com.ibm.wala.util.collections.HashMapFactory;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class CAstDumper {
|
public class CAstDumper {
|
||||||
|
private static final boolean NORMALISE = false;
|
||||||
private final NodeLabeller labeller;
|
private final NodeLabeller labeller;
|
||||||
|
|
||||||
public CAstDumper() {
|
public CAstDumper() {
|
||||||
|
@ -112,10 +118,37 @@ public class CAstDumper {
|
||||||
return scopedEntities;
|
return scopedEntities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isTrivial(CAstNode node) {
|
||||||
|
switch(node.getKind()) {
|
||||||
|
case ASSIGN:
|
||||||
|
return node.getChild(0).getKind() == CAstNode.VAR && isTrivial(node.getChild(1));
|
||||||
|
case EMPTY:
|
||||||
|
return true;
|
||||||
|
case BLOCK_EXPR:
|
||||||
|
case BLOCK_STMT:
|
||||||
|
return getNonTrivialChildCount(node) == 0;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getNonTrivialChildCount(CAstNode node) {
|
||||||
|
int cnt = 0;
|
||||||
|
for(int i=0;i<node.getChildCount();++i)
|
||||||
|
if(!isTrivial(node.getChild(i)))
|
||||||
|
++cnt;
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
private void dump(CAstNode node, int indent, StringBuilder buf, CAstControlFlowMap cfg) {
|
private void dump(CAstNode node, int indent, StringBuilder buf, CAstControlFlowMap cfg) {
|
||||||
|
if(isTrivial(node))
|
||||||
|
return;
|
||||||
// normalise away single-child block expressions
|
// normalise away single-child block expressions
|
||||||
if(node.getKind() == CAstNode.BLOCK_EXPR && node.getChildCount() == 1) {
|
if(NORMALISE && node.getKind() == CAstNode.BLOCK_EXPR && getNonTrivialChildCount(node) == 1) {
|
||||||
dump(node.getChild(0), indent, buf, cfg);
|
for(int i=0;i<node.getChildCount();++i)
|
||||||
|
if(!isTrivial(node.getChild(i)))
|
||||||
|
dump(node.getChild(i), indent, buf, cfg);
|
||||||
} else {
|
} else {
|
||||||
buf.append(indent(indent) + labeller.addNode(node) + ": ");
|
buf.append(indent(indent) + labeller.addNode(node) + ": ");
|
||||||
if(node.getKind() == CAstNode.CONSTANT) {
|
if(node.getKind() == CAstNode.CONSTANT) {
|
||||||
|
@ -153,7 +186,7 @@ public class CAstDumper {
|
||||||
for(int i=0;i<node.getChildCount();++i) {
|
for(int i=0;i<node.getChildCount();++i) {
|
||||||
CAstNode child = node.getChild(i);
|
CAstNode child = node.getChild(i);
|
||||||
// omit empty statements in a block
|
// omit empty statements in a block
|
||||||
if(node.getKind() == CAstNode.BLOCK_STMT && child != null && child.getKind() == CAstNode.EMPTY)
|
if(NORMALISE && node.getKind() == CAstNode.BLOCK_STMT && child != null && child.getKind() == CAstNode.EMPTY)
|
||||||
continue;
|
continue;
|
||||||
dump(child, indent+2, buf, cfg);
|
dump(child, indent+2, buf, cfg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import junit.framework.Assert;
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.ir.ssa.AstIRFactory;
|
||||||
import com.ibm.wala.cast.js.html.MappedSourceModule;
|
import com.ibm.wala.cast.js.html.MappedSourceModule;
|
||||||
import com.ibm.wala.cast.js.html.WebPageLoaderFactory;
|
import com.ibm.wala.cast.js.html.WebPageLoaderFactory;
|
||||||
import com.ibm.wala.cast.js.html.WebUtil;
|
import com.ibm.wala.cast.js.html.WebUtil;
|
||||||
|
@ -36,19 +37,55 @@ import com.ibm.wala.ipa.callgraph.propagation.PropagationCallGraphBuilder;
|
||||||
import com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroXInstanceKeys;
|
import com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroXInstanceKeys;
|
||||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||||
|
import com.ibm.wala.ssa.IRFactory;
|
||||||
import com.ibm.wala.util.CancelException;
|
import com.ibm.wala.util.CancelException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO this class is a mess. rewrite.
|
* TODO this class is a mess. rewrite.
|
||||||
*/
|
*/
|
||||||
public class Util extends com.ibm.wala.cast.js.ipa.callgraph.Util {
|
public class JSCallGraphBuilderUtil extends com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil {
|
||||||
|
|
||||||
public static JSCFABuilder makeScriptCGBuilder(String dir, String name, boolean useOneCFA) throws IOException {
|
public static enum CGBuilderType {
|
||||||
JavaScriptLoaderFactory loaders = Util.makeLoaders();
|
ZERO_ONE_CFA(false, false, true), ZERO_ONE_CFA_NO_CALL_APPLY(false, false, false), ZERO_ONE_CFA_PRECISE_LEXICAL(false, true,
|
||||||
|
true), ONE_CFA(true, false, true), ONE_CFA_PRECISE_LEXICAL(true, true, true);
|
||||||
|
|
||||||
URL script = Util.class.getClassLoader().getResource(dir + File.separator + name);
|
private final boolean useOneCFA;
|
||||||
|
|
||||||
|
private final boolean usePreciseLexical;
|
||||||
|
|
||||||
|
private final boolean handleCallApply;
|
||||||
|
|
||||||
|
private CGBuilderType(boolean useOneCFA, boolean usePreciseLexical, boolean handleCallApply) {
|
||||||
|
this.useOneCFA = useOneCFA;
|
||||||
|
this.usePreciseLexical = usePreciseLexical;
|
||||||
|
this.handleCallApply = handleCallApply;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean useOneCFA() {
|
||||||
|
return useOneCFA;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean usePreciseLexical() {
|
||||||
|
return usePreciseLexical;
|
||||||
|
}
|
||||||
|
public boolean handleCallApply() {
|
||||||
|
return handleCallApply;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSCFABuilder makeScriptCGBuilder(String dir, String name, CGBuilderType builderType) throws IOException {
|
||||||
|
JavaScriptLoaderFactory loaders = JSCallGraphBuilderUtil.makeLoaders();
|
||||||
|
|
||||||
|
AnalysisScope scope = makeScriptScope(dir, name, loaders);
|
||||||
|
|
||||||
|
return makeCG(loaders, scope, builderType, AstIRFactory.makeDefaultFactory());
|
||||||
|
}
|
||||||
|
|
||||||
|
static AnalysisScope makeScriptScope(String dir, String name, JavaScriptLoaderFactory loaders) throws IOException {
|
||||||
|
URL script = JSCallGraphBuilderUtil.class.getClassLoader().getResource(dir + File.separator + name);
|
||||||
if (script == null) {
|
if (script == null) {
|
||||||
script = Util.class.getClassLoader().getResource(dir + "/" + name);
|
script = JSCallGraphBuilderUtil.class.getClassLoader().getResource(dir + "/" + name);
|
||||||
}
|
}
|
||||||
assert script != null : "cannot find " + dir + " and " + name;
|
assert script != null : "cannot find " + dir + " and " + name;
|
||||||
|
|
||||||
|
@ -59,40 +96,41 @@ public class Util extends com.ibm.wala.cast.js.ipa.callgraph.Util {
|
||||||
scope = makeScope(new SourceFileModule[] { makeSourceModule(script, dir, name) }, loaders, JavaScriptLoader.JS);
|
scope = makeScope(new SourceFileModule[] { makeSourceModule(script, dir, name) }, loaders, JavaScriptLoader.JS);
|
||||||
}
|
}
|
||||||
|
|
||||||
return makeCG(loaders, scope, useOneCFA, true);
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JSCFABuilder makeScriptCGBuilder(String dir, String name) throws IOException {
|
public static JSCFABuilder makeScriptCGBuilder(String dir, String name) throws IOException {
|
||||||
return makeScriptCGBuilder(dir, name, false);
|
return makeScriptCGBuilder(dir, name, CGBuilderType.ZERO_ONE_CFA);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CallGraph makeScriptCG(String dir, String name) throws IOException, IllegalArgumentException, CancelException {
|
public static CallGraph makeScriptCG(String dir, String name) throws IOException, IllegalArgumentException, CancelException {
|
||||||
return makeScriptCG(dir, name, false);
|
return makeScriptCG(dir, name, CGBuilderType.ZERO_ONE_CFA);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CallGraph makeScriptCG(String dir, String name, boolean useOneCFA) throws IOException, IllegalArgumentException,
|
public static CallGraph makeScriptCG(String dir, String name, CGBuilderType builderType) throws IOException,
|
||||||
CancelException {
|
IllegalArgumentException, CancelException {
|
||||||
PropagationCallGraphBuilder b = makeScriptCGBuilder(dir, name, useOneCFA);
|
PropagationCallGraphBuilder b = makeScriptCGBuilder(dir, name, builderType);
|
||||||
CallGraph CG = b.makeCallGraph(b.getOptions());
|
CallGraph CG = b.makeCallGraph(b.getOptions());
|
||||||
dumpCG(b.getPointerAnalysis(), CG);
|
// dumpCG(b.getPointerAnalysis(), CG);
|
||||||
return CG;
|
return CG;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CallGraph makeScriptCG(SourceModule[] scripts, boolean useOneCFA) throws IOException, IllegalArgumentException,
|
public static CallGraph makeScriptCG(SourceModule[] scripts, CGBuilderType builderType, IRFactory irFactory) throws IOException, IllegalArgumentException,
|
||||||
CancelException {
|
CancelException {
|
||||||
PropagationCallGraphBuilder b = makeCGBuilder(makeLoaders(), scripts, useOneCFA, true);
|
PropagationCallGraphBuilder b = makeCGBuilder(makeLoaders(), scripts, builderType, irFactory);
|
||||||
CallGraph CG = b.makeCallGraph(b.getOptions());
|
CallGraph CG = b.makeCallGraph(b.getOptions());
|
||||||
dumpCG(b.getPointerAnalysis(), CG);
|
// dumpCG(b.getPointerAnalysis(), CG);
|
||||||
return CG;
|
return CG;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JSCFABuilder makeHTMLCGBuilder(URL url) throws IOException {
|
public static JSCFABuilder makeHTMLCGBuilder(URL url) throws IOException {
|
||||||
return makeHTMLCGBuilder(url, true);
|
return makeHTMLCGBuilder(url, CGBuilderType.ZERO_ONE_CFA);
|
||||||
}
|
}
|
||||||
public static JSCFABuilder makeHTMLCGBuilder(URL url, boolean handleCallApply) throws IOException {
|
|
||||||
|
public static JSCFABuilder makeHTMLCGBuilder(URL url, CGBuilderType builderType) throws IOException {
|
||||||
JavaScriptLoader.addBootstrapFile(WebUtil.preamble);
|
JavaScriptLoader.addBootstrapFile(WebUtil.preamble);
|
||||||
Set<MappedSourceModule> script = WebUtil.extractScriptFromHTML(url);
|
Set<MappedSourceModule> script = WebUtil.extractScriptFromHTML(url);
|
||||||
JSCFABuilder builder = makeCGBuilder(new WebPageLoaderFactory(translatorFactory, preprocessor), script.toArray(new SourceModule[script.size()]), false, handleCallApply);
|
JSCFABuilder builder = makeCGBuilder(new WebPageLoaderFactory(translatorFactory, preprocessor), script.toArray(new SourceModule[script.size()]), builderType, AstIRFactory.makeDefaultFactory());
|
||||||
builder.setBaseURL(url);
|
builder.setBaseURL(url);
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
@ -100,32 +138,33 @@ public class Util extends com.ibm.wala.cast.js.ipa.callgraph.Util {
|
||||||
public static CallGraph makeHTMLCG(URL url) throws IOException, IllegalArgumentException, CancelException {
|
public static CallGraph makeHTMLCG(URL url) throws IOException, IllegalArgumentException, CancelException {
|
||||||
PropagationCallGraphBuilder b = makeHTMLCGBuilder(url);
|
PropagationCallGraphBuilder b = makeHTMLCGBuilder(url);
|
||||||
CallGraph CG = b.makeCallGraph(b.getOptions());
|
CallGraph CG = b.makeCallGraph(b.getOptions());
|
||||||
//dumpCG(b.getPointerAnalysis(), CG);
|
dumpCG(b.getPointerAnalysis(), CG);
|
||||||
return CG;
|
return CG;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CallGraph makeHTMLCG(URL url, boolean handleCallApply) throws IOException, IllegalArgumentException,
|
public static CallGraph makeHTMLCG(URL url, CGBuilderType builderType) throws IOException, IllegalArgumentException,
|
||||||
CancelException {
|
CancelException {
|
||||||
PropagationCallGraphBuilder b = makeHTMLCGBuilder(url, handleCallApply);
|
PropagationCallGraphBuilder b = makeHTMLCGBuilder(url, builderType);
|
||||||
CallGraph CG = b.makeCallGraph(b.getOptions());
|
CallGraph CG = b.makeCallGraph(b.getOptions());
|
||||||
return CG;
|
return CG;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JSCFABuilder makeCGBuilder(JavaScriptLoaderFactory loaders, SourceModule[] scripts, boolean useOneCFA, boolean handleCallApply) throws IOException {
|
public static JSCFABuilder makeCGBuilder(JavaScriptLoaderFactory loaders, SourceModule[] scripts, CGBuilderType builderType, IRFactory irFactory) throws IOException {
|
||||||
AnalysisScope scope = makeScope(scripts, loaders, JavaScriptLoader.JS);
|
AnalysisScope scope = makeScope(scripts, loaders, JavaScriptLoader.JS);
|
||||||
return makeCG(loaders, scope, useOneCFA, handleCallApply);
|
return makeCG(loaders, scope, builderType, irFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static JSCFABuilder makeCG(JavaScriptLoaderFactory loaders, AnalysisScope scope, boolean useOneCFA, boolean handleCallApply) throws IOException {
|
protected static JSCFABuilder makeCG(JavaScriptLoaderFactory loaders, AnalysisScope scope, CGBuilderType builderType, IRFactory irFactory) throws IOException {
|
||||||
try {
|
try {
|
||||||
IClassHierarchy cha = makeHierarchy(scope, loaders);
|
IClassHierarchy cha = makeHierarchy(scope, loaders);
|
||||||
com.ibm.wala.cast.js.util.Util.checkForFrontEndErrors(cha);
|
com.ibm.wala.cast.js.util.Util.checkForFrontEndErrors(cha);
|
||||||
Iterable<Entrypoint> roots = makeScriptRoots(cha);
|
Iterable<Entrypoint> roots = makeScriptRoots(cha);
|
||||||
JSAnalysisOptions options = makeOptions(scope, cha, roots);
|
JSAnalysisOptions options = makeOptions(scope, cha, roots);
|
||||||
options.setHandleCallApply(handleCallApply);
|
options.setHandleCallApply(builderType.handleCallApply());
|
||||||
AnalysisCache cache = makeCache();
|
options.setUsePreciseLexical(builderType.usePreciseLexical());
|
||||||
|
AnalysisCache cache = makeCache(irFactory);
|
||||||
JSCFABuilder builder = new JSZeroOrOneXCFABuilder(cha, options, cache, null, null, ZeroXInstanceKeys.ALLOCATIONS, useOneCFA);
|
JSCFABuilder builder = new JSZeroOrOneXCFABuilder(cha, options, cache, null, null, ZeroXInstanceKeys.ALLOCATIONS,
|
||||||
|
builderType.useOneCFA());
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
} catch (ClassHierarchyException e) {
|
} catch (ClassHierarchyException e) {
|
|
@ -15,6 +15,7 @@ import java.net.URL;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.js.test.JSCallGraphBuilderUtil.CGBuilderType;
|
||||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||||
import com.ibm.wala.util.CancelException;
|
import com.ibm.wala.util.CancelException;
|
||||||
|
|
||||||
|
@ -31,7 +32,7 @@ public abstract class TestAjaxsltCallGraphShape extends TestJSCallGraphShape {
|
||||||
@Test public void testAjaxslt() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testAjaxslt() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("ajaxslt/test/xslt.html");
|
URL url = getClass().getClassLoader().getResource("ajaxslt/test/xslt.html");
|
||||||
// don't handle call / apply; it makes things blow up
|
// don't handle call / apply; it makes things blow up
|
||||||
CallGraph CG = Util.makeHTMLCG(url, false);
|
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url, CGBuilderType.ZERO_ONE_CFA_NO_CALL_APPLY);
|
||||||
|
|
||||||
verifyGraphAssertions(CG, assertionsForAjaxslt);
|
verifyGraphAssertions(CG, assertionsForAjaxslt);
|
||||||
}
|
}
|
||||||
|
@ -42,7 +43,7 @@ public abstract class TestAjaxsltCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test public void testAjaxpath() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testAjaxpath() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("ajaxslt/test/xpath.html");
|
URL url = getClass().getClassLoader().getResource("ajaxslt/test/xpath.html");
|
||||||
CallGraph CG = Util.makeHTMLCG(url);
|
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
|
||||||
verifyGraphAssertions(CG, assertionsForAjaxpath);
|
verifyGraphAssertions(CG, assertionsForAjaxpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
package com.ibm.wala.cast.js.test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.ipa.callgraph.CAstCallGraphUtil;
|
||||||
|
import com.ibm.wala.cast.js.ipa.callgraph.ArgumentSpecialization;
|
||||||
|
import com.ibm.wala.cast.js.ipa.callgraph.JSAnalysisOptions;
|
||||||
|
import com.ibm.wala.cast.js.ipa.callgraph.JSCFABuilder;
|
||||||
|
import com.ibm.wala.cast.js.ipa.callgraph.JSZeroOrOneXCFABuilder;
|
||||||
|
import com.ibm.wala.cast.js.loader.JavaScriptLoaderFactory;
|
||||||
|
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||||
|
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||||
|
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||||
|
import com.ibm.wala.ipa.callgraph.Entrypoint;
|
||||||
|
import com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroXInstanceKeys;
|
||||||
|
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||||
|
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||||
|
import com.ibm.wala.util.CancelException;
|
||||||
|
|
||||||
|
public abstract class TestArgumentSensitivity extends TestJSCallGraphShape {
|
||||||
|
|
||||||
|
protected static final Object[][] assertionsForArgs = new Object[][] {
|
||||||
|
new Object[] { ROOT, new String[] { "tests/args.js" } },
|
||||||
|
new Object[] {
|
||||||
|
"tests/args.js",
|
||||||
|
new String[] { "tests/args.js/a" } },
|
||||||
|
new Object[] { "tests/args.js/a", new String[] { "tests/args.js/x"} },
|
||||||
|
new Object[] { "tests/args.js/a", new String[] { "tests/args.js/y", "tests/args.js/z", "!tests/args.js/wrong" } } };
|
||||||
|
|
||||||
|
@Test public void testArgs() throws IOException, IllegalArgumentException, CancelException, ClassHierarchyException {
|
||||||
|
JavaScriptLoaderFactory loaders = JSCallGraphBuilderUtil.makeLoaders();
|
||||||
|
AnalysisScope scope = JSCallGraphBuilderUtil.makeScriptScope("tests", "args.js", loaders);
|
||||||
|
|
||||||
|
IClassHierarchy cha = JSCallGraphBuilderUtil.makeHierarchy(scope, loaders);
|
||||||
|
com.ibm.wala.cast.js.util.Util.checkForFrontEndErrors(cha);
|
||||||
|
Iterable<Entrypoint> roots = JSCallGraphBuilderUtil.makeScriptRoots(cha);
|
||||||
|
JSAnalysisOptions options = JSCallGraphBuilderUtil.makeOptions(scope, cha, roots);
|
||||||
|
|
||||||
|
AnalysisCache cache = JSCallGraphBuilderUtil.makeCache(new ArgumentSpecialization.ArgumentCountIRFactory(options.getSSAOptions()));
|
||||||
|
|
||||||
|
JSCFABuilder builder = new JSZeroOrOneXCFABuilder(cha, options, cache, null, null, ZeroXInstanceKeys.ALLOCATIONS, false);
|
||||||
|
builder.setContextSelector(new ArgumentSpecialization.ArgumentCountContextSelector(builder.getContextSelector()));
|
||||||
|
builder.setContextInterpreter(new ArgumentSpecialization.ArgumentSpecializationContextIntepreter(options, cache));
|
||||||
|
CallGraph CG = builder.makeCallGraph(options);
|
||||||
|
|
||||||
|
// CAstCallGraphUtil.AVOID_DUMP = false;
|
||||||
|
CAstCallGraphUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||||
|
|
||||||
|
verifyGraphAssertions(CG, assertionsForArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -227,6 +227,7 @@ public abstract class TestCorrelatedPairExtraction {
|
||||||
}
|
}
|
||||||
|
|
||||||
// another example with "this"
|
// another example with "this"
|
||||||
|
// fails since variables from enclosing functions are no longer in SSA form, hence no correlation is found
|
||||||
@Test
|
@Test
|
||||||
public void test9() {
|
public void test9() {
|
||||||
testRewriter("function defglobals(globals) {\n" +
|
testRewriter("function defglobals(globals) {\n" +
|
||||||
|
@ -413,7 +414,7 @@ public abstract class TestCorrelatedPairExtraction {
|
||||||
}
|
}
|
||||||
|
|
||||||
// fails since the assignment to "value" in the extracted version gets a (spurious) reference error CFG edge
|
// fails since the assignment to "value" in the extracted version gets a (spurious) reference error CFG edge
|
||||||
@Test @Ignore
|
@Test
|
||||||
public void test18() {
|
public void test18() {
|
||||||
testRewriter("function addMethods(source) {\n" +
|
testRewriter("function addMethods(source) {\n" +
|
||||||
" var properties = Object.keys(source);\n" +
|
" var properties = Object.keys(source);\n" +
|
||||||
|
@ -426,8 +427,50 @@ public abstract class TestCorrelatedPairExtraction {
|
||||||
"function addMethods(source) {\n" +
|
"function addMethods(source) {\n" +
|
||||||
" var properties = Object.keys(source);\n" +
|
" var properties = Object.keys(source);\n" +
|
||||||
" for (var i = 0, length = properties.length; i < length; i++) {\n" +
|
" for (var i = 0, length = properties.length; i < length; i++) {\n" +
|
||||||
" var property = properties[i], value; (function _forin_body_0(property, thi$) { value = source[property];\n" +
|
" var property = properties[i], value; value = (function _forin_body_0(property, thi$) { var value; value = source[property];\n" +
|
||||||
" thi$.prototype[property] = value; })(property, this);\n" +
|
" thi$.prototype[property] = value; return value; })(property, this);\n" +
|
||||||
|
" }\n" +
|
||||||
|
" return this;\n" +
|
||||||
|
"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// slight variation of test18
|
||||||
|
@Test
|
||||||
|
public void test18_b() {
|
||||||
|
testRewriter("function addMethods(source) {\n" +
|
||||||
|
" var properties = Object.keys(source);\n" +
|
||||||
|
" for (var i = 0, length = properties.length; i < length; i++) {\n" +
|
||||||
|
" var property = properties[i], foo = 23, value = source[property];\n" +
|
||||||
|
" this.prototype[property] = value;\n" +
|
||||||
|
" }\n" +
|
||||||
|
" return this;\n" +
|
||||||
|
"}",
|
||||||
|
"function addMethods(source) {\n" +
|
||||||
|
" var properties = Object.keys(source);\n" +
|
||||||
|
" for (var i = 0, length = properties.length; i < length; i++) {\n" +
|
||||||
|
" var property = properties[i], foo = 23, value; value = (function _forin_body_0(property, thi$) { var value; value = source[property];\n" +
|
||||||
|
" thi$.prototype[property] = value; return value; })(property, this);\n" +
|
||||||
|
" }\n" +
|
||||||
|
" return this;\n" +
|
||||||
|
"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// fails since the assignment to "value" in the extracted version gets a (spurious) reference error CFG edge
|
||||||
|
@Test
|
||||||
|
public void test18_c() {
|
||||||
|
testRewriter("function addMethods(source) {\n" +
|
||||||
|
" var properties = Object.keys(source);\n" +
|
||||||
|
" for (var i = 0, length = properties.length; i < length; i++) {\n" +
|
||||||
|
" var property = properties[i], foo = 23, value = source[property], bar = 42;\n" +
|
||||||
|
" this.prototype[property] = value;\n" +
|
||||||
|
" }\n" +
|
||||||
|
" return this;\n" +
|
||||||
|
"}",
|
||||||
|
"function addMethods(source) {\n" +
|
||||||
|
" var properties = Object.keys(source);\n" +
|
||||||
|
" for (var i = 0, length = properties.length; i < length; i++) {\n" +
|
||||||
|
" var property = properties[i], foo = 23, value, bar; value = (function _forin_body_0(property, thi$) { var value; value = source[property], bar = 42;\n" +
|
||||||
|
" thi$.prototype[property] = value; return value; })(property, this);\n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
" return this;\n" +
|
" return this;\n" +
|
||||||
"}");
|
"}");
|
||||||
|
@ -442,11 +485,12 @@ public abstract class TestCorrelatedPairExtraction {
|
||||||
"function write(p, v) { this[p] = v; }",
|
"function write(p, v) { this[p] = v; }",
|
||||||
"function extend(dest, src) {\n" +
|
"function extend(dest, src) {\n" +
|
||||||
" for(var p in src)\n" +
|
" for(var p in src)\n" +
|
||||||
" if(foo(p)) (function _forin_body_0(p) { write.call(dest, p, src[p]); })(p);\n" +
|
" (function _forin_body_0(p) { if(foo(p)) write.call(dest, p, src[p]); })(p);\n" +
|
||||||
"}\n" +
|
"}\n" +
|
||||||
"function write(p, v) { this[p] = v; }");
|
"function write(p, v) { this[p] = v; }");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fails due to a missing LOCAL_SCOPE node
|
||||||
@Test
|
@Test
|
||||||
public void test20() {
|
public void test20() {
|
||||||
testRewriter("function every(object, fn, bind) {\n" +
|
testRewriter("function every(object, fn, bind) {\n" +
|
||||||
|
@ -476,10 +520,69 @@ public abstract class TestCorrelatedPairExtraction {
|
||||||
"function extend(dest, src) {\n" +
|
"function extend(dest, src) {\n" +
|
||||||
" var x, y;\n" +
|
" var x, y;\n" +
|
||||||
" for(var name in src) {\n" +
|
" for(var name in src) {\n" +
|
||||||
" (function _forin_body_0(name) { { x = dest[name];\n" +
|
" (function _forin_body_0(name) { x = dest[name];\n" +
|
||||||
" y = src[name];\n" +
|
" y = src[name];\n" +
|
||||||
" dest[name] = join(x,y); } })(name);\n" +
|
" dest[name] = join(x,y); })(name);\n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
"}");
|
"}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test22() {
|
||||||
|
testRewriter("function(object, keys){\n" +
|
||||||
|
" var results = {};\n" +
|
||||||
|
" for (var i = 0, l = keys.length; i < l; i++){\n" +
|
||||||
|
" var k = keys[i];\n" +
|
||||||
|
" if (k in object) results[k] = object[k];\n" +
|
||||||
|
" }\n" +
|
||||||
|
" return results;\n" +
|
||||||
|
"}",
|
||||||
|
"function(object, keys){\n" +
|
||||||
|
" var results = {};\n" +
|
||||||
|
" for (var i = 0, l = keys.length; i < l; i++){\n" +
|
||||||
|
" var k = keys[i];\n" +
|
||||||
|
" (function _forin_body_0(k) { if (k in object) results[k] = object[k]; })(k);\n" +
|
||||||
|
" }\n" +
|
||||||
|
" return results;\n" +
|
||||||
|
"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// variant of test1
|
||||||
|
@Test
|
||||||
|
public void test23() {
|
||||||
|
testRewriter("function extend(dest, src) {\n" +
|
||||||
|
" var s;\n" +
|
||||||
|
" for(var p in src) {\n" +
|
||||||
|
" s = src[p];\n" +
|
||||||
|
" dest[p] = s;\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}",
|
||||||
|
"function extend(dest, src) {\n" +
|
||||||
|
" var s;\n" +
|
||||||
|
" for(var p in src) {\n" +
|
||||||
|
" s = (function _forin_body_0(p) {\n" +
|
||||||
|
" var s;" +
|
||||||
|
" s = src[p];\n" +
|
||||||
|
" dest[p] = s;\n" +
|
||||||
|
" return s;" +
|
||||||
|
" })(p);\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// cannot extract for-in body referring to "arguments"
|
||||||
|
@Test
|
||||||
|
public void test24() {
|
||||||
|
testRewriter("function extend(dest, src) {" +
|
||||||
|
" for(var p in src) {" +
|
||||||
|
" arguments[0][p] = src[p];" +
|
||||||
|
" }" +
|
||||||
|
"}",
|
||||||
|
"function extend(dest, src) {" +
|
||||||
|
" for(var p in src) {" +
|
||||||
|
" arguments[0][p] = src[p];" +
|
||||||
|
" }" +
|
||||||
|
"}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -587,7 +587,7 @@ public abstract class TestForInBodyExtraction {
|
||||||
}
|
}
|
||||||
|
|
||||||
// this test fails since the rewritten CAst contains one more level of blocks
|
// this test fails since the rewritten CAst contains one more level of blocks
|
||||||
@Test @Ignore
|
@Test
|
||||||
public void test24() {
|
public void test24() {
|
||||||
testRewriter("var addSlickPseudos = function() {" +
|
testRewriter("var addSlickPseudos = function() {" +
|
||||||
" for(var name in pseudos)" +
|
" for(var name in pseudos)" +
|
||||||
|
@ -759,4 +759,19 @@ public abstract class TestForInBodyExtraction {
|
||||||
" }" +
|
" }" +
|
||||||
"} catch(_) {}");
|
"} catch(_) {}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cannot extract for-in body referring to "arguments"
|
||||||
|
@Test
|
||||||
|
public void test31() {
|
||||||
|
testRewriter("function extend(dest, src) {" +
|
||||||
|
" for(var p in src) {" +
|
||||||
|
" arguments[0][p] = src[p];" +
|
||||||
|
" }" +
|
||||||
|
"}",
|
||||||
|
"function extend(dest, src) {" +
|
||||||
|
" for(var p in src) {" +
|
||||||
|
" arguments[0][p] = src[p];" +
|
||||||
|
" }" +
|
||||||
|
"}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,26 +24,26 @@ public abstract class TestForInLoopHack extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test public void testPage3WithoutHack() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testPage3WithoutHack() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/page3.html");
|
URL url = getClass().getClassLoader().getResource("pages/page3.html");
|
||||||
JSCFABuilder builder = Util.makeHTMLCGBuilder(url);
|
JSCFABuilder builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url);
|
||||||
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||||
Util.dumpCG(builder.getPointerAnalysis(), CG);
|
JSCallGraphBuilderUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void testPage3WithHack() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testPage3WithHack() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/page3.html");
|
URL url = getClass().getClassLoader().getResource("pages/page3.html");
|
||||||
JSCFABuilder builder = Util.makeHTMLCGBuilder(url);
|
JSCFABuilder builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url);
|
||||||
addHackedForInLoopSensitivity(builder);
|
addHackedForInLoopSensitivity(builder);
|
||||||
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||||
Util.dumpCG(builder.getPointerAnalysis(), CG);
|
JSCallGraphBuilderUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("This test now blows up due to proper handling of the || construct, used in extend(). Should handle this eventually.")
|
@Ignore("This test now blows up due to proper handling of the || construct, used in extend(). Should handle this eventually.")
|
||||||
@Test public void testJQueryWithHack() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testJQueryWithHack() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/jquery_hacked.html");
|
URL url = getClass().getClassLoader().getResource("pages/jquery_hacked.html");
|
||||||
JSCFABuilder builder = Util.makeHTMLCGBuilder(url);
|
JSCFABuilder builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url);
|
||||||
addHackedForInLoopSensitivity(builder);
|
addHackedForInLoopSensitivity(builder);
|
||||||
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||||
Util.dumpCG(builder.getPointerAnalysis(), CG);
|
JSCallGraphBuilderUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -74,9 +74,9 @@ public abstract class TestForInLoopHack extends TestJSCallGraphShape {
|
||||||
};
|
};
|
||||||
|
|
||||||
@Test public void testBadForInWithoutHack() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testBadForInWithoutHack() throws IOException, IllegalArgumentException, CancelException {
|
||||||
JSCFABuilder B = Util.makeScriptCGBuilder("tests", "badforin.js");
|
JSCFABuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "badforin.js");
|
||||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||||
Util.dumpCG(B.getPointerAnalysis(), CG);
|
JSCallGraphBuilderUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||||
verifyGraphAssertions(CG, assertionsForBadForin);
|
verifyGraphAssertions(CG, assertionsForBadForin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,10 +92,10 @@ public abstract class TestForInLoopHack extends TestJSCallGraphShape {
|
||||||
};
|
};
|
||||||
|
|
||||||
@Test public void testBadForInWithHack() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testBadForInWithHack() throws IOException, IllegalArgumentException, CancelException {
|
||||||
JSCFABuilder B = Util.makeScriptCGBuilder("tests", "badforin.js");
|
JSCFABuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "badforin.js");
|
||||||
addHackedForInLoopSensitivity(B);
|
addHackedForInLoopSensitivity(B);
|
||||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||||
Util.dumpCG(B.getPointerAnalysis(), CG);
|
JSCallGraphBuilderUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||||
verifyGraphAssertions(CG, assertionsForBadForin);
|
verifyGraphAssertions(CG, assertionsForBadForin);
|
||||||
verifyGraphAssertions(CG, assertionsForBadForinHackPrecision);
|
verifyGraphAssertions(CG, assertionsForBadForinHackPrecision);
|
||||||
}
|
}
|
||||||
|
@ -118,9 +118,9 @@ public abstract class TestForInLoopHack extends TestJSCallGraphShape {
|
||||||
};
|
};
|
||||||
|
|
||||||
@Test public void testbadforin2WithoutHack() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testbadforin2WithoutHack() throws IOException, IllegalArgumentException, CancelException {
|
||||||
JSCFABuilder B = Util.makeScriptCGBuilder("tests", "badforin2.js");
|
JSCFABuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "badforin2.js");
|
||||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||||
Util.dumpCG(B.getPointerAnalysis(), CG);
|
JSCallGraphBuilderUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||||
verifyGraphAssertions(CG, assertionsForbadforin2);
|
verifyGraphAssertions(CG, assertionsForbadforin2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,14 +136,22 @@ public abstract class TestForInLoopHack extends TestJSCallGraphShape {
|
||||||
};
|
};
|
||||||
|
|
||||||
@Test public void testbadforin2WithHack() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testbadforin2WithHack() throws IOException, IllegalArgumentException, CancelException {
|
||||||
JSCFABuilder B = Util.makeScriptCGBuilder("tests", "badforin2.js");
|
JSCFABuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "badforin2.js");
|
||||||
addHackedForInLoopSensitivity(B);
|
addHackedForInLoopSensitivity(B);
|
||||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||||
Util.dumpCG(B.getPointerAnalysis(), CG);
|
JSCallGraphBuilderUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||||
verifyGraphAssertions(CG, assertionsForbadforin2);
|
verifyGraphAssertions(CG, assertionsForbadforin2);
|
||||||
verifyGraphAssertions(CG, assertionsForbadforin2HackPrecision);
|
verifyGraphAssertions(CG, assertionsForbadforin2HackPrecision);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test public void testForInRecursion() throws IOException, IllegalArgumentException, CancelException {
|
||||||
|
JSCFABuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "badforin3.js");
|
||||||
|
addHackedForInLoopSensitivity(B);
|
||||||
|
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||||
|
JSCallGraphBuilderUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@Test public void testYahooWithoutHack() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testYahooWithoutHack() throws IOException, IllegalArgumentException, CancelException {
|
||||||
JSCFABuilder B = Util.makeScriptCGBuilder("frameworks", "yahoo.js");
|
JSCFABuilder B = Util.makeScriptCGBuilder("frameworks", "yahoo.js");
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.ibm.wala.cast.js.test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.ipa.callgraph.CAstCallGraphUtil;
|
||||||
|
import com.ibm.wala.cast.js.html.JSSourceExtractor;
|
||||||
|
import com.ibm.wala.cast.js.ipa.callgraph.JSCFABuilder;
|
||||||
|
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||||
|
import com.ibm.wala.util.CancelException;
|
||||||
|
|
||||||
|
public class TestJQueryExamples extends TestJSCallGraphShape {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
justThisTest(TestJQueryExamples.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void config() {
|
||||||
|
JSSourceExtractor.USE_TEMP_NAME = false;
|
||||||
|
JSSourceExtractor.DELETE_UPON_EXIT = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore("This tries to analyze unmodified jquery, which we can't do yet")
|
||||||
|
@Test public void testEx1() throws IOException, IllegalArgumentException, CancelException {
|
||||||
|
URL url = getClass().getClassLoader().getResource("pages/jquery/ex1.html");
|
||||||
|
JSCFABuilder builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url);
|
||||||
|
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||||
|
CAstCallGraphUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,7 +18,7 @@ import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||||
public abstract class TestJSCallGraphShape extends TestCallGraphShape {
|
public abstract class TestJSCallGraphShape extends TestCallGraphShape {
|
||||||
|
|
||||||
protected Collection getNodes(CallGraph CG, String functionIdentifier) {
|
protected Collection getNodes(CallGraph CG, String functionIdentifier) {
|
||||||
return Util.getNodes(CG, functionIdentifier);
|
return JSCallGraphBuilderUtil.getNodes(CG, functionIdentifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ package com.ibm.wala.cast.js.test;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||||
|
@ -28,9 +29,10 @@ public abstract class TestMediawikiCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@Ignore("not terminating; Julian, take a look?")
|
||||||
@Test public void testSwineFlu() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testSwineFlu() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = new URL("http://en.wikipedia.org/wiki/2009_swine_flu_outbreak");
|
URL url = new URL("http://en.wikipedia.org/wiki/2009_swine_flu_outbreak");
|
||||||
CallGraph CG = Util.makeHTMLCG(url);
|
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
|
||||||
verifyGraphAssertions(CG, assertionsForSwineFlu);
|
verifyGraphAssertions(CG, assertionsForSwineFlu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,30 +25,30 @@ public abstract class TestMozillaBugPages extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test public void testMozilla439164() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testMozilla439164() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/mochitest/mozillaBug439164.html");
|
URL url = getClass().getClassLoader().getResource("pages/mochitest/mozillaBug439164.html");
|
||||||
JSCFABuilder builder = Util.makeHTMLCGBuilder(url);
|
JSCFABuilder builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url);
|
||||||
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||||
Util.dumpCG(builder.getPointerAnalysis(), CG);
|
JSCallGraphBuilderUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void testMozilla488233() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testMozilla488233() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/mochitest/mozillaBug488233NoExtJS.html");
|
URL url = getClass().getClassLoader().getResource("pages/mochitest/mozillaBug488233NoExtJS.html");
|
||||||
JSCFABuilder builder = Util.makeHTMLCGBuilder(url);
|
JSCFABuilder builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url);
|
||||||
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||||
Util.dumpCG(builder.getPointerAnalysis(), CG);
|
JSCallGraphBuilderUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void testMozilla490152() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testMozilla490152() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/mochitest/mozillaBug490152NoExtJS.html");
|
URL url = getClass().getClassLoader().getResource("pages/mochitest/mozillaBug490152NoExtJS.html");
|
||||||
JSCFABuilder builder = Util.makeHTMLCGBuilder(url);
|
JSCFABuilder builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url);
|
||||||
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||||
Util.dumpCG(builder.getPointerAnalysis(), CG);
|
JSCallGraphBuilderUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void testMozilla625562() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testMozilla625562() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/mochitest/mozillaBug625562NoExtJS.html");
|
URL url = getClass().getClassLoader().getResource("pages/mochitest/mozillaBug625562NoExtJS.html");
|
||||||
JSCFABuilder builder = Util.makeHTMLCGBuilder(url);
|
JSCFABuilder builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url);
|
||||||
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||||
Util.dumpCG(builder.getPointerAnalysis(), CG);
|
JSCallGraphBuilderUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ import junit.framework.Assert;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.js.ipa.callgraph.JSCFABuilder;
|
||||||
|
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil;
|
||||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||||
|
@ -42,6 +44,18 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
justThisTest(TestSimpleCallGraphShape.class);
|
justThisTest(TestSimpleCallGraphShape.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static final Object[][] assertionsForArgs = new Object[][] {
|
||||||
|
new Object[] { ROOT, new String[] { "tests/args.js" } },
|
||||||
|
new Object[] {
|
||||||
|
"tests/args.js",
|
||||||
|
new String[] { "tests/args.js/a" } },
|
||||||
|
new Object[] { "tests/args.js/a", new String[] { "tests/args.js/x", "tests/args.js/y" } } };
|
||||||
|
|
||||||
|
@Test public void testArgs() throws IOException, IllegalArgumentException, CancelException {
|
||||||
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "args.js");
|
||||||
|
verifyGraphAssertions(CG, assertionsForArgs);
|
||||||
|
}
|
||||||
|
|
||||||
protected static final Object[][] assertionsForSimple = new Object[][] {
|
protected static final Object[][] assertionsForSimple = new Object[][] {
|
||||||
new Object[] { ROOT, new String[] { "tests/simple.js" } },
|
new Object[] { ROOT, new String[] { "tests/simple.js" } },
|
||||||
new Object[] {
|
new Object[] {
|
||||||
|
@ -56,7 +70,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSimple() throws IOException, IllegalArgumentException, CancelException {
|
public void testSimple() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "simple.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "simple.js");
|
||||||
verifyGraphAssertions(CG, assertionsForSimple);
|
verifyGraphAssertions(CG, assertionsForSimple);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +84,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testObjects() throws IOException, IllegalArgumentException, CancelException {
|
public void testObjects() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "objects.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "objects.js");
|
||||||
verifyGraphAssertions(CG, assertionsForObjects);
|
verifyGraphAssertions(CG, assertionsForObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +105,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInherit() throws IOException, IllegalArgumentException, CancelException {
|
public void testInherit() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "inherit.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "inherit.js");
|
||||||
verifyGraphAssertions(CG, assertionsForInherit);
|
verifyGraphAssertions(CG, assertionsForInherit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +116,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNewfn() throws IOException, IllegalArgumentException, CancelException {
|
public void testNewfn() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "newfn.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "newfn.js");
|
||||||
verifyGraphAssertions(CG, assertionsForNewfn);
|
verifyGraphAssertions(CG, assertionsForNewfn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +129,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testControlflow() throws IOException, IllegalArgumentException, CancelException {
|
public void testControlflow() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "control-flow.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "control-flow.js");
|
||||||
verifyGraphAssertions(CG, assertionsForControlflow);
|
verifyGraphAssertions(CG, assertionsForControlflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +143,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMoreControlflow() throws IOException, IllegalArgumentException, CancelException {
|
public void testMoreControlflow() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "more-control-flow.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "more-control-flow.js");
|
||||||
verifyGraphAssertions(CG, assertionsForMoreControlflow);
|
verifyGraphAssertions(CG, assertionsForMoreControlflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +153,10 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testForin() throws IOException, IllegalArgumentException, CancelException {
|
public void testForin() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "forin.js");
|
JSCFABuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "forin.js");
|
||||||
|
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||||
|
// JSCallGraphUtil.AVOID_DUMP = false;
|
||||||
|
JSCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||||
verifyGraphAssertions(CG, assertionsForForin);
|
verifyGraphAssertions(CG, assertionsForForin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,14 +174,14 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSimpleLexical() throws IOException, IllegalArgumentException, CancelException {
|
public void testSimpleLexical() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "simple-lexical.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "simple-lexical.js");
|
||||||
verifyGraphAssertions(CG, assertionsForSimpleLexical);
|
verifyGraphAssertions(CG, assertionsForSimpleLexical);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRecursiveLexical() throws IOException, IllegalArgumentException, CancelException {
|
public void testRecursiveLexical() throws IOException, IllegalArgumentException, CancelException {
|
||||||
// just checking that we have a sufficient bailout to ensure termination
|
// just checking that we have a sufficient bailout to ensure termination
|
||||||
Util.makeScriptCG("tests", "recursive_lexical.js");
|
JSCallGraphBuilderUtil.makeScriptCG("tests", "recursive_lexical.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Object[][] assertionsForLexicalMultiple = new Object[][] {
|
private static final Object[][] assertionsForLexicalMultiple = new Object[][] {
|
||||||
|
@ -174,7 +191,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLexicalMultiple() throws IOException, IllegalArgumentException, CancelException {
|
public void testLexicalMultiple() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "lexical_multiple_calls.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "lexical_multiple_calls.js");
|
||||||
verifyGraphAssertions(CG, assertionsForLexicalMultiple);
|
verifyGraphAssertions(CG, assertionsForLexicalMultiple);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +209,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTry() throws IOException, IllegalArgumentException, CancelException {
|
public void testTry() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "try.js", true);
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "try.js");
|
||||||
verifyGraphAssertions(CG, assertionsForTry);
|
verifyGraphAssertions(CG, assertionsForTry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,7 +219,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStringOp() throws IOException, IllegalArgumentException, CancelException {
|
public void testStringOp() throws IOException, IllegalArgumentException, CancelException {
|
||||||
PropagationCallGraphBuilder B = Util.makeScriptCGBuilder("tests", "string-op.js");
|
PropagationCallGraphBuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "string-op.js");
|
||||||
B.getOptions().setTraceStringConstants(true);
|
B.getOptions().setTraceStringConstants(true);
|
||||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||||
verifyGraphAssertions(CG, assertionsForStringOp);
|
verifyGraphAssertions(CG, assertionsForStringOp);
|
||||||
|
@ -217,7 +234,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpward() throws IOException, IllegalArgumentException, CancelException {
|
public void testUpward() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "upward.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "upward.js");
|
||||||
verifyGraphAssertions(CG, assertionsForUpward);
|
verifyGraphAssertions(CG, assertionsForUpward);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,9 +244,11 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStringPrims() throws IOException, IllegalArgumentException, CancelException {
|
public void testStringPrims() throws IOException, IllegalArgumentException, CancelException {
|
||||||
PropagationCallGraphBuilder B = Util.makeScriptCGBuilder("tests", "string-prims.js");
|
PropagationCallGraphBuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "string-prims.js");
|
||||||
B.getOptions().setTraceStringConstants(true);
|
B.getOptions().setTraceStringConstants(true);
|
||||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||||
|
// JSCallGraphUtil.AVOID_DUMP = false;
|
||||||
|
JSCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||||
verifyGraphAssertions(CG, assertionsForStringPrims);
|
verifyGraphAssertions(CG, assertionsForStringPrims);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,7 +257,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNested() throws IOException, IllegalArgumentException, CancelException {
|
public void testNested() throws IOException, IllegalArgumentException, CancelException {
|
||||||
PropagationCallGraphBuilder B = Util.makeScriptCGBuilder("tests", "nested.js");
|
PropagationCallGraphBuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "nested.js");
|
||||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||||
verifyGraphAssertions(CG, assertionsForNested);
|
verifyGraphAssertions(CG, assertionsForNested);
|
||||||
}
|
}
|
||||||
|
@ -248,7 +267,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInstanceof() throws IOException, IllegalArgumentException, CancelException {
|
public void testInstanceof() throws IOException, IllegalArgumentException, CancelException {
|
||||||
PropagationCallGraphBuilder B = Util.makeScriptCGBuilder("tests", "instanceof.js");
|
PropagationCallGraphBuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "instanceof.js");
|
||||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||||
verifyGraphAssertions(CG, assertionsForInstanceof);
|
verifyGraphAssertions(CG, assertionsForInstanceof);
|
||||||
}
|
}
|
||||||
|
@ -266,19 +285,19 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCrash1() throws IOException, IllegalArgumentException, CancelException {
|
public void testCrash1() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "crash1.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "crash1.js");
|
||||||
verifyGraphAssertions(CG, null);
|
verifyGraphAssertions(CG, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCrash2() throws IOException, IllegalArgumentException, CancelException {
|
public void testCrash2() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "crash2.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "crash2.js");
|
||||||
verifyGraphAssertions(CG, null);
|
verifyGraphAssertions(CG, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLexicalCtor() throws IOException, IllegalArgumentException, CancelException {
|
public void testLexicalCtor() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "lexical-ctor.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "lexical-ctor.js");
|
||||||
verifyGraphAssertions(CG, null);
|
verifyGraphAssertions(CG, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +307,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMultivar() throws IOException, IllegalArgumentException, CancelException {
|
public void testMultivar() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "multivar.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "multivar.js");
|
||||||
verifyGraphAssertions(CG, assertionsForMultivar);
|
verifyGraphAssertions(CG, assertionsForMultivar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,7 +318,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testProtoypeContamination() throws IOException, IllegalArgumentException, CancelException {
|
public void testProtoypeContamination() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "prototype_contamination_bug.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "prototype_contamination_bug.js");
|
||||||
verifyGraphAssertions(CG, assertionsForPrototypeContamination);
|
verifyGraphAssertions(CG, assertionsForPrototypeContamination);
|
||||||
verifyNoEdges(CG, "suffix:test1", "suffix:foo_of_B");
|
verifyNoEdges(CG, "suffix:test1", "suffix:foo_of_B");
|
||||||
verifyNoEdges(CG, "suffix:test2", "suffix:foo_of_A");
|
verifyNoEdges(CG, "suffix:test2", "suffix:foo_of_A");
|
||||||
|
@ -307,20 +326,20 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStackOverflowOnSsaConversionBug() throws IOException, IllegalArgumentException, CancelException {
|
public void testStackOverflowOnSsaConversionBug() throws IOException, IllegalArgumentException, CancelException {
|
||||||
Util.makeScriptCG("tests", "stack_overflow_on_ssa_conversion.js");
|
JSCallGraphBuilderUtil.makeScriptCG("tests", "stack_overflow_on_ssa_conversion.js");
|
||||||
// all we need is for it to finish building CG successfully.
|
// all we need is for it to finish building CG successfully.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExtJSSwitch() throws IOException, IllegalArgumentException, CancelException {
|
public void testExtJSSwitch() throws IOException, IllegalArgumentException, CancelException {
|
||||||
Util.makeScriptCG("tests", "extjs_switch.js");
|
JSCallGraphBuilderUtil.makeScriptCG("tests", "extjs_switch.js");
|
||||||
// all we need is for it to finish building CG successfully.
|
// all we need is for it to finish building CG successfully.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFunctionDotCall() throws IOException, IllegalArgumentException, CancelException {
|
public void testFunctionDotCall() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph cg = Util.makeScriptCG("tests", "function_call.js");
|
CallGraph cg = JSCallGraphBuilderUtil.makeScriptCG("tests", "function_call.js");
|
||||||
for (CGNode n : cg) {
|
for (CGNode n : cg) {
|
||||||
if (n.getMethod().getName().toString().equals("call4")) {
|
if (n.getMethod().getName().toString().equals("call4")) {
|
||||||
Assert.assertEquals(2, cg.getSuccNodeCount(n));
|
Assert.assertEquals(2, cg.getSuccNodeCount(n));
|
||||||
|
@ -342,7 +361,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFunctionDotApply() throws IOException, IllegalArgumentException, CancelException {
|
public void testFunctionDotApply() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "function_apply.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "function_apply.js");
|
||||||
verifyGraphAssertions(CG, assertionsForFunctionApply);
|
verifyGraphAssertions(CG, assertionsForFunctionApply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,7 +371,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFunctionDotApply2() throws IOException, IllegalArgumentException, CancelException {
|
public void testFunctionDotApply2() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "function_apply2.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "function_apply2.js");
|
||||||
verifyGraphAssertions(CG, assertionsForFunctionApply2);
|
verifyGraphAssertions(CG, assertionsForFunctionApply2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,7 +381,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testWrap1() throws IllegalArgumentException, IOException, CancelException {
|
public void testWrap1() throws IllegalArgumentException, IOException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "wrap1.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "wrap1.js");
|
||||||
verifyGraphAssertions(CG, assertionsForWrap1);
|
verifyGraphAssertions(CG, assertionsForWrap1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,7 +391,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testWrap2() throws IllegalArgumentException, IOException, CancelException {
|
public void testWrap2() throws IllegalArgumentException, IOException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "wrap2.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "wrap2.js");
|
||||||
verifyGraphAssertions(CG, assertionsForWrap2);
|
verifyGraphAssertions(CG, assertionsForWrap2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,7 +401,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testWrap3() throws IllegalArgumentException, IOException, CancelException {
|
public void testWrap3() throws IllegalArgumentException, IOException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "wrap3.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "wrap3.js");
|
||||||
verifyGraphAssertions(CG, assertionsForWrap3);
|
verifyGraphAssertions(CG, assertionsForWrap3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,7 +411,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testComplexCall() throws IOException, IllegalArgumentException, CancelException {
|
public void testComplexCall() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "complex_call.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "complex_call.js");
|
||||||
for(CGNode nd : CG)
|
for(CGNode nd : CG)
|
||||||
System.out.println(nd);
|
System.out.println(nd);
|
||||||
verifyGraphAssertions(CG, assertionsForComplexCall);
|
verifyGraphAssertions(CG, assertionsForComplexCall);
|
||||||
|
@ -405,7 +424,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGlobalObjPassing() throws IOException, IllegalArgumentException, CancelException {
|
public void testGlobalObjPassing() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "global_object.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "global_object.js");
|
||||||
verifyGraphAssertions(CG, assertionsForGlobalObj);
|
verifyGraphAssertions(CG, assertionsForGlobalObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,7 +434,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGlobalObj2() throws IOException, IllegalArgumentException, CancelException {
|
public void testGlobalObj2() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "global_object2.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "global_object2.js");
|
||||||
verifyGraphAssertions(CG, assertionsForGlobalObj2);
|
verifyGraphAssertions(CG, assertionsForGlobalObj2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,7 +446,10 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReturnThis() throws IOException, IllegalArgumentException, CancelException {
|
public void testReturnThis() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "return_this.js");
|
PropagationCallGraphBuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "return_this.js");
|
||||||
|
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||||
|
// JSCallGraphUtil.AVOID_DUMP = false;
|
||||||
|
JSCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||||
verifyGraphAssertions(CG, assertionsForReturnThis);
|
verifyGraphAssertions(CG, assertionsForReturnThis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,19 +467,19 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReturnThis2() throws IOException, IllegalArgumentException, CancelException {
|
public void testReturnThis2() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "return_this2.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "return_this2.js");
|
||||||
verifyGraphAssertions(CG, assertionsForReturnThis2);
|
verifyGraphAssertions(CG, assertionsForReturnThis2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Object[][] assertionsForArguments = new Object[][] {
|
private static final Object[][] assertionsForArguments = new Object[][] {
|
||||||
new Object[] { ROOT, new String[] { "tests/arguments.js" } },
|
new Object[] { ROOT, new String[] { "tests/arguments.js" } },
|
||||||
new Object[] { "suffix:arguments.js", new String[] { "suffix:f" } },
|
new Object[] { "suffix:arguments.js", new String[] { "suffix:f" } },
|
||||||
new Object[] { "suffix:f", new String[] { "suffix:g3" } } // but neither "suffix:g1" nor "suffix:g2"
|
new Object[] { "suffix:f", new String[] { "!suffix:g1", "!suffix:g2", "suffix:g3", } }
|
||||||
};
|
};
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testArguments() throws IOException, IllegalArgumentException, CancelException {
|
public void testArguments() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "arguments.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "arguments.js");
|
||||||
verifyGraphAssertions(CG, assertionsForArguments);
|
verifyGraphAssertions(CG, assertionsForArguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,7 +489,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFunctionIsAFunction() throws IOException, IllegalArgumentException, CancelException {
|
public void testFunctionIsAFunction() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "Function_is_a_function.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "Function_is_a_function.js");
|
||||||
verifyGraphAssertions(CG, assertionsForFunctionIsAFunction);
|
verifyGraphAssertions(CG, assertionsForFunctionIsAFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,13 +501,51 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLexicalBroken() throws IOException, IllegalArgumentException, CancelException {
|
public void testLexicalBroken() throws IOException, IllegalArgumentException, CancelException {
|
||||||
CallGraph CG = Util.makeScriptCG("tests", "lexical_broken.js");
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "lexical_broken.js");
|
||||||
verifyGraphAssertions(CG, assertionsForLexicalBroken);
|
verifyGraphAssertions(CG, assertionsForLexicalBroken);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeadPhi() throws IllegalArgumentException, IOException, CancelException {
|
public void testDeadPhi() throws IllegalArgumentException, IOException, CancelException {
|
||||||
Util.makeScriptCG("tests", "dead_phi.js");
|
JSCallGraphBuilderUtil.makeScriptCG("tests", "dead_phi.js");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Object[][] assertionsForScopingOverwriteFunction = new Object[][] {
|
||||||
|
new Object[] { ROOT, new String[] { "tests/scoping_test.js" } },
|
||||||
|
new Object[] { "suffix:scoping_test.js", new String[] { "suffix:i_am_reachable" } }
|
||||||
|
};
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testScopingOverwriteFunction() throws IllegalArgumentException, IOException, CancelException {
|
||||||
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "scoping_test.js");
|
||||||
|
verifyGraphAssertions(CG, assertionsForScopingOverwriteFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Object[][] assertionsForNestedParamAssign = new Object[][] {
|
||||||
|
new Object[] { ROOT, new String[] { "tests/nested_assign_to_param.js" } },
|
||||||
|
new Object[] { "suffix:nested_assign_to_param.js", new String[] { "suffix:i_am_reachable" } }
|
||||||
|
};
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNestedAssignToParam() throws IllegalArgumentException, IOException, CancelException {
|
||||||
|
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "nested_assign_to_param.js");
|
||||||
|
verifyGraphAssertions(CG, assertionsForNestedParamAssign);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Object[][] assertionsForDispatch = new Object[][] {
|
||||||
|
new Object[] { ROOT, new String[] { "tests/dispatch.js" } },
|
||||||
|
new Object[] { "tests/dispatch.js", new String[] { "tests/dispatch.js/left_outer", "tests/dispatch.js/right_outer" } },
|
||||||
|
new Object[] { "tests/dispatch.js/left_outer", new String[]{ "tests/dispatch.js/left_inner" } },
|
||||||
|
new Object[] { "tests/dispatch.js/right_outer", new String[]{ "tests/dispatch.js/right_inner" } }
|
||||||
|
};
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDispatch() throws IOException, IllegalArgumentException, CancelException {
|
||||||
|
PropagationCallGraphBuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "dispatch.js");
|
||||||
|
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||||
|
// JSCallGraphUtil.AVOID_DUMP = false;
|
||||||
|
JSCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||||
|
verifyGraphAssertions(CG, assertionsForDispatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IVector<Set<Pair<CGNode, Integer>>> computeIkIdToVns(PointerAnalysis pa) {
|
protected IVector<Set<Pair<CGNode, Integer>>> computeIkIdToVns(PointerAnalysis pa) {
|
||||||
|
|
|
@ -41,12 +41,6 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
|
||||||
public void config() {
|
|
||||||
JSSourceExtractor.USE_TEMP_NAME = false;
|
|
||||||
JSSourceExtractor.DELETE_UPON_EXIT = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Object[][] assertionsForPage1 = new Object[][] {
|
private static final Object[][] assertionsForPage1 = new Object[][] {
|
||||||
new Object[] { ROOT, new String[] { "page1.html" } },
|
new Object[] { ROOT, new String[] { "page1.html" } },
|
||||||
new Object[] { "page1.html", new String[] { "page1.html/__WINDOW_MAIN__" } },
|
new Object[] { "page1.html", new String[] { "page1.html/__WINDOW_MAIN__" } },
|
||||||
|
@ -61,7 +55,7 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
|
||||||
|
|
||||||
@Test public void testPage1() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testPage1() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/page1.html");
|
URL url = getClass().getClassLoader().getResource("pages/page1.html");
|
||||||
CallGraph CG = Util.makeHTMLCG(url);
|
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
|
||||||
verifyGraphAssertions(CG, assertionsForPage1);
|
verifyGraphAssertions(CG, assertionsForPage1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +66,7 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
|
||||||
|
|
||||||
@Test public void testPage2() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testPage2() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/page2.html");
|
URL url = getClass().getClassLoader().getResource("pages/page2.html");
|
||||||
CallGraph CG = Util.makeHTMLCG(url);
|
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
|
||||||
verifyGraphAssertions(CG, assertionsForPage2);
|
verifyGraphAssertions(CG, assertionsForPage2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +83,7 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
|
||||||
|
|
||||||
@Test public void testCrawlPage11() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testCrawlPage11() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/crawl/page11.html");
|
URL url = getClass().getClassLoader().getResource("pages/crawl/page11.html");
|
||||||
CallGraph CG = Util.makeHTMLCG(url);
|
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
|
||||||
verifyGraphAssertions(CG, assertionsForPage11);
|
verifyGraphAssertions(CG, assertionsForPage11);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +100,7 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
|
||||||
|
|
||||||
@Test public void testCrawlPage11b() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testCrawlPage11b() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/crawl/page11b.html");
|
URL url = getClass().getClassLoader().getResource("pages/crawl/page11b.html");
|
||||||
CallGraph CG = Util.makeHTMLCG(url);
|
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
|
||||||
verifyGraphAssertions(CG, assertionsForPage11b);
|
verifyGraphAssertions(CG, assertionsForPage11b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +132,7 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
|
||||||
|
|
||||||
@Test public void testCrawlPage12() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testCrawlPage12() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/crawl/page12.html");
|
URL url = getClass().getClassLoader().getResource("pages/crawl/page12.html");
|
||||||
CallGraph CG = Util.makeHTMLCG(url);
|
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
|
||||||
verifyGraphAssertions(CG, assertionsForPage12);
|
verifyGraphAssertions(CG, assertionsForPage12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +165,7 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
|
||||||
|
|
||||||
@Test public void testCrawlPage13() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testCrawlPage13() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/crawl/page13.html");
|
URL url = getClass().getClassLoader().getResource("pages/crawl/page13.html");
|
||||||
CallGraph CG = Util.makeHTMLCG(url);
|
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
|
||||||
verifyGraphAssertions(CG, assertionsForPage13);
|
verifyGraphAssertions(CG, assertionsForPage13);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +183,7 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
|
||||||
|
|
||||||
@Test public void testCrawlPage15() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testCrawlPage15() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/crawl/page15.html");
|
URL url = getClass().getClassLoader().getResource("pages/crawl/page15.html");
|
||||||
CallGraph CG = Util.makeHTMLCG(url);
|
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
|
||||||
verifyGraphAssertions(CG, assertionsForPage15);
|
verifyGraphAssertions(CG, assertionsForPage15);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +201,7 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
|
||||||
|
|
||||||
@Test public void testCrawlPage16() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testCrawlPage16() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/crawl/page16.html");
|
URL url = getClass().getClassLoader().getResource("pages/crawl/page16.html");
|
||||||
CallGraph CG = Util.makeHTMLCG(url);
|
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
|
||||||
verifyGraphAssertions(CG, assertionsForPage16);
|
verifyGraphAssertions(CG, assertionsForPage16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,7 +224,7 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
|
||||||
|
|
||||||
@Test public void testCrawlPage17() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testCrawlPage17() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/crawl/page17.html");
|
URL url = getClass().getClassLoader().getResource("pages/crawl/page17.html");
|
||||||
CallGraph CG = Util.makeHTMLCG(url);
|
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
|
||||||
verifyGraphAssertions(CG, assertionsForPage17);
|
verifyGraphAssertions(CG, assertionsForPage17);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,25 +237,25 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
|
||||||
|
|
||||||
@Test public void testApolloExample() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testApolloExample() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/apollo-example.html");
|
URL url = getClass().getClassLoader().getResource("pages/apollo-example.html");
|
||||||
CallGraph CG = Util.makeHTMLCG(url);
|
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
|
||||||
verifyGraphAssertions(CG, assertionsForApolloExample);
|
verifyGraphAssertions(CG, assertionsForApolloExample);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void testNojs() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testNojs() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/nojs.html");
|
URL url = getClass().getClassLoader().getResource("pages/nojs.html");
|
||||||
// all we need is for it to finish building CG successfully.
|
// all we need is for it to finish building CG successfully.
|
||||||
Util.makeHTMLCG(url);
|
JSCallGraphBuilderUtil.makeHTMLCG(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void testPage4() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testPage4() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/page4.html");
|
URL url = getClass().getClassLoader().getResource("pages/page4.html");
|
||||||
Util.makeHTMLCG(url);
|
JSCallGraphBuilderUtil.makeHTMLCG(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Object[][] sourceAssertionsForList = new Object[][] {
|
private static final Object[][] sourceAssertionsForList = new Object[][] {
|
||||||
new Object[]{ "suffix:update_display", "list.html", 9, 18 },
|
new Object[]{ "suffix:update_display", "list.html#2", 4, 13 },
|
||||||
new Object[]{ "suffix:update_with_item", "list.html", 14, 16 },
|
new Object[]{ "suffix:update_with_item", "list.html#2", 9, 11 },
|
||||||
new Object[]{ "suffix:add_item", "list.html", 20, 25 },
|
new Object[]{ "suffix:add_item", "list.html#2", 15, 20 },
|
||||||
new Object[]{ "suffix:collection", "pages/collection.js", 2, 14 },
|
new Object[]{ "suffix:collection", "pages/collection.js", 2, 14 },
|
||||||
new Object[]{ "suffix:collection_add", "pages/collection.js", 7, 13 },
|
new Object[]{ "suffix:collection_add", "pages/collection.js", 7, 13 },
|
||||||
new Object[]{ "suffix:forall_elt", "pages/collection.js", 9, 12 },
|
new Object[]{ "suffix:forall_elt", "pages/collection.js", 9, 12 },
|
||||||
|
@ -270,15 +264,16 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
|
||||||
|
|
||||||
@Test public void testList() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testList() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/list.html");
|
URL url = getClass().getClassLoader().getResource("pages/list.html");
|
||||||
JSCFABuilder builder = Util.makeHTMLCGBuilder(url);
|
JSCFABuilder builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url);
|
||||||
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||||
Util.dumpCG(builder.getPointerAnalysis(), CG);
|
// JSCallGraphBuilderUtil.AVOID_DUMP = false;
|
||||||
|
JSCallGraphBuilderUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||||
verifySourceAssertions(CG, sourceAssertionsForList);
|
verifySourceAssertions(CG, sourceAssertionsForList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void testIframeTest2() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testIframeTest2() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/iframeTest2.html");
|
URL url = getClass().getClassLoader().getResource("pages/iframeTest2.html");
|
||||||
Util.makeHTMLCG(url);
|
JSCallGraphBuilderUtil.makeHTMLCG(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Object[][] assertionsForWindowx = new Object[][] {
|
private static final Object[][] assertionsForWindowx = new Object[][] {
|
||||||
|
@ -292,9 +287,9 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
|
||||||
|
|
||||||
@Test public void testWindowx() throws IOException, IllegalArgumentException, CancelException {
|
@Test public void testWindowx() throws IOException, IllegalArgumentException, CancelException {
|
||||||
URL url = getClass().getClassLoader().getResource("pages/windowx.html");
|
URL url = getClass().getClassLoader().getResource("pages/windowx.html");
|
||||||
JSCFABuilder builder = Util.makeHTMLCGBuilder(url);
|
JSCFABuilder builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url);
|
||||||
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||||
Util.dumpCG(builder.getPointerAnalysis(), CG);
|
JSCallGraphBuilderUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||||
verifyGraphAssertions(CG, assertionsForWindowx);
|
verifyGraphAssertions(CG, assertionsForWindowx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,8 +2,8 @@
|
||||||
<classpath>
|
<classpath>
|
||||||
<classpathentry kind="src" path="source"/>
|
<classpathentry kind="src" path="source"/>
|
||||||
<classpathentry kind="src" path="dat"/>
|
<classpathentry kind="src" path="dat"/>
|
||||||
|
<classpathentry kind="lib" path="lib/jericho-html-3.2.jar"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
||||||
<classpathentry kind="lib" path="lib/jericho-html-3.2.jar"/>
|
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|
|
@ -3,11 +3,16 @@ primitive = new Primitives();
|
||||||
|
|
||||||
// core definitions needed to make anything work, even what follows
|
// core definitions needed to make anything work, even what follows
|
||||||
Object = primitive("NewObject");
|
Object = primitive("NewObject");
|
||||||
Function = primitive("NewFunction");
|
var local_function = primitive("NewFunction");
|
||||||
Array = primitive("NewArray");
|
Function = local_function;
|
||||||
String = primitive("NewString");
|
var local_array = primitive("NewArray");
|
||||||
Number = primitive("NewNumber");
|
Array = local_array;
|
||||||
RegExp = primitive("NewRegExp");
|
var local_string = primitive("NewString");
|
||||||
|
String = local_string;
|
||||||
|
var local_number = primitive("NewNumber");
|
||||||
|
Number = local_number;
|
||||||
|
var local_regexp = primitive("NewRegExp");
|
||||||
|
RegExp = local_regexp;
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* Global properties, see spec 15.1 */
|
/* Global properties, see spec 15.1 */
|
||||||
|
@ -104,7 +109,7 @@ Object.prototype = {
|
||||||
/* Function properties, see spec 15.3 */
|
/* Function properties, see spec 15.3 */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
Function.prototype = {
|
local_function.prototype = {
|
||||||
|
|
||||||
constructor: Function,
|
constructor: Function,
|
||||||
|
|
||||||
|
@ -124,15 +129,15 @@ Function.prototype = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Function.__proto__ = Function.prototype;
|
local_function.__proto__ = Function.prototype;
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* Array properties, see spec 15.4 */
|
/* Array properties, see spec 15.4 */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
Array.__proto__ = Function.prototype;
|
local_array.__proto__ = Function.prototype;
|
||||||
|
|
||||||
Array.prototype = {
|
local_array.prototype = {
|
||||||
|
|
||||||
__proto__: Object.prototype,
|
__proto__: Object.prototype,
|
||||||
|
|
||||||
|
@ -251,9 +256,9 @@ Array.prototype = {
|
||||||
/* String properties, see spec 15.4 */
|
/* String properties, see spec 15.4 */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
String.__proto__ = Function.prototype;
|
local_string.__proto__ = Function.prototype;
|
||||||
|
|
||||||
String.prototype = {
|
local_string.prototype = {
|
||||||
|
|
||||||
__proto__: Object.prototype,
|
__proto__: Object.prototype,
|
||||||
|
|
||||||
|
@ -329,9 +334,9 @@ String.prototype = {
|
||||||
/* Number properties, see spec 15.7 */
|
/* Number properties, see spec 15.7 */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
Number.__proto__ = Function.prototype;
|
local_number.__proto__ = Function.prototype;
|
||||||
|
|
||||||
Number.prototype = {
|
local_number.prototype = {
|
||||||
|
|
||||||
__proto__: Object.prototype,
|
__proto__: Object.prototype,
|
||||||
|
|
||||||
|
@ -419,9 +424,9 @@ Math = {
|
||||||
/* RegExp properties, see spec 15.10 */
|
/* RegExp properties, see spec 15.10 */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
RegExp.__proto__ = Function.prototype;
|
local_regexp.__proto__ = Function.prototype;
|
||||||
|
|
||||||
RegExp.prototype = {
|
local_regexp.prototype = {
|
||||||
|
|
||||||
__proto__: Object.prototype,
|
__proto__: Object.prototype,
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ import com.ibm.wala.cast.js.ssa.JavaScriptPropertyRead;
|
||||||
import com.ibm.wala.cast.js.ssa.JavaScriptPropertyWrite;
|
import com.ibm.wala.cast.js.ssa.JavaScriptPropertyWrite;
|
||||||
import com.ibm.wala.cast.js.ssa.JavaScriptTypeOfInstruction;
|
import com.ibm.wala.cast.js.ssa.JavaScriptTypeOfInstruction;
|
||||||
import com.ibm.wala.cast.js.ssa.JavaScriptWithRegion;
|
import com.ibm.wala.cast.js.ssa.JavaScriptWithRegion;
|
||||||
|
import com.ibm.wala.cast.js.ssa.PrototypeLookup;
|
||||||
|
import com.ibm.wala.cast.js.ssa.SetPrototype;
|
||||||
import com.ibm.wala.cast.js.types.JavaScriptTypes;
|
import com.ibm.wala.cast.js.types.JavaScriptTypes;
|
||||||
import com.ibm.wala.fixpoint.IVariable;
|
import com.ibm.wala.fixpoint.IVariable;
|
||||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||||
|
@ -36,7 +38,7 @@ public class JSTypeInference extends AstTypeInference {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initialize() {
|
protected void initialize() {
|
||||||
class JSTypeOperatorFactory extends AstTypeOperatorFactory implements com.ibm.wala.cast.js.ssa.InstructionVisitor {
|
class JSTypeOperatorFactory extends AstTypeOperatorFactory implements com.ibm.wala.cast.js.ssa.JSInstructionVisitor {
|
||||||
public void visitJavaScriptInvoke(JavaScriptInvoke inst) {
|
public void visitJavaScriptInvoke(JavaScriptInvoke inst) {
|
||||||
result = new DeclaredTypeOperator(new ConeType(cha.getRootClass()));
|
result = new DeclaredTypeOperator(new ConeType(cha.getRootClass()));
|
||||||
}
|
}
|
||||||
|
@ -61,6 +63,15 @@ public class JSTypeInference extends AstTypeInference {
|
||||||
|
|
||||||
public void visitWithRegion(JavaScriptWithRegion instruction) {
|
public void visitWithRegion(JavaScriptWithRegion instruction) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitSetPrototype(SetPrototype instruction) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitPrototypeLookup(PrototypeLookup instruction) {
|
||||||
|
result = new DeclaredTypeOperator(new ConeType(cha.getRootClass()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
package com.ibm.wala.cast.js.cfg;
|
package com.ibm.wala.cast.js.cfg;
|
||||||
|
|
||||||
import com.ibm.wala.cast.ir.cfg.AstInducedCFG;
|
import com.ibm.wala.cast.ir.cfg.AstInducedCFG;
|
||||||
import com.ibm.wala.cast.js.ssa.InstructionVisitor;
|
import com.ibm.wala.cast.js.ssa.JSInstructionVisitor;
|
||||||
import com.ibm.wala.cast.js.ssa.JavaScriptCheckReference;
|
import com.ibm.wala.cast.js.ssa.JavaScriptCheckReference;
|
||||||
import com.ibm.wala.cast.js.ssa.JavaScriptInstanceOf;
|
import com.ibm.wala.cast.js.ssa.JavaScriptInstanceOf;
|
||||||
import com.ibm.wala.cast.js.ssa.JavaScriptInvoke;
|
import com.ibm.wala.cast.js.ssa.JavaScriptInvoke;
|
||||||
|
@ -19,6 +19,8 @@ import com.ibm.wala.cast.js.ssa.JavaScriptPropertyRead;
|
||||||
import com.ibm.wala.cast.js.ssa.JavaScriptPropertyWrite;
|
import com.ibm.wala.cast.js.ssa.JavaScriptPropertyWrite;
|
||||||
import com.ibm.wala.cast.js.ssa.JavaScriptTypeOfInstruction;
|
import com.ibm.wala.cast.js.ssa.JavaScriptTypeOfInstruction;
|
||||||
import com.ibm.wala.cast.js.ssa.JavaScriptWithRegion;
|
import com.ibm.wala.cast.js.ssa.JavaScriptWithRegion;
|
||||||
|
import com.ibm.wala.cast.js.ssa.PrototypeLookup;
|
||||||
|
import com.ibm.wala.cast.js.ssa.SetPrototype;
|
||||||
import com.ibm.wala.classLoader.IMethod;
|
import com.ibm.wala.classLoader.IMethod;
|
||||||
import com.ibm.wala.ipa.callgraph.Context;
|
import com.ibm.wala.ipa.callgraph.Context;
|
||||||
import com.ibm.wala.ssa.SSAInstruction;
|
import com.ibm.wala.ssa.SSAInstruction;
|
||||||
|
@ -29,7 +31,7 @@ public class JSInducedCFG extends AstInducedCFG {
|
||||||
super(instructions, method, context);
|
super(instructions, method, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
class JSPEIVisitor extends AstPEIVisitor implements InstructionVisitor {
|
class JSPEIVisitor extends AstPEIVisitor implements JSInstructionVisitor {
|
||||||
|
|
||||||
JSPEIVisitor(boolean[] r) {
|
JSPEIVisitor(boolean[] r) {
|
||||||
super(r);
|
super(r);
|
||||||
|
@ -59,9 +61,17 @@ public class JSInducedCFG extends AstInducedCFG {
|
||||||
public void visitWithRegion(JavaScriptWithRegion instruction) {
|
public void visitWithRegion(JavaScriptWithRegion instruction) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitSetPrototype(SetPrototype instruction) {
|
||||||
}
|
}
|
||||||
|
|
||||||
class JSBranchVisitor extends AstBranchVisitor implements InstructionVisitor {
|
@Override
|
||||||
|
public void visitPrototypeLookup(PrototypeLookup instruction) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class JSBranchVisitor extends AstBranchVisitor implements JSInstructionVisitor {
|
||||||
|
|
||||||
JSBranchVisitor(boolean[] r) {
|
JSBranchVisitor(boolean[] r) {
|
||||||
super(r);
|
super(r);
|
||||||
|
@ -87,6 +97,14 @@ public class JSInducedCFG extends AstInducedCFG {
|
||||||
|
|
||||||
public void visitWithRegion(JavaScriptWithRegion instruction) {
|
public void visitWithRegion(JavaScriptWithRegion instruction) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitSetPrototype(SetPrototype instruction) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitPrototypeLookup(PrototypeLookup instruction) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected BranchVisitor makeBranchVisitor(boolean[] r) {
|
protected BranchVisitor makeBranchVisitor(boolean[] r) {
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.ibm.wala.cast.js.html;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
||||||
|
|
||||||
|
public class CompositeFileMapping implements FileMapping {
|
||||||
|
private final FileMapping a;
|
||||||
|
private final FileMapping b;
|
||||||
|
|
||||||
|
public CompositeFileMapping(FileMapping a, FileMapping b) {
|
||||||
|
this.a = a;
|
||||||
|
this.b = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IncludedPosition getIncludedPosition(Position line) {
|
||||||
|
IncludedPosition p = a.getIncludedPosition(line);
|
||||||
|
if (p != null) {
|
||||||
|
return p;
|
||||||
|
} else {
|
||||||
|
return b.getIncludedPosition(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dump(PrintStream ps) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return a + "," + b;
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,19 +11,22 @@
|
||||||
|
|
||||||
package com.ibm.wala.cast.js.html;
|
package com.ibm.wala.cast.js.html;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
||||||
import com.ibm.wala.util.collections.HashMapFactory;
|
import com.ibm.wala.util.collections.HashMapFactory;
|
||||||
import com.ibm.wala.util.collections.Pair;
|
import com.ibm.wala.util.collections.Pair;
|
||||||
|
|
||||||
public class DefaultSourceExtractor extends DomLessSourceExtractor{
|
public class DefaultSourceExtractor extends DomLessSourceExtractor{
|
||||||
|
|
||||||
private static class HtmlCallBack extends DomLessSourceExtractor.HtmlCallback{
|
protected static class HtmlCallBack extends DomLessSourceExtractor.HtmlCallback{
|
||||||
|
|
||||||
private final HashMap<String, String> constructors = HashMapFactory.make();
|
private final HashMap<String, String> constructors = HashMapFactory.make();
|
||||||
|
|
||||||
|
@ -45,9 +48,15 @@ public class DefaultSourceExtractor extends DomLessSourceExtractor{
|
||||||
if (tag.getName().equalsIgnoreCase("FORM")) {
|
if (tag.getName().equalsIgnoreCase("FORM")) {
|
||||||
forms.pop();
|
forms.pop();
|
||||||
}
|
}
|
||||||
for(String v : tag.getAllAttributes().values()) {
|
for(Entry<String,Pair<String, Position>> e : tag.getAllAttributes().entrySet()) {
|
||||||
|
String a = e.getKey();
|
||||||
|
String v = e.getValue().fst;
|
||||||
if (v != null && v.startsWith("javascript:")) {
|
if (v != null && v.startsWith("javascript:")) {
|
||||||
entrypointRegion.println(v.substring(11), makePos(tag.getStartingLineNum(), tag));
|
try {
|
||||||
|
entrypointRegion.println(" " + v.substring(11), e.getValue().snd, new URL(tag.getElementPosition().getURL().toString() + "#" + a));
|
||||||
|
} catch (MalformedURLException ex) {
|
||||||
|
entrypointRegion.println(v.substring(11), e.getValue().snd, entrypointUrl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,16 +71,20 @@ public class DefaultSourceExtractor extends DomLessSourceExtractor{
|
||||||
}
|
}
|
||||||
|
|
||||||
private void printlnIndented(String line, ITag relatedTag){
|
private void printlnIndented(String line, ITag relatedTag){
|
||||||
|
printlnIndented(line, relatedTag==null? null: relatedTag.getElementPosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printlnIndented(String line, Position pos){
|
||||||
StringBuilder indentedLine = new StringBuilder();
|
StringBuilder indentedLine = new StringBuilder();
|
||||||
for (int i = 0 ; i < stack.size() ; i++){
|
for (int i = 0 ; i < stack.size() ; i++){
|
||||||
indentedLine.append(" ");
|
indentedLine.append(" ");
|
||||||
}
|
}
|
||||||
indentedLine.append(line);
|
indentedLine.append(line);
|
||||||
|
|
||||||
if (relatedTag == null){
|
if (pos == null){
|
||||||
domRegion.println(indentedLine.toString());
|
domRegion.println(indentedLine.toString());
|
||||||
} else {
|
} else {
|
||||||
domRegion.println(indentedLine.toString(), makePos(relatedTag.getStartingLineNum(), relatedTag));
|
domRegion.println(indentedLine.toString(), pos, entrypointUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,16 +93,17 @@ public class DefaultSourceExtractor extends DomLessSourceExtractor{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void writeElement(ITag tag, String cons, String varName){
|
protected void writeElement(ITag tag, String cons, String varName){
|
||||||
|
Map<String, Pair<String, Position>> attrs = tag.getAllAttributes();
|
||||||
|
|
||||||
printlnIndented("function make_" + varName + "(parent) {", tag);
|
printlnIndented("function make_" + varName + "(parent) {", tag);
|
||||||
stack.push(varName);
|
stack.push(varName);
|
||||||
|
|
||||||
printlnIndented("this.temp = " + cons + ";", tag);
|
printlnIndented("this.temp = " + cons + ";", tag);
|
||||||
printlnIndented("this.temp(\"" + tag.getName() + "\");", tag);
|
printlnIndented("this.temp(\"" + tag.getName() + "\");", tag);
|
||||||
for (Map.Entry<String, String> e : tag.getAllAttributes().entrySet()){
|
for (Map.Entry<String, Pair<String, Position>> e : attrs.entrySet()){
|
||||||
String attr = e.getKey();
|
String attr = e.getKey();
|
||||||
String value = e.getValue();
|
String value = e.getValue().fst;
|
||||||
writeAttribute(tag, attr, value, "this", varName);
|
writeAttribute(tag, e.getValue().snd, attr, value, "this", varName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tag.getName().equalsIgnoreCase("FORM")) {
|
if (tag.getName().equalsIgnoreCase("FORM")) {
|
||||||
|
@ -97,15 +111,8 @@ public class DefaultSourceExtractor extends DomLessSourceExtractor{
|
||||||
printlnIndented(" document.forms[document.formCount++] = this;", tag);
|
printlnIndented(" document.forms[document.formCount++] = this;", tag);
|
||||||
printlnIndented(" var currentForm = this;", tag);
|
printlnIndented(" var currentForm = this;", tag);
|
||||||
} if (tag.getName().equalsIgnoreCase("INPUT")) {
|
} if (tag.getName().equalsIgnoreCase("INPUT")) {
|
||||||
String prop = tag.getAttributeByName("NAME");
|
String prop = attrs.containsKey("name") ? attrs.get("name").fst : null;
|
||||||
if (prop == null) {
|
String type = attrs.containsKey("type") ? attrs.get("type").fst : null;
|
||||||
prop = tag.getAttributeByName("name");
|
|
||||||
}
|
|
||||||
|
|
||||||
String type = tag.getAttributeByName("TYPE");
|
|
||||||
if (type == null) {
|
|
||||||
type = tag.getAttributeByName("type");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type != null && prop != null) {
|
if (type != null && prop != null) {
|
||||||
if (type.equalsIgnoreCase("RADIO")) {
|
if (type.equalsIgnoreCase("RADIO")) {
|
||||||
|
@ -126,15 +133,15 @@ public class DefaultSourceExtractor extends DomLessSourceExtractor{
|
||||||
printlnIndented("parent.appendChild(this);", tag);
|
printlnIndented("parent.appendChild(this);", tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void writeAttribute(ITag tag, String attr, String value, String varName, String varName2) {
|
protected void writeAttribute(ITag tag, Position pos, String attr, String value, String varName, String varName2) {
|
||||||
writePortletAttribute(tag, attr, value, varName);
|
writePortletAttribute(tag, attr, value, varName);
|
||||||
writeEventAttribute(tag, attr, value, varName, varName2);
|
writeEventAttribute(tag, pos, attr, value, varName, varName2);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void writeEventAttribute(ITag tag, String attr, String value, String varName, String varName2){
|
protected void writeEventAttribute(ITag tag, Position pos, String attr, String value, String varName, String varName2){
|
||||||
if(attr.substring(0,2).equals("on")) {
|
if(attr.substring(0,2).equals("on")) {
|
||||||
printlnIndented(varName + "." + attr + " = function " + tag.getName().toLowerCase() + "_" + attr + "(event) {" + value + "};", tag);
|
printlnIndented(varName + "." + attr + " = function " + tag.getName().toLowerCase() + "_" + attr + "(event) {" + value + "};", tag);
|
||||||
entrypointRegion.println(varName2 + "." + attr + "(null);", makePos(tag.getStartingLineNum(), tag));
|
entrypointRegion.println(varName2 + "." + attr + "(null);", tag.getElementPosition(), entrypointUrl);
|
||||||
} else if (value != null) {
|
} else if (value != null) {
|
||||||
if (value.indexOf('\'') > 0) {
|
if (value.indexOf('\'') > 0) {
|
||||||
value = value.replaceAll("\\'", "\\\\'");
|
value = value.replaceAll("\\'", "\\\\'");
|
||||||
|
@ -162,11 +169,11 @@ public class DefaultSourceExtractor extends DomLessSourceExtractor{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void endElement(String name) {
|
protected void endElement(String name) {
|
||||||
printlnIndented("};", null);
|
printlnIndented("};", (Position)null);
|
||||||
if (stack.isEmpty()) {
|
if (stack.isEmpty()) {
|
||||||
printlnIndented("new make_" + name + "(document);\n\n", null);
|
printlnIndented("new make_" + name + "(document);\n\n", (Position)null);
|
||||||
} else {
|
} else {
|
||||||
printlnIndented("new make_" + name + "(this);\n", null);
|
printlnIndented("new make_" + name + "(this);\n", (Position)null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,13 +24,13 @@ import java.util.Set;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import com.ibm.wala.cast.js.html.jericho.JerichoHtmlParser;
|
import com.ibm.wala.cast.js.html.jericho.JerichoHtmlParser;
|
||||||
import com.ibm.wala.cast.tree.impl.LineNumberPosition;
|
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
||||||
import com.ibm.wala.util.functions.Function;
|
import com.ibm.wala.util.collections.Pair;
|
||||||
|
|
||||||
|
|
||||||
public class DomLessSourceExtractor extends JSSourceExtractor {
|
public class DomLessSourceExtractor extends JSSourceExtractor {
|
||||||
private static final Pattern LEGAL_JS_IDENTIFIER_REGEXP = Pattern.compile("[a-zA-Z$_][a-zA-Z\\d$_]*");
|
private static final Pattern LEGAL_JS_IDENTIFIER_REGEXP = Pattern.compile("[a-zA-Z$_][a-zA-Z\\d$_]*");
|
||||||
interface IGeneratorCallback extends IHtmlCallback {
|
protected interface IGeneratorCallback extends IHtmlCallback {
|
||||||
void writeToFinalRegion(SourceRegion finalRegion);
|
void writeToFinalRegion(SourceRegion finalRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,8 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
|
||||||
|
|
||||||
private ITag currentScriptTag;
|
private ITag currentScriptTag;
|
||||||
|
|
||||||
private int counter = 0;
|
private int nodeCounter = 0;
|
||||||
|
private int scriptNodeCounter = 0;
|
||||||
|
|
||||||
public HtmlCallback(URL entrypointUrl, IUrlResolver urlResolver) {
|
public HtmlCallback(URL entrypointUrl, IUrlResolver urlResolver) {
|
||||||
this.entrypointUrl = entrypointUrl;
|
this.entrypointUrl = entrypointUrl;
|
||||||
|
@ -54,17 +55,12 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
|
||||||
this.entrypointRegion = new SourceRegion();
|
this.entrypointRegion = new SourceRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Function<Integer,IncludedPosition> makePos(int lineNumber, ITag governingTag) {
|
protected Position makePos(int lineNumber, ITag governingTag) {
|
||||||
return makePos(entrypointUrl, lineNumber, governingTag);
|
return makePos(entrypointUrl, lineNumber, governingTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Function<Integer,IncludedPosition> makePos(final URL url, final int lineNumber, ITag governingTag) {
|
protected Position makePos(final URL url, final int lineNumber, ITag governingTag) {
|
||||||
final LineNumberPosition includePos = new LineNumberPosition(entrypointUrl, entrypointUrl, governingTag.getStartingLineNum());
|
return governingTag.getElementPosition();
|
||||||
return new Function<Integer,IncludedPosition>() {
|
|
||||||
public IncludedPosition apply(Integer object) {
|
|
||||||
return new IncludedLineNumberPosition(url, url, lineNumber + object.intValue(), includePos);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleEndTag(ITag tag) {
|
public void handleEndTag(ITag tag) {
|
||||||
|
@ -74,14 +70,22 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void handleText(Position p, String text) {
|
||||||
public void handleText(final int lineNumber, String text) {
|
|
||||||
if (currentScriptTag != null) {
|
if (currentScriptTag != null) {
|
||||||
if (text.startsWith("<![CDATA[")) {
|
if (text.startsWith("<![CDATA[")) {
|
||||||
assert text.endsWith("]]>");
|
assert text.endsWith("]]>");
|
||||||
text = text.substring(9, text.length()-11);
|
text = text.substring(9, text.length()-11);
|
||||||
}
|
}
|
||||||
scriptRegion.println(text, makePos(lineNumber, currentScriptTag));
|
|
||||||
|
URL url = entrypointUrl;
|
||||||
|
try {
|
||||||
|
url = new URL(entrypointUrl, "#" + scriptNodeCounter);
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
scriptRegion.println(text, currentScriptTag.getContentPosition(), url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +94,7 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
|
||||||
handleScript(tag);
|
handleScript(tag);
|
||||||
assert currentScriptTag == null;
|
assert currentScriptTag == null;
|
||||||
currentScriptTag = tag;
|
currentScriptTag = tag;
|
||||||
|
scriptNodeCounter++;
|
||||||
}
|
}
|
||||||
handleDOM(tag);
|
handleDOM(tag);
|
||||||
}
|
}
|
||||||
|
@ -103,44 +108,47 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
|
||||||
protected void handleDOM(ITag tag) {
|
protected void handleDOM(ITag tag) {
|
||||||
// Get the name of the modeling function either from the id attribute or a
|
// Get the name of the modeling function either from the id attribute or a
|
||||||
// running counter
|
// running counter
|
||||||
String idAttribute = tag.getAttributeByName("id");
|
Pair<String,Position> idAttribute = tag.getAttributeByName("id");
|
||||||
String funcName;
|
String funcName;
|
||||||
if (idAttribute != null && LEGAL_JS_IDENTIFIER_REGEXP.matcher(idAttribute).matches()) {
|
if (idAttribute != null && LEGAL_JS_IDENTIFIER_REGEXP.matcher(idAttribute.fst).matches()) {
|
||||||
funcName = idAttribute;
|
funcName = idAttribute.fst;
|
||||||
} else {
|
} else {
|
||||||
funcName = "node" + (counter++);
|
funcName = "node" + (nodeCounter++);
|
||||||
}
|
}
|
||||||
handleDOM(tag, funcName);
|
handleDOM(tag, funcName);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void handleDOM(ITag tag, String funcName) {
|
protected void handleDOM(ITag tag, String funcName) {
|
||||||
Map<String, String> attributeSet = tag.getAllAttributes();
|
Map<String, Pair<String,Position>> attributeSet = tag.getAllAttributes();
|
||||||
for (Entry<String, String> a : attributeSet.entrySet()) {
|
for (Entry<String, Pair<String, Position>> a : attributeSet.entrySet()) {
|
||||||
handleAttribute(a, funcName, tag);
|
handleAttribute(a, funcName, tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleAttribute(Entry<String, String> a, String funcName, ITag tag) {
|
private void handleAttribute(Entry<String, Pair<String,Position>> a, String funcName, ITag tag) {
|
||||||
int lineNum = tag.getStartingLineNum();
|
URL url = entrypointUrl;
|
||||||
|
try {
|
||||||
|
url = new URL(entrypointUrl, "#" + tag.getElementPosition().getFirstOffset());
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
Position pos = a.getValue().snd;
|
||||||
String attName = a.getKey();
|
String attName = a.getKey();
|
||||||
String attValue = a.getValue();
|
String attValue = a.getValue().fst;
|
||||||
if (attName.toLowerCase().startsWith("on") || (attValue != null && attValue.toLowerCase().startsWith("javascript:"))) {
|
if (attName.toLowerCase().startsWith("on") || (attValue != null && attValue.toLowerCase().startsWith("javascript:"))) {
|
||||||
String fName = tag.getName().toLowerCase() + "_" + attName + "_" + funcName;
|
String fName = tag.getName().toLowerCase() + "_" + attName + "_" + funcName;
|
||||||
String signatureLine = "function " + fName + "(event) {";
|
String signatureLine = "function " + fName + "(event) {";
|
||||||
domRegion.println(signatureLine, makePos(lineNum, tag));// Defines the function
|
// Defines the function
|
||||||
int offset = 0;
|
domRegion.println(signatureLine + "\n" + extructJS(attValue) + "\n}", pos, url);
|
||||||
for (String eventContentLine : extructJS(attValue)){
|
// Run it
|
||||||
domRegion.println("\t" + eventContentLine, makePos(lineNum + (offset++), tag));
|
entrypointRegion.println("\t" + fName + "(null);", pos, url);
|
||||||
}
|
|
||||||
domRegion.println("}", makePos(lineNum, tag));// Defines the function
|
|
||||||
|
|
||||||
entrypointRegion.println("\t" + fName + "(null);", makePos(lineNum, tag));// Run it
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] extructJS(String attValue) {
|
private String extructJS(String attValue) {
|
||||||
if (attValue == null){
|
if (attValue == null){
|
||||||
return new String[] {};
|
return "";
|
||||||
}
|
}
|
||||||
String content;
|
String content;
|
||||||
if (attValue.toLowerCase().equals("javascript:")) {
|
if (attValue.toLowerCase().equals("javascript:")) {
|
||||||
|
@ -149,17 +157,17 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
|
||||||
content = attValue;
|
content = attValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return content.split("\\n");
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void handleScript(ITag tag) {
|
protected void handleScript(ITag tag) {
|
||||||
|
|
||||||
String value = tag.getAttributeByName("src");
|
Pair<String,Position> value = tag.getAttributeByName("src");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
// script is out-of-line
|
// script is out-of-line
|
||||||
getScriptFromUrl(value, tag);
|
getScriptFromUrl(value.fst, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -176,13 +184,15 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
|
||||||
|
|
||||||
InputStream scriptInputStream = scriptSrc.openConnection().getInputStream();
|
InputStream scriptInputStream = scriptSrc.openConnection().getInputStream();
|
||||||
try{
|
try{
|
||||||
int lineNum = 1;
|
|
||||||
String line;
|
String line;
|
||||||
BufferedReader scriptReader = new BufferedReader(new UnicodeReader(scriptInputStream, "UTF8"));
|
BufferedReader scriptReader = new BufferedReader(new UnicodeReader(scriptInputStream, "UTF8"));
|
||||||
|
StringBuffer x = new StringBuffer();
|
||||||
while ((line = scriptReader.readLine()) != null) {
|
while ((line = scriptReader.readLine()) != null) {
|
||||||
scriptRegion.println(line, makePos(scriptSrc, lineNum++, scriptTag));
|
x.append(line).append("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scriptRegion.println(x.toString(), scriptTag.getElementPosition(), scriptSrc);
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
scriptInputStream.close();
|
scriptInputStream.close();
|
||||||
}
|
}
|
||||||
|
@ -219,7 +229,7 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
|
||||||
|
|
||||||
InputStream inputStreamReader = WebUtil.getStream(entrypointUrl);
|
InputStream inputStreamReader = WebUtil.getStream(entrypointUrl);
|
||||||
IGeneratorCallback htmlCallback = createHtmlCallback(entrypointUrl, urlResolver);
|
IGeneratorCallback htmlCallback = createHtmlCallback(entrypointUrl, urlResolver);
|
||||||
htmlParser.parse(inputStreamReader, htmlCallback, entrypointUrl.getFile());
|
htmlParser.parse(entrypointUrl, inputStreamReader, htmlCallback, entrypointUrl.getFile());
|
||||||
|
|
||||||
SourceRegion finalRegion = new SourceRegion();
|
SourceRegion finalRegion = new SourceRegion();
|
||||||
htmlCallback.writeToFinalRegion(finalRegion);
|
htmlCallback.writeToFinalRegion(finalRegion);
|
||||||
|
|
|
@ -1,43 +1,17 @@
|
||||||
/******************************************************************************
|
|
||||||
* Copyright (c) 2002 - 2011 IBM Corporation.
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* IBM Corporation - initial API and implementation
|
|
||||||
*****************************************************************************/
|
|
||||||
package com.ibm.wala.cast.js.html;
|
package com.ibm.wala.cast.js.html;
|
||||||
|
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
|
|
||||||
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
||||||
import com.ibm.wala.util.collections.HashMapFactory;
|
|
||||||
|
|
||||||
/**
|
public interface FileMapping {
|
||||||
* Maps line numbers to lines of other files (fileName + line).
|
|
||||||
*/
|
|
||||||
public class FileMapping{
|
|
||||||
protected Map<Integer, IncludedPosition> lineNumberToFileAndLine = HashMapFactory.make();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param line
|
* @param line
|
||||||
* @return Null if no mapping for the given line.
|
* @return Null if no mapping for the given line.
|
||||||
*/
|
*/
|
||||||
public IncludedPosition getAssociatedFileAndLine(int line){
|
public abstract IncludedPosition getIncludedPosition(Position line);
|
||||||
return lineNumberToFileAndLine.get(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dump(PrintStream ps){
|
public abstract void dump(PrintStream ps);
|
||||||
Set<Integer> lines = new TreeSet<Integer>(lineNumberToFileAndLine.keySet());
|
|
||||||
for (Integer line : lines){
|
|
||||||
Position fnAndln = lineNumberToFileAndLine.get(line);
|
|
||||||
ps.println(line + ": " + fnAndln);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -10,6 +10,8 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
package com.ibm.wala.cast.js.html;
|
package com.ibm.wala.cast.js.html;
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,7 +24,7 @@ public interface IHtmlCallback {
|
||||||
|
|
||||||
void handleStartTag(ITag tag);
|
void handleStartTag(ITag tag);
|
||||||
|
|
||||||
void handleText(int lineNumber, String text);
|
void handleText(Position pos, String text);
|
||||||
|
|
||||||
void handleEndTag(ITag tag);
|
void handleEndTag(ITag tag);
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
package com.ibm.wala.cast.js.html;
|
package com.ibm.wala.cast.js.html;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author danielk
|
* @author danielk
|
||||||
|
@ -25,6 +26,6 @@ public interface IHtmlParser {
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param fileName
|
* @param fileName
|
||||||
*/
|
*/
|
||||||
public void parse(InputStream reader, IHtmlCallback callback, String fileName);
|
public void parse(URL url, InputStream reader, IHtmlCallback callback, String fileName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,9 @@ package com.ibm.wala.cast.js.html;
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
||||||
|
import com.ibm.wala.util.collections.Pair;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author danielk
|
* @author danielk
|
||||||
* Data structure representing an HTML tag, with its attributes and content. Used by the HTML parser when calling the callback.
|
* Data structure representing an HTML tag, with its attributes and content. Used by the HTML parser when calling the callback.
|
||||||
|
@ -28,13 +31,15 @@ public interface ITag {
|
||||||
* @param name
|
* @param name
|
||||||
* @return null if there is no such attribute
|
* @return null if there is no such attribute
|
||||||
*/
|
*/
|
||||||
public String getAttributeByName(String name);
|
public Pair<String, Position> getAttributeByName(String name);
|
||||||
|
|
||||||
public Map<String, String> getAllAttributes();
|
public Map<String, Pair<String, Position>> getAllAttributes();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the starting line number of the tag.
|
* Returns the starting line number of the tag.
|
||||||
* @return null if no known
|
* @return null if no known
|
||||||
*/
|
*/
|
||||||
public int getStartingLineNum();
|
public Position getElementPosition();
|
||||||
|
|
||||||
|
public Position getContentPosition();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
* Copyright (c) 2002 - 2011 IBM Corporation.
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* IBM Corporation - initial API and implementation
|
|
||||||
*****************************************************************************/
|
|
||||||
package com.ibm.wala.cast.js.html;
|
|
||||||
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
|
||||||
import com.ibm.wala.cast.tree.impl.LineNumberPosition;
|
|
||||||
|
|
||||||
public class IncludedLineNumberPosition extends LineNumberPosition implements IncludedPosition {
|
|
||||||
private final Position includePosition;
|
|
||||||
|
|
||||||
public IncludedLineNumberPosition(URL url, URL localFile, int lineNumber, Position includePosition) {
|
|
||||||
super(url, localFile, lineNumber);
|
|
||||||
this.includePosition = includePosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Position getIncludePosition() {
|
|
||||||
return includePosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return super.toString() + "(from " + includePosition +")";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -23,9 +23,9 @@ import java.util.Set;
|
||||||
*/
|
*/
|
||||||
public abstract class JSSourceExtractor {
|
public abstract class JSSourceExtractor {
|
||||||
|
|
||||||
public static boolean DELETE_UPON_EXIT = true;
|
public static boolean DELETE_UPON_EXIT = false;
|
||||||
|
|
||||||
public static boolean USE_TEMP_NAME = true;
|
public static boolean USE_TEMP_NAME = false;
|
||||||
|
|
||||||
public abstract Set<MappedSourceModule> extractSources(URL entrypointUrl, IHtmlParser htmlParser, IUrlResolver urlResolver) throws IOException;
|
public abstract Set<MappedSourceModule> extractSources(URL entrypointUrl, IHtmlParser htmlParser, IUrlResolver urlResolver) throws IOException;
|
||||||
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
* Copyright (c) 2002 - 2011 IBM Corporation.
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* IBM Corporation - initial API and implementation
|
|
||||||
*****************************************************************************/
|
|
||||||
package com.ibm.wala.cast.js.html;
|
|
||||||
|
|
||||||
public class MutableFileMapping extends FileMapping {
|
|
||||||
|
|
||||||
void map(int line, IncludedPosition originalPos){
|
|
||||||
lineNumberToFileAndLine.put(line, originalPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
package com.ibm.wala.cast.js.html;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.js.html.RangeFileMapping.Range;
|
||||||
|
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
||||||
|
import com.ibm.wala.cast.tree.impl.AbstractSourcePosition;
|
||||||
|
|
||||||
|
public class NestedRangeMapping implements FileMapping {
|
||||||
|
private final Range range;
|
||||||
|
private final FileMapping innerMapping;
|
||||||
|
|
||||||
|
public NestedRangeMapping(int rangeStart, int rangeEnd, int rangeStartingLine, int rangeEndingLine, FileMapping innerMapping) {
|
||||||
|
assert innerMapping != null;
|
||||||
|
this.range = new Range(rangeStart, rangeEnd, rangeStartingLine, rangeEndingLine);
|
||||||
|
this.innerMapping = innerMapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IncludedPosition getIncludedPosition(final Position pos) {
|
||||||
|
if (range.includes(pos)) {
|
||||||
|
return innerMapping.getIncludedPosition(
|
||||||
|
new AbstractSourcePosition() {
|
||||||
|
@Override
|
||||||
|
public int getFirstLine() {
|
||||||
|
return pos.getFirstLine()-range.getStartingLine()+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLastLine() {
|
||||||
|
return pos.getLastLine()==-1? -1: (pos.getLastLine()-range.getStartingLine()+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFirstCol() {
|
||||||
|
return pos.getFirstCol();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLastCol() {
|
||||||
|
return pos.getLastCol();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFirstOffset() {
|
||||||
|
return pos.getFirstOffset()==-1? -1: (pos.getFirstOffset()-range.getStart());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLastOffset() {
|
||||||
|
return pos.getLastOffset()==-1? -1: (pos.getLastOffset()-range.getStart());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URL getURL() {
|
||||||
|
return pos.getURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getInputStream() throws IOException {
|
||||||
|
return pos.getInputStream();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dump(PrintStream ps) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return range + "(" + innerMapping + ")";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
package com.ibm.wala.cast.js.html;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
||||||
|
import com.ibm.wala.cast.tree.impl.AbstractSourcePosition;
|
||||||
|
|
||||||
|
public class RangeFileMapping implements FileMapping {
|
||||||
|
|
||||||
|
public static class Range {
|
||||||
|
private final int rangeStart;
|
||||||
|
private final int rangeEnd;
|
||||||
|
private final int rangeStartingLine;
|
||||||
|
private final int rangeEndingLine;
|
||||||
|
|
||||||
|
public boolean includes(Position offset) {
|
||||||
|
return
|
||||||
|
offset.getFirstOffset() != -1?
|
||||||
|
rangeStart <= offset.getFirstOffset() && offset.getLastOffset() <= rangeEnd:
|
||||||
|
rangeStartingLine <= offset.getFirstLine() &&
|
||||||
|
(offset.getLastLine() == -1? offset.getFirstLine(): offset.getLastLine()) <= rangeEndingLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Range(int rangeStart, int rangeEnd, int rangeStartingLine, int rangeEndingLine) {
|
||||||
|
super();
|
||||||
|
this.rangeStart = rangeStart;
|
||||||
|
this.rangeEnd = rangeEnd;
|
||||||
|
this.rangeStartingLine = rangeStartingLine;
|
||||||
|
this.rangeEndingLine = rangeEndingLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStart() {
|
||||||
|
return rangeStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEnd() {
|
||||||
|
return rangeEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStartingLine() {
|
||||||
|
return rangeStartingLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEndingLine() {
|
||||||
|
return rangeEndingLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "{"+rangeStart+"->"+rangeEnd+"}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Range range;
|
||||||
|
private final URL includedURL;
|
||||||
|
private final Position includePosition;
|
||||||
|
|
||||||
|
public RangeFileMapping(int rangeStart, int rangeEnd, int rangeStartingLine, int rangeEndingLine, Position parentPosition, URL url) {
|
||||||
|
assert parentPosition != null;
|
||||||
|
this.range = new Range(rangeStart, rangeEnd, rangeStartingLine, rangeEndingLine);
|
||||||
|
this.includePosition = parentPosition;
|
||||||
|
includedURL = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return range + ":" + includePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IncludedPosition getIncludedPosition(final Position offset) {
|
||||||
|
if (range.includes(offset)) {
|
||||||
|
class Pos extends AbstractSourcePosition implements IncludedPosition {
|
||||||
|
@Override
|
||||||
|
public int getFirstLine() {
|
||||||
|
// line numbers are decreed to start at 1, rather than 0
|
||||||
|
return offset.getFirstLine() - range.getStartingLine() + 1;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int getLastLine() {
|
||||||
|
return offset.getLastLine() == -1? -1: offset.getLastLine()-range.getStartingLine()+1;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int getFirstCol() {
|
||||||
|
return offset.getFirstCol();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int getLastCol() {
|
||||||
|
return offset.getLastCol();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int getFirstOffset() {
|
||||||
|
return offset.getFirstOffset() == -1? -1: offset.getFirstOffset()-range.getStart();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int getLastOffset() {
|
||||||
|
return offset.getLastOffset() == -1? -1: offset.getLastOffset()-range.getStart();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public URL getURL() {
|
||||||
|
return includedURL;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public InputStream getInputStream() throws IOException {
|
||||||
|
return includedURL.openConnection().getInputStream();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Position getIncludePosition() {
|
||||||
|
return includePosition;
|
||||||
|
}
|
||||||
|
public String toString() {
|
||||||
|
return "[include:"+includePosition+"]"+super.toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return new Pos();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dump(PrintStream ps) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -10,46 +10,45 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
package com.ibm.wala.cast.js.html;
|
package com.ibm.wala.cast.js.html;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.io.StringReader;
|
import java.net.URL;
|
||||||
import java.util.StringTokenizer;
|
|
||||||
|
|
||||||
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
||||||
import com.ibm.wala.util.functions.Function;
|
|
||||||
|
|
||||||
public class SourceRegion {
|
public class SourceRegion {
|
||||||
|
|
||||||
private final StringBuilder source = new StringBuilder();
|
private final StringBuilder source = new StringBuilder();
|
||||||
private final MutableFileMapping fileMapping = new MutableFileMapping();
|
private FileMapping fileMapping;
|
||||||
private int currentLine = 1;
|
private int currentLine = 1;
|
||||||
|
|
||||||
public SourceRegion() {
|
public SourceRegion() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void print(String text, Function<Integer,IncludedPosition> originalPos){
|
public void print(String text, Position originalPos, URL url){
|
||||||
|
int startOffset = source.length();
|
||||||
source.append(text);
|
source.append(text);
|
||||||
int ln = 0;
|
int endOffset = source.length();
|
||||||
|
|
||||||
int numberOfLineDrops = getNumberOfLineDrops(text);
|
int numberOfLineDrops = getNumberOfLineDrops(text);
|
||||||
if (originalPos != null){
|
|
||||||
for (int i = 0; i < numberOfLineDrops; i++){
|
if (originalPos != null) {
|
||||||
fileMapping.map(currentLine++, originalPos.apply(ln++));
|
RangeFileMapping map = new RangeFileMapping(startOffset, endOffset, currentLine, currentLine+numberOfLineDrops, originalPos, url);
|
||||||
}
|
if (fileMapping == null) {
|
||||||
if (! text.endsWith("\n")){ // avoid mapping one line too much
|
fileMapping = map;
|
||||||
fileMapping.map(currentLine, originalPos.apply(ln)); // required for handling text with no CRs.
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
currentLine += numberOfLineDrops;
|
fileMapping = new CompositeFileMapping(map, fileMapping);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void println(String text, Function<Integer,IncludedPosition> originalPos){
|
currentLine += numberOfLineDrops;
|
||||||
print(text + "\n", originalPos);
|
}
|
||||||
|
|
||||||
|
public void println(String text, Position originalPos, URL url){
|
||||||
|
print(text + "\n", originalPos, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void print(String text){
|
public void print(String text){
|
||||||
print(text, null);
|
print(text, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void println(String text){
|
public void println(String text){
|
||||||
|
@ -62,42 +61,27 @@ public class SourceRegion {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(SourceRegion otherRegion){
|
public void write(SourceRegion otherRegion){
|
||||||
BufferedReader br = new BufferedReader(new StringReader(otherRegion.source.toString()));
|
int rangeStart = source.length();
|
||||||
int lineNum = 0;
|
String text = otherRegion.source.toString();
|
||||||
String line;
|
source.append(text);
|
||||||
try {
|
int rangeEnd = source.length();
|
||||||
while ((line = br.readLine()) != null){
|
|
||||||
lineNum++;
|
|
||||||
|
|
||||||
IncludedPosition fileAndLine = otherRegion.fileMapping.getAssociatedFileAndLine(lineNum);
|
int numberOfLineDrops = getNumberOfLineDrops(text);
|
||||||
if (fileAndLine!= null){
|
|
||||||
fileMapping.map(currentLine, fileAndLine);
|
if (otherRegion.fileMapping != null) {
|
||||||
|
FileMapping map = new NestedRangeMapping(rangeStart, rangeEnd, currentLine, currentLine+numberOfLineDrops, otherRegion.fileMapping);
|
||||||
|
if (fileMapping == null) {
|
||||||
|
fileMapping = map;
|
||||||
|
} else {
|
||||||
|
fileMapping = new CompositeFileMapping(map, fileMapping);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.println(line);
|
currentLine += numberOfLineDrops;
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
assert false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dump(PrintStream ps){
|
public void dump(PrintStream ps){
|
||||||
StringTokenizer st = new StringTokenizer(source.toString(),"\n");
|
ps.println(source.toString());
|
||||||
int lineNum = 0;
|
|
||||||
while (st.hasMoreElements()){
|
|
||||||
String line = (String) st.nextElement();
|
|
||||||
lineNum++;
|
|
||||||
|
|
||||||
Position fileAndLine = fileMapping.getAssociatedFileAndLine(lineNum);
|
|
||||||
if (fileAndLine!= null){
|
|
||||||
ps.print(fileAndLine + "\t:");
|
|
||||||
} else {
|
|
||||||
ps.print("N/A \t\t:");
|
|
||||||
}
|
|
||||||
|
|
||||||
ps.println(line);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getNumberOfLineDrops(String text) {
|
private static int getNumberOfLineDrops(String text) {
|
||||||
|
|
|
@ -12,6 +12,7 @@ package com.ibm.wala.cast.js.html.jericho;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -20,7 +21,6 @@ import net.htmlparser.jericho.Element;
|
||||||
import net.htmlparser.jericho.LoggerProvider;
|
import net.htmlparser.jericho.LoggerProvider;
|
||||||
import net.htmlparser.jericho.Source;
|
import net.htmlparser.jericho.Source;
|
||||||
|
|
||||||
|
|
||||||
import com.ibm.wala.cast.js.html.IHtmlCallback;
|
import com.ibm.wala.cast.js.html.IHtmlCallback;
|
||||||
import com.ibm.wala.cast.js.html.IHtmlParser;
|
import com.ibm.wala.cast.js.html.IHtmlParser;
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ public class JerichoHtmlParser implements IHtmlParser{
|
||||||
Config.LoggerProvider = LoggerProvider.STDERR;
|
Config.LoggerProvider = LoggerProvider.STDERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void parse(InputStream reader, IHtmlCallback callback, String fileName) {
|
public void parse(URL url, InputStream reader, IHtmlCallback callback, String fileName) {
|
||||||
Parser parser = new Parser(callback, fileName);
|
Parser parser = new Parser(callback, fileName);
|
||||||
Source src;
|
Source src;
|
||||||
try {
|
try {
|
||||||
|
@ -64,7 +64,7 @@ public class JerichoHtmlParser implements IHtmlParser{
|
||||||
private void parse(Element root) {
|
private void parse(Element root) {
|
||||||
JerichoTag tag = new JerichoTag(root, fileName);
|
JerichoTag tag = new JerichoTag(root, fileName);
|
||||||
handler.handleStartTag(tag);
|
handler.handleStartTag(tag);
|
||||||
handler.handleText(tag.getStartingLineNum(), tag.getBodyText().snd);
|
handler.handleText(tag.getElementPosition(), tag.getBodyText().snd);
|
||||||
List<Element> childElements = root.getChildElements();
|
List<Element> childElements = root.getChildElements();
|
||||||
for (Iterator<Element> nodeIterator = childElements.iterator(); nodeIterator.hasNext();) {
|
for (Iterator<Element> nodeIterator = childElements.iterator(); nodeIterator.hasNext();) {
|
||||||
Element child = nodeIterator.next();
|
Element child = nodeIterator.next();
|
||||||
|
|
|
@ -10,14 +10,20 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
package com.ibm.wala.cast.js.html.jericho;
|
package com.ibm.wala.cast.js.html.jericho;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import net.htmlparser.jericho.Attributes;
|
import net.htmlparser.jericho.Attribute;
|
||||||
import net.htmlparser.jericho.Element;
|
import net.htmlparser.jericho.Element;
|
||||||
import net.htmlparser.jericho.Segment;
|
import net.htmlparser.jericho.Segment;
|
||||||
|
|
||||||
|
|
||||||
import com.ibm.wala.cast.js.html.ITag;
|
import com.ibm.wala.cast.js.html.ITag;
|
||||||
|
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
||||||
|
import com.ibm.wala.cast.tree.impl.AbstractSourcePosition;
|
||||||
import com.ibm.wala.util.collections.HashMapFactory;
|
import com.ibm.wala.util.collections.HashMapFactory;
|
||||||
import com.ibm.wala.util.collections.Pair;
|
import com.ibm.wala.util.collections.Pair;
|
||||||
|
|
||||||
|
@ -29,24 +35,86 @@ public class JerichoTag implements ITag {
|
||||||
|
|
||||||
private final Element innerElement;
|
private final Element innerElement;
|
||||||
private final String sourceFile;
|
private final String sourceFile;
|
||||||
private Map<String, String> attributesMap;
|
private Map<String, Pair<String, Position>> allAttributes = null;
|
||||||
|
|
||||||
public JerichoTag(Element root, String sourceFile) {
|
public JerichoTag(Element root, String sourceFile) {
|
||||||
this.innerElement = root;
|
this.innerElement = root;
|
||||||
Attributes attributes = innerElement.getStartTag().getAttributes();
|
|
||||||
attributesMap = HashMapFactory.make();
|
|
||||||
if (attributes != null) {
|
|
||||||
attributesMap = attributes.populateMap(attributesMap, true);
|
|
||||||
}
|
|
||||||
this.sourceFile = sourceFile;
|
this.sourceFile = sourceFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getAllAttributes() {
|
private Position getPosition(final Segment e) {
|
||||||
return attributesMap;
|
return new AbstractSourcePosition() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFirstLine() {
|
||||||
|
return e.getSource().getRowColumnVector(e.getBegin()).getRow();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAttributeByName(String name) {
|
@Override
|
||||||
return attributesMap.get(name.toLowerCase());
|
public int getLastLine() {
|
||||||
|
return e.getSource().getRowColumnVector(e.getEnd()).getRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFirstCol() {
|
||||||
|
return e.getSource().getRowColumnVector(e.getBegin()).getColumn();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLastCol() {
|
||||||
|
return e.getSource().getRowColumnVector(e.getEnd()).getColumn();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFirstOffset() {
|
||||||
|
return e.getBegin();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLastOffset() {
|
||||||
|
return e.getEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URL getURL() {
|
||||||
|
try {
|
||||||
|
return new URL("file://" + sourceFile);
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getInputStream() throws IOException {
|
||||||
|
return new FileInputStream(sourceFile);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Pair<String, Position>> makeAllAttributes() {
|
||||||
|
Map<String, Pair<String, Position>> result = HashMapFactory.make();
|
||||||
|
if (innerElement.getStartTag().getAttributes() != null) {
|
||||||
|
for (Attribute a : innerElement.getStartTag().getAttributes()) {
|
||||||
|
result.put(
|
||||||
|
a.getName().toLowerCase(),
|
||||||
|
Pair.make(a.getValue(), getPosition(a.getValueSegment())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Pair<String, Position>> getAllAttributes() {
|
||||||
|
if (allAttributes == null) {
|
||||||
|
allAttributes = makeAllAttributes();
|
||||||
|
}
|
||||||
|
return allAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pair<String, Position> getAttributeByName(String name) {
|
||||||
|
if (allAttributes == null) {
|
||||||
|
allAttributes = makeAllAttributes();
|
||||||
|
}
|
||||||
|
return allAttributes.get(name.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<Integer, String> getBodyText() {
|
public Pair<Integer, String> getBodyText() {
|
||||||
|
@ -69,7 +137,11 @@ public class JerichoTag implements ITag {
|
||||||
return innerElement.toString();
|
return innerElement.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStartingLineNum() {
|
public Position getElementPosition() {
|
||||||
return innerElement.getSource().getRow(innerElement.getStartTag().getBegin());
|
return getPosition(innerElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Position getContentPosition() {
|
||||||
|
return getPosition(innerElement.getContent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,328 @@
|
||||||
|
package com.ibm.wala.cast.js.ipa.callgraph;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.ibm.wala.cast.ipa.callgraph.AstContextInsensitiveSSAContextInterpreter;
|
||||||
|
import com.ibm.wala.cast.ir.ssa.AstIRFactory;
|
||||||
|
import com.ibm.wala.cast.js.loader.JavaScriptLoader;
|
||||||
|
import com.ibm.wala.cast.js.translator.JSAstTranslator;
|
||||||
|
import com.ibm.wala.cast.js.translator.JSConstantFoldingRewriter;
|
||||||
|
import com.ibm.wala.cast.loader.AstMethod.DebuggingInformation;
|
||||||
|
import com.ibm.wala.cast.loader.AstMethod.Retranslatable;
|
||||||
|
import com.ibm.wala.cast.tree.CAst;
|
||||||
|
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.impl.CAstBasicRewriter;
|
||||||
|
import com.ibm.wala.cast.tree.impl.CAstImpl;
|
||||||
|
import com.ibm.wala.cast.util.CAstPattern;
|
||||||
|
import com.ibm.wala.cast.util.CAstPattern.Segments;
|
||||||
|
import com.ibm.wala.cfg.AbstractCFG;
|
||||||
|
import com.ibm.wala.cfg.ControlFlowGraph;
|
||||||
|
import com.ibm.wala.classLoader.CallSiteReference;
|
||||||
|
import com.ibm.wala.classLoader.IMethod;
|
||||||
|
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||||
|
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||||
|
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||||
|
import com.ibm.wala.ipa.callgraph.Context;
|
||||||
|
import com.ibm.wala.ipa.callgraph.ContextItem;
|
||||||
|
import com.ibm.wala.ipa.callgraph.ContextItem.Value;
|
||||||
|
import com.ibm.wala.ipa.callgraph.ContextKey;
|
||||||
|
import com.ibm.wala.ipa.callgraph.ContextSelector;
|
||||||
|
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||||
|
import com.ibm.wala.ssa.DefUse;
|
||||||
|
import com.ibm.wala.ssa.IR;
|
||||||
|
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
|
||||||
|
import com.ibm.wala.ssa.SSAOptions;
|
||||||
|
import com.ibm.wala.ssa.SymbolTable;
|
||||||
|
import com.ibm.wala.types.TypeReference;
|
||||||
|
import com.ibm.wala.util.collections.HashMapFactory;
|
||||||
|
import com.ibm.wala.util.collections.Pair;
|
||||||
|
import com.ibm.wala.util.intset.IntSet;
|
||||||
|
|
||||||
|
public class ArgumentSpecialization {
|
||||||
|
|
||||||
|
public static class ArgumentSpecializationContextIntepreter extends AstContextInsensitiveSSAContextInterpreter {
|
||||||
|
|
||||||
|
public ArgumentSpecializationContextIntepreter(AnalysisOptions options, AnalysisCache cache) {
|
||||||
|
super(options, cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IR getIR(CGNode node) {
|
||||||
|
if (node.getMethod() instanceof Retranslatable) {
|
||||||
|
return getAnalysisCache().getSSACache().findOrCreateIR(node.getMethod(), node.getContext(), options.getSSAOptions());
|
||||||
|
} else {
|
||||||
|
return super.getIR(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DefUse getDU(CGNode node) {
|
||||||
|
if (node.getMethod() instanceof Retranslatable) {
|
||||||
|
return getAnalysisCache().getSSACache().findOrCreateDU(node.getMethod(), node.getContext(), options.getSSAOptions());
|
||||||
|
} else {
|
||||||
|
return super.getDU(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ArgumentCountContext implements Context {
|
||||||
|
private final Context base;
|
||||||
|
private final int argumentCount;
|
||||||
|
|
||||||
|
public static ContextKey ARGUMENT_COUNT = new ContextKey() {
|
||||||
|
public String toString() {
|
||||||
|
return "argument count key";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
return base.hashCode() + (argumentCount * 4073);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
return
|
||||||
|
o.getClass() == this.getClass() &&
|
||||||
|
base.equals(((ArgumentCountContext)o).base) &&
|
||||||
|
argumentCount == ((ArgumentCountContext)o).argumentCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArgumentCountContext(int argumentCount, Context base) {
|
||||||
|
this.argumentCount = argumentCount;
|
||||||
|
this.base = base;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContextItem get(ContextKey name) {
|
||||||
|
return (name == ARGUMENT_COUNT)? ContextItem.Value.make(argumentCount): base.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return base.toString() + "(nargs:" + argumentCount + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ArgumentCountContextSelector implements ContextSelector, ContextKey {
|
||||||
|
private final ContextSelector base;
|
||||||
|
|
||||||
|
public ArgumentCountContextSelector(ContextSelector base) {
|
||||||
|
this.base = base;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, InstanceKey[] actualParameters) {
|
||||||
|
Context baseContext = base.getCalleeTarget(caller, site, callee, actualParameters);
|
||||||
|
if (caller.getMethod() instanceof Retranslatable) {
|
||||||
|
int v = -1;
|
||||||
|
for (SSAAbstractInvokeInstruction x : caller.getIR().getCalls(site)) {
|
||||||
|
if (v == -1) {
|
||||||
|
v = x.getNumberOfParameters();
|
||||||
|
} else {
|
||||||
|
if (v != x.getNumberOfParameters()) {
|
||||||
|
return baseContext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ArgumentCountContext(v, baseContext);
|
||||||
|
} else {
|
||||||
|
return baseContext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntSet getRelevantParameters(CGNode caller, CallSiteReference site) {
|
||||||
|
return base.getRelevantParameters(caller, site);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ArgumentCountIRFactory extends AstIRFactory.AstDefaultIRFactory {
|
||||||
|
private static final CAstPattern directAccessPattern = CAstPattern.parse("|(ARRAY_REF(VAR(\"arguments\"),<value>*)||OBJECT_REF(VAR(\"arguments\"),<value>*))|");
|
||||||
|
|
||||||
|
private static final CAstPattern destructuredAccessPattern = CAstPattern.parse("BLOCK_EXPR(ASSIGN(VAR(/[$][$]destructure[$]rcvr[0-9]+/),VAR(\"arguments\")),ASSIGN(VAR(<name>/[$][$]destructure[$]elt[0-9]+/),<value>*))");
|
||||||
|
|
||||||
|
private static final CAstPattern destructuredCallPattern = CAstPattern.parse("CALL(VAR(<name>/[$][$]destructure[$]elt[0-9]+/),\"dispatch\",VAR(<thisptr>/[$][$]destructure[$]rcvr[0-9]+/),<args>**)");
|
||||||
|
|
||||||
|
private final SSAOptions defaultOptions;
|
||||||
|
|
||||||
|
public ArgumentCountIRFactory(SSAOptions defaultOptions) {
|
||||||
|
this.defaultOptions = defaultOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contextIsIrrelevant(IMethod method) {
|
||||||
|
return method instanceof Retranslatable? false: super.contextIsIrrelevant(method);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IR makeIR(final IMethod method, Context context, SSAOptions options) {
|
||||||
|
if (method instanceof Retranslatable) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final Value<Integer> v = (Value<Integer>) context.get(ArgumentCountContext.ARGUMENT_COUNT);
|
||||||
|
final Retranslatable m = (Retranslatable)method;
|
||||||
|
if (v != null) {
|
||||||
|
final JavaScriptLoader myloader = (JavaScriptLoader) method.getDeclaringClass().getClassLoader();
|
||||||
|
|
||||||
|
class FixedArgumentsRewriter extends CAstBasicRewriter {
|
||||||
|
private final CAstEntity e;
|
||||||
|
Map<String, CAstNode> argRefs = HashMapFactory.make();
|
||||||
|
|
||||||
|
public FixedArgumentsRewriter(CAst Ast) {
|
||||||
|
super(Ast, false);
|
||||||
|
this.e = m.getEntity();
|
||||||
|
for(Segments s : CAstPattern.findAll(destructuredAccessPattern, m.getEntity())) {
|
||||||
|
argRefs.put(s.getSingle("name").getValue().toString(), s.getSingle("value"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private CAstNode handleArgumentRef(CAstNode n) {
|
||||||
|
Object x = n.getValue();
|
||||||
|
if (x != null) {
|
||||||
|
if (x instanceof Number && ((Number)x).intValue() < v.getValue()-2) {
|
||||||
|
int arg = ((Number)x).intValue() + 2;
|
||||||
|
if (arg < e.getArgumentCount()) {
|
||||||
|
return Ast.makeNode(CAstNode.VAR, Ast.makeConstant(e.getArgumentNames()[arg]));
|
||||||
|
} else {
|
||||||
|
return Ast.makeNode(CAstNode.VAR, Ast.makeConstant("$arg" + arg));
|
||||||
|
}
|
||||||
|
} else if (x instanceof String && "length".equals(x)) {
|
||||||
|
return Ast.makeConstant(v.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CAstNode copyNodes(CAstNode root,
|
||||||
|
CAstControlFlowMap cfg,
|
||||||
|
NonCopyingContext context,
|
||||||
|
Map<Pair<CAstNode, NoKey>, CAstNode> nodeMap)
|
||||||
|
{
|
||||||
|
CAstNode result = null;
|
||||||
|
Segments s;
|
||||||
|
|
||||||
|
if ((s = CAstPattern.match(directAccessPattern, root)) != null) {
|
||||||
|
result = handleArgumentRef(s.getSingle("value"));
|
||||||
|
|
||||||
|
} else if ((s = CAstPattern.match(destructuredCallPattern, root)) != null) {
|
||||||
|
if (argRefs.containsKey(s.getSingle("name").getValue().toString())) {
|
||||||
|
List<CAstNode> x = new ArrayList<CAstNode>();
|
||||||
|
CAstNode ref = handleArgumentRef(argRefs.get(s.getSingle("name").getValue().toString()));
|
||||||
|
if (ref != null) {
|
||||||
|
x.add(ref);
|
||||||
|
x.add(Ast.makeConstant("do"));
|
||||||
|
x.add(Ast.makeNode(CAstNode.VAR, Ast.makeConstant("arguments")));
|
||||||
|
for (CAstNode c : s.getMultiple("args")) {
|
||||||
|
x.add(copyNodes(c, cfg, context, nodeMap));
|
||||||
|
}
|
||||||
|
result = Ast.makeNode(CAstNode.CALL, x.toArray(new CAstNode[ x.size() ]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (root.getKind() == CAstNode.CONSTANT) {
|
||||||
|
result = Ast.makeConstant(root.getValue());
|
||||||
|
|
||||||
|
} else if (root.getKind() == CAstNode.OPERATOR) {
|
||||||
|
result = root;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == null) {
|
||||||
|
CAstNode children[] = new CAstNode[root.getChildCount()];
|
||||||
|
for (int i = 0; i < children.length; i++) {
|
||||||
|
children[i] = copyNodes(root.getChild(i), cfg, context, nodeMap);
|
||||||
|
}
|
||||||
|
for(Object label: cfg.getTargetLabels(root)) {
|
||||||
|
if (label instanceof CAstNode) {
|
||||||
|
copyNodes((CAstNode)label, cfg, context, nodeMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CAstNode copy = Ast.makeNode(root.getKind(), children);
|
||||||
|
result = copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeMap.put(Pair.make(root, context.key()), result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
final FixedArgumentsRewriter args = new FixedArgumentsRewriter(new CAstImpl());
|
||||||
|
final JSConstantFoldingRewriter fold = new JSConstantFoldingRewriter(new CAstImpl());
|
||||||
|
|
||||||
|
class ArgumentativeTranslator extends JSAstTranslator {
|
||||||
|
|
||||||
|
public ArgumentativeTranslator(JavaScriptLoader loader) {
|
||||||
|
super(loader);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CAstEntity codeBodyEntity;
|
||||||
|
private IMethod specializedCode;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getArgumentCount(CAstEntity f) {
|
||||||
|
return Math.max(super.getArgumentCount(f), v.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getArgumentNames(CAstEntity f) {
|
||||||
|
if (super.getArgumentCount(f) >= v.getValue()) {
|
||||||
|
return super.getArgumentNames(f);
|
||||||
|
} else {
|
||||||
|
String[] argNames = new String[ v.getValue() ];
|
||||||
|
System.arraycopy(super.getArgumentNames(f), 0, argNames, 0, super.getArgumentCount(f));
|
||||||
|
for(int i = super.getArgumentCount(f); i < argNames.length; i++) {
|
||||||
|
argNames[i] = "$arg" + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return argNames;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String composeEntityName(WalkContext parent, CAstEntity f) {
|
||||||
|
if (f == codeBodyEntity) {
|
||||||
|
return super.composeEntityName(parent, f) + "_" + v.getValue().intValue();
|
||||||
|
} else {
|
||||||
|
return super.composeEntityName(parent, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void defineFunction(CAstEntity N, WalkContext definingContext, AbstractCFG cfg, SymbolTable symtab,
|
||||||
|
boolean hasCatchBlock, TypeReference[][] caughtTypes, boolean hasMonitorOp, AstLexicalInformation LI,
|
||||||
|
DebuggingInformation debugInfo) {
|
||||||
|
if (N == codeBodyEntity) {
|
||||||
|
specializedCode = myloader.makeCodeBodyCode(cfg, symtab, hasCatchBlock, caughtTypes, hasMonitorOp, LI, debugInfo, method.getDeclaringClass());
|
||||||
|
} else {
|
||||||
|
super.defineFunction(N, definingContext, cfg, symtab, hasCatchBlock, caughtTypes, hasMonitorOp, LI, debugInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void translate(CAstEntity N, WalkContext context) {
|
||||||
|
if (N == m.getEntity()) {
|
||||||
|
codeBodyEntity = fold.rewrite(args.rewrite(N));
|
||||||
|
super.translate(codeBodyEntity, context);
|
||||||
|
} else {
|
||||||
|
super.translate(N, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
ArgumentativeTranslator a = new ArgumentativeTranslator(myloader);
|
||||||
|
m.retranslate(a);
|
||||||
|
return super.makeIR(a.specializedCode, context, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.makeIR(method, context, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ControlFlowGraph makeCFG(IMethod method, Context context) {
|
||||||
|
return makeIR(method, context, defaultOptions).getControlFlowGraph();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,8 +31,8 @@ import com.ibm.wala.ipa.callgraph.impl.Everywhere;
|
||||||
import com.ibm.wala.ipa.callgraph.propagation.ConcreteTypeKey;
|
import com.ibm.wala.ipa.callgraph.propagation.ConcreteTypeKey;
|
||||||
import com.ibm.wala.ipa.callgraph.propagation.ConstantKey;
|
import com.ibm.wala.ipa.callgraph.propagation.ConstantKey;
|
||||||
import com.ibm.wala.ipa.callgraph.propagation.FilteredPointerKey;
|
import com.ibm.wala.ipa.callgraph.propagation.FilteredPointerKey;
|
||||||
|
import com.ibm.wala.ipa.callgraph.propagation.FilteredPointerKey.SingleInstanceFilter;
|
||||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||||
import com.ibm.wala.ipa.callgraph.propagation.cfa.OneLevelSiteContextSelector;
|
|
||||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||||
import com.ibm.wala.ssa.DefUse;
|
import com.ibm.wala.ssa.DefUse;
|
||||||
import com.ibm.wala.ssa.IR;
|
import com.ibm.wala.ssa.IR;
|
||||||
|
@ -50,8 +50,8 @@ import com.ibm.wala.util.intset.IntSetUtil;
|
||||||
import com.ibm.wala.util.intset.MutableIntSet;
|
import com.ibm.wala.util.intset.MutableIntSet;
|
||||||
|
|
||||||
public class ForInContextSelector implements ContextSelector {
|
public class ForInContextSelector implements ContextSelector {
|
||||||
|
|
||||||
public final static ContextKey FORIN_KEY = new ContextKey() { };
|
public final static ContextKey FORIN_KEY = new ContextKey() { };
|
||||||
|
public final static ContextKey FORIN_PARM_INDEX = new ContextKey() { };
|
||||||
|
|
||||||
public static final ContextItem FORIN_MARKER = new ContextItem() { };
|
public static final ContextItem FORIN_MARKER = new ContextItem() { };
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ public class ForInContextSelector implements ContextSelector {
|
||||||
|
|
||||||
public static boolean USE_CPA_IN_BODIES = false;
|
public static boolean USE_CPA_IN_BODIES = false;
|
||||||
|
|
||||||
public static boolean USE_1LEVEL_IN_BODIES = false;
|
public static boolean USE_1LEVEL_IN_BODIES = true;
|
||||||
|
|
||||||
public static boolean DEPENDENT_THRU_READS = true;
|
public static boolean DEPENDENT_THRU_READS = true;
|
||||||
|
|
||||||
|
@ -108,6 +108,9 @@ public class ForInContextSelector implements ContextSelector {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object other) {
|
public boolean equals(Object other) {
|
||||||
|
if (this == other) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return other != null &&
|
return other != null &&
|
||||||
getClass().equals(other.getClass()) &&
|
getClass().equals(other.getClass()) &&
|
||||||
base.equals(((SelectiveCPAContext)other).base) &&
|
base.equals(((SelectiveCPAContext)other).base) &&
|
||||||
|
@ -126,6 +129,8 @@ public class ForInContextSelector implements ContextSelector {
|
||||||
public ContextItem get(ContextKey key) {
|
public ContextItem get(ContextKey key) {
|
||||||
if (FORIN_KEY.equals(key)) {
|
if (FORIN_KEY.equals(key)) {
|
||||||
return FORIN_MARKER;
|
return FORIN_MARKER;
|
||||||
|
} else if(FORIN_PARM_INDEX.equals(key)) {
|
||||||
|
return ContextItem.Value.make(index);
|
||||||
} else {
|
} else {
|
||||||
return super.get(key);
|
return super.get(key);
|
||||||
}
|
}
|
||||||
|
@ -136,10 +141,51 @@ public class ForInContextSelector implements ContextSelector {
|
||||||
return "for in hack filter for " + get(ContextKey.PARAMETERS[index]) + " over " + this.base;
|
return "for in hack filter for " + get(ContextKey.PARAMETERS[index]) + " over " + this.base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the {@link InstanceKey} used to distinguish this context
|
||||||
|
*/
|
||||||
|
public InstanceKey getInstanceKey() {
|
||||||
|
return ((SingleInstanceFilter)get(ContextKey.PARAMETERS[index])).getInstance();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A "dummy" for-in context used for callees of a method analyzed in a real
|
||||||
|
* {@link ForInContext}. The purpose of this class is to clone callees based
|
||||||
|
* on the same {@link InstanceKey} used for the caller context, but without
|
||||||
|
* returning a {@link SingleInstanceFilter} {@link ContextItem} that filters
|
||||||
|
* possible parameter values.
|
||||||
|
*/
|
||||||
|
class MarkerForInContext extends ForInContext {
|
||||||
|
|
||||||
|
MarkerForInContext(Context base, InstanceKey obj) {
|
||||||
|
super(base, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like {@link ForInContext#get(ContextKey)}, but don't return a
|
||||||
|
* {@link SingleInstanceFilter} for the distinguishing {@link InstanceKey}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ContextItem get(ContextKey key) {
|
||||||
|
final ContextItem contextItem = super.get(key);
|
||||||
|
return (contextItem instanceof SingleInstanceFilter) ? null : contextItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* we need to override this method since
|
||||||
|
* {@link MarkerForInContext#get(ContextKey)} does not return the
|
||||||
|
* {@link SingleInstanceFilter} containing the {@link InstanceKey}. Instead,
|
||||||
|
* we invoke {@link ForInContext#get(ContextKey)} from the superclass.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public InstanceKey getInstanceKey() {
|
||||||
|
return ((SingleInstanceFilter)super.get(ContextKey.PARAMETERS[index])).getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
private final ContextSelector base;
|
private final ContextSelector base;
|
||||||
private final ContextSelector oneLevel;
|
// private final ContextSelector oneLevel;
|
||||||
private final int index;
|
private final int index;
|
||||||
|
|
||||||
private void collectValues(DefUse du, SSAInstruction inst, MutableIntSet values) {
|
private void collectValues(DefUse du, SSAInstruction inst, MutableIntSet values) {
|
||||||
|
@ -168,7 +214,7 @@ public class ForInContextSelector implements ContextSelector {
|
||||||
if (DEPENDENT_THRU_READS) {
|
if (DEPENDENT_THRU_READS) {
|
||||||
collectValues(du, du.getDef(inst.getUse(i)), values);
|
collectValues(du, du.getDef(inst.getUse(i)), values);
|
||||||
}
|
}
|
||||||
if (values.contains(3)) {
|
if (values.contains(index+1)) {
|
||||||
dependentParameters.add(i);
|
dependentParameters.add(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,14 +228,15 @@ public class ForInContextSelector implements ContextSelector {
|
||||||
public ForInContextSelector(int index, ContextSelector base) {
|
public ForInContextSelector(int index, ContextSelector base) {
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.base = base;
|
this.base = base;
|
||||||
this.oneLevel = new OneLevelSiteContextSelector(base);
|
// this.oneLevel = new OneLevelSiteContextSelector(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final HashMap<MethodReference, Boolean> forInOnFirstArg_cache = HashMapFactory.make();
|
private final HashMap<MethodReference, Boolean> forInOnFirstArg_cache = HashMapFactory.make();
|
||||||
public static final HashMap<MethodReference, DefUse> du_cache = HashMapFactory.make();
|
private final HashMap<MethodReference, DefUse> du_cache = HashMapFactory.make();
|
||||||
public static final IRFactory<IMethod> factory = AstIRFactory.makeDefaultFactory();
|
private final IRFactory<IMethod> factory = AstIRFactory.makeDefaultFactory();
|
||||||
|
|
||||||
// determine whether the method performs a for-in loop over the properties of its index'th argument
|
// determine whether the method performs a for-in loop over the properties of its index'th argument
|
||||||
|
@SuppressWarnings("unused")
|
||||||
private boolean forInOnFirstArg(IMethod method) {
|
private boolean forInOnFirstArg(IMethod method) {
|
||||||
MethodReference mref = method.getReference();
|
MethodReference mref = method.getReference();
|
||||||
if(method.getNumberOfParameters() < index)
|
if(method.getNumberOfParameters() < index)
|
||||||
|
@ -198,7 +245,7 @@ public class ForInContextSelector implements ContextSelector {
|
||||||
if(b != null)
|
if(b != null)
|
||||||
return b;
|
return b;
|
||||||
DefUse du = getDefUse(method);
|
DefUse du = getDefUse(method);
|
||||||
for(SSAInstruction use : Iterator2Iterable.make(du.getUses(3))) {
|
for(SSAInstruction use : Iterator2Iterable.make(du.getUses(index+1))) {
|
||||||
if(use instanceof EachElementGetInstruction) {
|
if(use instanceof EachElementGetInstruction) {
|
||||||
forInOnFirstArg_cache.put(mref, true);
|
forInOnFirstArg_cache.put(mref, true);
|
||||||
return true;
|
return true;
|
||||||
|
@ -208,7 +255,7 @@ public class ForInContextSelector implements ContextSelector {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DefUse getDefUse(IMethod method) {
|
private DefUse getDefUse(IMethod method) {
|
||||||
MethodReference mref = method.getReference();
|
MethodReference mref = method.getReference();
|
||||||
DefUse du = du_cache.get(mref);
|
DefUse du = du_cache.get(mref);
|
||||||
if(du == null) {
|
if(du == null) {
|
||||||
|
@ -231,16 +278,16 @@ public class ForInContextSelector implements ContextSelector {
|
||||||
return f;
|
return f;
|
||||||
boolean usedAsPropertyName = false, usedAsSomethingElse = false;
|
boolean usedAsPropertyName = false, usedAsSomethingElse = false;
|
||||||
DefUse du = getDefUse(method);
|
DefUse du = getDefUse(method);
|
||||||
for(SSAInstruction use : Iterator2Iterable.make(du.getUses(3))) {
|
for(SSAInstruction use : Iterator2Iterable.make(du.getUses(index+1))) {
|
||||||
if(use instanceof ReflectiveMemberAccess) {
|
if(use instanceof ReflectiveMemberAccess) {
|
||||||
ReflectiveMemberAccess rma = (ReflectiveMemberAccess)use;
|
ReflectiveMemberAccess rma = (ReflectiveMemberAccess)use;
|
||||||
if(rma.getMemberRef() == 3) {
|
if(rma.getMemberRef() == index+1) {
|
||||||
usedAsPropertyName = true;
|
usedAsPropertyName = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if(use instanceof AstIsDefinedInstruction) {
|
} else if(use instanceof AstIsDefinedInstruction) {
|
||||||
AstIsDefinedInstruction aidi = (AstIsDefinedInstruction)use;
|
AstIsDefinedInstruction aidi = (AstIsDefinedInstruction)use;
|
||||||
if(aidi.getNumberOfUses() > 1 && aidi.getUse(1) == 3) {
|
if(aidi.getNumberOfUses() > 1 && aidi.getUse(1) == index+1) {
|
||||||
usedAsPropertyName = true;
|
usedAsPropertyName = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -293,7 +340,7 @@ public class ForInContextSelector implements ContextSelector {
|
||||||
Frequency f = usesFirstArgAsPropertyName(callee);
|
Frequency f = usesFirstArgAsPropertyName(callee);
|
||||||
if(f == Frequency.ALWAYS) {
|
if(f == Frequency.ALWAYS) {
|
||||||
return new ForInContext(baseContext, simulateToString(caller.getClassHierarchy(), receiver[index]));
|
return new ForInContext(baseContext, simulateToString(caller.getClassHierarchy(), receiver[index]));
|
||||||
} else if(f == Frequency.SOMETIMES || forInOnFirstArg(callee)) {
|
} else if(f == Frequency.SOMETIMES) {
|
||||||
if(receiver[index] == null) {
|
if(receiver[index] == null) {
|
||||||
IClass undef = caller.getClassHierarchy().lookupClass(JavaScriptTypes.Undefined);
|
IClass undef = caller.getClassHierarchy().lookupClass(JavaScriptTypes.Undefined);
|
||||||
return new ForInContext(baseContext, new ConcreteTypeKey(undef));
|
return new ForInContext(baseContext, new ConcreteTypeKey(undef));
|
||||||
|
@ -306,7 +353,15 @@ public class ForInContextSelector implements ContextSelector {
|
||||||
return new SelectiveCPAContext(baseContext, receiver);
|
return new SelectiveCPAContext(baseContext, receiver);
|
||||||
} else if (USE_1LEVEL_IN_BODIES && FORIN_MARKER.equals(caller.getContext().get(FORIN_KEY))) {
|
} else if (USE_1LEVEL_IN_BODIES && FORIN_MARKER.equals(caller.getContext().get(FORIN_KEY))) {
|
||||||
if (! identifyDependentParameters(caller, site).isEmpty()) {
|
if (! identifyDependentParameters(caller, site).isEmpty()) {
|
||||||
return oneLevel.getCalleeTarget(caller, site, callee, receiver);
|
// final Context calleeTarget = oneLevel.getCalleeTarget(caller, site, callee, receiver);
|
||||||
|
// // RECURSION CHECK: only add one level of caller-site contexts if the caller and callee methods are distinct
|
||||||
|
// if (!RecursionCheckContextSelector.recursiveContext(calleeTarget, callee)) {
|
||||||
|
// return calleeTarget;
|
||||||
|
// }
|
||||||
|
// use a MarkerForInContext to clone based on the InstanceKey used in the caller context
|
||||||
|
// TODO the cast below isn't safe; fix
|
||||||
|
InstanceKey callerIk = ((ForInContext)caller.getContext()).getInstanceKey();
|
||||||
|
return new MarkerForInContext(baseContext, callerIk);
|
||||||
} else {
|
} else {
|
||||||
return baseContext;
|
return baseContext;
|
||||||
}
|
}
|
||||||
|
@ -314,8 +369,10 @@ public class ForInContextSelector implements ContextSelector {
|
||||||
return baseContext;
|
return baseContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public IntSet getRelevantParameters(CGNode caller, CallSiteReference site) {
|
public IntSet getRelevantParameters(CGNode caller, CallSiteReference site) {
|
||||||
if (USE_CPA_IN_BODIES && FORIN_MARKER.equals(caller.getContext().get(FORIN_KEY))) {
|
if (USE_CPA_IN_BODIES && FORIN_MARKER.equals(caller.getContext().get(FORIN_KEY))) {
|
||||||
|
// what about base.getRelevantParameters() here?
|
||||||
return identifyDependentParameters(caller, site);
|
return identifyDependentParameters(caller, site);
|
||||||
} else if (caller.getIR().getCalls(site)[0].getNumberOfUses() > index) {
|
} else if (caller.getIR().getCalls(site)[0].getNumberOfUses() > index) {
|
||||||
return IntSetUtil.make(new int[]{index}).union(base.getRelevantParameters(caller, site));
|
return IntSetUtil.make(new int[]{index}).union(base.getRelevantParameters(caller, site));
|
||||||
|
|
|
@ -16,7 +16,6 @@ public class GlobalObjectKey implements InstanceKey {
|
||||||
this.concreteType = concreteType;
|
this.concreteType = concreteType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IClass getConcreteType() {
|
public IClass getConcreteType() {
|
||||||
return concreteType;
|
return concreteType;
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue