Initial contribution of core script analysis code
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@618 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
0eaad4c106
commit
c4b9499bd2
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/polyglot.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/java_cup.jar"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
|
@ -0,0 +1,2 @@
|
|||
bin
|
||||
domo-trace.txt*
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.ibm.wala.cast.java</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,40 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Java Source DOMO Front End
|
||||
Bundle-SymbolicName: com.ibm.domo.ast.java
|
||||
Bundle-Version: 1.0.0
|
||||
Bundle-Activator: com.ibm.wala.cast.java.JavaSourcePlugin
|
||||
Bundle-Vendor: rfuhrer@watson.ibm.com
|
||||
Bundle-Localization: plugin
|
||||
Require-Bundle: com.ibm.wala.cast,
|
||||
com.ibm.wala.core,
|
||||
org.eclipse.jdt.core,
|
||||
org.eclipse.core.runtime
|
||||
Eclipse-AutoStart: true
|
||||
Export-Package: com.ibm.wala.cast.java,
|
||||
com.ibm.wala.cast.java.analysis.typeInference,
|
||||
com.ibm.wala.cast.java.client,
|
||||
com.ibm.wala.cast.java.client.impl,
|
||||
com.ibm.wala.cast.java.ipa.callgraph,
|
||||
com.ibm.wala.cast.java.loader,
|
||||
com.ibm.wala.cast.java.ssa,
|
||||
com.ibm.wala.cast.java.translator,
|
||||
com.ibm.wala.cast.java.translator.polyglot,
|
||||
com.ibm.wala.cast.java.types,
|
||||
java_cup,
|
||||
java_cup.runtime,
|
||||
polyglot.ast,
|
||||
polyglot.ext.param,
|
||||
polyglot.ext.param.types,
|
||||
polyglot.frontend,
|
||||
polyglot.frontend.goals,
|
||||
polyglot.frontend.passes,
|
||||
polyglot.lex,
|
||||
polyglot.main,
|
||||
polyglot.parse,
|
||||
polyglot.qq,
|
||||
polyglot.types,
|
||||
polyglot.types.reflect,
|
||||
polyglot.util,
|
||||
polyglot.util.typedump,
|
||||
polyglot.visit
|
|
@ -0,0 +1,4 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.
|
|
@ -0,0 +1,53 @@
|
|||
/******************************************************************************
|
||||
* 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;
|
||||
|
||||
import org.eclipse.core.runtime.Plugin;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
* The main plugin class to be used in the desktop.
|
||||
*/
|
||||
public class JavaSourcePlugin extends Plugin {
|
||||
|
||||
//The shared instance.
|
||||
private static JavaSourcePlugin plugin;
|
||||
|
||||
/**
|
||||
* The constructor.
|
||||
*/
|
||||
public JavaSourcePlugin() {
|
||||
plugin = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called upon plug-in activation
|
||||
*/
|
||||
public void start(BundleContext context) throws Exception {
|
||||
super.start(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when the plug-in is stopped
|
||||
*/
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
super.stop(context);
|
||||
plugin = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shared instance.
|
||||
*/
|
||||
public static JavaSourcePlugin getDefault() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/******************************************************************************
|
||||
* 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.analysis.typeInference;
|
||||
|
||||
import com.ibm.wala.analysis.typeInference.*;
|
||||
import com.ibm.wala.cast.analysis.typeInference.*;
|
||||
import com.ibm.wala.cast.ir.ssa.AstConstants;
|
||||
import com.ibm.wala.cast.java.ssa.*;
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.ipa.cha.*;
|
||||
import com.ibm.wala.shrikeBT.BinaryOpInstruction;
|
||||
import com.ibm.wala.ssa.*;
|
||||
import com.ibm.wala.types.*;
|
||||
|
||||
public class AstJavaTypeInference extends AstTypeInference {
|
||||
|
||||
protected class AstJavaTypeOperatorFactory
|
||||
extends AstTypeOperatorFactory
|
||||
implements AstJavaInstructionVisitor
|
||||
{
|
||||
public void visitBinaryOp(SSABinaryOpInstruction instruction) {
|
||||
if (doPrimitives) {
|
||||
BinaryOpInstruction.IOperator op = instruction.getOperator();
|
||||
if (op == AstConstants.BinaryOp.EQ ||
|
||||
op == AstConstants.BinaryOp.NE ||
|
||||
op == AstConstants.BinaryOp.LT ||
|
||||
op == AstConstants.BinaryOp.GE ||
|
||||
op == AstConstants.BinaryOp.GT ||
|
||||
op == AstConstants.BinaryOp.LE) {
|
||||
result = new DeclaredTypeOperator(PrimitiveType.BOOLEAN);
|
||||
} else {
|
||||
super.visitBinaryOp(instruction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void visitJavaInvoke(AstJavaInvokeInstruction instruction) {
|
||||
TypeReference type = instruction.getDeclaredResultType();
|
||||
if (type.isReferenceType()) {
|
||||
IClass klass = cha.lookupClass(type);
|
||||
if (klass == null) {
|
||||
// a type that cannot be loaded.
|
||||
// be pessimistic
|
||||
result = new DeclaredTypeOperator(BOTTOM);
|
||||
} else {
|
||||
result = new DeclaredTypeOperator(new ConeType(klass, cha));
|
||||
}
|
||||
} else {
|
||||
if (doPrimitives && type.isPrimitiveType()) {
|
||||
result = new DeclaredTypeOperator(PrimitiveType.getPrimitive(type));
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AstJavaTypeInference(IR ir, ClassHierarchy cha, boolean doPrimitives) {
|
||||
super(ir, cha, doPrimitives);
|
||||
}
|
||||
|
||||
protected void initialize() {
|
||||
init(ir, new TypeVarFactory(), new AstJavaTypeOperatorFactory());
|
||||
}
|
||||
|
||||
public TypeAbstraction getConstantPrimitiveType(int valueNumber) {
|
||||
SymbolTable st = ir.getSymbolTable();
|
||||
if (st.isIntegerConstant(valueNumber)) {
|
||||
int val = ((Number)st.getConstantValue(valueNumber)).intValue();
|
||||
if (val < 2) {
|
||||
return PrimitiveType.BOOLEAN;
|
||||
} else if (val < 256) {
|
||||
return PrimitiveType.BYTE;
|
||||
} else if (val < 16384) {
|
||||
return PrimitiveType.SHORT;
|
||||
} else {
|
||||
return PrimitiveType.INT;
|
||||
}
|
||||
} else {
|
||||
return super.getConstantPrimitiveType(valueNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
/******************************************************************************
|
||||
* 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.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.eclipse.jdt.core.*;
|
||||
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
import com.ibm.wala.cast.ir.ssa.*;
|
||||
import com.ibm.wala.cast.java.client.impl.ZeroCFABuilderFactory;
|
||||
import com.ibm.wala.cast.java.ipa.callgraph.JavaSourceAnalysisScope;
|
||||
import com.ibm.wala.cast.java.translator.polyglot.*;
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.client.impl.EclipseProjectAnalysisEngine;
|
||||
import com.ibm.wala.ipa.callgraph.*;
|
||||
import com.ibm.wala.ipa.callgraph.impl.SetOfClasses;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Util;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
|
||||
public class EclipseProjectSourceAnalysisEngine extends
|
||||
EclipseProjectAnalysisEngine
|
||||
{
|
||||
|
||||
public EclipseProjectSourceAnalysisEngine(IJavaProject project) {
|
||||
super(project);
|
||||
setCallGraphBuilderFactory( new ZeroCFABuilderFactory() );
|
||||
}
|
||||
|
||||
public EclipseProjectSourceAnalysisEngine() {
|
||||
super();
|
||||
setCallGraphBuilderFactory( new ZeroCFABuilderFactory() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given source module to the source loader's module list.
|
||||
* Clients should/may call this
|
||||
* method if they don't supply an IJavaProject to the constructor.
|
||||
*/
|
||||
public void addSourceModule(Module M) {
|
||||
Assertions._assert(project == null);
|
||||
sourceEntries.add(M);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given compiled module to the application loader's module list.
|
||||
* Clients should/may call this
|
||||
* method if they don't supply an IJavaProject to the constructor.
|
||||
*/
|
||||
public void addCompiledModule(Module M) {
|
||||
Assertions._assert(project == null);
|
||||
userEntries.add(M);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given module to the primordial loader's module list.
|
||||
* Clients should/may call this
|
||||
* method if they don't supply an IJavaProject to the constructor.
|
||||
*/
|
||||
public void addSystemModule(Module M) {
|
||||
Assertions._assert(project == null);
|
||||
systemEntries.add(M);
|
||||
}
|
||||
|
||||
protected void addApplicationModulesToScope() {
|
||||
ClassLoaderReference app = scope.getApplicationLoader();
|
||||
for (Iterator it = userEntries.iterator(); it.hasNext();) {
|
||||
Module M = (Module) it.next();
|
||||
scope.addToScope(app, M);
|
||||
}
|
||||
|
||||
ClassLoaderReference src =
|
||||
((JavaSourceAnalysisScope) scope).getSourceLoader();
|
||||
|
||||
for (Iterator it = sourceEntries.iterator(); it.hasNext();) {
|
||||
Module M = (Module) it.next();
|
||||
scope.addToScope(src, M);
|
||||
}
|
||||
}
|
||||
|
||||
protected void buildAnalysisScope() {
|
||||
try {
|
||||
scope = new JavaSourceAnalysisScope();
|
||||
|
||||
if (project != null) {
|
||||
resolveClasspathEntries(project.getRawClasspath(), true);
|
||||
}
|
||||
|
||||
for (Iterator modules = systemEntries.iterator(); modules.hasNext();) {
|
||||
scope.addToScope(scope.getPrimordialLoader(),
|
||||
(Module) modules.next());
|
||||
}
|
||||
|
||||
// add user stuff
|
||||
addApplicationModulesToScope();
|
||||
} catch (JavaModelException e) {
|
||||
Assertions.UNREACHABLE();
|
||||
} catch (IOException e) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
protected IRTranslatorExtension getTranslatorExtension() {
|
||||
return new JavaIRTranslatorExtension();
|
||||
}
|
||||
|
||||
protected ClassLoaderFactory getClassLoaderFactory(SetOfClasses exclusions, WarningSet warnings, IRTranslatorExtension extInfo) {
|
||||
return new PolyglotClassLoaderFactory(exclusions, warnings, extInfo);
|
||||
}
|
||||
|
||||
protected ClassHierarchy buildClassHierarchy() {
|
||||
ClassHierarchy cha = null;
|
||||
ClassLoaderFactory factory = getClassLoaderFactory(scope.getExclusions(),
|
||||
getWarnings(), getTranslatorExtension());
|
||||
|
||||
try {
|
||||
cha = ClassHierarchy.make(getScope(), factory, getWarnings());
|
||||
} catch (ClassHierarchyException e) {
|
||||
System.err.println("Class Hierarchy construction failed");
|
||||
System.err.println(e.toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
return cha;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the call graph for the analysis scope in effect, using all of entry points
|
||||
* on the given entry set of "entry classes".
|
||||
* <p>Prerequisite: you must have either supplied an IJavaProject at construction time,
|
||||
* or called addSource/Compiled/SystemModule() to set up the analysis scope.
|
||||
* @param entryClassNames an array of class names, each main method of which is to be
|
||||
* used as an entry point during call graph construction.
|
||||
*/
|
||||
public CallGraph buildDefaultCallGraph(String[] entryClassNames) {
|
||||
buildAnalysisScope();
|
||||
ClassHierarchy cha= buildClassHierarchy();
|
||||
setClassHierarchy(cha);
|
||||
Entrypoints entryPoints= Util.makeMainEntrypoints(JavaSourceAnalysisScope.SOURCE_REF, cha, entryClassNames);
|
||||
AnalysisOptions options= getDefaultOptions(entryPoints);
|
||||
CallGraphBuilder cgb= buildCallGraph(cha, options, true);
|
||||
CallGraph cg= cgb.makeCallGraph(options);
|
||||
return cg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the call graph for the analysis scope in effect, using all of the given entry points.
|
||||
* <p>Prerequisite: you must have either supplied an IJavaProject at construction time,
|
||||
* or called addSource/Compiled/SystemModule() to set up the analysis scope.
|
||||
*/
|
||||
public CallGraph buildDefaultCallGraph(Entrypoints entryPoints) {
|
||||
buildAnalysisScope();
|
||||
ClassHierarchy cha= buildClassHierarchy();
|
||||
setClassHierarchy(cha);
|
||||
AnalysisOptions options= getDefaultOptions(entryPoints);
|
||||
CallGraphBuilder cgb= buildCallGraph(cha, options, true);
|
||||
CallGraph cg= cgb.makeCallGraph(options);
|
||||
return cg;
|
||||
}
|
||||
|
||||
public AnalysisOptions getDefaultOptions(Entrypoints entrypoints) {
|
||||
return
|
||||
new AnalysisOptions(
|
||||
getScope(),
|
||||
AstIRFactory.makeDefaultFactory(true),
|
||||
entrypoints);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/******************************************************************************
|
||||
* 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.client.impl;
|
||||
|
||||
import com.ibm.wala.cast.java.ipa.callgraph.*;
|
||||
import com.ibm.wala.client.CallGraphBuilderFactory;
|
||||
import com.ibm.wala.ipa.callgraph.*;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Util;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.cfa.*;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
|
||||
/**
|
||||
* @author Julian Dolby (dolby@us.ibm.com)
|
||||
*
|
||||
* A factory to create call graph builders using 0-CFA
|
||||
*/
|
||||
public class ZeroCFABuilderFactory implements CallGraphBuilderFactory {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.domo.j2ee.client.CallGraphBuilderFactory#make(com.ibm.domo.ipa.callgraph.AnalysisOptions,
|
||||
* com.ibm.domo.ipa.cha.ClassHierarchy, java.lang.ClassLoader,
|
||||
* com.ibm.domo.j2ee.J2EEAnalysisScope,
|
||||
* com.ibm.domo.util.warnings.WarningSet, boolean)
|
||||
*/
|
||||
public CallGraphBuilder make(AnalysisOptions options,
|
||||
ClassHierarchy cha,
|
||||
AnalysisScope scope,
|
||||
WarningSet warnings,
|
||||
boolean keepPointsTo)
|
||||
{
|
||||
Util.addDefaultSelectors(options, cha, warnings);
|
||||
Util.addDefaultBypassLogic(options, scope, Util.class.getClassLoader(), cha);
|
||||
return new AstJavaZeroXCFABuilder(cha, warnings, options, null, null, options.getReflectionSpec(), ZeroXInstanceKeys.NONE);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/******************************************************************************
|
||||
* 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.ipa.callgraph;
|
||||
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.cfa.CFAPointerKeys;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
|
||||
/**
|
||||
* @author sfink
|
||||
*
|
||||
* Common utilities for CFA-style call graph builders.
|
||||
*/
|
||||
public class AstJavaCFABuilder extends AstJavaSSAPropagationCallGraphBuilder {
|
||||
|
||||
/**
|
||||
* @param cha
|
||||
* @param warnings
|
||||
*/
|
||||
public AstJavaCFABuilder(ClassHierarchy cha, WarningSet warnings, AnalysisOptions options) {
|
||||
super(cha, warnings, options, new CFAPointerKeys());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
/******************************************************************************
|
||||
* 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.ipa.callgraph;
|
||||
|
||||
import com.ibm.wala.util.debug.Trace;
|
||||
import com.ibm.wala.analysis.typeInference.TypeInference;
|
||||
import com.ibm.wala.cast.ipa.callgraph.AstSSAPropagationCallGraphBuilder;
|
||||
import com.ibm.wala.cast.ir.ssa.*;
|
||||
import com.ibm.wala.cast.java.analysis.typeInference.AstJavaTypeInference;
|
||||
import com.ibm.wala.cast.java.ssa.AstJavaInstructionVisitor;
|
||||
import com.ibm.wala.cast.java.ssa.AstJavaInvokeInstruction;
|
||||
import com.ibm.wala.ipa.callgraph.*;
|
||||
import com.ibm.wala.ipa.callgraph.impl.ExplicitCallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.*;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ssa.DefUse;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSACFG.BasicBlock;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
|
||||
public class AstJavaSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraphBuilder {
|
||||
|
||||
protected
|
||||
AstJavaSSAPropagationCallGraphBuilder(ClassHierarchy cha,
|
||||
WarningSet warnings,
|
||||
AnalysisOptions options,
|
||||
PointerKeyFactory pointerKeyFactory)
|
||||
{
|
||||
super(cha, warnings, options, pointerKeyFactory);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// language specialization interface
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected boolean useObjectCatalog() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// top-level node constraint generation
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected TypeInference makeTypeInference(IR ir, ClassHierarchy cha) {
|
||||
TypeInference ti = new AstJavaTypeInference(ir, cha, false);
|
||||
ti.solve();
|
||||
|
||||
if (DEBUG_TYPE_INFERENCE) {
|
||||
Trace.println("IR of " + ir.getMethod());
|
||||
Trace.println( ir );
|
||||
Trace.println("TypeInference of " + ir.getMethod());
|
||||
for(int i = 0; i < ir.getSymbolTable().getMaxValueNumber(); i++) {
|
||||
if (ti.isUndefined(i)) {
|
||||
Trace.println(" value " + i + " is undefined");
|
||||
} else {
|
||||
Trace.println(" value " + i + " has type " + ti.getType(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ti;
|
||||
}
|
||||
|
||||
protected class AstJavaInterestingVisitor
|
||||
extends AstInterestingVisitor
|
||||
implements AstJavaInstructionVisitor
|
||||
{
|
||||
protected AstJavaInterestingVisitor(int vn) {
|
||||
super(vn);
|
||||
}
|
||||
|
||||
public void visitJavaInvoke(AstJavaInvokeInstruction instruction) {
|
||||
bingo = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected InterestingVisitor makeInterestingVisitor(int vn) {
|
||||
return new AstJavaInterestingVisitor(vn);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// specialized pointer analysis
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected class AstJavaPointerFlowGraph extends AstPointerFlowGraph {
|
||||
|
||||
protected class AstJavaPointerFlowVisitor
|
||||
extends AstPointerFlowVisitor
|
||||
implements AstJavaInstructionVisitor
|
||||
{
|
||||
protected AstJavaPointerFlowVisitor(CGNode node, IR ir, BasicBlock bb) {
|
||||
super(node, ir, bb);
|
||||
}
|
||||
|
||||
public void visitJavaInvoke(AstJavaInvokeInstruction instruction) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected AstJavaPointerFlowGraph(PointerAnalysis pa, CallGraph cg) {
|
||||
super(pa,cg);
|
||||
}
|
||||
|
||||
protected InstructionVisitor makeInstructionVisitor(CGNode node, IR ir, BasicBlock bb) {
|
||||
return new AstJavaPointerFlowVisitor(node,ir, bb);
|
||||
}
|
||||
}
|
||||
|
||||
public PointerFlowGraphFactory getPointerFlowGraphFactory() {
|
||||
return new PointerFlowGraphFactory() {
|
||||
public PointerFlowGraph make(PointerAnalysis pa, CallGraph cg) {
|
||||
return new AstJavaPointerFlowGraph(pa, cg);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IR visitor specialization for AST-based Java
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected class AstJavaConstraintVisitor
|
||||
extends AstConstraintVisitor
|
||||
implements AstJavaInstructionVisitor
|
||||
{
|
||||
|
||||
public AstJavaConstraintVisitor(ExplicitCallGraph.ExplicitNode node, IR ir, ExplicitCallGraph callGraph, DefUse du) {
|
||||
super(node, ir, callGraph, du);
|
||||
}
|
||||
|
||||
public void visitJavaInvoke(AstJavaInvokeInstruction instruction) {
|
||||
visitInvokeInternal(instruction);
|
||||
}
|
||||
}
|
||||
|
||||
protected ConstraintVisitor makeVisitor(ExplicitCallGraph.ExplicitNode node,
|
||||
IR ir,
|
||||
DefUse du,
|
||||
ExplicitCallGraph callGraph)
|
||||
{
|
||||
return new AstJavaConstraintVisitor(node, ir, callGraph, du);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
/******************************************************************************
|
||||
* 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.ipa.callgraph;
|
||||
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.ipa.callgraph.ContextSelector;
|
||||
import com.ibm.wala.ipa.callgraph.ReflectionSpecification;
|
||||
import com.ibm.wala.ipa.callgraph.impl.DefaultContextSelector;
|
||||
import com.ibm.wala.ipa.callgraph.impl.DelegatingContextSelector;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.*;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroXInstanceKeys;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
|
||||
/**
|
||||
* @author sfink
|
||||
*
|
||||
* 0-1-CFA Call graph builder, optimized to not disambiguate instances of
|
||||
* "uninteresting" types
|
||||
*/
|
||||
public class AstJavaZeroXCFABuilder extends AstJavaCFABuilder {
|
||||
|
||||
/**
|
||||
* @param cha
|
||||
* @param warnings
|
||||
* @param entrypoints
|
||||
* @param bypass
|
||||
* @param contextProvider
|
||||
*/
|
||||
public AstJavaZeroXCFABuilder(ClassHierarchy cha,
|
||||
WarningSet warnings,
|
||||
AnalysisOptions options,
|
||||
ContextSelector appContextSelector,
|
||||
SSAContextInterpreter appContextInterpreter,
|
||||
ReflectionSpecification reflect,
|
||||
int instancePolicy) {
|
||||
super(cha, warnings, options);
|
||||
|
||||
SSAContextInterpreter contextInterpreter =
|
||||
makeDefaultContextInterpreters(appContextInterpreter, options, cha, reflect, warnings);
|
||||
setContextInterpreter(contextInterpreter);
|
||||
|
||||
ContextSelector def = new DefaultContextSelector(cha, options.getMethodTargetSelector());
|
||||
ContextSelector contextSelector =
|
||||
appContextSelector == null?
|
||||
def:
|
||||
new DelegatingContextSelector(appContextSelector, def);
|
||||
|
||||
setContextSelector(contextSelector);
|
||||
|
||||
setInstanceKeys(
|
||||
new JavaScopeMappingInstanceKeys(cha, this,
|
||||
new ZeroXInstanceKeys(options, cha, contextInterpreter, warnings, instancePolicy)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param options
|
||||
* options that govern call graph construction
|
||||
* @param cha
|
||||
* governing class hierarchy
|
||||
* @param cl
|
||||
* classloader that can find DOMO resources
|
||||
* @param scope
|
||||
* representation of the analysis scope
|
||||
* @param xmlFiles
|
||||
* set of Strings that are names of XML files holding bypass logic
|
||||
* specifications.
|
||||
* @param dmd
|
||||
* deployment descriptor abstraction
|
||||
* @return a 0-1-Opt-CFA Call Graph Builder.
|
||||
*/
|
||||
public static AstJavaCFABuilder make(AnalysisOptions options, ClassHierarchy cha, ClassLoader cl, AnalysisScope scope,
|
||||
String[] xmlFiles, WarningSet warnings, byte instancePolicy) {
|
||||
|
||||
com.ibm.wala.ipa.callgraph.impl.Util.addDefaultSelectors(options, cha, warnings);
|
||||
for (int i = 0; i < xmlFiles.length; i++) {
|
||||
com.ibm.wala.ipa.callgraph.impl.Util.addBypassLogic(options, scope, cl, xmlFiles[i], cha);
|
||||
}
|
||||
|
||||
return new AstJavaZeroXCFABuilder(cha, warnings, options, null, null, options.getReflectionSpec(), instancePolicy);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.domo.ipa.callgraph.propagation.PropagationCallGraphBuilder#getDefaultDispatchBoundHeuristic()
|
||||
*/
|
||||
protected byte getDefaultDispatchBoundHeuristic() {
|
||||
return AnalysisOptions.NO_DISPATCH_BOUND;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/******************************************************************************
|
||||
* 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.ipa.callgraph;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import com.ibm.wala.cast.ipa.callgraph.ScopeMappingInstanceKeys;
|
||||
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.*;
|
||||
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.*;
|
||||
import com.ibm.wala.util.debug.*;
|
||||
|
||||
public class JavaScopeMappingInstanceKeys extends ScopeMappingInstanceKeys {
|
||||
|
||||
|
||||
|
||||
public JavaScopeMappingInstanceKeys(ClassHierarchy cha,
|
||||
PropagationCallGraphBuilder builder,
|
||||
InstanceKeyFactory basic)
|
||||
{
|
||||
super(builder, basic);
|
||||
|
||||
}
|
||||
|
||||
protected LexicalParent[] getParents(InstanceKey base) {
|
||||
IClass cls = base.getConcreteType();
|
||||
if (cls instanceof JavaClass) {
|
||||
try {
|
||||
Set result = new HashSet();
|
||||
|
||||
for(Iterator MS = cls.getAllMethods().iterator(); MS.hasNext(); ) {
|
||||
IMethod m = (IMethod)MS.next();
|
||||
if ((m instanceof AstMethod) && !m.isStatic()) {
|
||||
AstMethod M = (AstMethod)m;
|
||||
LexicalParent[] parents = M.getParents();
|
||||
for(int i = 0; i < parents.length; i++) {
|
||||
result.add( parents[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! result.isEmpty()) {
|
||||
if (AstTranslator.DEBUG_LEXICAL)
|
||||
Trace.println(base + " has parents: " + result);
|
||||
|
||||
return (LexicalParent[]) result.toArray(new LexicalParent[result.size()]);
|
||||
}
|
||||
} catch (ClassHierarchyException e) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
if (AstTranslator.DEBUG_LEXICAL)
|
||||
Trace.println(base + " has no parents");
|
||||
|
||||
return new LexicalParent[0];
|
||||
}
|
||||
|
||||
protected boolean needsScopeMappingKey(InstanceKey base) {
|
||||
boolean result = getParents(base).length > 0;
|
||||
if (AstTranslator.DEBUG_LEXICAL)
|
||||
Trace.println("does " + base + " need scope mapping? " + result);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Sep 27, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.ipa.callgraph;
|
||||
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.util.Atom;
|
||||
|
||||
public class JavaSourceAnalysisScope extends AnalysisScope {
|
||||
|
||||
public static final Atom SOURCE= Atom.findOrCreateUnicodeAtom("Source");
|
||||
|
||||
public static final ClassLoaderReference SOURCE_REF= new ClassLoaderReference(SOURCE);
|
||||
|
||||
public JavaSourceAnalysisScope() {
|
||||
SOURCE_REF.setParent(getLoader(APPLICATION));
|
||||
getLoader(SYNTHETIC).setParent(SOURCE_REF);
|
||||
|
||||
loadersByName.put(SOURCE, SOURCE_REF);
|
||||
|
||||
setLoaderImpl(getLoader(SYNTHETIC), "com.ibm.wala.ipa.summaries.BypassSyntheticClassLoader");
|
||||
setLoaderImpl(SOURCE_REF, "com.ibm.domo.ast.java.translator.polyglot.PolyglotSourceLoaderImpl");
|
||||
}
|
||||
|
||||
public ClassLoaderReference getSourceLoader() {
|
||||
return getLoader(SOURCE);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,476 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Aug 22, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.loader;
|
||||
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.debug.Trace;
|
||||
|
||||
import com.ibm.wala.cast.ir.translator.*;
|
||||
import com.ibm.wala.cast.java.translator.*;
|
||||
import com.ibm.wala.cast.java.types.*;
|
||||
import com.ibm.wala.cast.loader.*;
|
||||
import com.ibm.wala.cast.loader.AstMethod.*;
|
||||
import com.ibm.wala.cast.tree.*;
|
||||
import com.ibm.wala.cast.tree.CAstType.Function;
|
||||
import com.ibm.wala.cfg.AbstractCFG;
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.ipa.callgraph.impl.SetOfClasses;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.ssa.SymbolTable;
|
||||
import com.ibm.wala.types.*;
|
||||
import com.ibm.wala.util.Atom;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
import com.ibm.wala.shrikeCT.ClassConstants;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A DOMO ClassLoaderImpl that processes source file entities in the compile-time classpath.
|
||||
* @author rfuhrer
|
||||
*/
|
||||
public abstract class JavaSourceLoaderImpl extends ClassLoaderImpl {
|
||||
public Map/*<CAstEntity,JavaClass>*/ fTypeMap= new HashMap();
|
||||
|
||||
/**
|
||||
* DOMO representation of a Java class residing in a source file
|
||||
* @author rfuhrer
|
||||
*/
|
||||
public class JavaClass extends AstClass {
|
||||
private final IClass enclosingClass;
|
||||
private final Collection superTypeNames;
|
||||
|
||||
public JavaClass(String typeName,
|
||||
Collection superTypeNames,
|
||||
CAstSourcePositionMap.Position position,
|
||||
Collection qualifiers,
|
||||
JavaSourceLoaderImpl loader,
|
||||
IClass enclosingClass)
|
||||
{
|
||||
super(position,
|
||||
TypeName.string2TypeName(typeName),
|
||||
loader,
|
||||
(short)mapToInt(qualifiers),
|
||||
new HashMap(),
|
||||
new HashMap());
|
||||
this.superTypeNames = superTypeNames;
|
||||
this.enclosingClass = enclosingClass;
|
||||
}
|
||||
|
||||
public ClassHierarchy getClassHierarchy() {
|
||||
return cha;
|
||||
}
|
||||
|
||||
public IClass getSuperclass() {
|
||||
for(Iterator iter= superTypeNames.iterator(); iter.hasNext(); ) {
|
||||
TypeName name = (TypeName) iter.next();
|
||||
IClass domoType = lookupClass(name, cha);
|
||||
if (domoType != null && !domoType.isInterface()) {
|
||||
return domoType;
|
||||
}
|
||||
}
|
||||
|
||||
Assertions.UNREACHABLE(
|
||||
"Cannot find super class for " + this + " in " + superTypeNames);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Collection getDirectInterfaces() {
|
||||
List result = new ArrayList();
|
||||
for(Iterator iter= superTypeNames.iterator(); iter.hasNext(); ) {
|
||||
TypeName name = (TypeName) iter.next();
|
||||
IClass domoType = lookupClass(name, cha);
|
||||
if (domoType != null && domoType.isInterface()) {
|
||||
result.add(domoType);
|
||||
}
|
||||
}
|
||||
|
||||
Assertions._assert(result.size() == superTypeNames.size()-1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void addMethod(CAstEntity methodEntity,
|
||||
IClass owner,
|
||||
AbstractCFG cfg,
|
||||
SymbolTable symtab,
|
||||
boolean hasCatchBlock,
|
||||
TypeReference[][] catchTypes,
|
||||
LexicalInformation lexicalInfo,
|
||||
DebuggingInformation debugInfo)
|
||||
{
|
||||
declaredMethods.put(
|
||||
Util.methodEntityToSelector(methodEntity),
|
||||
new ConcreteJavaMethod(methodEntity, owner, cfg, symtab, hasCatchBlock, catchTypes, lexicalInfo, debugInfo));
|
||||
}
|
||||
|
||||
private void addMethod(CAstEntity methodEntity, IClass owner) {
|
||||
declaredMethods.put(
|
||||
Util.methodEntityToSelector(methodEntity),
|
||||
new AbstractJavaMethod(methodEntity, owner));
|
||||
}
|
||||
|
||||
private void addField(CAstEntity fieldEntity) {
|
||||
declaredFields.put(Util.fieldEntityToAtom(fieldEntity), new JavaField(fieldEntity, JavaSourceLoaderImpl.this, this));
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (enclosingClass == null) {
|
||||
return "<src-class: " + getName().toString() + ">";
|
||||
} else {
|
||||
return "<src-class: " + getName().toString() + "(within " + enclosingClass.getName() + ")>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DOMO representation of a field on a Java type that resides in a source file
|
||||
* @author rfuhrer
|
||||
*/
|
||||
private class JavaField extends AstField {
|
||||
private JavaField(CAstEntity fieldEntity,
|
||||
IClassLoader loader,
|
||||
IClass declaringClass) {
|
||||
super(
|
||||
FieldReference.findOrCreate(
|
||||
declaringClass.getReference(),
|
||||
Atom.findOrCreateUnicodeAtom(fieldEntity.getName()),
|
||||
TypeReference.findOrCreate(
|
||||
loader.getReference(),
|
||||
TypeName.string2TypeName(fieldEntity.getType().getName()))),
|
||||
fieldEntity.getQualifiers(),
|
||||
declaringClass,
|
||||
declaringClass.getClassHierarchy());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic DOMO representation of a method on a Java type that resides in a source file
|
||||
* @author rfuhrer
|
||||
*/
|
||||
private abstract class JavaEntityMethod extends AstMethod {
|
||||
private final TypeReference[] parameterTypes;
|
||||
private final TypeReference[] exceptionTypes;
|
||||
|
||||
public JavaEntityMethod(CAstEntity methodEntity,
|
||||
IClass owner,
|
||||
AbstractCFG cfg,
|
||||
SymbolTable symtab,
|
||||
boolean hasCatchBlock,
|
||||
TypeReference[][] catchTypes,
|
||||
LexicalInformation lexicalInfo,
|
||||
DebuggingInformation debugInfo)
|
||||
{
|
||||
super(owner,
|
||||
methodEntity.getQualifiers(),
|
||||
cfg,
|
||||
symtab,
|
||||
MethodReference.findOrCreate(
|
||||
owner.getReference(),
|
||||
Util.methodEntityToSelector(methodEntity)),
|
||||
hasCatchBlock,
|
||||
catchTypes,
|
||||
lexicalInfo,
|
||||
debugInfo);
|
||||
this.parameterTypes = computeParameterTypes(methodEntity);
|
||||
this.exceptionTypes = computeExceptionTypes(methodEntity);
|
||||
}
|
||||
|
||||
public JavaEntityMethod(CAstEntity methodEntity, IClass owner) {
|
||||
super(owner,
|
||||
methodEntity.getQualifiers(),
|
||||
MethodReference.findOrCreate(
|
||||
owner.getReference(),
|
||||
Util.methodEntityToSelector(methodEntity)));
|
||||
this.parameterTypes = computeParameterTypes(methodEntity);
|
||||
this.exceptionTypes = computeExceptionTypes(methodEntity);
|
||||
}
|
||||
|
||||
public int getMaxLocals() {
|
||||
Assertions.UNREACHABLE("AbstractJavaMethod.getMaxLocals() called");
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMaxStackHeight() {
|
||||
Assertions.UNREACHABLE("AbstractJavaMethod.getMaxStackHeight() called");
|
||||
return 0;
|
||||
}
|
||||
|
||||
public TypeReference getParameterType(int i) {
|
||||
return parameterTypes[i];
|
||||
}
|
||||
|
||||
private TypeReference[] computeParameterTypes(CAstEntity methodEntity) {
|
||||
TypeReference[] types;
|
||||
CAstType.Function type= (Function) methodEntity.getType();
|
||||
int argCount = type.getArgumentTypes().size();
|
||||
if (isStatic()) {
|
||||
types = new TypeReference[ argCount ];
|
||||
for(int i = 0; i < argCount;i++) {
|
||||
types[i] =
|
||||
TypeReference.findOrCreate(
|
||||
JavaSourceLoaderImpl.this.getReference(),
|
||||
((CAstType) type.getArgumentTypes().get(i)).getName());
|
||||
}
|
||||
} else {
|
||||
types = new TypeReference[ argCount+1 ];
|
||||
types[0] = cls.getReference();
|
||||
for(int i = 0; i < argCount;i++) {
|
||||
types[i+1] =
|
||||
TypeReference.findOrCreate(
|
||||
JavaSourceLoaderImpl.this.getReference(),
|
||||
((CAstType) type.getArgumentTypes().get(i)).getName());
|
||||
}
|
||||
}
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
public TypeReference[] getDeclaredExceptions() {
|
||||
return exceptionTypes;
|
||||
}
|
||||
|
||||
private TypeReference[] computeExceptionTypes(CAstEntity methodEntity) {
|
||||
CAstType.Function fType= (Function) methodEntity.getType();
|
||||
Collection exceptionTypes= fType.getExceptionTypes();
|
||||
|
||||
TypeReference[] result= new TypeReference[exceptionTypes.size()];
|
||||
int i = 0;
|
||||
for(Iterator iter= exceptionTypes.iterator(); iter.hasNext(); i++) {
|
||||
CAstType type = (CAstType) iter.next();
|
||||
result[i] =
|
||||
TypeReference.findOrCreate(
|
||||
JavaSourceLoaderImpl.this.getReference(),
|
||||
type.getName());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "<src-method: " + this.getReference() + ">";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DOMO representation of an abstract (body-less) method on a Java type that resides
|
||||
* in a source file
|
||||
* @author rfuhrer
|
||||
*/
|
||||
private class AbstractJavaMethod extends JavaEntityMethod {
|
||||
public AbstractJavaMethod(CAstEntity methodEntity, IClass owner) {
|
||||
super(methodEntity, owner);
|
||||
}
|
||||
|
||||
public String getLocalVariableName(int bcIndex, int localNumber) {
|
||||
Assertions.UNREACHABLE("AbstractJavaMethod.getLocalVariableName() called");
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean hasLocalVariableTable() {
|
||||
Assertions.UNREACHABLE("AbstractJavaMethod.hasLocalVariableTable() called");
|
||||
return false;
|
||||
}
|
||||
|
||||
public LexicalParent[] getParents() {
|
||||
return new LexicalParent[0];
|
||||
}
|
||||
|
||||
public ClassHierarchy getClassHierarchy() {
|
||||
return cha;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DOMO representation of a concrete method (which has a body) on a Java type that
|
||||
* resides in a source file
|
||||
* @author rfuhrer
|
||||
*/
|
||||
public class ConcreteJavaMethod extends JavaEntityMethod {
|
||||
public ConcreteJavaMethod(CAstEntity methodEntity,
|
||||
IClass owner,
|
||||
AbstractCFG cfg,
|
||||
SymbolTable symtab,
|
||||
boolean hasCatchBlock,
|
||||
TypeReference[][] catchTypes,
|
||||
LexicalInformation lexicalInfo,
|
||||
DebuggingInformation debugInfo) {
|
||||
super(methodEntity, owner, cfg, symtab, hasCatchBlock, catchTypes,
|
||||
lexicalInfo, debugInfo);
|
||||
}
|
||||
|
||||
public ClassHierarchy getClassHierarchy() {
|
||||
return cha;
|
||||
}
|
||||
|
||||
public String getLocalVariableName(int bcIndex, int localNumber) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean hasLocalVariableTable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public LexicalParent[] getParents() {
|
||||
if (AstTranslator.DEBUG_LEXICAL){
|
||||
Trace.println("resolving parents of " + this);
|
||||
}
|
||||
|
||||
if (lexicalInfo == null) {
|
||||
if (AstTranslator.DEBUG_LEXICAL) Trace.println("no info");
|
||||
return new LexicalParent[ 0 ];
|
||||
}
|
||||
|
||||
final String[] parents = lexicalInfo.getScopingParents();
|
||||
|
||||
if (parents == null) {
|
||||
if (AstTranslator.DEBUG_LEXICAL) Trace.println("no parents");
|
||||
return new LexicalParent[ 0 ];
|
||||
}
|
||||
|
||||
LexicalParent result[] = new LexicalParent[ parents.length ];
|
||||
|
||||
for(int i = 0; i < parents.length; i++) {
|
||||
int lastLeftParen= parents[i].lastIndexOf('(');
|
||||
int lastQ = parents[i].lastIndexOf('/', lastLeftParen);
|
||||
String typeName = parents[i].substring(0, lastQ);
|
||||
final IClass cls =
|
||||
lookupClass(TypeName.string2TypeName(typeName), cha);
|
||||
|
||||
String sig = parents[i].substring(lastQ);
|
||||
int nameEnd = sig.indexOf('(');
|
||||
String nameStr = sig.substring(1, nameEnd);
|
||||
Atom name = Atom.findOrCreateUnicodeAtom(nameStr);
|
||||
|
||||
String descStr = sig.substring(nameEnd);
|
||||
Descriptor desc = Descriptor.findOrCreateUTF8(descStr);
|
||||
|
||||
final Selector sel = new Selector(name, desc);
|
||||
|
||||
if (AstTranslator.DEBUG_LEXICAL)
|
||||
Trace.println("get "+typeName+", "+nameStr+", "+descStr);
|
||||
|
||||
final int hack = i;
|
||||
result[i] = new LexicalParent() {
|
||||
public String getName() {
|
||||
return parents[hack];
|
||||
}
|
||||
public AstMethod getMethod() {
|
||||
return (AstMethod)cls.getMethod(sel);
|
||||
}
|
||||
};
|
||||
|
||||
if (AstTranslator.DEBUG_LEXICAL)
|
||||
Trace.println("parent " + result[i].getName() + " is " + result[i].getMethod());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static int mapToInt(Collection/*<CAstQualifier>*/ qualifiers) {
|
||||
int result= 0;
|
||||
for(Iterator iter= qualifiers.iterator(); iter.hasNext();) {
|
||||
CAstQualifier q= (CAstQualifier) iter.next();
|
||||
|
||||
if (q == CAstQualifier.PUBLIC)
|
||||
result|= ClassConstants.ACC_PUBLIC;
|
||||
if (q == CAstQualifier.PROTECTED)
|
||||
result|= ClassConstants.ACC_PROTECTED;
|
||||
if (q == CAstQualifier.PRIVATE)
|
||||
result|= ClassConstants.ACC_PRIVATE;
|
||||
if (q == CAstQualifier.STATIC)
|
||||
result|= ClassConstants.ACC_STATIC;
|
||||
if (q == CAstQualifier.FINAL)
|
||||
result|= ClassConstants.ACC_FINAL;
|
||||
if (q == CAstQualifier.SYNCHRONIZED)
|
||||
result|= ClassConstants.ACC_SYNCHRONIZED;
|
||||
if (q == CAstQualifier.TRANSIENT)
|
||||
result|= ClassConstants.ACC_TRANSIENT;
|
||||
if (q == CAstQualifier.NATIVE)
|
||||
result|= ClassConstants.ACC_NATIVE;
|
||||
if (q == CAstQualifier.INTERFACE)
|
||||
result|= ClassConstants.ACC_INTERFACE;
|
||||
if (q == CAstQualifier.ABSTRACT)
|
||||
result|= ClassConstants.ACC_ABSTRACT;
|
||||
if (q == CAstQualifier.VOLATILE)
|
||||
result|= ClassConstants.ACC_VOLATILE;
|
||||
if (q == CAstQualifier.STRICTFP)
|
||||
result|= ClassConstants.ACC_STRICT;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public JavaSourceLoaderImpl(ClassLoaderReference loaderRef,
|
||||
IClassLoader parent,
|
||||
SetOfClasses exclusions,
|
||||
ClassHierarchy cha,
|
||||
WarningSet warnings) throws IOException {
|
||||
super(loaderRef, cha.getScope().getArrayClassLoader(), parent, cha.getScope().getExclusions(),
|
||||
cha.getScope().getModules(loaderRef), cha, warnings);
|
||||
}
|
||||
|
||||
public ClassHierarchy getClassHierarchy() {
|
||||
return cha;
|
||||
}
|
||||
|
||||
protected void loadAllSources(Set/*<ModuleEntry>*/ modules) {
|
||||
getTranslator().loadAllSources(modules);
|
||||
fTypeMap = null;
|
||||
}
|
||||
|
||||
protected abstract SourceModuleTranslator getTranslator();
|
||||
|
||||
public void defineFunction(CAstEntity n, IClass owner, AbstractCFG cfg,
|
||||
SymbolTable symtab, boolean hasCatchBlock, TypeReference[][] catchTypes,
|
||||
LexicalInformation lexicalInfo, DebuggingInformation debugInfo) {
|
||||
((JavaClass) owner).addMethod(n, owner, cfg, symtab, hasCatchBlock, catchTypes, lexicalInfo, debugInfo);
|
||||
}
|
||||
|
||||
public void defineAbstractFunction(CAstEntity n, IClass owner) {
|
||||
((JavaClass) owner).addMethod(n, owner);
|
||||
}
|
||||
|
||||
public void defineField(CAstEntity n, IClass owner) {
|
||||
((JavaClass) owner).addField(n);
|
||||
}
|
||||
|
||||
public IClass defineType(CAstEntity type, String typeName, CAstEntity owner) {
|
||||
Collection superTypeNames = new ArrayList();
|
||||
for(Iterator superTypes = type.getType().getSupertypes().iterator();
|
||||
superTypes.hasNext(); )
|
||||
{
|
||||
superTypeNames.add(TypeName.string2TypeName(((CAstType)superTypes.next()).getName()));
|
||||
}
|
||||
|
||||
JavaClass javaClass =
|
||||
new JavaClass(
|
||||
typeName,
|
||||
superTypeNames,
|
||||
type.getPosition(),
|
||||
type.getQualifiers(),
|
||||
this,
|
||||
(owner!=null)?(JavaClass)fTypeMap.get(owner): (JavaClass)null);
|
||||
|
||||
fTypeMap.put(type, javaClass);
|
||||
loadedClasses.put(javaClass.getName(), javaClass);
|
||||
return javaClass;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Java Source Loader (classes " + loadedClasses.values() + ")";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/******************************************************************************
|
||||
* 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.loader;
|
||||
|
||||
|
||||
import com.ibm.wala.cast.tree.*;
|
||||
import com.ibm.wala.types.*;
|
||||
import com.ibm.wala.util.Atom;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class Util {
|
||||
|
||||
public static Selector methodEntityToSelector(CAstEntity methodEntity) {
|
||||
Atom name= Atom.findOrCreateUnicodeAtom(methodEntity.getName());
|
||||
CAstType.Function signature= (CAstType.Function) methodEntity.getType();
|
||||
// Use signature to determine # of args; (entity's args includes 'this')
|
||||
TypeName retTypeName=
|
||||
TypeName.string2TypeName(signature.getReturnType().getName());
|
||||
TypeName[] argTypeNames=
|
||||
(signature.getArgumentCount() == 0) ?
|
||||
null :
|
||||
new TypeName[signature.getArgumentCount()];
|
||||
|
||||
int i= 0;
|
||||
for(Iterator iter= signature.getArgumentTypes().iterator();
|
||||
iter.hasNext(); i++)
|
||||
{
|
||||
CAstType argType= (CAstType) iter.next();
|
||||
argTypeNames[i]= TypeName.string2TypeName(argType.getName());
|
||||
}
|
||||
|
||||
Descriptor desc= Descriptor.findOrCreate(argTypeNames, retTypeName);
|
||||
|
||||
return new Selector(name, desc);
|
||||
}
|
||||
|
||||
public static Atom fieldEntityToAtom(CAstEntity fieldEntity) {
|
||||
return Atom.findOrCreateUnicodeAtom(fieldEntity.getName());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/******************************************************************************
|
||||
* 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.ssa;
|
||||
|
||||
import com.ibm.wala.cast.ir.ssa.*;
|
||||
|
||||
public class AstJavaAbstractInstructionVisitor
|
||||
extends AstAbstractInstructionVisitor
|
||||
implements AstJavaInstructionVisitor
|
||||
{
|
||||
|
||||
public void visitJavaInvoke(AstJavaInvokeInstruction instruction) {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/******************************************************************************
|
||||
* 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.ssa;
|
||||
|
||||
import com.ibm.wala.cast.ir.ssa.*;
|
||||
|
||||
public interface AstJavaInstructionVisitor extends AstInstructionVisitor {
|
||||
|
||||
public void visitJavaInvoke(AstJavaInvokeInstruction instruction);
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/******************************************************************************
|
||||
* 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.ssa;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
import com.ibm.wala.cast.ir.ssa.*;
|
||||
import com.ibm.wala.cast.ir.ssa.AstLexicalAccess.Access;
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.ssa.*;
|
||||
import com.ibm.wala.util.Exceptions;
|
||||
|
||||
public class AstJavaInvokeInstruction extends FixedParametersLexicalInvokeInstruction {
|
||||
|
||||
public AstJavaInvokeInstruction(int result, int[] params, int exception, CallSiteReference site) {
|
||||
super(result, params, exception, site);
|
||||
if (Assertions.verifyAssertions) {
|
||||
SSAInvokeInstruction.assertParamsKosher(result, params, site);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor InvokeInstruction. This case for void return values
|
||||
* @param i
|
||||
* @param params
|
||||
*/
|
||||
public AstJavaInvokeInstruction(int[] params, int exception, CallSiteReference site) {
|
||||
this(-1, params, exception, site);
|
||||
}
|
||||
|
||||
private AstJavaInvokeInstruction(int result, int[] params, int exception, CallSiteReference site, Access[] lexicalReads, Access[] lexicalWrites) {
|
||||
super(result, params, exception, site, lexicalReads, lexicalWrites);
|
||||
if (Assertions.verifyAssertions) {
|
||||
SSAInvokeInstruction.assertParamsKosher(result, params, site);
|
||||
}
|
||||
}
|
||||
|
||||
protected SSAInstruction copyInstruction(int result, int[] params, int exception, Access[] lexicalReads, Access[] lexicalWrites) {
|
||||
return new AstJavaInvokeInstruction(result, params, exception, getCallSite(), lexicalReads, lexicalWrites);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.ibm.domo.ssa.SSAInstruction#visit(IVisitor)
|
||||
*/
|
||||
public void visit(IVisitor v) {
|
||||
((AstJavaInstructionVisitor)v).visitJavaInvoke(this);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.domo.ssa.Instruction#getExceptionTypes()
|
||||
*/
|
||||
public Collection getExceptionTypes() {
|
||||
return Exceptions.getNullPointerException();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Aug 22, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import com.ibm.wala.cast.java.loader.JavaSourceLoaderImpl;
|
||||
import com.ibm.wala.cast.tree.CAstEntity;
|
||||
import com.ibm.wala.cast.util.CAstPrinter;
|
||||
|
||||
public class Java2IRTranslator {
|
||||
private final boolean DEBUG;
|
||||
|
||||
protected final JavaSourceLoaderImpl fLoader;
|
||||
protected final TranslatorToCAst fSourceTranslator;
|
||||
|
||||
public Java2IRTranslator(TranslatorToCAst sourceTranslator,
|
||||
JavaSourceLoaderImpl srcLoader)
|
||||
{
|
||||
this(sourceTranslator, srcLoader, false);
|
||||
}
|
||||
|
||||
public Java2IRTranslator(TranslatorToCAst sourceTranslator,
|
||||
JavaSourceLoaderImpl srcLoader,
|
||||
boolean debug)
|
||||
{
|
||||
DEBUG = debug;
|
||||
fLoader= srcLoader;
|
||||
fSourceTranslator = sourceTranslator;
|
||||
}
|
||||
|
||||
public void translate(Object ast, String N) {
|
||||
CAstEntity ce= fSourceTranslator.translate(ast, N);
|
||||
|
||||
if (DEBUG) {
|
||||
PrintWriter printWriter= new PrintWriter(System.out);
|
||||
CAstPrinter.printTo(ce, printWriter);
|
||||
printWriter.flush();
|
||||
}
|
||||
|
||||
new JavaCAst2IRTranslator(ce, fLoader).translate();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,379 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Aug 22, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.cast.ir.translator.AstTranslator;
|
||||
import com.ibm.wala.cast.java.loader.JavaSourceLoaderImpl;
|
||||
import com.ibm.wala.cast.java.ssa.AstJavaInvokeInstruction;
|
||||
import com.ibm.wala.cast.loader.AstMethod.DebuggingInformation;
|
||||
import com.ibm.wala.cast.loader.AstMethod.LexicalInformation;
|
||||
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.CAstQualifier;
|
||||
import com.ibm.wala.cast.tree.CAstType;
|
||||
import com.ibm.wala.cast.tree.CAstType.Method;
|
||||
import com.ibm.wala.cast.tree.visit.*;
|
||||
import com.ibm.wala.cfg.AbstractCFG;
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.NewSiteReference;
|
||||
import com.ibm.wala.ssa.SSAInstructionFactory;
|
||||
import com.ibm.wala.ssa.SSANewInstruction;
|
||||
import com.ibm.wala.ssa.SymbolTable;
|
||||
import com.ibm.wala.types.FieldReference;
|
||||
import com.ibm.wala.types.TypeName;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
|
||||
public class JavaCAst2IRTranslator extends AstTranslator {
|
||||
private final CAstEntity fSourceEntity;
|
||||
|
||||
public JavaCAst2IRTranslator(CAstEntity sourceFileEntity, JavaSourceLoaderImpl loader) {
|
||||
super(loader);
|
||||
fSourceEntity= sourceFileEntity;
|
||||
}
|
||||
|
||||
public void translate() {
|
||||
translate(fSourceEntity, fSourceEntity.getName());
|
||||
}
|
||||
|
||||
public CAstEntity sourceFileEntity() { return fSourceEntity; }
|
||||
public JavaSourceLoaderImpl loader() {
|
||||
return (JavaSourceLoaderImpl)loader;
|
||||
}
|
||||
|
||||
// Java does not have standalone global variables, and let's not
|
||||
// adopt the nasty JavaScript practice of creating globals without
|
||||
// explicit definitions
|
||||
protected boolean hasImplicitGlobals() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected TypeReference defaultCatchType() {
|
||||
return TypeReference.JavaLangException;
|
||||
}
|
||||
|
||||
protected TypeReference makeType(CAstType type) {
|
||||
return
|
||||
TypeReference.findOrCreate(
|
||||
loader.getReference(),
|
||||
TypeName.string2TypeName( type.getName() ));
|
||||
}
|
||||
|
||||
// Java globals are disguised as fields (statics), so we should never
|
||||
// ask this question when parsing Java code
|
||||
protected boolean treatGlobalsAsLexicallyScoped() {
|
||||
Assertions.UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean useLocalValuesForLexicalVars() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
protected void doThrow(WalkContext context, int exception) {
|
||||
context.cfg().addInstruction(SSAInstructionFactory.ThrowInstruction(exception));
|
||||
}
|
||||
|
||||
protected void doArrayRead(WalkContext context, int result, int arrayValue, CAstNode arrayRefNode, int[] dimValues) {
|
||||
TypeReference arrayTypeRef= (TypeReference) arrayRefNode.getChild(1).getValue();
|
||||
context.cfg().addInstruction(SSAInstructionFactory.ArrayLoadInstruction(result, arrayValue, dimValues[0], arrayTypeRef));
|
||||
}
|
||||
|
||||
protected void doArrayWrite(WalkContext context, int arrayValue, CAstNode arrayRefNode, int[] dimValues, int rval) {
|
||||
TypeReference arrayTypeRef =
|
||||
arrayRefNode.getKind() == CAstNode.ARRAY_LITERAL?
|
||||
((TypeReference) arrayRefNode.getChild(0).getChild(0).getValue())
|
||||
.getArrayElementType():
|
||||
(TypeReference) arrayRefNode.getChild(1).getValue();
|
||||
|
||||
|
||||
context.cfg().addInstruction(
|
||||
SSAInstructionFactory.ArrayStoreInstruction(
|
||||
arrayValue,
|
||||
dimValues[0],
|
||||
rval,
|
||||
arrayTypeRef));
|
||||
}
|
||||
|
||||
protected void doFieldRead(WalkContext context, int result, int receiver, CAstNode elt, CAstNode parent) {
|
||||
// elt is a constant CAstNode whose value is a FieldReference.
|
||||
FieldReference fieldRef= (FieldReference) elt.getValue();
|
||||
|
||||
if (receiver == -1) { // a static field: AstTranslator.getValue() produces -1 for null, we hope
|
||||
context.cfg().addInstruction(SSAInstructionFactory.GetInstruction(result, fieldRef));
|
||||
} else {
|
||||
context.cfg().addInstruction(SSAInstructionFactory.GetInstruction(result, receiver, fieldRef));
|
||||
processExceptions(parent, context);
|
||||
}
|
||||
}
|
||||
|
||||
protected void doFieldWrite(WalkContext context, int receiver, CAstNode elt, CAstNode parent, int rval) {
|
||||
FieldReference fieldRef= (FieldReference) elt.getValue();
|
||||
|
||||
if (receiver == -1) { // a static field: AstTranslator.getValue() produces -1 for null, we hope
|
||||
context.cfg().addInstruction(SSAInstructionFactory.PutInstruction(rval, fieldRef));
|
||||
} else {
|
||||
context.cfg().addInstruction(SSAInstructionFactory.PutInstruction(receiver, rval, fieldRef));
|
||||
processExceptions(parent, context);
|
||||
}
|
||||
}
|
||||
|
||||
protected void doMaterializeFunction(WalkContext context, int result, int exception, CAstEntity fn) {
|
||||
// Not possible in Java (no free-standing functions)
|
||||
Assertions.UNREACHABLE("Real functions in Java??? I don't think so!");
|
||||
}
|
||||
|
||||
protected void doNewObject(WalkContext context, CAstNode newNode, int result, Object type, int[] arguments) {
|
||||
TypeReference typeRef = (TypeReference) type;
|
||||
|
||||
NewSiteReference site =
|
||||
NewSiteReference.make(context.cfg().getCurrentInstruction(), typeRef);
|
||||
|
||||
context.cfg().addInstruction(
|
||||
(arguments == null)?
|
||||
SSAInstructionFactory.NewInstruction(result, site):
|
||||
new SSANewInstruction(result, site, arguments));
|
||||
|
||||
processExceptions(newNode, context);
|
||||
}
|
||||
|
||||
private void processExceptions(CAstNode n, WalkContext context) {
|
||||
context.cfg().addPreNode(n, context.getUnwindState());
|
||||
context.cfg().newBlock( true );
|
||||
|
||||
Collection labels = context.getControlFlow().getTargetLabels(n);
|
||||
|
||||
for(Iterator iter= labels.iterator(); iter.hasNext(); ) {
|
||||
Object label = iter.next();
|
||||
CAstNode target = context.getControlFlow().getTarget(n, label);
|
||||
if (target == CAstControlFlowMap.EXCEPTION_TO_EXIT)
|
||||
context.cfg().addPreEdgeToExit( n, true );
|
||||
else
|
||||
context.cfg().addPreEdge(n, target, true);
|
||||
}
|
||||
}
|
||||
|
||||
protected void doCall(WalkContext context, CAstNode call, int result, int exception,
|
||||
CAstNode name, int receiver, int[] arguments) {
|
||||
Assertions._assert(name.getKind() == CAstNode.CONSTANT);
|
||||
CallSiteReference dummySiteRef= (CallSiteReference) name.getValue();
|
||||
int pc= context.cfg().getCurrentInstruction();
|
||||
boolean isStatic= (receiver == -1);
|
||||
int[] realArgs= isStatic ? arguments : new int[arguments.length + 1];
|
||||
|
||||
if (!isStatic) {
|
||||
realArgs[0]= receiver;
|
||||
System.arraycopy(arguments, 0, realArgs, 1, arguments.length);
|
||||
}
|
||||
CallSiteReference realSiteRef= CallSiteReference.make(pc, dummySiteRef.getDeclaredTarget(), dummySiteRef.getInvocationCode());
|
||||
|
||||
if (realSiteRef.getDeclaredTarget().getReturnType().equals(TypeReference.Void))
|
||||
context.cfg().addInstruction(new AstJavaInvokeInstruction(realArgs, exception, realSiteRef));
|
||||
else
|
||||
context.cfg().addInstruction(new AstJavaInvokeInstruction(result, realArgs, exception, realSiteRef));
|
||||
processExceptions(call, context);
|
||||
}
|
||||
|
||||
protected void doGlobalRead(WalkContext context, int result, String name) {
|
||||
Assertions.UNREACHABLE("doGlobalRead() called for Java code???");
|
||||
}
|
||||
|
||||
protected void doGlobalWrite(WalkContext context, String name, int rval) {
|
||||
Assertions.UNREACHABLE("doGlobalWrite() called for Java code???");
|
||||
}
|
||||
|
||||
protected void defineField(CAstEntity topEntity, WalkContext definingContext, CAstEntity n) {
|
||||
Assertions._assert(topEntity.getKind() == CAstEntity.TYPE_ENTITY);
|
||||
Assertions._assert(n.getKind() == CAstEntity.FIELD_ENTITY);
|
||||
|
||||
// N.B.: base class may actually ask to create a synthetic type to wrap
|
||||
// code bodies, so we may see other things than TYPE_ENTITY here.
|
||||
IClass owner =
|
||||
loader.lookupClass(makeType(topEntity.getType()).getName(),
|
||||
loader().getClassHierarchy());
|
||||
|
||||
if (owner == null) {
|
||||
Assertions._assert(owner != null, makeType(topEntity.getType()).getName() + " not found in " + loader);
|
||||
}
|
||||
|
||||
((JavaSourceLoaderImpl)loader).defineField(n, owner);
|
||||
}
|
||||
|
||||
// handles abstract method declarations, which do not get defineFunction called for them
|
||||
protected void declareFunction(CAstEntity N, WalkContext definingContext) {
|
||||
CAstType.Method methodType= (Method) N.getType();
|
||||
CAstType owningType= methodType.getDeclaringType();
|
||||
IClass owner =
|
||||
loader.lookupClass(makeType(owningType).getName(),
|
||||
loader().getClassHierarchy());
|
||||
|
||||
if (owner == null) {
|
||||
Assertions._assert(owner != null, makeType(owningType).getName().toString() + " not found in " + loader);
|
||||
}
|
||||
|
||||
((JavaSourceLoaderImpl)loader).defineAbstractFunction(N, owner);
|
||||
}
|
||||
|
||||
protected void defineFunction(CAstEntity N,
|
||||
WalkContext definingContext,
|
||||
AbstractCFG cfg,
|
||||
SymbolTable symtab,
|
||||
boolean hasCatchBlock,
|
||||
TypeReference[][] caughtTypes,
|
||||
LexicalInformation lexicalInfo,
|
||||
DebuggingInformation debugInfo) {
|
||||
// N.B.: base class may actually ask to create a synthetic type to wrap
|
||||
// code bodies, so we may see other things than TYPE_ENTITY here.
|
||||
CAstType.Method methodType= (Method) N.getType();
|
||||
CAstType owningType= methodType.getDeclaringType();
|
||||
IClass owner =
|
||||
loader.lookupClass(makeType(owningType).getName(),
|
||||
loader().getClassHierarchy());
|
||||
|
||||
if (owner == null) {
|
||||
Assertions._assert(owner != null, makeType(owningType).getName().toString() + " not found in " + loader);
|
||||
}
|
||||
|
||||
((JavaSourceLoaderImpl)loader).defineFunction(N, owner, cfg, symtab, hasCatchBlock, caughtTypes, lexicalInfo, debugInfo);
|
||||
}
|
||||
|
||||
protected void doPrimitive(int resultVal, WalkContext context, CAstNode primitiveCall) {
|
||||
// For now, no-op (no primitives in normal Java code)
|
||||
Assertions.UNREACHABLE("doPrimitive() called for Java code???");
|
||||
}
|
||||
|
||||
protected String composeEntityName(WalkContext parent, CAstEntity f) {
|
||||
switch(f.getKind()) {
|
||||
case CAstEntity.TYPE_ENTITY: {
|
||||
return (parent.getName().length() == 0) ? f.getName() : parent.getName() + "/" + f.getName();
|
||||
}
|
||||
case CAstEntity.FUNCTION_ENTITY: {
|
||||
// TODO properly handle types with clashing names/signatures within a given method
|
||||
return parent.getName() + "/" + f.getSignature();
|
||||
}
|
||||
default: {
|
||||
return parent.getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private CAstEntity getEnclosingType(CAstEntity entity) {
|
||||
if (entity.getQualifiers().contains(CAstQualifier.STATIC))
|
||||
return null;
|
||||
else
|
||||
return getEnclosingTypeInternal( getParent( entity ) );
|
||||
}
|
||||
|
||||
private CAstEntity getEnclosingTypeInternal(CAstEntity entity) {
|
||||
switch (entity.getKind()) {
|
||||
case CAstEntity.TYPE_ENTITY: {
|
||||
return entity;
|
||||
}
|
||||
case CAstEntity.FUNCTION_ENTITY: {
|
||||
if (entity.getQualifiers().contains(CAstQualifier.STATIC))
|
||||
return null;
|
||||
else
|
||||
return getEnclosingTypeInternal( getParent( entity ) );
|
||||
}
|
||||
case CAstEntity.FILE_ENTITY: {
|
||||
return null;
|
||||
}
|
||||
default: {
|
||||
return getEnclosingTypeInternal( getParent( entity ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void defineType(CAstEntity type, WalkContext wc) {
|
||||
CAstEntity parentType = getEnclosingType( type );
|
||||
// ((JavaSourceLoaderImpl)loader).defineType(type, composeEntityName(wc,type), parentType);
|
||||
((JavaSourceLoaderImpl)loader).defineType(type, type.getType().getName(), parentType);
|
||||
}
|
||||
|
||||
protected boolean visitCast(CAstNode n, Context c, CAstVisitor visitor) {
|
||||
WalkContext context = (WalkContext)c;
|
||||
int result = context.currentScope().allocateTempValue();
|
||||
setValue(n, result);
|
||||
return false;
|
||||
}
|
||||
protected void leaveCast(CAstNode n, Context c, CAstVisitor visitor) {
|
||||
WalkContext context = (WalkContext)c;
|
||||
int result = getValue(n);
|
||||
CAstType type = (CAstType) n.getChild(0).getValue();
|
||||
TypeReference ref = makeType(type);
|
||||
|
||||
if (ref.isPrimitiveType()) {
|
||||
context.cfg().addInstruction(
|
||||
SSAInstructionFactory.ConversionInstruction(
|
||||
result,
|
||||
getValue(n.getChild(1)),
|
||||
ref,
|
||||
ref));
|
||||
|
||||
} else {
|
||||
context.cfg().addInstruction(
|
||||
SSAInstructionFactory.CheckCastInstruction(
|
||||
result,
|
||||
getValue(n.getChild(1)),
|
||||
ref));
|
||||
}
|
||||
}
|
||||
protected boolean visitInstanceOf(CAstNode n, Context c, CAstVisitor visitor) {
|
||||
WalkContext context = (WalkContext)c;
|
||||
int result = context.currentScope().allocateTempValue();
|
||||
setValue(n, result);
|
||||
return false;
|
||||
}
|
||||
protected void leaveInstanceOf(CAstNode n, Context c, CAstVisitor visitor) {
|
||||
WalkContext context = (WalkContext)c;
|
||||
int result = getValue(n);
|
||||
CAstType type = (CAstType) n.getChild(0).getValue();
|
||||
|
||||
TypeReference ref = makeType( type );
|
||||
context.cfg().addInstruction(
|
||||
SSAInstructionFactory.InstanceofInstruction(
|
||||
result,
|
||||
getValue(n.getChild(1)),
|
||||
ref));
|
||||
}
|
||||
|
||||
protected boolean doVisit(CAstNode n, Context context, CAstVisitor visitor) {
|
||||
WalkContext wc = (WalkContext) context;
|
||||
if (n.getKind() == CAstNode.MONITOR_ENTER) {
|
||||
visitor.visit(n.getChild(0), wc, visitor);
|
||||
wc.cfg().addInstruction(
|
||||
SSAInstructionFactory.MonitorInstruction(
|
||||
getValue(n.getChild(0)),
|
||||
true));
|
||||
|
||||
return true;
|
||||
} else if (n.getKind() == CAstNode.MONITOR_EXIT) {
|
||||
visitor.visit(n.getChild(0), wc, visitor);
|
||||
wc.cfg().addInstruction(
|
||||
SSAInstructionFactory.MonitorInstruction(
|
||||
getValue(n.getChild(0)),
|
||||
false));
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return super.doVisit(n, wc, visitor);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/******************************************************************************
|
||||
* 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.*;
|
||||
|
||||
public interface JavaProcedureEntity extends CAstEntity {
|
||||
|
||||
public String getSignature();
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Oct 6, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* An interface used by the JavaSourceLoaderImpl to encapsulate the loading of source
|
||||
* entities on the compile-time classpath into the DOMO analysis infrastructure.
|
||||
* @author rfuhrer
|
||||
*/
|
||||
public interface SourceModuleTranslator {
|
||||
void loadAllSources(Set/*<ModuleEntry>*/ modules);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/******************************************************************************
|
||||
* 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.*;
|
||||
|
||||
public interface TranslatorToCAst {
|
||||
|
||||
public CAstEntity translate(Object astRoot, String unitName);
|
||||
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Sep 1, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import polyglot.ast.*;
|
||||
|
||||
import com.ibm.wala.cast.java.translator.polyglot.PolyglotJava2CAstTranslator.*;
|
||||
import com.ibm.wala.cast.tree.CAstNode;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
/**
|
||||
* Wrapper for the logic (nasty cascaded instanceof tests) necessary to visit a Polyglot AST
|
||||
* and dispatch to the appropriate TranslatingVisitor methods for each AST node type.
|
||||
* @author rfuhrer
|
||||
*/
|
||||
public class ASTTraverser {
|
||||
protected ASTTraverser() { }
|
||||
|
||||
public static CAstNode visit(Node n, TranslatingVisitor tv, WalkContext wc) {
|
||||
if (n instanceof MethodDecl) {
|
||||
return tv.visit((MethodDecl) n, (MethodContext) wc);
|
||||
} else if (n instanceof ConstructorDecl) {
|
||||
return tv.visit((ConstructorDecl) n, (MethodContext) wc);
|
||||
} else if (n instanceof FieldDecl) {
|
||||
return tv.visit((FieldDecl) n, (MethodContext) wc);
|
||||
} else if (n instanceof Import) {
|
||||
return tv.visit((Import) n, wc);
|
||||
} else if (n instanceof PackageNode) {
|
||||
return tv.visit((PackageNode) n, wc);
|
||||
} else if (n instanceof CanonicalTypeNode) {
|
||||
return tv.visit((CanonicalTypeNode) n, wc);
|
||||
} else if (n instanceof ArrayTypeNode) {
|
||||
return tv.visit((ArrayTypeNode) n, wc);
|
||||
} else if (n instanceof ArrayInit) {
|
||||
return tv.visit((ArrayInit) n, wc);
|
||||
} else if (n instanceof ArrayAccessAssign) {
|
||||
return tv.visit((ArrayAccessAssign) n, wc);
|
||||
} else if (n instanceof FieldAssign) {
|
||||
return tv.visit((FieldAssign) n, wc);
|
||||
} else if (n instanceof LocalAssign) {
|
||||
return tv.visit((LocalAssign) n, wc);
|
||||
} else if (n instanceof Binary) {
|
||||
return tv.visit((Binary) n, wc);
|
||||
} else if (n instanceof Call) {
|
||||
return tv.visit((Call) n, wc);
|
||||
} else if (n instanceof ConstructorCall) {
|
||||
return tv.visit((ConstructorCall) n, wc);
|
||||
} else if (n instanceof Cast) {
|
||||
return tv.visit((Cast) n, wc);
|
||||
} else if (n instanceof Conditional) {
|
||||
return tv.visit((Conditional) n, wc);
|
||||
} else if (n instanceof Instanceof) {
|
||||
return tv.visit((Instanceof) n, wc);
|
||||
} else if (n instanceof BooleanLit) {
|
||||
return tv.visit((BooleanLit) n, wc);
|
||||
} else if (n instanceof ClassLit) {
|
||||
return tv.visit((ClassLit) n, wc);
|
||||
} else if (n instanceof FloatLit) {
|
||||
return tv.visit((FloatLit) n, wc);
|
||||
} else if (n instanceof NullLit) {
|
||||
return tv.visit((NullLit) n, wc);
|
||||
} else if (n instanceof CharLit) {
|
||||
return tv.visit((CharLit) n, wc);
|
||||
} else if (n instanceof IntLit) {
|
||||
return tv.visit((IntLit) n, wc);
|
||||
} else if (n instanceof StringLit) {
|
||||
return tv.visit((StringLit) n, wc);
|
||||
} else if (n instanceof New) {
|
||||
return tv.visit((New) n, wc);
|
||||
} else if (n instanceof NewArray) {
|
||||
return tv.visit((NewArray) n, wc);
|
||||
} else if (n instanceof Special) {
|
||||
return tv.visit((Special) n, wc);
|
||||
} else if (n instanceof Unary) {
|
||||
return tv.visit((Unary) n, wc);
|
||||
} else if (n instanceof ArrayAccess) {
|
||||
return tv.visit((ArrayAccess) n, wc);
|
||||
} else if (n instanceof Field) {
|
||||
return tv.visit((Field) n, wc);
|
||||
} else if (n instanceof Local) {
|
||||
return tv.visit((Local) n, wc);
|
||||
} else if (n instanceof ClassBody) {
|
||||
return tv.visit((ClassBody) n, wc);
|
||||
} else if (n instanceof ClassDecl) {
|
||||
return tv.visit((ClassDecl) n, wc);
|
||||
} else if (n instanceof Initializer) {
|
||||
return tv.visit((Initializer) n, wc);
|
||||
} else if (n instanceof Assert) {
|
||||
return tv.visit((Assert) n, wc);
|
||||
} else if (n instanceof Branch) {
|
||||
return tv.visit((Branch) n, wc);
|
||||
} else if (n instanceof SwitchBlock) { // must test for this one before Block
|
||||
return tv.visit((SwitchBlock) n, wc);
|
||||
} else if (n instanceof Block) { // must test for this one before Block
|
||||
return tv.visit((Block) n, wc);
|
||||
} else if (n instanceof Catch) {
|
||||
return tv.visit((Catch) n, wc);
|
||||
} else if (n instanceof If) {
|
||||
return tv.visit((If) n, wc);
|
||||
} else if (n instanceof Labeled) {
|
||||
return tv.visit((Labeled) n, wc);
|
||||
} else if (n instanceof LocalClassDecl) {
|
||||
return tv.visit((LocalClassDecl) n, wc);
|
||||
} else if (n instanceof Do) {
|
||||
return tv.visit((Do) n, wc);
|
||||
} else if (n instanceof For) {
|
||||
return tv.visit((For) n, wc);
|
||||
} else if (n instanceof While) {
|
||||
return tv.visit((While) n, wc);
|
||||
} else if (n instanceof Switch) {
|
||||
return tv.visit((Switch) n, wc);
|
||||
} else if (n instanceof Synchronized) {
|
||||
return tv.visit((Synchronized) n, wc);
|
||||
} else if (n instanceof Try) {
|
||||
return tv.visit((Try) n, wc);
|
||||
} else if (n instanceof Empty) {
|
||||
return tv.visit((Empty) n, wc);
|
||||
} else if (n instanceof Eval) {
|
||||
return tv.visit((Eval) n, wc);
|
||||
} else if (n instanceof LocalDecl) {
|
||||
return tv.visit((LocalDecl) n, wc);
|
||||
} else if (n instanceof Return) {
|
||||
return tv.visit((Return) n, wc);
|
||||
} else if (n instanceof Case) {
|
||||
return tv.visit((Case) n, wc);
|
||||
} else if (n instanceof Throw) {
|
||||
return tv.visit((Throw) n, wc);
|
||||
} else if (n instanceof Formal) {
|
||||
return tv.visit((Formal) n, wc);
|
||||
} else {
|
||||
Assertions.UNREACHABLE("Unhandled node type in ASTTraverser.visit(): "+n.getClass());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/******************************************************************************
|
||||
* 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.polyglot;
|
||||
|
||||
import polyglot.ast.ArrayInit;
|
||||
import polyglot.ast.Expr;
|
||||
import polyglot.frontend.CyclicDependencyException;
|
||||
import polyglot.frontend.ExtensionInfo;
|
||||
import polyglot.frontend.Job;
|
||||
import polyglot.frontend.Pass;
|
||||
import polyglot.frontend.Scheduler;
|
||||
import polyglot.frontend.VisitorPass;
|
||||
import polyglot.frontend.goals.AbstractGoal;
|
||||
import polyglot.types.SemanticException;
|
||||
import polyglot.types.Type;
|
||||
import polyglot.util.ErrorInfo;
|
||||
import polyglot.visit.AscriptionVisitor;
|
||||
|
||||
/**
|
||||
* Runs an AscriptionVisitor to make sure that empty array literals actually get a type.
|
||||
* @author rfuhrer
|
||||
*/
|
||||
public class AscriptionGoal extends AbstractGoal {
|
||||
public AscriptionGoal(Job job) {
|
||||
super(job);
|
||||
try {
|
||||
Scheduler scheduler= job.extensionInfo().scheduler();
|
||||
|
||||
addPrerequisiteGoal(scheduler.TypeChecked(job), scheduler);
|
||||
} catch (CyclicDependencyException e) {
|
||||
job.compiler().errorQueue().enqueue(ErrorInfo.INTERNAL_ERROR, "Cycle encountered in goal graph?");
|
||||
throw new IllegalStateException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public Pass createPass(ExtensionInfo extInfo) {
|
||||
return new VisitorPass(this,
|
||||
new AscriptionVisitor(job(), extInfo.typeSystem(), extInfo.nodeFactory()) {
|
||||
public Expr ascribe(Expr e, Type toType) throws SemanticException {
|
||||
if (e instanceof ArrayInit && e.type().isNull()) {
|
||||
return e.type(toType);
|
||||
}
|
||||
return super.ascribe(e, toType);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Oct 6, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import polyglot.frontend.CyclicDependencyException;
|
||||
import polyglot.frontend.Job;
|
||||
import polyglot.frontend.Pass;
|
||||
import polyglot.frontend.Scheduler;
|
||||
import polyglot.frontend.goals.AbstractGoal;
|
||||
import polyglot.frontend.goals.EndGoal;
|
||||
import polyglot.util.ErrorInfo;
|
||||
|
||||
import com.ibm.wala.cast.java.loader.*;
|
||||
import com.ibm.wala.cast.java.translator.*;
|
||||
|
||||
/**
|
||||
* A kind of EndGoal that indicates that DOMO IR has been generated for the given compilation unit.
|
||||
* @author rfuhrer
|
||||
*/
|
||||
public class IRGoal extends AbstractGoal implements EndGoal {
|
||||
private JavaSourceLoaderImpl fSourceLoader;
|
||||
|
||||
public IRGoal(Job job, JavaSourceLoaderImpl sourceLoader) {
|
||||
super(job);
|
||||
fSourceLoader = sourceLoader;
|
||||
try {
|
||||
Scheduler scheduler= job.extensionInfo().scheduler();
|
||||
|
||||
addPrerequisiteGoal(scheduler.TypeChecked(job), scheduler);
|
||||
// Need ConstantsChecked in order to make sure that case statements have non-zero labels.
|
||||
addPrerequisiteGoal(scheduler.ConstantsChecked(job), scheduler);
|
||||
// Need to add an AscriptionGoal as a prereq to make sure that empty array initializers get a type ascribed.
|
||||
addPrerequisiteGoal(new AscriptionGoal(job), scheduler);
|
||||
} catch (CyclicDependencyException e) {
|
||||
job.compiler().errorQueue().enqueue(ErrorInfo.INTERNAL_ERROR, "Cycle encountered in goal graph?");
|
||||
throw new IllegalStateException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public Pass createPass(polyglot.frontend.ExtensionInfo extInfo) {
|
||||
return new JavaIRPass(this, job(),
|
||||
new Java2IRTranslator(
|
||||
new PolyglotJava2CAstTranslator(
|
||||
fSourceLoader.getReference(),
|
||||
extInfo.nodeFactory(),
|
||||
extInfo.typeSystem()),
|
||||
fSourceLoader));
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "<DOMO IR goal for " + job().source().path() + ">";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Oct 21, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
|
||||
public interface IRTranslatorExtension {
|
||||
void setSourceLoader(PolyglotSourceLoaderImpl jsli);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Oct 6, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import polyglot.frontend.AbstractPass;
|
||||
import polyglot.frontend.Job;
|
||||
import polyglot.frontend.goals.Goal;
|
||||
|
||||
import com.ibm.wala.cast.java.translator.*;
|
||||
|
||||
/**
|
||||
* A Pass that creates DOMO IR for the given Java compilation unit.
|
||||
* @author rfuhrer
|
||||
*/
|
||||
public final class JavaIRPass extends AbstractPass {
|
||||
private final Job fJob;
|
||||
private final Java2IRTranslator fTranslator;
|
||||
|
||||
public JavaIRPass(Goal goal, Job job, Java2IRTranslator translator) {
|
||||
super(goal);
|
||||
this.fJob= job;
|
||||
this.fTranslator= translator;
|
||||
}
|
||||
|
||||
public boolean run() {
|
||||
fTranslator.translate(fJob.ast(), fJob.source().name());
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Oct 6, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import java.io.Reader;
|
||||
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
import polyglot.frontend.*;
|
||||
import polyglot.frontend.goals.Goal;
|
||||
import polyglot.util.ErrorQueue;
|
||||
|
||||
/**
|
||||
* A Polyglot extension descriptor for a test harness extension that generates DOMO IR for
|
||||
* the sources and class files in the classpath.
|
||||
* @author rfuhrer
|
||||
*/
|
||||
public class JavaIRTranslatorExtension extends JLExtensionInfo implements IRTranslatorExtension {
|
||||
protected PolyglotSourceLoaderImpl fSourceLoader;
|
||||
|
||||
public void setSourceLoader(PolyglotSourceLoaderImpl sourceLoader) {
|
||||
fSourceLoader= sourceLoader;
|
||||
}
|
||||
|
||||
public Goal getCompileGoal(Job job) {
|
||||
return new IRGoal(job, fSourceLoader);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Oct 7, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.ibm.wala.cast.java.ipa.callgraph.*;
|
||||
import com.ibm.wala.classLoader.ClassLoaderFactoryImpl;
|
||||
import com.ibm.wala.classLoader.ClassLoaderImpl;
|
||||
import com.ibm.wala.classLoader.IClassLoader;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.ipa.callgraph.impl.SetOfClasses;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
|
||||
public class PolyglotClassLoaderFactory extends ClassLoaderFactoryImpl {
|
||||
|
||||
final protected IRTranslatorExtension fExtInfo;
|
||||
|
||||
public PolyglotClassLoaderFactory(SetOfClasses exclusions, WarningSet warnings, IRTranslatorExtension extInfo) {
|
||||
super(exclusions, warnings);
|
||||
fExtInfo= extInfo;
|
||||
}
|
||||
|
||||
protected IClassLoader makeNewClassLoader(ClassLoaderReference classLoaderReference, ClassHierarchy cha, IClassLoader parent, AnalysisScope scope) throws IOException {
|
||||
if (classLoaderReference.equals(JavaSourceAnalysisScope.SOURCE_REF)) {
|
||||
ClassLoaderImpl cl = new PolyglotSourceLoaderImpl(classLoaderReference, parent, getExclusions(), cha, getWarnings(), fExtInfo);
|
||||
cl.init( scope.getModules( classLoaderReference ));
|
||||
return cl;
|
||||
} else {
|
||||
return super.makeNewClassLoader(classLoaderReference, cha, parent, scope);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Oct 6, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import polyglot.frontend.Compiler;
|
||||
import polyglot.frontend.ExtensionInfo;
|
||||
import polyglot.frontend.Job;
|
||||
import polyglot.frontend.Scheduler;
|
||||
import polyglot.util.ErrorInfo;
|
||||
import polyglot.util.ErrorLimitError;
|
||||
import polyglot.util.ErrorQueue;
|
||||
import polyglot.util.InternalCompilerError;
|
||||
import polyglot.util.Position;
|
||||
import polyglot.util.StdErrorQueue;
|
||||
|
||||
/**
|
||||
* Enhancement of core Polyglot compiler that takes as input a Collection of StreamSources.
|
||||
* Identical to Compiler in all other respects.
|
||||
* @author rfuhrer
|
||||
*/
|
||||
public final class PolyglotFrontEnd extends Compiler {
|
||||
public PolyglotFrontEnd(ExtensionInfo info, ErrorQueue eq) {
|
||||
super(info, eq);
|
||||
}
|
||||
public PolyglotFrontEnd(ExtensionInfo info) {
|
||||
this(info, new StdErrorQueue(System.err, 1000 * 1000, info.compilerName()));
|
||||
}
|
||||
|
||||
public boolean compile(Collection/*<StreamSource>*/sources) {
|
||||
boolean okay= false;
|
||||
|
||||
try {
|
||||
try {
|
||||
Scheduler scheduler= sourceExtension().scheduler();
|
||||
List jobs= new ArrayList();
|
||||
|
||||
// First, create a goal to compile every source file.
|
||||
for(Iterator i= sources.iterator(); i.hasNext(); ) {
|
||||
StreamSource source= (StreamSource) i.next();
|
||||
|
||||
// mark this source as being explicitly specified by the user.
|
||||
source.setUserSpecified(true);
|
||||
|
||||
// Add a new SourceJob for the given source. If a Job for the source
|
||||
// already exists, then we will be given the existing job.
|
||||
Job job= scheduler.addJob(source);
|
||||
jobs.add(job);
|
||||
|
||||
// Now, add a goal for completing the job.
|
||||
scheduler.addGoal(sourceExtension().getCompileGoal(job));
|
||||
}
|
||||
|
||||
scheduler.setCommandLineJobs(jobs);
|
||||
|
||||
// Then, compile the files to completion.
|
||||
okay= scheduler.runToCompletion();
|
||||
} catch (InternalCompilerError e) {
|
||||
// Report it like other errors, but rethrow to get the stack trace.
|
||||
try {
|
||||
errorQueue().enqueue(ErrorInfo.INTERNAL_ERROR, e.message(), e.position());
|
||||
} catch (ErrorLimitError e2) {
|
||||
}
|
||||
errorQueue().flush();
|
||||
throw e;
|
||||
} catch (RuntimeException e) {
|
||||
// Flush the error queue, then rethrow to get the stack trace.
|
||||
errorQueue().enqueue(ErrorInfo.INTERNAL_ERROR, "Internal polyglot compiler error: " + e.getMessage(), Position.COMPILER_GENERATED);
|
||||
errorQueue().flush();
|
||||
throw e;
|
||||
}
|
||||
} catch (ErrorLimitError e) {
|
||||
}
|
||||
errorQueue().flush();
|
||||
|
||||
for(Iterator i= allExtensions().iterator(); i.hasNext(); ) {
|
||||
ExtensionInfo ext= (ExtensionInfo) i.next();
|
||||
ext.getStats().report();
|
||||
}
|
||||
return okay;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,38 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Oct 7, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.ibm.wala.cast.java.loader.*;
|
||||
import com.ibm.wala.cast.java.translator.*;
|
||||
import com.ibm.wala.classLoader.IClassLoader;
|
||||
import com.ibm.wala.ipa.callgraph.impl.SetOfClasses;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
|
||||
public class PolyglotSourceLoaderImpl extends JavaSourceLoaderImpl {
|
||||
protected final IRTranslatorExtension fExtInfo;
|
||||
|
||||
public PolyglotSourceLoaderImpl(ClassLoaderReference loaderRef, IClassLoader parent, SetOfClasses exclusions,
|
||||
ClassHierarchy cha, WarningSet warnings, IRTranslatorExtension extInfo) throws IOException {
|
||||
super(loaderRef, parent, exclusions, cha, warnings);
|
||||
fExtInfo= extInfo;
|
||||
}
|
||||
|
||||
protected SourceModuleTranslator getTranslator() {
|
||||
return new PolyglotSourceModuleTranslator(cha.getScope(), fExtInfo, this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Oct 6, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import polyglot.frontend.Compiler;
|
||||
import polyglot.frontend.ExtensionInfo;
|
||||
import polyglot.main.Options;
|
||||
import polyglot.main.UsageError;
|
||||
import polyglot.util.ErrorInfo;
|
||||
import polyglot.util.Position;
|
||||
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.cast.java.translator.*;
|
||||
import com.ibm.wala.classLoader.DirectoryTreeModule;
|
||||
import com.ibm.wala.classLoader.JarFileModule;
|
||||
import com.ibm.wala.classLoader.Module;
|
||||
import com.ibm.wala.classLoader.SourceFileModule;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
|
||||
/**
|
||||
* A SourceModuleTranslator whose implementation of loadAllSources() uses the PolyglotFrontEnd
|
||||
* pseudo-compiler to generate DOMO IR for the sources in the compile-time classpath.
|
||||
* @author rfuhrer
|
||||
*/
|
||||
public class PolyglotSourceModuleTranslator implements SourceModuleTranslator {
|
||||
private final ExtensionInfo fExtInfo;
|
||||
|
||||
private String fClassPath;
|
||||
|
||||
public PolyglotSourceModuleTranslator(AnalysisScope scope, IRTranslatorExtension extInfo, PolyglotSourceLoaderImpl sourceLoader) {
|
||||
fExtInfo= (ExtensionInfo) extInfo;
|
||||
computeClassPath(scope);
|
||||
extInfo.setSourceLoader(sourceLoader);
|
||||
}
|
||||
|
||||
private void computeClassPath(AnalysisScope scope) {
|
||||
StringBuffer buf= new StringBuffer();
|
||||
|
||||
ClassLoaderReference cl= scope.getApplicationLoader();
|
||||
|
||||
while (cl != null) {
|
||||
Set/* <Module> */modules= scope.getModules(cl);
|
||||
|
||||
for(Iterator iter= modules.iterator(); iter.hasNext();) {
|
||||
Module m= (Module) iter.next();
|
||||
|
||||
if (buf.length() > 0)
|
||||
buf.append(File.pathSeparator);
|
||||
if (m instanceof JarFileModule) {
|
||||
JarFileModule jarFileModule= (JarFileModule) m;
|
||||
|
||||
buf.append(jarFileModule.getAbsolutePath());
|
||||
} else if (m instanceof DirectoryTreeModule) {
|
||||
DirectoryTreeModule directoryTreeModule= (DirectoryTreeModule) m;
|
||||
|
||||
buf.append(directoryTreeModule.getPath());
|
||||
} else
|
||||
Assertions.UNREACHABLE("Module entry is neither jar file nor directory");
|
||||
}
|
||||
cl= cl.getParent();
|
||||
}
|
||||
fClassPath= buf.toString();
|
||||
}
|
||||
|
||||
public void loadAllSources(Set modules) {
|
||||
Options opts= fExtInfo.getOptions();
|
||||
opts.assertions = true;
|
||||
Options.global = opts;
|
||||
try {
|
||||
opts.parseCommandLine(new String[] { "-cp", fClassPath }, new HashSet());
|
||||
} catch (UsageError e) {
|
||||
// Assertions.UNREACHABLE("Error parsing classpath spec???");
|
||||
}
|
||||
|
||||
Compiler compiler= new PolyglotFrontEnd(fExtInfo);
|
||||
List/*<SourceStream>*/ streams= new ArrayList();
|
||||
|
||||
// N.B.: 'modules' is a flat set of source file ModuleEntry's.
|
||||
for(Iterator it= modules.iterator(); it.hasNext(); ) {
|
||||
SourceFileModule entry= (SourceFileModule) it.next();
|
||||
|
||||
Assertions._assert(entry.isSourceFile());
|
||||
|
||||
String filePath= entry.getAbsolutePath();
|
||||
|
||||
try {
|
||||
StreamSource srcStream= new StreamSource(entry.getInputStream(), filePath);
|
||||
|
||||
streams.add(srcStream);
|
||||
} catch (IOException e) {
|
||||
compiler.errorQueue().enqueue(new ErrorInfo(ErrorInfo.IO_ERROR, "Unable to open source file '" + entry.getName() + "'", Position.COMPILER_GENERATED));
|
||||
}
|
||||
}
|
||||
compiler.compile(streams);
|
||||
// At this point, DOMO now "knows" about all the source-originated stuff
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Sep 28, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
|
||||
import polyglot.types.ArrayType;
|
||||
import polyglot.types.ClassType;
|
||||
import polyglot.types.PrimitiveType;
|
||||
import polyglot.types.ReferenceType;
|
||||
import polyglot.types.Type;
|
||||
import polyglot.types.TypeSystem;
|
||||
|
||||
import com.ibm.wala.cast.java.types.*;
|
||||
import com.ibm.wala.cast.tree.CAstType;
|
||||
import com.ibm.wala.cast.tree.impl.CAstTypeDictionaryImpl;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
|
||||
public class PolyglotTypeDictionary extends CAstTypeDictionaryImpl {
|
||||
private final class PolyglotJavaArrayType implements CAstType.Array {
|
||||
private final Type fEltPolyglotType;
|
||||
|
||||
private final CAstType fEltCAstType;
|
||||
|
||||
private PolyglotJavaArrayType(ArrayType arrayType) {
|
||||
super();
|
||||
fEltPolyglotType= arrayType.base();
|
||||
fEltCAstType= getCAstTypeFor(fEltPolyglotType);
|
||||
}
|
||||
|
||||
public int getNumDimensions() {
|
||||
return 1; // always 1 for Java
|
||||
}
|
||||
|
||||
public CAstType getElementType() {
|
||||
return fEltCAstType;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "[" + fEltCAstType.getName();
|
||||
}
|
||||
|
||||
public Collection getSupertypes() {
|
||||
if (fEltPolyglotType.isPrimitive())
|
||||
return Collections.singleton(getCAstTypeFor(fTypeSystem.Object()));
|
||||
Assertions._assert(fEltPolyglotType.isReference(), "Non-primitive, non-reference array element type!");
|
||||
ReferenceType baseRefType= (ReferenceType) fEltPolyglotType;
|
||||
Collection supers= new ArrayList();
|
||||
for(Iterator superIter= baseRefType.interfaces().iterator(); superIter.hasNext(); ) {
|
||||
supers.add(getCAstTypeFor(superIter.next()));
|
||||
}
|
||||
if (baseRefType.superType() != null)
|
||||
supers.add(getCAstTypeFor(baseRefType.superType()));
|
||||
return supers;
|
||||
}
|
||||
}
|
||||
|
||||
protected final TypeSystem fTypeSystem;
|
||||
|
||||
private final PolyglotJava2CAstTranslator fTranslator;
|
||||
|
||||
public PolyglotTypeDictionary(TypeSystem typeSystem, PolyglotJava2CAstTranslator translator) {
|
||||
fTypeSystem= typeSystem;
|
||||
fTranslator= translator;
|
||||
}
|
||||
|
||||
public CAstType getCAstTypeFor(Object astType) {
|
||||
CAstType type= super.getCAstTypeFor(astType);
|
||||
// Handle the case where we haven't seen an AST decl for some type before
|
||||
// processing a reference. This can certainly happen with classes in byte-
|
||||
// code libraries, for which we never see an AST decl.
|
||||
// In this case, just create a new type and return that.
|
||||
if (type == null) {
|
||||
final Type polyglotType= (Type) astType;
|
||||
|
||||
if (polyglotType.isClass())
|
||||
type= fTranslator.new PolyglotJavaType((ClassType) astType, this, fTypeSystem);
|
||||
else if (polyglotType.isPrimitive()) {
|
||||
type= JavaPrimitiveTypeMap.lookupType(((PrimitiveType) polyglotType).name());
|
||||
} else if (polyglotType.isArray()) {
|
||||
type= new PolyglotJavaArrayType((ArrayType) polyglotType);
|
||||
} else
|
||||
Assertions.UNREACHABLE("getCAstTypeFor() passed type that is not primitive, array, or class?");
|
||||
super.map(astType, type);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Oct 6, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
|
||||
import polyglot.frontend.FileSource;
|
||||
|
||||
/**
|
||||
* A Polyglot Source whose input comes from an InputStream.<br>
|
||||
* Currently extends FileSource since that's all that the Polyglot Compiler class
|
||||
* will accept.
|
||||
* @author rfuhrer
|
||||
*/
|
||||
public class StreamSource extends FileSource {
|
||||
private InputStream fStream;
|
||||
private Reader fReader;
|
||||
|
||||
public StreamSource(InputStream s, String fullPath) throws IOException {
|
||||
super(new File(fullPath), true);
|
||||
fStream= s;
|
||||
}
|
||||
|
||||
public Reader open() throws IOException {
|
||||
// If only the 'reader' base-class field wasn't a FileReader, we
|
||||
// could assign that field and not have to save the reader in a
|
||||
// separate redundant field and override close()...
|
||||
if (fReader == null)
|
||||
fReader= new InputStreamReader(fStream);
|
||||
return fReader;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
if (fReader != null) {
|
||||
fReader.close();
|
||||
fReader= null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Sep 1, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import polyglot.ast.*;
|
||||
|
||||
import com.ibm.wala.cast.java.translator.polyglot.PolyglotJava2CAstTranslator.*;
|
||||
import com.ibm.wala.cast.tree.CAstNode;
|
||||
|
||||
/**
|
||||
* An alternative visitor API for Polyglot, whose API is somewhat brain-damaged...
|
||||
* @author rfuhrer
|
||||
*/
|
||||
public interface TranslatingVisitor {
|
||||
CAstNode visit(MethodDecl m, MethodContext context);
|
||||
CAstNode visit(ConstructorDecl cd, MethodContext cc);
|
||||
CAstNode visit(FieldDecl f, MethodContext mc); // yes, a MethodContext; we process FieldDecl's only to add their initializers to each constructor
|
||||
CAstNode visit(Import i, WalkContext wc);
|
||||
CAstNode visit(PackageNode p, WalkContext wc);
|
||||
CAstNode visit(CanonicalTypeNode ctn, WalkContext wc);
|
||||
CAstNode visit(ArrayTypeNode ctn, WalkContext wc);
|
||||
CAstNode visit(ArrayInit ai, WalkContext wc);
|
||||
CAstNode visit(ArrayAccessAssign aaa, WalkContext wc);
|
||||
CAstNode visit(FieldAssign fa, WalkContext wc);
|
||||
CAstNode visit(LocalAssign la, WalkContext wc);
|
||||
CAstNode visit(Binary b, WalkContext wc);
|
||||
CAstNode visit(Call c, WalkContext wc);
|
||||
CAstNode visit(ConstructorCall cc, WalkContext wc);
|
||||
CAstNode visit(Cast c, WalkContext wc);
|
||||
CAstNode visit(Conditional c, WalkContext wc);
|
||||
CAstNode visit(Instanceof io, WalkContext wc);
|
||||
CAstNode visit(BooleanLit bl, WalkContext wc);
|
||||
CAstNode visit(ClassLit cl, WalkContext wc);
|
||||
CAstNode visit(FloatLit fl, WalkContext wc);
|
||||
CAstNode visit(NullLit nl, WalkContext wc);
|
||||
CAstNode visit(CharLit cl, WalkContext wc);
|
||||
CAstNode visit(IntLit il, WalkContext wc);
|
||||
CAstNode visit(StringLit sl, WalkContext wc);
|
||||
CAstNode visit(New n, WalkContext wc);
|
||||
CAstNode visit(NewArray na, WalkContext wc);
|
||||
CAstNode visit(Special s, WalkContext wc);
|
||||
CAstNode visit(Unary u, WalkContext wc);
|
||||
CAstNode visit(ArrayAccess aa, WalkContext wc);
|
||||
CAstNode visit(Field f, WalkContext wc);
|
||||
CAstNode visit(Local l, WalkContext wc);
|
||||
CAstNode visit(ClassBody cb, WalkContext wc); // should never see this when producing CAstNodes
|
||||
CAstNode visit(ClassDecl cd, WalkContext wc); // should never see this when producing CAstNodes
|
||||
CAstNode visit(Initializer i, WalkContext wc); // should never see this when producing CAstNodes
|
||||
CAstNode visit(Assert a, WalkContext wc);
|
||||
CAstNode visit(Branch b, WalkContext wc);
|
||||
CAstNode visit(Block b, WalkContext wc);
|
||||
CAstNode visit(SwitchBlock sb, WalkContext wc);
|
||||
CAstNode visit(Catch c, WalkContext wc);
|
||||
CAstNode visit(If i, WalkContext wc);
|
||||
CAstNode visit(Labeled l, WalkContext wc);
|
||||
CAstNode visit(LocalClassDecl lcd, WalkContext wc);
|
||||
CAstNode visit(Do d, WalkContext wc);
|
||||
CAstNode visit(For f, WalkContext wc);
|
||||
CAstNode visit(While w, WalkContext wc);
|
||||
CAstNode visit(Switch s, WalkContext wc);
|
||||
CAstNode visit(Synchronized s, WalkContext wc);
|
||||
CAstNode visit(Try t, WalkContext wc);
|
||||
CAstNode visit(Empty e, WalkContext wc);
|
||||
CAstNode visit(Eval e, WalkContext wc);
|
||||
CAstNode visit(LocalDecl ld, WalkContext wc);
|
||||
CAstNode visit(Return r, WalkContext wc);
|
||||
CAstNode visit(Case c, WalkContext wc);
|
||||
CAstNode visit(Throw t, WalkContext wc);
|
||||
CAstNode visit(Formal f, WalkContext wc); // may not see these (might be handled by parent)
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Sep 28, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.types;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.ibm.wala.cast.tree.CAstType;
|
||||
|
||||
public class JavaPrimitiveTypeMap {
|
||||
public static final Map/*<String javaTypeName, JavaPrimitiveType javaTypeDesc>*/ primNameMap= new HashMap();
|
||||
|
||||
public static class JavaPrimitiveType implements CAstType.Primitive {
|
||||
String fLongName;
|
||||
String fShortName;
|
||||
|
||||
private JavaPrimitiveType(String longName, String shortName) {
|
||||
fLongName= longName;
|
||||
fShortName= shortName;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return fShortName;
|
||||
}
|
||||
|
||||
public String getLongName() {
|
||||
return fLongName;
|
||||
}
|
||||
|
||||
public Collection getSupertypes() {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getShortName(String longName) {
|
||||
return ((JavaPrimitiveType) primNameMap.get(longName)).getName();
|
||||
}
|
||||
|
||||
public static JavaPrimitiveType lookupType(String longName) {
|
||||
return (JavaPrimitiveType) primNameMap.get(longName);
|
||||
}
|
||||
|
||||
public static final JavaPrimitiveType VoidType= new JavaPrimitiveType("void", "V");
|
||||
|
||||
static {
|
||||
primNameMap.put("int", new JavaPrimitiveType("int", "I"));
|
||||
primNameMap.put("long", new JavaPrimitiveType("long", "J"));
|
||||
primNameMap.put("short", new JavaPrimitiveType("short", "S"));
|
||||
primNameMap.put("char", new JavaPrimitiveType("char", "C"));
|
||||
primNameMap.put("byte", new JavaPrimitiveType("byte", "B"));
|
||||
primNameMap.put("boolean", new JavaPrimitiveType("boolean", "Z"));
|
||||
primNameMap.put("float", new JavaPrimitiveType("float", "F"));
|
||||
primNameMap.put("double", new JavaPrimitiveType("double", "D"));
|
||||
primNameMap.put("void", VoidType);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Sep 21, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.types;
|
||||
|
||||
import com.ibm.wala.cast.tree.CAstType;
|
||||
|
||||
public interface JavaType extends CAstType.Class {
|
||||
boolean isInterface();
|
||||
}
|
Loading…
Reference in New Issue