Merge branch 'github_master' into internal_merge

This commit is contained in:
Manu Sridharan 2012-08-21 16:57:27 -07:00
commit bb2c45803c
342 changed files with 16092 additions and 18247 deletions

1
.gitignore vendored
View File

@ -10,3 +10,4 @@ com.ibm.wala.core.testdata/@dot/
com.ibm.wala.core.testdata/lib/
com.ibm.wala.core/dat/wala.properties
com.ibm.wala.cast.js.html.nu_validator/lib/
com.ibm.wala.cast.java.test/testdata/

View File

@ -1,5 +1,2 @@
This is a mirror of the <a
href="http://wala.svn.sourceforge.net/viewvc/wala/">WALA SVN repository</a>. It
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>.
This is the main source repository for WALA. For more details on WALA, see <a
href="http://wala.sourceforge.net">the WALA home page</a>.

View File

@ -5,18 +5,18 @@ Bundle-SymbolicName: com.ibm.wala.cast.java.jdt.test
Bundle-Version: 1.0.0
Bundle-Activator: com.ibm.wala.cast.java.jdt.test.Activator
Bundle-Vendor: IBM
Require-Bundle: com.ibm.wala.cast;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",
Require-Bundle: com.ibm.wala.cast.java.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.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.core;bundle-version="1.1.3",
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.junit4;bundle-version="4.3.1"
org.junit4;bundle-version="4.8.1",
org.eclipse.core.runtime
Bundle-ActivationPolicy: lazy
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

View File

@ -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.plugin.CoreTestsPlugin;
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.Entrypoint;
import com.ibm.wala.ipa.callgraph.impl.Util;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.util.io.FileProvider;
public class JDTJava15IRTests extends IRTests {
@ -62,7 +62,7 @@ public class JDTJava15IRTests extends IRTests {
};
try {
engine.setExclusionsFile(FileProvider
engine.setExclusionsFile((new EclipseFileProvider())
.getFileFromPlugin(CoreTestsPlugin.getDefault(), CallGraphTestUtil.REGRESSION_EXCLUSIONS).getAbsolutePath());
} catch (IOException e) {
Assert.assertFalse("Cannot find exclusions file", true);

View File

@ -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.plugin.CoreTestsPlugin;
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.Entrypoint;
import com.ibm.wala.ipa.callgraph.impl.Util;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.util.io.FileProvider;
public class JDTJavaIRTests extends JavaIRTests {
@ -96,7 +96,7 @@ public class JDTJavaIRTests extends JavaIRTests {
};
try {
engine.setExclusionsFile(FileProvider
engine.setExclusionsFile((new EclipseFileProvider())
.getFileFromPlugin(CoreTestsPlugin.getDefault(), CallGraphTestUtil.REGRESSION_EXCLUSIONS).getAbsolutePath());
} catch (IOException e) {
Assert.assertFalse("Cannot find exclusions file", true);

View File

@ -128,10 +128,11 @@ import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.jdt.core.dom.WhileStatement;
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.Util;
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.CAstControlFlowMap;
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)
@SuppressWarnings("unchecked")
public class JDTJava2CAstTranslator implements TranslatorToCAst {
public class JDTJava2CAstTranslator {
protected final CAst fFactory = new CAstImpl();
// ///////////////////////////////////////////
@ -203,6 +204,8 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
protected ITypeBinding OutOfMemoryError;
protected DoLoopTranslator doLoopTranslator;
private String fullPath;
private CompilationUnit cu;
@ -211,20 +214,7 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
// COMPILATION UNITS & TYPES
//
public JDTJava2CAstTranslator(JavaSourceLoaderImpl sourceLoader) {
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);
public JDTJava2CAstTranslator(JavaSourceLoaderImpl sourceLoader, CompilationUnit astRoot, String fullPath, boolean replicateForDoLoops) {
fDivByZeroExcType = FakeExceptionTypeBinding.arithmetic;
fNullPointerExcType = FakeExceptionTypeBinding.nullPointer;
fClassCastExcType = FakeExceptionTypeBinding.classCast;
@ -232,12 +222,27 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
ExceptionInInitializerError = FakeExceptionTypeBinding.initException;
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");
assert fRuntimeExcType != null;
}
public CAstEntity translateToCAst() {
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();
// can be of type AnnotationTypeDeclaration, EnumDeclaration, TypeDeclaration
declEntities.add(visit(decl, new RootContext()));
@ -2095,7 +2100,6 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
// ////////////////
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)
ASTNode stmt = n.getBody();
@ -2108,10 +2112,12 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
CAstNode result;
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);
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 {
result = makeNode(context, fFactory, n, CAstNode.LABEL_STMT, fFactory.makeConstant(n.getLabel().getIdentifier()), visitNode(n
.getBody(), context));
@ -2163,7 +2169,10 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
Statement body = n.getBody();
ASTNode breakTarget = makeBreakOrContinueTarget(n, "breakLabel" + n.getStartPosition());
CAstNode breakNode = visitNode(breakTarget, context);
ASTNode continueTarget = makeBreakOrContinueTarget(n, "continueLabel" + n.getStartPosition());
CAstNode continueNode = visitNode(continueTarget, context);
String loopLabel = (String) context.getLabelMap().get(n);
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.
*/
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))),
visitNode(breakTarget, context));
context), makeNode(context, fFactory, n, CAstNode.BLOCK_STMT, visitNode(body, lc), continueNode)),
breakNode);
}
private CAstNode getSwitchCaseConstant(SwitchCase n, WalkContext context) {
@ -2282,22 +2291,21 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
}
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)
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 loopTest = visitNode(n.getExpression(), context);
return makeNode(context, fFactory, n, CAstNode.BLOCK_STMT, visitNode(header, context), makeNode(context, fFactory, n,
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() {
Assertions.UNREACHABLE("CompilationUnitEntity.getPosition()");
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
* mapping which each node registers
*/
public static interface WalkContext {
// LEFTOUT: plenty of stuff
public CAstControlFlowRecorder cfg();
public void addScopedEntity(CAstNode newNode, CAstEntity visit);
public static interface WalkContext extends TranslatorToCAst.WalkContext<WalkContext, ASTNode> {
public Collection<Pair<ITypeBinding, Object>> getCatchTargets(ITypeBinding type);
public CAstSourcePositionRecorder pos();
public CAstNodeTypeMapRecorder getNodeTypeMap();
public Map<ASTNode, String> getLabelMap();
public ASTNode getContinueFor(String label);
public ASTNode getBreakFor(String label);
public boolean needLValue();
}
@ -2914,46 +2909,21 @@ 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
* source pos. mapping per MethodContext, so loop contexts delegate it up.
*/
public static class DelegatingContext implements WalkContext {
protected WalkContext parent;
public static class DelegatingContext extends TranslatorToCAst.DelegatingContext<WalkContext, ASTNode> implements WalkContext {
public DelegatingContext(WalkContext parent) {
this.parent = parent;
}
public CAstControlFlowRecorder cfg() {
return parent.cfg();
}
public CAstSourcePositionRecorder pos() {
return parent.pos();
}
public CAstNodeTypeMapRecorder getNodeTypeMap() {
return parent.getNodeTypeMap();
super(parent);
}
public Collection<Pair<ITypeBinding, Object>> getCatchTargets(ITypeBinding type) {
return parent.getCatchTargets(type);
}
public void addScopedEntity(CAstNode newNode, CAstEntity visit) {
parent.addScopedEntity(newNode, visit);
}
public Map<ASTNode, String> 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();
}
}
@ -2961,27 +2931,8 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
/*
* Root context. Doesn't do anything.
*/
public static class RootContext 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 static class RootContext extends TranslatorToCAst.RootContext<WalkContext, ASTNode> implements WalkContext {
public Collection<Pair<ITypeBinding, Object>> getCatchTargets(ITypeBinding type) {
Assertions.UNREACHABLE("RootContext.getCatchTargets()");
return null;
}
@ -2991,16 +2942,6 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst {
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() {
Assertions.UNREACHABLE("Rootcontext.needLValue()");
return false;

View File

@ -115,8 +115,6 @@ public class JDTSourceModuleTranslator implements SourceModuleTranslator {
public void loadAllSources(Set<ModuleEntry> modules) {
// TODO: we might need one AST (-> "Object" class) for all files.
// TODO: group by project and send 'em in
JDTJava2CAstTranslator jdt2cast = makeCAstTranslator();
final Java2IRTranslator java2ir = makeIRTranslator(jdt2cast);
System.out.println(modules);
@ -143,7 +141,9 @@ public class JDTSourceModuleTranslator implements SourceModuleTranslator {
public void acceptAST(ICompilationUnit source, CompilationUnit ast) {
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) {
e.printStackTrace();
}
@ -165,12 +165,12 @@ public class JDTSourceModuleTranslator implements SourceModuleTranslator {
}
}
protected Java2IRTranslator makeIRTranslator(JDTJava2CAstTranslator jdt2cast) {
return new Java2IRTranslator(jdt2cast, sourceLoader);
protected Java2IRTranslator makeIRTranslator() {
return new Java2IRTranslator(sourceLoader);
}
protected JDTJava2CAstTranslator makeCAstTranslator() {
return new JDTJava2CAstTranslator(sourceLoader);
protected JDTJava2CAstTranslator makeCAstTranslator(CompilationUnit cu, String fullPath) {
return new JDTJava2CAstTranslator(sourceLoader, cu, fullPath, false);
}
}

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<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="src" path="source"/>
<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"/>
</classpath>

View File

@ -1,10 +1,5 @@
#Thu Feb 03 10:12:26 EST 2011
#Mon Jul 02 13:01:58 EDT 2012
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.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0

View File

@ -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">
<stringAttribute key="bad_container_name" value="/com.ibm.wala.cast.java.polyglottest/launchers"/>
<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.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.VM_ARGUMENTS" value="-ea -Xmx512M"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:com.ibm.wala.cast.java.test.data}"/>
</launchConfiguration>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="source"/>
<classpathentry exported="true" kind="lib" path="lib/polyglot.jar"/>
<classpathentry exported="true" kind="lib" path="lib/java_cup.jar"/>
<classpathentry kind="lib" path="lib/polyglot.jar"/>
<classpathentry kind="lib" path="lib/java_cup.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/J2SE-1.5"/>
<classpathentry kind="output" path="bin"/>

View File

@ -1,263 +1,258 @@
#Mon Apr 13 15:38:50 EDT 2009
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.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_explicit_constructor_call=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
org.eclipse.jdt.core.formatter.blank_lines_before_field=1
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
org.eclipse.jdt.core.formatter.comment.format_header=false
org.eclipse.jdt.core.formatter.comment.format_html=true
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
org.eclipse.jdt.core.formatter.comment.format_source_code=true
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
org.eclipse.jdt.core.formatter.comment.line_length=132
org.eclipse.jdt.core.formatter.compact_else_if=true
org.eclipse.jdt.core.formatter.continuation_indentation=2
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_empty_lines=false
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
org.eclipse.jdt.core.formatter.indentation.size=4
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
org.eclipse.jdt.core.formatter.lineSplit=132
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
org.eclipse.jdt.core.formatter.tabulation.char=space
org.eclipse.jdt.core.formatter.tabulation.size=2
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
#Mon Apr 16 10:59:09 EDT 2012
eclipse.preferences.version=1
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_enum_constant=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
org.eclipse.jdt.core.formatter.blank_lines_before_field=1
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
org.eclipse.jdt.core.formatter.comment.format_header=false
org.eclipse.jdt.core.formatter.comment.format_html=true
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
org.eclipse.jdt.core.formatter.comment.format_source_code=true
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
org.eclipse.jdt.core.formatter.comment.line_length=132
org.eclipse.jdt.core.formatter.compact_else_if=true
org.eclipse.jdt.core.formatter.continuation_indentation=2
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_empty_lines=false
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
org.eclipse.jdt.core.formatter.indentation.size=4
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
org.eclipse.jdt.core.formatter.lineSplit=132
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
org.eclipse.jdt.core.formatter.tabulation.char=space
org.eclipse.jdt.core.formatter.tabulation.size=2
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true

View File

@ -25,7 +25,8 @@ import com.ibm.wala.classLoader.BinaryDirectoryTreeModule;
import com.ibm.wala.classLoader.ClassLoaderFactory;
import com.ibm.wala.classLoader.Module;
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.Loader;
import com.ibm.wala.ipa.callgraph.AnalysisCache;
@ -64,7 +65,7 @@ public class EclipseProjectSourceAnalysisEngine extends EclipseProjectAnalysisEn
super(project);
this.fileExt = fileExt;
try {
setExclusionsFile(FileProvider.getFileFromPlugin(CorePlugin.getDefault(), "J2SEClassHierarchyExclusions.txt")
setExclusionsFile((new EclipseFileProvider()).getFileFromPlugin(CorePlugin.getDefault(), "J2SEClassHierarchyExclusions.txt")
.getAbsolutePath());
} catch (IOException e) {
Assertions.UNREACHABLE("Cannot find exclusions file");

View File

@ -51,16 +51,18 @@ public class IRGoal extends SourceGoal_c /* PORT1.7 removed 'implements EndGoal'
ExtensionInfo extInfo= job.extensionInfo();
fTranslator= new Java2IRTranslator(
fSourceLoader,
((IRTranslatorExtension)extInfo).getCAstRewriterFactory());
ModuleSource src = (ModuleSource) job.source();
fTranslator.translate(
src.getModule(),
new PolyglotJava2CAstTranslator(
job.ast(),
fSourceLoader.getReference(),
extInfo.nodeFactory(),
extInfo.typeSystem(),
new PolyglotIdentityMapper(fSourceLoader.getReference()),
((IRTranslatorExtension)extInfo).getReplicateForDoLoops()),
fSourceLoader,
((IRTranslatorExtension)extInfo).getCAstRewriterFactory());
ModuleSource src = (ModuleSource) job.source();
fTranslator.translate(src.getModule(),job.ast(), src.name());
((IRTranslatorExtension)extInfo).getReplicateForDoLoops()).translateToCAst());
return true;
}

View File

@ -20,6 +20,7 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@ -34,6 +35,7 @@ import polyglot.ast.ArrayTypeNode;
import polyglot.ast.Assert;
import polyglot.ast.Assign;
import polyglot.ast.Binary;
import polyglot.ast.Binary.Operator;
import polyglot.ast.Block;
import polyglot.ast.BooleanLit;
import polyglot.ast.Branch;
@ -49,6 +51,7 @@ import polyglot.ast.ClassLit;
import polyglot.ast.ClassMember;
import polyglot.ast.Conditional;
import polyglot.ast.ConstructorCall;
import polyglot.ast.ConstructorCall.Kind;
import polyglot.ast.ConstructorDecl;
import polyglot.ast.Do;
import polyglot.ast.Empty;
@ -94,8 +97,6 @@ import polyglot.ast.TopLevelDecl;
import polyglot.ast.Try;
import polyglot.ast.Unary;
import polyglot.ast.While;
import polyglot.ast.Binary.Operator;
import polyglot.ast.ConstructorCall.Kind;
import polyglot.types.ArrayType;
import polyglot.types.ClassType;
import polyglot.types.CodeInstance;
@ -117,9 +118,11 @@ import polyglot.types.Types;
import polyglot.util.Position;
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.translator.JavaProcedureEntity;
import com.ibm.wala.cast.java.translator.TranslatorToCAst;
import com.ibm.wala.cast.java.types.JavaType;
import com.ibm.wala.cast.tree.CAst;
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.CAstTypeDictionary;
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.CAstImpl;
import com.ibm.wala.cast.tree.impl.CAstNodeTypeMapRecorder;
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.CAstSymbolImpl;
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.debug.Assertions;
@SuppressWarnings("unchecked")
public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
public class PolyglotJava2CAstTranslator {
protected final CAst fFactory = new CAstImpl();
protected final NodeFactory fNodeFactory;
@ -179,10 +179,12 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
protected PolyglotIdentityMapper fIdentityMapper;
protected boolean replicateForDoLoops = false;
protected final DoLoopTranslator doLoopTranslator;
protected final boolean DEBUG = true;
private final Node ast;
final protected TranslatingVisitor getTranslator() {
if (fTranslator == null)
fTranslator = createTranslator();
@ -1133,42 +1135,17 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
String loopLabel = (String) wc.getLabelMap().get(d);
CAstNode continueNode = walkNodes(continueTarget, wc);
CAstNode breakBody = walkNodes(breakTarget, wc);
CAstNode breakNode = walkNodes(breakTarget, wc);
WalkContext lc = new LoopContext(wc, loopLabel, breakTarget, continueTarget);
CAstNode loopBody = walkNodes(d.body(), lc);
if (replicateForDoLoops) {
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());
WalkContext lc = new LoopContext(wc, loopLabel, breakTarget, continueTarget);
CAstNode loopExpr = walkNodes(d.cond(), wc);
CAstNode loopBody = walkNodes(d.body(), lc);
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);
}
return doLoopTranslator.translateDoLoop(loopExpr, loopBody, continueNode, breakNode, wc);
}
public CAstNode visit(For f, WalkContext wc) {
Node breakTarget = makeBreakTarget(f);
Node continueTarget = makeContinueTarget(f);
@ -1434,7 +1411,6 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
}
public CAstSourcePositionMap.Position getPosition() {
Assertions.UNREACHABLE("CompilationUnitEntity.getPosition()");
return null;
}
@ -1529,12 +1505,8 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
protected abstract static class CodeBodyEntity implements CAstEntity {
private final Map<CAstNode, Collection<CAstEntity>> fEntities;
public CodeBodyEntity(Map<CAstNode, CAstEntity> entities) {
fEntities = new LinkedHashMap<CAstNode, Collection<CAstEntity>>();
for (Iterator<CAstNode> keys = entities.keySet().iterator(); keys.hasNext();) {
CAstNode key = keys.next();
fEntities.put(key, Collections.singleton(entities.get(key)));
}
public CodeBodyEntity(Map<CAstNode, Collection<CAstEntity>> entities) {
fEntities = new LinkedHashMap<CAstNode, Collection<CAstEntity>>(entities);
}
public Map<CAstNode, Collection<CAstEntity>> getAllScopedEntities() {
@ -1674,7 +1646,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
private final 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);
fPdast = pdast;
fSystem = system;
@ -1685,7 +1657,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
}
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);
this(pdast, system, pd, ((MemberDef) pd.def()).container().get(), argumentNames, entities, mc);
}
@ -1916,21 +1888,9 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
}
}
public interface WalkContext {
void addScopedEntity(CAstNode node, CAstEntity e);
CAstControlFlowRecorder cfg();
CAstSourcePositionRecorder pos();
CAstNodeTypeMapRecorder getNodeTypeMap();
public interface WalkContext extends TranslatorToCAst.WalkContext<WalkContext, Node> {
Collection<Pair<Type, Object>> getCatchTargets(Type label);
Node getContinueFor(String label);
Node getBreakFor(String label);
Node getFinally();
CodeInstance getEnclosingMethod();
@ -1948,49 +1908,15 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
boolean needLVal();
}
protected static class DelegatingContext implements WalkContext {
private final WalkContext parent;
public WalkContext getParent() {
return parent;
}
protected static class DelegatingContext extends TranslatorToCAst.DelegatingContext<WalkContext, Node> implements WalkContext {
protected DelegatingContext(WalkContext parent) {
this.parent = 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();
super(parent);
}
public Collection<Pair<Type, Object>> getCatchTargets(Type 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() {
return parent.getFinally();
}
@ -2121,9 +2047,9 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
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);
fEntities = entities;
}
@ -2141,10 +2067,11 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
}
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;
}
@ -2160,7 +2087,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
public class MethodContext extends CodeBodyContext {
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);
fPI = pi;
}
@ -2188,8 +2115,8 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
this.tryNode = tryNode;
this.context = context;
for (Iterator catchIter = tryNode.catchBlocks().iterator(); catchIter.hasNext();) {
Catch c = (Catch) catchIter.next();
for (Iterator<Catch> catchIter = tryNode.catchBlocks().iterator(); catchIter.hasNext();) {
Catch c = catchIter.next();
Pair<Type,Object> p = Pair.make(c.catchType(), (Object)c);
fCatchNodes.add(p);
@ -2217,7 +2144,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
continue;
}
}
catchNodes.addAll(getParent().getCatchTargets(label));
catchNodes.addAll(parent.getCatchTargets(label));
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;
public RootContext(CAstTypeDictionary 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) {
Assertions.UNREACHABLE("RootContext.getCatchTargets()");
return null;
}
public CAstNodeTypeMapRecorder getNodeTypeMap() {
Assertions.UNREACHABLE("RootContext.getNodeTypeMap()");
return null;
}
public Node getFinally() {
Assertions.UNREACHABLE("RootContext.getFinally()");
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() {
Assertions.UNREACHABLE("RootContext.getEnclosingMethod()");
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;
fTypeSystem = ts;
fNodeFactory = nf;
fIdentityMapper = identityMapper;
this.replicateForDoLoops = replicateForDoLoops;
doLoopTranslator = new DoLoopTranslator(replicateForDoLoops, fFactory);
fNPEType = fTypeSystem.NullPointerException();
fCCEType = fTypeSystem.ClassCastException();
fREType = fTypeSystem.RuntimeException();
@ -2530,8 +2428,8 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
return cn;
}
public CAstEntity translate(Object ast, String fileName) {
return walkEntity((Node) ast, new RootContext(getTypeDict()));
public CAstEntity translateToCAst() {
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);
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);
List inits = classContext.getStaticInitializers();
@ -2644,7 +2542,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
for (Iterator iter = superConstructors.iterator(); iter.hasNext();) {
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);
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());
} else if (rootNode instanceof ProcedureDecl) {
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);
CAstNode pdAST = null;

View File

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

View File

@ -1,70 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="com.ibm.wala.cast.java.test.data" default="getSources" basedir=".">
<property name="basews" value="${ws}"/>
<property name="baseos" value="${os}"/>
<property name="basearch" value="${arch}"/>
<property name="basenl" value="${nl}"/>
<property name="basews" value="${ws}"/>
<property name="baseos" value="${os}"/>
<property name="basearch" value="${arch}"/>
<property name="basenl" value="${nl}"/>
<!-- Compiler settings. -->
<property name="javacFailOnError" value="true"/>
<property name="javacDebugInfo" value="on"/>
<property name="javacVerbose" value="false"/>
<property name="logExtension" value=".log"/>
<property name="compilerArg" value=""/>
<property name="javacSource" value="1.5"/>
<property name="javacTarget" value="1.5"/>
<!-- This property has been updated to correspond to the paths used by the latest Java update
on Mac OS X 10.6 (Java version 1.6.0_22). If you are not using this version of Mac OS X or Java,
try changing the value of the property to "${java.home}/../../../Classes" -->
<condition property="dir_bootclasspath" value="${java.home}/../Classes">
<os family="mac"/>
<!-- Compiler settings. -->
<property name="javacFailOnError" value="true"/>
<property name="javacDebugInfo" value="on"/>
<property name="javacVerbose" value="false"/>
<property name="logExtension" value=".log"/>
<property name="compilerArg" value=""/>
<property name="javacSource" value="1.5"/>
<property name="javacTarget" value="1.5"/>
<!-- This property has been updated to correspond to the paths used by the latest Java update
on Mac OS X 10.6 (Java version 1.6.0_22). If you are not using this version of Mac OS X or Java,
try changing the value of the property to "${java.home}/../../../Classes" -->
<condition property="dir_bootclasspath" value="${java.home}/../Classes">
<os family="mac"/>
</condition>
<property name="dir_bootclasspath" value="${java.home}/lib"/>
<path id="path_bootclasspath">
<fileset dir="${dir_bootclasspath}">
<include name="*.jar"/>
</fileset>
</path>
<property name="bootclasspath" refid="path_bootclasspath"/>
<property name="bundleJavacSource" value="${javacSource}"/>
<property name="bundleJavacTarget" value="${javacTarget}"/>
<property name="bundleBootClasspath" value="${bootclasspath}"/>
<target name="JLexPresent" depends="init">
<available file="${plugin.destination}/src/JLex/Main.java" property="jlex.present"/>
</target>
<target name="fetchJLex" depends="JLexPresent" unless="jlex.present">
<delete dir="${temp.folder}"/>
<mkdir dir="${temp.folder}/JLex"/>
<get src="http://www.cs.princeton.edu/~appel/modern/java/JLex/current/Main.java" dest="${temp.folder}/JLex/Main.java"/>
<delete dir="${plugin.destination}/src/JLex"/>
<mkdir dir="${plugin.destination}/src/JLex"/>
<copy file="${temp.folder}/JLex/Main.java" tofile="${plugin.destination}/src/JLex/Main.java"/>
<delete dir="${temp.folder}"/>
</target>
<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">
<condition property="pluginTemp" value="${buildTempFolder}/plugins">
<isset property="buildTempFolder"/>
</condition>
<property name="dir_bootclasspath" value="${java.home}/lib"/>
<path id="path_bootclasspath">
<fileset dir="${dir_bootclasspath}">
<include name="*.jar"/>
</fileset>
</path>
<property name="bootclasspath" refid="path_bootclasspath"/>
<property name="bundleJavacSource" value="${javacSource}"/>
<property name="bundleJavacTarget" value="${javacTarget}"/>
<property name="bundleBootClasspath" value="${bootclasspath}"/>
<target name="JLexPresent" depends="init">
<available file="${plugin.destination}/src/JLex/Main.java" property="jlex.present"/>
</target>
<target name="fetchJLex" depends="JLexPresent" unless="jlex.present">
<delete dir="${temp.folder}"/>
<mkdir dir="${temp.folder}/JLex"/>
<get src="http://www.cs.princeton.edu/~appel/modern/java/JLex/current/Main.java" dest="${temp.folder}/JLex/Main.java"/>
<delete dir="${plugin.destination}/src/JLex"/>
<mkdir dir="${plugin.destination}/src/JLex"/>
<copy file="${temp.folder}/JLex/Main.java" tofile="${plugin.destination}/src/JLex/Main.java"/>
<delete dir="${temp.folder}"/>
</target>
<target name="getSources" depends="fetchJLex" />
<target name="init" depends="properties">
<condition property="pluginTemp" value="${buildTempFolder}/plugins">
<isset property="buildTempFolder"/>
</condition>
<property name="pluginTemp" value="${basedir}"/>
<condition property="build.result.folder" value="${pluginTemp}/com.ibm.wala.core.testdata">
<isset property="buildTempFolder"/>
</condition>
<property name="build.result.folder" value="${basedir}"/>
<property name="temp.folder" value="${basedir}/temp.folder"/>
<property name="plugin.destination" value="${basedir}"/>
</target>
<target name="properties" if="eclipse.running">
<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
</target>
<property name="pluginTemp" value="${basedir}"/>
<condition property="build.result.folder" value="${pluginTemp}/com.ibm.wala.core.testdata">
<isset property="buildTempFolder"/>
</condition>
<property name="build.result.folder" value="${basedir}"/>
<property name="temp.folder" value="${basedir}/temp.folder"/>
<property name="plugin.destination" value="${basedir}"/>
</target>
<target name="properties" if="eclipse.running">
<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
</target>
</project>

View File

@ -186,7 +186,7 @@ public class SynchronizedBlockDuplicator extends
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;
// don't copy operators or constants (presumably since they are immutable?)
if (n instanceof CAstOperator) {
@ -204,15 +204,15 @@ public class SynchronizedBlockDuplicator extends
Ast.makeNode(CAstNode.VAR, Ast.makeConstant(varName)));
// the new if conditional
return Ast.makeNode(CAstNode.IF_STMT, test, copyNodes(n, new SyncContext(true, n, c), nodeMap),
copyNodes(n, new SyncContext(false, n, c), nodeMap));
return Ast.makeNode(CAstNode.IF_STMT, test, copyNodes(n, cfg, new SyncContext(true, n, c), nodeMap),
copyNodes(n, cfg, new SyncContext(false, n, c), nodeMap));
} else {
// invoke copyNodes() on the children with context c, ensuring, e.g., that
// the body of a synchronized block gets cloned
CAstNode[] newChildren = new CAstNode[n.getChildCount()];
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);

View File

@ -272,7 +272,7 @@ public class AstJavaSSAPropagationCallGraphBuilder extends AstSSAPropagationCall
}
public void visitJavaInvoke(AstJavaInvokeInstruction instruction) {
visitInvokeInternal(instruction);
visitInvokeInternal(instruction, new DefaultInvariantComputer());
}
}

View File

@ -10,21 +10,26 @@
*****************************************************************************/
package com.ibm.wala.cast.java.ipa.callgraph;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
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.java.loader.JavaSourceLoaderImpl.JavaClass;
import com.ibm.wala.cast.loader.AstMethod;
import com.ibm.wala.cast.loader.AstMethod.LexicalParent;
import com.ibm.wala.classLoader.IClass;
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.InstanceKeyFactory;
import com.ibm.wala.ipa.callgraph.propagation.PropagationCallGraphBuilder;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.util.collections.HashSetFactory;
import com.ibm.wala.util.collections.Pair;
public class JavaScopeMappingInstanceKeys extends ScopeMappingInstanceKeys {
@ -75,4 +80,11 @@ public class JavaScopeMappingInstanceKeys extends ScopeMappingInstanceKeys {
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());
}
}

View File

@ -15,6 +15,7 @@ package com.ibm.wala.cast.java.translator;
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.tree.CAst;
import com.ibm.wala.cast.tree.CAstEntity;
@ -29,34 +30,29 @@ public class Java2IRTranslator {
protected final JavaSourceLoaderImpl fLoader;
protected final TranslatorToCAst fSourceTranslator;
CAstRewriterFactory castRewriterFactory = null;
public Java2IRTranslator(TranslatorToCAst sourceTranslator, JavaSourceLoaderImpl srcLoader) {
this(sourceTranslator, srcLoader, false);
public Java2IRTranslator(JavaSourceLoaderImpl srcLoader) {
this(srcLoader, false);
}
public Java2IRTranslator(TranslatorToCAst sourceTranslator, JavaSourceLoaderImpl srcLoader, boolean debug) {
this(sourceTranslator, srcLoader, null, debug);
public Java2IRTranslator(JavaSourceLoaderImpl srcLoader, boolean debug) {
this(srcLoader, null, debug);
}
public Java2IRTranslator(TranslatorToCAst sourceTranslator, JavaSourceLoaderImpl srcLoader,
public Java2IRTranslator(JavaSourceLoaderImpl srcLoader,
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) {
DEBUG = debug;
fLoader = srcLoader;
fSourceTranslator = sourceTranslator;
this.castRewriterFactory = castRewriterFactory;
}
public void translate(ModuleEntry module, Object ast, String N) {
CAstEntity ce = fSourceTranslator.translate(ast, N);
public void translate(ModuleEntry module, CAstEntity ce) {
if (DEBUG) {
PrintWriter printWriter = new PrintWriter(System.out);
CAstPrinter.printTo(ce, printWriter);

View File

@ -304,26 +304,24 @@ public class JavaCAst2IRTranslator extends AstTranslator {
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) {
super.leaveThis(n, c, visitor);
} else {
WalkContext wc = (WalkContext) c;
int result = wc.currentScope().allocateTempValue();
setValue(n, result);
wc.cfg().addInstruction(new EnclosingObjectReference(result, (TypeReference) n.getChild(0).getValue()));
int result = c.currentScope().allocateTempValue();
c.setValue(n, result);
c.cfg().addInstruction(new EnclosingObjectReference(result, (TypeReference) n.getChild(0).getValue()));
}
}
protected boolean visitCast(CAstNode n, Context c, CAstVisitor visitor) {
WalkContext context = (WalkContext)c;
protected boolean visitCast(CAstNode n, WalkContext context, CAstVisitor<WalkContext> visitor) {
int result = context.currentScope().allocateTempValue();
setValue(n, result);
context.setValue(n, result);
return false;
}
protected void leaveCast(CAstNode n, Context c, CAstVisitor visitor) {
WalkContext context = (WalkContext)c;
int result = getValue(n);
protected void leaveCast(CAstNode n, WalkContext context, CAstVisitor<WalkContext> visitor) {
int result = context.getValue(n);
CAstType toType = (CAstType) n.getChild(0).getValue();
TypeReference toRef = makeType(toType);
@ -334,7 +332,7 @@ public class JavaCAst2IRTranslator extends AstTranslator {
context.cfg().addInstruction(
insts.ConversionInstruction(
result,
getValue(n.getChild(1)),
context.getValue(n.getChild(1)),
fromRef,
toRef,
false));
@ -343,43 +341,42 @@ public class JavaCAst2IRTranslator extends AstTranslator {
context.cfg().addInstruction(
insts.CheckCastInstruction(
result,
getValue(n.getChild(1)),
context.getValue(n.getChild(1)),
toRef,
true));
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();
setValue(n, result);
context.setValue(n, result);
return false;
}
protected void leaveInstanceOf(CAstNode n, Context c, CAstVisitor visitor) {
WalkContext context = (WalkContext)c;
int result = getValue(n);
protected void leaveInstanceOf(CAstNode n, WalkContext context, CAstVisitor<WalkContext> visitor) {
int result = context.getValue(n);
CAstType type = (CAstType) n.getChild(0).getValue();
TypeReference ref = makeType( type );
context.cfg().addInstruction(
insts.InstanceofInstruction(
result,
getValue(n.getChild(1)),
context.getValue(n.getChild(1)),
ref));
}
protected boolean doVisit(CAstNode n, Context context, CAstVisitor visitor) {
WalkContext wc = (WalkContext) context;
protected boolean doVisit(CAstNode n, WalkContext wc, CAstVisitor<WalkContext> visitor) {
if (n.getKind() == CAstNode.MONITOR_ENTER) {
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);
return true;
} else if (n.getKind() == CAstNode.MONITOR_EXIT) {
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);
return true;
} else {
@ -387,4 +384,6 @@ processExceptions(n, context);
}
}
}

View File

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

View File

@ -2,8 +2,8 @@
<classpath>
<classpathentry kind="src" path="src"/>
<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="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"/>
</classpath>

View File

@ -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.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;bundle-version="1.1.3"
com.ibm.wala.core;bundle-version="1.1.3",
org.junit;bundle-version="4.8.1"

View File

@ -14,6 +14,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.LineNumberReader;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.AbstractMap;
import java.util.HashSet;
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.IHtmlParser;
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 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();
parser.setXmlPolicy(XmlViolationPolicy.ALLOW);
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 {
final int line = locator.getLineNumber();
final Position line = new LineNumberPosition(url, localFileName, locator.getLineNumber());
tags.push(new ITag() {
public String getName() {
return localName;
}
public String getAttributeByName(String name) {
return atts.getValue(name);
public Pair<String,Position> getAttributeByName(String name) {
if (atts.getValue(name) != null) {
return Pair.make(atts.getValue(name), line);
} else {
return null;
}
}
public Map<String, String> getAllAttributes() {
return new AbstractMap<String,String>() {
private Set<Map.Entry<String,String>> es = null;
public Map<String, Pair<String,Position>> getAllAttributes() {
return new AbstractMap<String,Pair<String,Position>>() {
private Set<Map.Entry<String,Pair<String,Position>>> es = null;
@Override
public Set<java.util.Map.Entry<String, String>> entrySet() {
public Set<java.util.Map.Entry<String, Pair<String,Position>>> entrySet() {
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++) {
final int index = i;
es.add(new Map.Entry<String,String>() {
es.add(new Map.Entry<String,Pair<String,Position>>() {
public String getKey() {
return atts.getLocalName(index);
return atts.getLocalName(index).toLowerCase();
}
public String getValue() {
return atts.getValue(index);
public Pair<String,Position> getValue() {
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();
}
});
@ -99,10 +120,15 @@ public class NuValidatorHtmlParser implements IHtmlParser {
};
}
public int getStartingLineNum() {
public Position getElementPosition() {
return line;
}
public Position getContentPosition() {
return line;
}
});
handler.handleStartTag(tags.peek());
}
@ -111,11 +137,11 @@ public class NuValidatorHtmlParser implements IHtmlParser {
}
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 {
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 {

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<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="src" path="harness-src"/>
<classpathentry kind="output" path="bin"/>

View File

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

View File

@ -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.test;bundle-version="1.0.0",
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-ActivationPolicy: lazy
Export-Package: com.ibm.wala.cast.js.test

View File

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

View File

@ -22,7 +22,7 @@ public class TestAjaxsltCallGraphShapeRhino extends TestAjaxsltCallGraphShape {
@Before
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());
}

View File

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

View File

@ -15,10 +15,10 @@ import java.io.IOException;
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.RhinoToAstTranslator;
import com.ibm.wala.cast.tree.CAstEntity;
import com.ibm.wala.cast.tree.impl.CAstImpl;
import com.ibm.wala.classLoader.SourceModule;
import org.mozilla.javascript.RhinoToAstTranslator;
public class TestCorrelatedPairExtractionRhino extends TestCorrelatedPairExtraction {
protected CorrelationFinder makeCorrelationFinder() {
@ -26,9 +26,8 @@ public class TestCorrelatedPairExtractionRhino extends TestCorrelatedPairExtract
}
protected CAstEntity parseJS(CAstImpl ast, SourceModule module) throws IOException {
RhinoToAstTranslator.resetGensymCounters();
RhinoToAstTranslator translator = new RhinoToAstTranslator(ast, module, module.getName());
CAstEntity entity = translator.translate();
RhinoToAstTranslator translator = new RhinoToAstTranslator(ast, module, module.getName(), false);
CAstEntity entity = translator.translateToCAst();
return entity;
}
}

View File

@ -13,17 +13,16 @@ package com.ibm.wala.cast.js.test;
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.impl.CAstImpl;
import com.ibm.wala.classLoader.SourceModule;
public class TestForInBodyExtractionRhino extends TestForInBodyExtraction {
protected CAstEntity parseJS(CAstImpl ast, SourceModule module) throws IOException {
RhinoToAstTranslator.resetGensymCounters();
RhinoToAstTranslator translator = new RhinoToAstTranslator(ast, module, module.getName());
CAstEntity entity = translator.translate();
RhinoToAstTranslator translator = new RhinoToAstTranslator(ast, module, module.getName(), false);
CAstEntity entity = translator.translateToCAst();
return entity;
}
}

View File

@ -8,7 +8,7 @@ public class TestForInLoopHackRhino extends TestForInLoopHack {
@Before
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());
}
}

View File

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

View File

@ -22,7 +22,7 @@ public class TestMediawikiCallGraphShapeRhino extends TestMediawikiCallGraphShap
@Before
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());
}
}

View File

@ -12,7 +12,7 @@ public class TestMozillaBugPagesRhino extends TestMozillaBugPages {
@Before
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());
}
}

View File

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

View File

@ -28,12 +28,12 @@ public class TestSimpleCallGraphShapeRhino extends TestSimpleCallGraphShape {
@Before
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
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());
PointerAnalysis PA = b.getPointerAnalysis();
// just make sure this does not crash
@ -42,22 +42,27 @@ public class TestSimpleCallGraphShapeRhino extends TestSimpleCallGraphShape {
@Test
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.
}
@Test
public void testRepr() throws IllegalArgumentException, IOException, CancelException {
Util.makeScriptCG("tests", "repr.js");
JSCallGraphBuilderUtil.makeScriptCG("tests", "repr.js");
}
@Test
public void testTranslateToCAstCrash1() throws IllegalArgumentException, IOException, CancelException {
Util.makeScriptCG("tests", "rhino_crash1.js");
JSCallGraphBuilderUtil.makeScriptCG("tests", "rhino_crash1.js");
}
@Test
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");
}
}

View File

@ -32,7 +32,7 @@ public abstract class TestSimplePageCallGraphShapeRhino extends TestSimplePageCa
@Test public void testPage3() throws IOException, IllegalArgumentException, CancelException {
URL url = getClass().getClassLoader().getResource("pages/page3.html");
CallGraph CG = Util.makeHTMLCG(url);
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
verifyGraphAssertions(CG, assertionsForPage3);
}
@ -44,7 +44,7 @@ public abstract class TestSimplePageCallGraphShapeRhino extends TestSimplePageCa
@Before
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() {
public IHtmlParser getParser() {
return TestSimplePageCallGraphShapeRhino.this.getParser();

View File

@ -15,7 +15,7 @@ public class TestSimplePageCallGraphShapeRhinoJericho extends TestSimplePageCall
@Test public void testCrawl() throws IOException, IllegalArgumentException, CancelException {
URL url = getClass().getClassLoader().getResource("pages/crawl.html");
CallGraph CG = Util.makeHTMLCG(url);
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
verifyGraphAssertions(CG, null);
}

View File

@ -4,6 +4,7 @@ import java.io.IOException;
import java.net.URL;
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.DomLessSourceExtractor;
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.ipa.callgraph.JSCFABuilder;
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.classLoader.SourceFileModule;
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.util.CancelException;
public class JsViewerDriver extends Util {
public class JsViewerDriver extends JSCallGraphBuilderUtil {
public static void main(String args[]) throws ClassHierarchyException, IllegalArgumentException, IOException, CancelException {
if (args.length != 1){
@ -35,13 +36,13 @@ public class JsViewerDriver extends Util {
URL url = new URL(args[0]);
// computing CG + PA
Util.setTranslatorFactory(new CAstRhinoTranslatorFactory());
JSCallGraphBuilderUtil.setTranslatorFactory(new CAstRhinoTranslatorFactory());
JavaScriptLoader.addBootstrapFile(WebUtil.preamble);
SourceModule[] sources = getSources(domless, url);
JSCFABuilder builder = makeCGBuilder(new WebPageLoaderFactory(translatorFactory), sources, false, true);
builder.setBaseURL(url);
JSCFABuilder builder = makeCGBuilder(new WebPageLoaderFactory(translatorFactory), sources, CGBuilderType.ZERO_ONE_CFA, AstIRFactory.makeDefaultFactory());
builder.setBaseURL(url);
CallGraph cg = builder.makeCallGraph(builder.getOptions());
PointerAnalysis pa = builder.getPointerAnalysis();

View File

@ -39,9 +39,9 @@
<target name="fetchRhino" depends="RhinoPresent" unless="rhino.present">
<delete 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" />
<unzip src="${temp.folder}/rhino1_7R2.zip" dest="${temp.folder}"/>
<copy file="${temp.folder}/rhino1_7R2/js.jar" tofile="${plugin.destination}/lib/js.jar" />
<get src="http://ftp.mozilla.org/pub/mozilla.org/js/rhino1_7R3.zip" dest="${temp.folder}/rhino1_7R3.zip" />
<unzip src="${temp.folder}/rhino1_7R3.zip" dest="${temp.folder}"/>
<copy file="${temp.folder}/rhino1_7R3/js.jar" tofile="${plugin.destination}/lib/js.jar" />
<delete dir="${temp.folder}"/>
</target>

View File

@ -14,14 +14,9 @@ import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import org.mozilla.javascript.RhinoToAstTranslator;
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.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.RewriteContext;
import com.ibm.wala.cast.tree.impl.CAstRewriterFactory;
@ -31,15 +26,12 @@ import com.ibm.wala.classLoader.SourceModule;
public class CAstRhinoTranslator implements TranslatorToCAst {
private final List<CAstRewriterFactory> rewriters = new LinkedList<CAstRewriterFactory>();
private final SourceModule M;
public CAstRhinoTranslator(SourceModule M) {
private final boolean replicateForDoLoops;
public CAstRhinoTranslator(SourceModule M, boolean replicateForDoLoops) {
this.M = M;
this.addRewriter(new CAstRewriterFactory<PropertyReadExpander.RewriteContext, ExpanderKey>() {
public CAstRewriter<PropertyReadExpander.RewriteContext, ExpanderKey> createCAstRewriter(CAst ast) {
return new PropertyReadExpander(ast);
}
}, true);
}
this.replicateForDoLoops = replicateForDoLoops;
}
public <C extends RewriteContext<K>, K extends CopyKey<K>> void addRewriter(CAstRewriterFactory<C, K> factory, boolean prepend) {
if(prepend)
@ -57,9 +49,10 @@ public class CAstRhinoTranslator implements TranslatorToCAst {
}
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)
entity = rwf.createCAstRewriter(Ast).rewrite(entity);
return entity;
}
}

View File

@ -7,7 +7,7 @@ import com.ibm.wala.classLoader.SourceModule;
public class CAstRhinoTranslatorFactory implements JavaScriptTranslatorFactory {
public TranslatorToCAst make(CAst ast, SourceModule M) {
return new CAstRhinoTranslator(M);
return new CAstRhinoTranslator(M, false);
}
}

View File

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

View File

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

View File

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

View File

@ -1,5 +1,6 @@
function f() {
arguments[0].g();
for(var p in arguments)
arguments[p].g();
}
f.g = function g1() {};
@ -12,4 +13,10 @@ var oo = {
g: function g3() { }
}
o.f(oo);
// 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);
// make g1 and g2 reachable so we can check assertions
f.g();
o.g();

View File

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

View File

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

View File

@ -1,8 +1,11 @@
function() {
switch(0) {
(function(x) {
switch(x) {
case Ext.Date:
return 1;
break;
}
}
return -1;
})(0);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
function foo(x) {
function bar() {
x = function i_am_reachable() {}
}
bar();
return x;
}
var y = foo(null);
y();

View File

@ -44,3 +44,7 @@ var foo = strObj.toLowerCase();
var whatnot = [ , , , 7, numObj, arg2, strObj ];
whatnot[ 5 ].otherMethod( 7 );
delete arg2.bar();
delete whatnot[ 5 ];
delete arg2;

View File

@ -0,0 +1,9 @@
function f() {
switch (0) {
default:
break;
}
oParsedResponse || 0;
}
f();

View File

@ -0,0 +1,10 @@
function f() {
switch (0) {
default:
break;
}
oParsedResponse || 0;
}
f();

View File

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

View File

@ -11,6 +11,11 @@
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.Collection;
import java.util.Collections;
@ -38,6 +43,7 @@ import com.ibm.wala.util.collections.HashMapFactory;
*
*/
public class CAstDumper {
private static final boolean NORMALISE = false;
private final NodeLabeller labeller;
public CAstDumper() {
@ -112,10 +118,37 @@ public class CAstDumper {
return scopedEntities;
}
private void dump(CAstNode node, int indent, StringBuilder buf, CAstControlFlowMap cfg) {
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) {
if(isTrivial(node))
return;
// normalise away single-child block expressions
if(node.getKind() == CAstNode.BLOCK_EXPR && node.getChildCount() == 1) {
dump(node.getChild(0), indent, buf, cfg);
if(NORMALISE && node.getKind() == CAstNode.BLOCK_EXPR && getNonTrivialChildCount(node) == 1) {
for(int i=0;i<node.getChildCount();++i)
if(!isTrivial(node.getChild(i)))
dump(node.getChild(i), indent, buf, cfg);
} else {
buf.append(indent(indent) + labeller.addNode(node) + ": ");
if(node.getKind() == CAstNode.CONSTANT) {
@ -153,7 +186,7 @@ public class CAstDumper {
for(int i=0;i<node.getChildCount();++i) {
CAstNode child = node.getChild(i);
// 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;
dump(child, indent+2, buf, cfg);
}

View File

@ -18,6 +18,7 @@ import java.util.Set;
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.WebPageLoaderFactory;
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.cha.ClassHierarchyException;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ssa.IRFactory;
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 {
JavaScriptLoaderFactory loaders = Util.makeLoaders();
public static enum CGBuilderType {
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) {
script = Util.class.getClassLoader().getResource(dir + "/" + name);
script = JSCallGraphBuilderUtil.class.getClassLoader().getResource(dir + "/" + 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);
}
return makeCG(loaders, scope, useOneCFA, true);
return scope;
}
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 {
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,
CancelException {
PropagationCallGraphBuilder b = makeScriptCGBuilder(dir, name, useOneCFA);
public static CallGraph makeScriptCG(String dir, String name, CGBuilderType builderType) throws IOException,
IllegalArgumentException, CancelException {
PropagationCallGraphBuilder b = makeScriptCGBuilder(dir, name, builderType);
CallGraph CG = b.makeCallGraph(b.getOptions());
dumpCG(b.getPointerAnalysis(), CG);
// dumpCG(b.getPointerAnalysis(), 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 {
PropagationCallGraphBuilder b = makeCGBuilder(makeLoaders(), scripts, useOneCFA, true);
PropagationCallGraphBuilder b = makeCGBuilder(makeLoaders(), scripts, builderType, irFactory);
CallGraph CG = b.makeCallGraph(b.getOptions());
dumpCG(b.getPointerAnalysis(), CG);
// dumpCG(b.getPointerAnalysis(), CG);
return CG;
}
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);
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);
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 {
PropagationCallGraphBuilder b = makeHTMLCGBuilder(url);
CallGraph CG = b.makeCallGraph(b.getOptions());
//dumpCG(b.getPointerAnalysis(), CG);
dumpCG(b.getPointerAnalysis(), 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 {
PropagationCallGraphBuilder b = makeHTMLCGBuilder(url, handleCallApply);
PropagationCallGraphBuilder b = makeHTMLCGBuilder(url, builderType);
CallGraph CG = b.makeCallGraph(b.getOptions());
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);
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 {
IClassHierarchy cha = makeHierarchy(scope, loaders);
com.ibm.wala.cast.js.util.Util.checkForFrontEndErrors(cha);
Iterable<Entrypoint> roots = makeScriptRoots(cha);
JSAnalysisOptions options = makeOptions(scope, cha, roots);
options.setHandleCallApply(handleCallApply);
AnalysisCache cache = makeCache();
JSCFABuilder builder = new JSZeroOrOneXCFABuilder(cha, options, cache, null, null, ZeroXInstanceKeys.ALLOCATIONS, useOneCFA);
options.setHandleCallApply(builderType.handleCallApply());
options.setUsePreciseLexical(builderType.usePreciseLexical());
AnalysisCache cache = makeCache(irFactory);
JSCFABuilder builder = new JSZeroOrOneXCFABuilder(cha, options, cache, null, null, ZeroXInstanceKeys.ALLOCATIONS,
builderType.useOneCFA());
return builder;
} catch (ClassHierarchyException e) {

View File

@ -15,6 +15,7 @@ import java.net.URL;
import org.junit.Test;
import com.ibm.wala.cast.js.test.JSCallGraphBuilderUtil.CGBuilderType;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.util.CancelException;
@ -31,7 +32,7 @@ public abstract class TestAjaxsltCallGraphShape extends TestJSCallGraphShape {
@Test public void testAjaxslt() throws IOException, IllegalArgumentException, CancelException {
URL url = getClass().getClassLoader().getResource("ajaxslt/test/xslt.html");
// 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);
}
@ -42,7 +43,7 @@ public abstract class TestAjaxsltCallGraphShape extends TestJSCallGraphShape {
@Test public void testAjaxpath() throws IOException, IllegalArgumentException, CancelException {
URL url = getClass().getClassLoader().getResource("ajaxslt/test/xpath.html");
CallGraph CG = Util.makeHTMLCG(url);
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
verifyGraphAssertions(CG, assertionsForAjaxpath);
}

View File

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

View File

@ -227,6 +227,7 @@ public abstract class TestCorrelatedPairExtraction {
}
// another example with "this"
// fails since variables from enclosing functions are no longer in SSA form, hence no correlation is found
@Test
public void test9() {
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
@Test @Ignore
@Test
public void test18() {
testRewriter("function addMethods(source) {\n" +
" var properties = Object.keys(source);\n" +
@ -426,13 +427,55 @@ public abstract class TestCorrelatedPairExtraction {
"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], value; (function _forin_body_0(property, thi$) { value = source[property];\n" +
" thi$.prototype[property] = value; })(property, this);\n" +
" var property = properties[i], 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" +
"}");
}
// 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" +
" return this;\n" +
"}");
}
@Test
public void test19() {
testRewriter("function extend(dest, src) {\n" +
@ -442,11 +485,12 @@ public abstract class TestCorrelatedPairExtraction {
"function write(p, v) { this[p] = v; }",
"function extend(dest, 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" +
"function write(p, v) { this[p] = v; }");
}
// fails due to a missing LOCAL_SCOPE node
@Test
public void test20() {
testRewriter("function every(object, fn, bind) {\n" +
@ -476,10 +520,69 @@ public abstract class TestCorrelatedPairExtraction {
"function extend(dest, src) {\n" +
" var x, y;\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" +
" dest[name] = join(x,y); } })(name);\n" +
" dest[name] = join(x,y); })(name);\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];" +
" }" +
"}");
}
}

View File

@ -73,7 +73,7 @@ public abstract class TestForInBodyExtraction {
" dest[p] = src[p];" +
" })(p);" +
" }" +
"}");
"}");
}
// example from the paper, but with single-statement loop body
@ -587,7 +587,7 @@ public abstract class TestForInBodyExtraction {
}
// this test fails since the rewritten CAst contains one more level of blocks
@Test @Ignore
@Test
public void test24() {
testRewriter("var addSlickPseudos = function() {" +
" for(var name in pseudos)" +
@ -759,4 +759,19 @@ public abstract class TestForInBodyExtraction {
" }" +
"} 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];" +
" }" +
"}");
}
}

View File

@ -24,26 +24,26 @@ public abstract class TestForInLoopHack extends TestJSCallGraphShape {
@Test public void testPage3WithoutHack() throws IOException, IllegalArgumentException, CancelException {
URL url = getClass().getClassLoader().getResource("pages/page3.html");
JSCFABuilder builder = Util.makeHTMLCGBuilder(url);
JSCFABuilder builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url);
CallGraph CG = builder.makeCallGraph(builder.getOptions());
Util.dumpCG(builder.getPointerAnalysis(), CG);
JSCallGraphBuilderUtil.dumpCG(builder.getPointerAnalysis(), CG);
}
@Test public void testPage3WithHack() throws IOException, IllegalArgumentException, CancelException {
URL url = getClass().getClassLoader().getResource("pages/page3.html");
JSCFABuilder builder = Util.makeHTMLCGBuilder(url);
JSCFABuilder builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url);
addHackedForInLoopSensitivity(builder);
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.")
@Test public void testJQueryWithHack() throws IOException, IllegalArgumentException, CancelException {
URL url = getClass().getClassLoader().getResource("pages/jquery_hacked.html");
JSCFABuilder builder = Util.makeHTMLCGBuilder(url);
JSCFABuilder builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url);
addHackedForInLoopSensitivity(builder);
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 {
JSCFABuilder B = Util.makeScriptCGBuilder("tests", "badforin.js");
JSCFABuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "badforin.js");
CallGraph CG = B.makeCallGraph(B.getOptions());
Util.dumpCG(B.getPointerAnalysis(), CG);
JSCallGraphBuilderUtil.dumpCG(B.getPointerAnalysis(), CG);
verifyGraphAssertions(CG, assertionsForBadForin);
}
@ -92,10 +92,10 @@ public abstract class TestForInLoopHack extends TestJSCallGraphShape {
};
@Test public void testBadForInWithHack() throws IOException, IllegalArgumentException, CancelException {
JSCFABuilder B = Util.makeScriptCGBuilder("tests", "badforin.js");
JSCFABuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "badforin.js");
addHackedForInLoopSensitivity(B);
CallGraph CG = B.makeCallGraph(B.getOptions());
Util.dumpCG(B.getPointerAnalysis(), CG);
JSCallGraphBuilderUtil.dumpCG(B.getPointerAnalysis(), CG);
verifyGraphAssertions(CG, assertionsForBadForin);
verifyGraphAssertions(CG, assertionsForBadForinHackPrecision);
}
@ -118,9 +118,9 @@ public abstract class TestForInLoopHack extends TestJSCallGraphShape {
};
@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());
Util.dumpCG(B.getPointerAnalysis(), CG);
JSCallGraphBuilderUtil.dumpCG(B.getPointerAnalysis(), CG);
verifyGraphAssertions(CG, assertionsForbadforin2);
}
@ -136,14 +136,22 @@ public abstract class TestForInLoopHack extends TestJSCallGraphShape {
};
@Test public void testbadforin2WithHack() throws IOException, IllegalArgumentException, CancelException {
JSCFABuilder B = Util.makeScriptCGBuilder("tests", "badforin2.js");
JSCFABuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "badforin2.js");
addHackedForInLoopSensitivity(B);
CallGraph CG = B.makeCallGraph(B.getOptions());
Util.dumpCG(B.getPointerAnalysis(), CG);
JSCallGraphBuilderUtil.dumpCG(B.getPointerAnalysis(), CG);
verifyGraphAssertions(CG, assertionsForbadforin2);
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 {
JSCFABuilder B = Util.makeScriptCGBuilder("frameworks", "yahoo.js");

View File

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

View File

@ -18,7 +18,7 @@ import com.ibm.wala.ipa.callgraph.CallGraph;
public abstract class TestJSCallGraphShape extends TestCallGraphShape {
protected Collection getNodes(CallGraph CG, String functionIdentifier) {
return Util.getNodes(CG, functionIdentifier);
return JSCallGraphBuilderUtil.getNodes(CG, functionIdentifier);
}
}

View File

@ -13,6 +13,7 @@ package com.ibm.wala.cast.js.test;
import java.io.IOException;
import java.net.URL;
import org.junit.Ignore;
import org.junit.Test;
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 {
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);
}

View File

@ -25,30 +25,30 @@ public abstract class TestMozillaBugPages extends TestJSCallGraphShape {
@Test public void testMozilla439164() throws IOException, IllegalArgumentException, CancelException {
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());
Util.dumpCG(builder.getPointerAnalysis(), CG);
JSCallGraphBuilderUtil.dumpCG(builder.getPointerAnalysis(), CG);
}
@Test public void testMozilla488233() throws IOException, IllegalArgumentException, CancelException {
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());
Util.dumpCG(builder.getPointerAnalysis(), CG);
JSCallGraphBuilderUtil.dumpCG(builder.getPointerAnalysis(), CG);
}
@Test public void testMozilla490152() throws IOException, IllegalArgumentException, CancelException {
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());
Util.dumpCG(builder.getPointerAnalysis(), CG);
JSCallGraphBuilderUtil.dumpCG(builder.getPointerAnalysis(), CG);
}
@Test public void testMozilla625562() throws IOException, IllegalArgumentException, CancelException {
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());
Util.dumpCG(builder.getPointerAnalysis(), CG);
JSCallGraphBuilderUtil.dumpCG(builder.getPointerAnalysis(), CG);
}
}

View File

@ -19,6 +19,8 @@ import junit.framework.Assert;
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.CallGraph;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
@ -42,6 +44,18 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
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[][] {
new Object[] { ROOT, new String[] { "tests/simple.js" } },
new Object[] {
@ -56,7 +70,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
public void testSimple() throws IOException, IllegalArgumentException, CancelException {
CallGraph CG = Util.makeScriptCG("tests", "simple.js");
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "simple.js");
verifyGraphAssertions(CG, assertionsForSimple);
}
@ -70,7 +84,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
public void testObjects() throws IOException, IllegalArgumentException, CancelException {
CallGraph CG = Util.makeScriptCG("tests", "objects.js");
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "objects.js");
verifyGraphAssertions(CG, assertionsForObjects);
}
@ -91,7 +105,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
public void testInherit() throws IOException, IllegalArgumentException, CancelException {
CallGraph CG = Util.makeScriptCG("tests", "inherit.js");
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "inherit.js");
verifyGraphAssertions(CG, assertionsForInherit);
}
@ -102,7 +116,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
public void testNewfn() throws IOException, IllegalArgumentException, CancelException {
CallGraph CG = Util.makeScriptCG("tests", "newfn.js");
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "newfn.js");
verifyGraphAssertions(CG, assertionsForNewfn);
}
@ -115,7 +129,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
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);
}
@ -129,7 +143,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
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);
}
@ -139,7 +153,10 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
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);
}
@ -157,14 +174,14 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
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);
}
@Test
public void testRecursiveLexical() throws IOException, IllegalArgumentException, CancelException {
// 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[][] {
@ -174,7 +191,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
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);
}
@ -192,7 +209,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
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);
}
@ -202,7 +219,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
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);
CallGraph CG = B.makeCallGraph(B.getOptions());
verifyGraphAssertions(CG, assertionsForStringOp);
@ -217,7 +234,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
public void testUpward() throws IOException, IllegalArgumentException, CancelException {
CallGraph CG = Util.makeScriptCG("tests", "upward.js");
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "upward.js");
verifyGraphAssertions(CG, assertionsForUpward);
}
@ -227,9 +244,11 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
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);
CallGraph CG = B.makeCallGraph(B.getOptions());
// JSCallGraphUtil.AVOID_DUMP = false;
JSCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
verifyGraphAssertions(CG, assertionsForStringPrims);
}
@ -238,7 +257,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
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());
verifyGraphAssertions(CG, assertionsForNested);
}
@ -248,7 +267,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
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());
verifyGraphAssertions(CG, assertionsForInstanceof);
}
@ -266,19 +285,19 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
public void testCrash1() throws IOException, IllegalArgumentException, CancelException {
CallGraph CG = Util.makeScriptCG("tests", "crash1.js");
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "crash1.js");
verifyGraphAssertions(CG, null);
}
@Test
public void testCrash2() throws IOException, IllegalArgumentException, CancelException {
CallGraph CG = Util.makeScriptCG("tests", "crash2.js");
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "crash2.js");
verifyGraphAssertions(CG, null);
}
@Test
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);
}
@ -288,7 +307,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
public void testMultivar() throws IOException, IllegalArgumentException, CancelException {
CallGraph CG = Util.makeScriptCG("tests", "multivar.js");
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "multivar.js");
verifyGraphAssertions(CG, assertionsForMultivar);
}
@ -299,7 +318,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
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);
verifyNoEdges(CG, "suffix:test1", "suffix:foo_of_B");
verifyNoEdges(CG, "suffix:test2", "suffix:foo_of_A");
@ -307,20 +326,20 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
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.
}
@Test
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.
}
@Test
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) {
if (n.getMethod().getName().toString().equals("call4")) {
Assert.assertEquals(2, cg.getSuccNodeCount(n));
@ -342,7 +361,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
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);
}
@ -352,7 +371,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
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);
}
@ -362,7 +381,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
public void testWrap1() throws IllegalArgumentException, IOException, CancelException {
CallGraph CG = Util.makeScriptCG("tests", "wrap1.js");
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "wrap1.js");
verifyGraphAssertions(CG, assertionsForWrap1);
}
@ -372,7 +391,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
public void testWrap2() throws IllegalArgumentException, IOException, CancelException {
CallGraph CG = Util.makeScriptCG("tests", "wrap2.js");
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "wrap2.js");
verifyGraphAssertions(CG, assertionsForWrap2);
}
@ -382,7 +401,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
public void testWrap3() throws IllegalArgumentException, IOException, CancelException {
CallGraph CG = Util.makeScriptCG("tests", "wrap3.js");
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "wrap3.js");
verifyGraphAssertions(CG, assertionsForWrap3);
}
@ -392,7 +411,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
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)
System.out.println(nd);
verifyGraphAssertions(CG, assertionsForComplexCall);
@ -405,7 +424,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
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);
}
@ -415,7 +434,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
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);
}
@ -427,7 +446,10 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
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);
}
@ -445,19 +467,19 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
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);
}
private static final Object[][] assertionsForArguments = new Object[][] {
new Object[] { ROOT, new String[] { "tests/arguments.js" } },
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
public void testArguments() throws IOException, IllegalArgumentException, CancelException {
CallGraph CG = Util.makeScriptCG("tests", "arguments.js");
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "arguments.js");
verifyGraphAssertions(CG, assertionsForArguments);
}
@ -467,7 +489,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
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);
}
@ -479,15 +501,53 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
@Test
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);
}
@Test
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) {
// Created by reversing the points to mapping for local pointer keys.

View File

@ -40,12 +40,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[][] {
new Object[] { ROOT, new String[] { "page1.html" } },
@ -61,7 +55,7 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
@Test public void testPage1() throws IOException, IllegalArgumentException, CancelException {
URL url = getClass().getClassLoader().getResource("pages/page1.html");
CallGraph CG = Util.makeHTMLCG(url);
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
verifyGraphAssertions(CG, assertionsForPage1);
}
@ -72,7 +66,7 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
@Test public void testPage2() throws IOException, IllegalArgumentException, CancelException {
URL url = getClass().getClassLoader().getResource("pages/page2.html");
CallGraph CG = Util.makeHTMLCG(url);
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
verifyGraphAssertions(CG, assertionsForPage2);
}
@ -89,7 +83,7 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
@Test public void testCrawlPage11() throws IOException, IllegalArgumentException, CancelException {
URL url = getClass().getClassLoader().getResource("pages/crawl/page11.html");
CallGraph CG = Util.makeHTMLCG(url);
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
verifyGraphAssertions(CG, assertionsForPage11);
}
@ -106,7 +100,7 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
@Test public void testCrawlPage11b() throws IOException, IllegalArgumentException, CancelException {
URL url = getClass().getClassLoader().getResource("pages/crawl/page11b.html");
CallGraph CG = Util.makeHTMLCG(url);
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
verifyGraphAssertions(CG, assertionsForPage11b);
}
@ -138,7 +132,7 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
@Test public void testCrawlPage12() throws IOException, IllegalArgumentException, CancelException {
URL url = getClass().getClassLoader().getResource("pages/crawl/page12.html");
CallGraph CG = Util.makeHTMLCG(url);
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
verifyGraphAssertions(CG, assertionsForPage12);
}
@ -171,7 +165,7 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
@Test public void testCrawlPage13() throws IOException, IllegalArgumentException, CancelException {
URL url = getClass().getClassLoader().getResource("pages/crawl/page13.html");
CallGraph CG = Util.makeHTMLCG(url);
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
verifyGraphAssertions(CG, assertionsForPage13);
}
@ -189,7 +183,7 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
@Test public void testCrawlPage15() throws IOException, IllegalArgumentException, CancelException {
URL url = getClass().getClassLoader().getResource("pages/crawl/page15.html");
CallGraph CG = Util.makeHTMLCG(url);
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
verifyGraphAssertions(CG, assertionsForPage15);
}
@ -207,7 +201,7 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
@Test public void testCrawlPage16() throws IOException, IllegalArgumentException, CancelException {
URL url = getClass().getClassLoader().getResource("pages/crawl/page16.html");
CallGraph CG = Util.makeHTMLCG(url);
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
verifyGraphAssertions(CG, assertionsForPage16);
}
@ -230,7 +224,7 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
@Test public void testCrawlPage17() throws IOException, IllegalArgumentException, CancelException {
URL url = getClass().getClassLoader().getResource("pages/crawl/page17.html");
CallGraph CG = Util.makeHTMLCG(url);
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
verifyGraphAssertions(CG, assertionsForPage17);
}
@ -243,25 +237,25 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
@Test public void testApolloExample() throws IOException, IllegalArgumentException, CancelException {
URL url = getClass().getClassLoader().getResource("pages/apollo-example.html");
CallGraph CG = Util.makeHTMLCG(url);
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
verifyGraphAssertions(CG, assertionsForApolloExample);
}
@Test public void testNojs() throws IOException, IllegalArgumentException, CancelException {
URL url = getClass().getClassLoader().getResource("pages/nojs.html");
// 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 {
URL url = getClass().getClassLoader().getResource("pages/page4.html");
Util.makeHTMLCG(url);
JSCallGraphBuilderUtil.makeHTMLCG(url);
}
private static final Object[][] sourceAssertionsForList = new Object[][] {
new Object[]{ "suffix:update_display", "list.html", 9, 18 },
new Object[]{ "suffix:update_with_item", "list.html", 14, 16 },
new Object[]{ "suffix:add_item", "list.html", 20, 25 },
new Object[]{ "suffix:update_display", "list.html#2", 4, 13 },
new Object[]{ "suffix:update_with_item", "list.html#2", 9, 11 },
new Object[]{ "suffix:add_item", "list.html#2", 15, 20 },
new Object[]{ "suffix:collection", "pages/collection.js", 2, 14 },
new Object[]{ "suffix:collection_add", "pages/collection.js", 7, 13 },
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 {
URL url = getClass().getClassLoader().getResource("pages/list.html");
JSCFABuilder builder = Util.makeHTMLCGBuilder(url);
JSCFABuilder builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url);
CallGraph CG = builder.makeCallGraph(builder.getOptions());
Util.dumpCG(builder.getPointerAnalysis(), CG);
// JSCallGraphBuilderUtil.AVOID_DUMP = false;
JSCallGraphBuilderUtil.dumpCG(builder.getPointerAnalysis(), CG);
verifySourceAssertions(CG, sourceAssertionsForList);
}
@Test public void testIframeTest2() throws IOException, IllegalArgumentException, CancelException {
URL url = getClass().getClassLoader().getResource("pages/iframeTest2.html");
Util.makeHTMLCG(url);
JSCallGraphBuilderUtil.makeHTMLCG(url);
}
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 {
URL url = getClass().getClassLoader().getResource("pages/windowx.html");
JSCFABuilder builder = Util.makeHTMLCGBuilder(url);
JSCFABuilder builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url);
CallGraph CG = builder.makeCallGraph(builder.getOptions());
Util.dumpCG(builder.getPointerAnalysis(), CG);
JSCallGraphBuilderUtil.dumpCG(builder.getPointerAnalysis(), CG);
verifyGraphAssertions(CG, assertionsForWindowx);
}

File diff suppressed because it is too large Load Diff

View File

@ -2,8 +2,8 @@
<classpath>
<classpathentry kind="src" path="source"/>
<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.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"/>
</classpath>

View File

@ -3,11 +3,16 @@ primitive = new Primitives();
// core definitions needed to make anything work, even what follows
Object = primitive("NewObject");
Function = primitive("NewFunction");
Array = primitive("NewArray");
String = primitive("NewString");
Number = primitive("NewNumber");
RegExp = primitive("NewRegExp");
var local_function = primitive("NewFunction");
Function = local_function;
var local_array = primitive("NewArray");
Array = local_array;
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 */
@ -104,7 +109,7 @@ Object.prototype = {
/* Function properties, see spec 15.3 */
/************************************************************************/
Function.prototype = {
local_function.prototype = {
constructor: Function,
@ -124,15 +129,15 @@ Function.prototype = {
}
};
Function.__proto__ = Function.prototype;
local_function.__proto__ = Function.prototype;
/************************************************************************/
/* Array properties, see spec 15.4 */
/************************************************************************/
Array.__proto__ = Function.prototype;
local_array.__proto__ = Function.prototype;
Array.prototype = {
local_array.prototype = {
__proto__: Object.prototype,
@ -251,9 +256,9 @@ Array.prototype = {
/* String properties, see spec 15.4 */
/************************************************************************/
String.__proto__ = Function.prototype;
local_string.__proto__ = Function.prototype;
String.prototype = {
local_string.prototype = {
__proto__: Object.prototype,
@ -329,9 +334,9 @@ String.prototype = {
/* Number properties, see spec 15.7 */
/************************************************************************/
Number.__proto__ = Function.prototype;
local_number.__proto__ = Function.prototype;
Number.prototype = {
local_number.prototype = {
__proto__: Object.prototype,
@ -419,9 +424,9 @@ Math = {
/* RegExp properties, see spec 15.10 */
/************************************************************************/
RegExp.__proto__ = Function.prototype;
local_regexp.__proto__ = Function.prototype;
RegExp.prototype = {
local_regexp.prototype = {
__proto__: Object.prototype,

View File

@ -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.JavaScriptTypeOfInstruction;
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.fixpoint.IVariable;
import com.ibm.wala.ipa.cha.IClassHierarchy;
@ -36,7 +38,7 @@ public class JSTypeInference extends AstTypeInference {
}
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) {
result = new DeclaredTypeOperator(new ConeType(cha.getRootClass()));
}
@ -61,6 +63,15 @@ public class JSTypeInference extends AstTypeInference {
public void visitWithRegion(JavaScriptWithRegion instruction) {
}
@Override
public void visitSetPrototype(SetPrototype instruction) {
}
@Override
public void visitPrototypeLookup(PrototypeLookup instruction) {
result = new DeclaredTypeOperator(new ConeType(cha.getRootClass()));
}
}
;

View File

@ -11,7 +11,7 @@
package com.ibm.wala.cast.js.cfg;
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.JavaScriptInstanceOf;
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.JavaScriptTypeOfInstruction;
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.ipa.callgraph.Context;
import com.ibm.wala.ssa.SSAInstruction;
@ -29,7 +31,7 @@ public class JSInducedCFG extends AstInducedCFG {
super(instructions, method, context);
}
class JSPEIVisitor extends AstPEIVisitor implements InstructionVisitor {
class JSPEIVisitor extends AstPEIVisitor implements JSInstructionVisitor {
JSPEIVisitor(boolean[] r) {
super(r);
@ -59,9 +61,17 @@ public class JSInducedCFG extends AstInducedCFG {
public void visitWithRegion(JavaScriptWithRegion instruction) {
}
@Override
public void visitSetPrototype(SetPrototype instruction) {
}
@Override
public void visitPrototypeLookup(PrototypeLookup instruction) {
}
}
class JSBranchVisitor extends AstBranchVisitor implements InstructionVisitor {
class JSBranchVisitor extends AstBranchVisitor implements JSInstructionVisitor {
JSBranchVisitor(boolean[] r) {
super(r);
@ -87,6 +97,14 @@ public class JSInducedCFG extends AstInducedCFG {
public void visitWithRegion(JavaScriptWithRegion instruction) {
}
@Override
public void visitSetPrototype(SetPrototype instruction) {
}
@Override
public void visitPrototypeLookup(PrototypeLookup instruction) {
}
}
protected BranchVisitor makeBranchVisitor(boolean[] r) {

View File

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

View File

@ -11,19 +11,22 @@
package com.ibm.wala.cast.js.html;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
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.Pair;
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();
@ -45,9 +48,15 @@ public class DefaultSourceExtractor extends DomLessSourceExtractor{
if (tag.getName().equalsIgnoreCase("FORM")) {
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:")) {
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){
printlnIndented(line, relatedTag==null? null: relatedTag.getElementPosition());
}
private void printlnIndented(String line, Position pos){
StringBuilder indentedLine = new StringBuilder();
for (int i = 0 ; i < stack.size() ; i++){
indentedLine.append(" ");
}
indentedLine.append(line);
if (relatedTag == null){
if (pos == null){
domRegion.println(indentedLine.toString());
} 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){
Map<String, Pair<String, Position>> attrs = tag.getAllAttributes();
printlnIndented("function make_" + varName + "(parent) {", tag);
stack.push(varName);
printlnIndented("this.temp = " + cons + ";", 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 value = e.getValue();
writeAttribute(tag, attr, value, "this", varName);
String value = e.getValue().fst;
writeAttribute(tag, e.getValue().snd, attr, value, "this", varName);
}
if (tag.getName().equalsIgnoreCase("FORM")) {
@ -97,15 +111,8 @@ public class DefaultSourceExtractor extends DomLessSourceExtractor{
printlnIndented(" document.forms[document.formCount++] = this;", tag);
printlnIndented(" var currentForm = this;", tag);
} if (tag.getName().equalsIgnoreCase("INPUT")) {
String prop = tag.getAttributeByName("NAME");
if (prop == null) {
prop = tag.getAttributeByName("name");
}
String type = tag.getAttributeByName("TYPE");
if (type == null) {
type = tag.getAttributeByName("type");
}
String prop = attrs.containsKey("name") ? attrs.get("name").fst : null;
String type = attrs.containsKey("type") ? attrs.get("type").fst : null;
if (type != null && prop != null) {
if (type.equalsIgnoreCase("RADIO")) {
@ -126,15 +133,15 @@ public class DefaultSourceExtractor extends DomLessSourceExtractor{
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);
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")) {
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) {
if (value.indexOf('\'') > 0) {
value = value.replaceAll("\\'", "\\\\'");
@ -162,11 +169,11 @@ public class DefaultSourceExtractor extends DomLessSourceExtractor{
}
protected void endElement(String name) {
printlnIndented("};", null);
printlnIndented("};", (Position)null);
if (stack.isEmpty()) {
printlnIndented("new make_" + name + "(document);\n\n", null);
printlnIndented("new make_" + name + "(document);\n\n", (Position)null);
} else {
printlnIndented("new make_" + name + "(this);\n", null);
printlnIndented("new make_" + name + "(this);\n", (Position)null);
}
}
}

View File

@ -24,13 +24,13 @@ import java.util.Set;
import java.util.regex.Pattern;
import com.ibm.wala.cast.js.html.jericho.JerichoHtmlParser;
import com.ibm.wala.cast.tree.impl.LineNumberPosition;
import com.ibm.wala.util.functions.Function;
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
import com.ibm.wala.util.collections.Pair;
public class DomLessSourceExtractor extends JSSourceExtractor {
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);
}
@ -44,7 +44,8 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
private ITag currentScriptTag;
private int counter = 0;
private int nodeCounter = 0;
private int scriptNodeCounter = 0;
public HtmlCallback(URL entrypointUrl, IUrlResolver urlResolver) {
this.entrypointUrl = entrypointUrl;
@ -54,18 +55,13 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
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);
}
protected Function<Integer,IncludedPosition> makePos(final URL url, final int lineNumber, ITag governingTag) {
final LineNumberPosition includePos = new LineNumberPosition(entrypointUrl, entrypointUrl, governingTag.getStartingLineNum());
return new Function<Integer,IncludedPosition>() {
public IncludedPosition apply(Integer object) {
return new IncludedLineNumberPosition(url, url, lineNumber + object.intValue(), includePos);
}
};
}
protected Position makePos(final URL url, final int lineNumber, ITag governingTag) {
return governingTag.getElementPosition();
}
public void handleEndTag(ITag tag) {
if (tag.getName().equalsIgnoreCase("script")) {
@ -74,14 +70,22 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
}
}
public void handleText(final int lineNumber, String text) {
public void handleText(Position p, String text) {
if (currentScriptTag != null) {
if (text.startsWith("<![CDATA[")) {
assert text.endsWith("]]>");
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);
assert currentScriptTag == null;
currentScriptTag = tag;
scriptNodeCounter++;
}
handleDOM(tag);
}
@ -103,44 +108,47 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
protected void handleDOM(ITag tag) {
// Get the name of the modeling function either from the id attribute or a
// running counter
String idAttribute = tag.getAttributeByName("id");
Pair<String,Position> idAttribute = tag.getAttributeByName("id");
String funcName;
if (idAttribute != null && LEGAL_JS_IDENTIFIER_REGEXP.matcher(idAttribute).matches()) {
funcName = idAttribute;
if (idAttribute != null && LEGAL_JS_IDENTIFIER_REGEXP.matcher(idAttribute.fst).matches()) {
funcName = idAttribute.fst;
} else {
funcName = "node" + (counter++);
funcName = "node" + (nodeCounter++);
}
handleDOM(tag, funcName);
}
protected void handleDOM(ITag tag, String funcName) {
Map<String, String> attributeSet = tag.getAllAttributes();
for (Entry<String, String> a : attributeSet.entrySet()) {
Map<String, Pair<String,Position>> attributeSet = tag.getAllAttributes();
for (Entry<String, Pair<String, Position>> a : attributeSet.entrySet()) {
handleAttribute(a, funcName, tag);
}
}
private void handleAttribute(Entry<String, String> a, String funcName, ITag tag) {
int lineNum = tag.getStartingLineNum();
private void handleAttribute(Entry<String, Pair<String,Position>> a, String funcName, ITag tag) {
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 attValue = a.getValue();
String attValue = a.getValue().fst;
if (attName.toLowerCase().startsWith("on") || (attValue != null && attValue.toLowerCase().startsWith("javascript:"))) {
String fName = tag.getName().toLowerCase() + "_" + attName + "_" + funcName;
String signatureLine = "function " + fName + "(event) {";
domRegion.println(signatureLine, makePos(lineNum, tag));// Defines the function
int offset = 0;
for (String eventContentLine : extructJS(attValue)){
domRegion.println("\t" + eventContentLine, makePos(lineNum + (offset++), tag));
}
domRegion.println("}", makePos(lineNum, tag));// Defines the function
entrypointRegion.println("\t" + fName + "(null);", makePos(lineNum, tag));// Run it
// Defines the function
domRegion.println(signatureLine + "\n" + extructJS(attValue) + "\n}", pos, url);
// Run it
entrypointRegion.println("\t" + fName + "(null);", pos, url);
}
}
private String[] extructJS(String attValue) {
private String extructJS(String attValue) {
if (attValue == null){
return new String[] {};
return "";
}
String content;
if (attValue.toLowerCase().equals("javascript:")) {
@ -149,17 +157,17 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
content = attValue;
}
return content.split("\\n");
return content;
}
protected void handleScript(ITag tag) {
String value = tag.getAttributeByName("src");
Pair<String,Position> value = tag.getAttributeByName("src");
try {
if (value != null) {
// script is out-of-line
getScriptFromUrl(value, tag);
getScriptFromUrl(value.fst, tag);
}
} catch (IOException e) {
@ -176,13 +184,15 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
InputStream scriptInputStream = scriptSrc.openConnection().getInputStream();
try{
int lineNum = 1;
String line;
BufferedReader scriptReader = new BufferedReader(new UnicodeReader(scriptInputStream, "UTF8"));
StringBuffer x = new StringBuffer();
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 {
scriptInputStream.close();
}
@ -219,7 +229,7 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
InputStream inputStreamReader = WebUtil.getStream(entrypointUrl);
IGeneratorCallback htmlCallback = createHtmlCallback(entrypointUrl, urlResolver);
htmlParser.parse(inputStreamReader, htmlCallback, entrypointUrl.getFile());
htmlParser.parse(entrypointUrl, inputStreamReader, htmlCallback, entrypointUrl.getFile());
SourceRegion finalRegion = new SourceRegion();
htmlCallback.writeToFinalRegion(finalRegion);

View File

@ -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;
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.util.collections.HashMapFactory;
/**
* Maps line numbers to lines of other files (fileName + line).
*/
public class FileMapping{
protected Map<Integer, IncludedPosition> lineNumberToFileAndLine = HashMapFactory.make();
/**
* @param line
* @return Null if no mapping for the given line.
*/
public IncludedPosition getAssociatedFileAndLine(int line){
return lineNumberToFileAndLine.get(line);
}
public 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);
}
}
package com.ibm.wala.cast.js.html;
import java.io.PrintStream;
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
public interface FileMapping {
/**
* @param line
* @return Null if no mapping for the given line.
*/
public abstract IncludedPosition getIncludedPosition(Position line);
public abstract void dump(PrintStream ps);
}

View File

@ -10,6 +10,8 @@
*****************************************************************************/
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 handleText(int lineNumber, String text);
void handleText(Position pos, String text);
void handleEndTag(ITag tag);

View File

@ -11,6 +11,7 @@
package com.ibm.wala.cast.js.html;
import java.io.InputStream;
import java.net.URL;
/**
* @author danielk
@ -25,6 +26,6 @@ public interface IHtmlParser {
* @param callback
* @param fileName
*/
public void parse(InputStream reader, IHtmlCallback callback, String fileName);
public void parse(URL url, InputStream reader, IHtmlCallback callback, String fileName);
}

View File

@ -12,6 +12,9 @@ package com.ibm.wala.cast.js.html;
*****************************************************************************/
import java.util.Map;
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
import com.ibm.wala.util.collections.Pair;
/**
* @author danielk
* 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
* @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.
* @return null if no known
*/
public int getStartingLineNum();
public Position getElementPosition();
public Position getContentPosition();
}

View File

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

View File

@ -23,9 +23,9 @@ import java.util.Set;
*/
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;

View File

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

View File

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

View File

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

View File

@ -10,46 +10,45 @@
*****************************************************************************/
package com.ibm.wala.cast.js.html;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintStream;
import java.io.StringReader;
import java.util.StringTokenizer;
import java.net.URL;
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
import com.ibm.wala.util.functions.Function;
public class SourceRegion {
private final StringBuilder source = new StringBuilder();
private final MutableFileMapping fileMapping = new MutableFileMapping();
private FileMapping fileMapping;
private int currentLine = 1;
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);
int ln = 0;
int endOffset = source.length();
int numberOfLineDrops = getNumberOfLineDrops(text);
if (originalPos != null){
for (int i = 0; i < numberOfLineDrops; i++){
fileMapping.map(currentLine++, originalPos.apply(ln++));
if (originalPos != null) {
RangeFileMapping map = new RangeFileMapping(startOffset, endOffset, currentLine, currentLine+numberOfLineDrops, originalPos, url);
if (fileMapping == null) {
fileMapping = map;
} else {
fileMapping = new CompositeFileMapping(map, fileMapping);
}
if (! text.endsWith("\n")){ // avoid mapping one line too much
fileMapping.map(currentLine, originalPos.apply(ln)); // required for handling text with no CRs.
}
} else {
currentLine += numberOfLineDrops;
}
currentLine += numberOfLineDrops;
}
public void println(String text, Function<Integer,IncludedPosition> originalPos){
print(text + "\n", originalPos);
public void println(String text, Position originalPos, URL url){
print(text + "\n", originalPos, url);
}
public void print(String text){
print(text, null);
print(text, null, null);
}
public void println(String text){
@ -62,42 +61,27 @@ public class SourceRegion {
}
public void write(SourceRegion otherRegion){
BufferedReader br = new BufferedReader(new StringReader(otherRegion.source.toString()));
int lineNum = 0;
String line;
try {
while ((line = br.readLine()) != null){
lineNum++;
IncludedPosition fileAndLine = otherRegion.fileMapping.getAssociatedFileAndLine(lineNum);
if (fileAndLine!= null){
fileMapping.map(currentLine, fileAndLine);
}
this.println(line);
int rangeStart = source.length();
String text = otherRegion.source.toString();
source.append(text);
int rangeEnd = source.length();
int numberOfLineDrops = getNumberOfLineDrops(text);
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);
}
} catch (IOException e) {
e.printStackTrace();
assert false;
}
currentLine += numberOfLineDrops;
}
public void dump(PrintStream ps){
StringTokenizer st = new StringTokenizer(source.toString(),"\n");
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);
}
ps.println(source.toString());
}
private static int getNumberOfLineDrops(String text) {

View File

@ -12,6 +12,7 @@ package com.ibm.wala.cast.js.html.jericho;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
@ -20,7 +21,6 @@ import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.LoggerProvider;
import net.htmlparser.jericho.Source;
import com.ibm.wala.cast.js.html.IHtmlCallback;
import com.ibm.wala.cast.js.html.IHtmlParser;
@ -34,7 +34,7 @@ public class JerichoHtmlParser implements IHtmlParser{
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);
Source src;
try {
@ -64,7 +64,7 @@ public class JerichoHtmlParser implements IHtmlParser{
private void parse(Element root) {
JerichoTag tag = new JerichoTag(root, fileName);
handler.handleStartTag(tag);
handler.handleText(tag.getStartingLineNum(), tag.getBodyText().snd);
handler.handleText(tag.getElementPosition(), tag.getBodyText().snd);
List<Element> childElements = root.getChildElements();
for (Iterator<Element> nodeIterator = childElements.iterator(); nodeIterator.hasNext();) {
Element child = nodeIterator.next();

View File

@ -10,14 +10,20 @@
*****************************************************************************/
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 net.htmlparser.jericho.Attributes;
import net.htmlparser.jericho.Attribute;
import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.Segment;
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.Pair;
@ -29,24 +35,86 @@ public class JerichoTag implements ITag {
private final Element innerElement;
private final String sourceFile;
private Map<String, String> attributesMap;
private Map<String, Pair<String, Position>> allAttributes = null;
public JerichoTag(Element root, String sourceFile) {
this.innerElement = root;
Attributes attributes = innerElement.getStartTag().getAttributes();
attributesMap = HashMapFactory.make();
if (attributes != null) {
attributesMap = attributes.populateMap(attributesMap, true);
}
this.sourceFile = sourceFile;
}
public Map<String, String> getAllAttributes() {
return attributesMap;
private Position getPosition(final Segment e) {
return new AbstractSourcePosition() {
@Override
public int getFirstLine() {
return e.getSource().getRowColumnVector(e.getBegin()).getRow();
}
@Override
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 String getAttributeByName(String name) {
return attributesMap.get(name.toLowerCase());
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() {
@ -68,8 +136,12 @@ public class JerichoTag implements ITag {
public String toString() {
return innerElement.toString();
}
public int getStartingLineNum() {
return innerElement.getSource().getRow(innerElement.getStartTag().getBegin());
}
public Position getElementPosition() {
return getPosition(innerElement);
}
public Position getContentPosition() {
return getPosition(innerElement.getContent());
}
}

View File

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

View File

@ -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.ConstantKey;
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.cfa.OneLevelSiteContextSelector;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ssa.DefUse;
import com.ibm.wala.ssa.IR;
@ -50,8 +50,8 @@ import com.ibm.wala.util.intset.IntSetUtil;
import com.ibm.wala.util.intset.MutableIntSet;
public class ForInContextSelector implements ContextSelector {
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() { };
@ -63,7 +63,7 @@ public class ForInContextSelector implements ContextSelector {
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;
@ -108,6 +108,9 @@ public class ForInContextSelector implements ContextSelector {
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
return other != null &&
getClass().equals(other.getClass()) &&
base.equals(((SelectiveCPAContext)other).base) &&
@ -126,6 +129,8 @@ public class ForInContextSelector implements ContextSelector {
public ContextItem get(ContextKey key) {
if (FORIN_KEY.equals(key)) {
return FORIN_MARKER;
} else if(FORIN_PARM_INDEX.equals(key)) {
return ContextItem.Value.make(index);
} else {
return super.get(key);
}
@ -135,11 +140,52 @@ public class ForInContextSelector implements ContextSelector {
public String toString() {
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 oneLevel;
// private final ContextSelector oneLevel;
private final int index;
private void collectValues(DefUse du, SSAInstruction inst, MutableIntSet values) {
@ -168,7 +214,7 @@ public class ForInContextSelector implements ContextSelector {
if (DEPENDENT_THRU_READS) {
collectValues(du, du.getDef(inst.getUse(i)), values);
}
if (values.contains(3)) {
if (values.contains(index+1)) {
dependentParameters.add(i);
}
}
@ -182,14 +228,15 @@ public class ForInContextSelector implements ContextSelector {
public ForInContextSelector(int index, ContextSelector base) {
this.index = index;
this.base = base;
this.oneLevel = new OneLevelSiteContextSelector(base);
// this.oneLevel = new OneLevelSiteContextSelector(base);
}
private final HashMap<MethodReference, Boolean> forInOnFirstArg_cache = HashMapFactory.make();
public static final HashMap<MethodReference, DefUse> du_cache = HashMapFactory.make();
public static final IRFactory<IMethod> factory = AstIRFactory.makeDefaultFactory();
private final HashMap<MethodReference, DefUse> du_cache = HashMapFactory.make();
private final IRFactory<IMethod> factory = AstIRFactory.makeDefaultFactory();
// determine whether the method performs a for-in loop over the properties of its index'th argument
@SuppressWarnings("unused")
private boolean forInOnFirstArg(IMethod method) {
MethodReference mref = method.getReference();
if(method.getNumberOfParameters() < index)
@ -198,7 +245,7 @@ public class ForInContextSelector implements ContextSelector {
if(b != null)
return b;
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) {
forInOnFirstArg_cache.put(mref, true);
return true;
@ -208,7 +255,7 @@ public class ForInContextSelector implements ContextSelector {
return false;
}
public static DefUse getDefUse(IMethod method) {
private DefUse getDefUse(IMethod method) {
MethodReference mref = method.getReference();
DefUse du = du_cache.get(mref);
if(du == null) {
@ -231,16 +278,16 @@ public class ForInContextSelector implements ContextSelector {
return f;
boolean usedAsPropertyName = false, usedAsSomethingElse = false;
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) {
ReflectiveMemberAccess rma = (ReflectiveMemberAccess)use;
if(rma.getMemberRef() == 3) {
if(rma.getMemberRef() == index+1) {
usedAsPropertyName = true;
continue;
}
} else if(use instanceof AstIsDefinedInstruction) {
AstIsDefinedInstruction aidi = (AstIsDefinedInstruction)use;
if(aidi.getNumberOfUses() > 1 && aidi.getUse(1) == 3) {
if(aidi.getNumberOfUses() > 1 && aidi.getUse(1) == index+1) {
usedAsPropertyName = true;
continue;
}
@ -293,7 +340,7 @@ public class ForInContextSelector implements ContextSelector {
Frequency f = usesFirstArgAsPropertyName(callee);
if(f == Frequency.ALWAYS) {
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) {
IClass undef = caller.getClassHierarchy().lookupClass(JavaScriptTypes.Undefined);
return new ForInContext(baseContext, new ConcreteTypeKey(undef));
@ -306,16 +353,26 @@ public class ForInContextSelector implements ContextSelector {
return new SelectiveCPAContext(baseContext, receiver);
} else if (USE_1LEVEL_IN_BODIES && FORIN_MARKER.equals(caller.getContext().get(FORIN_KEY))) {
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 {
return baseContext;
}
}
}
return baseContext;
}
public IntSet getRelevantParameters(CGNode caller, CallSiteReference site) {
if (USE_CPA_IN_BODIES && FORIN_MARKER.equals(caller.getContext().get(FORIN_KEY))) {
// what about base.getRelevantParameters() here?
return identifyDependentParameters(caller, site);
} else if (caller.getIR().getCalls(site)[0].getNumberOfUses() > index) {
return IntSetUtil.make(new int[]{index}).union(base.getRelevantParameters(caller, site));

View File

@ -16,7 +16,6 @@ public class GlobalObjectKey implements InstanceKey {
this.concreteType = concreteType;
}
@Override
public IClass getConcreteType() {
return concreteType;
}

Some files were not shown because too many files have changed in this diff Show More