merge from polyglot3 branch

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@4155 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
dolby-oss 2011-04-27 16:20:21 +00:00
parent 41daeadbb8
commit 9e2c05f206
16 changed files with 346 additions and 492 deletions

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="source"/>
<classpathentry exported="true" kind="lib" path="lib/polyglot.jar"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -9,7 +9,6 @@ Require-Bundle: com.ibm.wala.cast.java,
com.ibm.wala.cast,
com.ibm.wala.core,
org.eclipse.core.runtime,
polyglot3,
com.ibm.wala.shrike,
org.eclipse.jdt.core,
org.eclipse.core.resources,
@ -34,3 +33,4 @@ Export-Package: com.ibm.wala.cast.java.client.polyglot,
com.ibm.wala.cast.tree.impl,
com.ibm.wala.cast.java.translator,
com.ibm.wala.cast.java.types"
Import-Package: polyglot.frontend

View File

@ -39,12 +39,14 @@
<target name="fetchPolyglot" depends="PolyglotPresent" unless="polyglot.present">
<delete dir="${temp.folder}"/>
<mkdir dir="${temp.folder}"/>
<get src="http://www.cs.cornell.edu/Projects/polyglot/src/polyglot-2.0.2-src.tar.gz" dest="${temp.folder}/polyglot-2.0.2-src.tar.gz" />
<gunzip src="${temp.folder}/polyglot-2.0.2-src.tar.gz" dest="${temp.folder}/polyglot-2.0.2-src.tar"/>
<untar src="${temp.folder}/polyglot-2.0.2-src.tar" dest="${temp.folder}"/>
<ant target="jar" inheritAll="false" dir="${temp.folder}/polyglot-2.0.2-src" />
<copy file="${temp.folder}/polyglot-2.0.2-src/lib/polyglot.jar" tofile="${plugin.destination}/lib/polyglot.jar" />
<copy file="${temp.folder}/polyglot-2.0.2-src/lib/java_cup.jar" tofile="${plugin.destination}/lib/java_cup.jar" />
<exec executable="svn"
dir="${temp.folder}">
<arg value="--quiet"/>
<arg value="checkout"/>
<arg value="http://polyglot-compiler.googlecode.com/svn/trunk/"/>
<arg value="polyglot-compiler-read-only"/>
</exec>
<copy file="${temp.folder}/polyglot-compiler-read-only/updates/plugins/polyglot3_3.2.0.jar" tofile="${plugin.destination}/lib/polyglot.jar" />
<delete dir="${temp.folder}"/>
</target>

View File

@ -40,6 +40,7 @@ import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ssa.ConstantValue;
import com.ibm.wala.ssa.SSAOptions;
import com.ibm.wala.ssa.SymbolTable;
import com.ibm.wala.ssa.Value;
import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.util.config.FileOfClasses;
import com.ibm.wala.util.debug.Assertions;

View File

@ -21,30 +21,22 @@ 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 class AscriptionGoal extends VisitorGoal {
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);
super(job,
new AscriptionVisitor(job, job.extensionInfo().typeSystem(), job.extensionInfo().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);
}
return super.ascribe(e, toType);
}
});
}
);
Scheduler scheduler= job.extensionInfo().scheduler();
addPrereq(scheduler.TypeChecked(job));
}
}

View File

@ -20,36 +20,46 @@ import com.ibm.wala.cast.java.translator.Java2IRTranslator;
/**
* A kind of EndGoal that indicates that WALA IR has been generated for the given compilation unit.
*
* @author rfuhrer
*/
public class IRGoal extends AbstractGoal implements EndGoal {
public class IRGoal extends SourceGoal_c /* PORT1.7 removed 'implements EndGoal' */ {
private JavaSourceLoaderImpl fSourceLoader;
protected Java2IRTranslator fTranslator;
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());
}
Scheduler scheduler= job.extensionInfo().scheduler();
addPrereq(scheduler.TypeChecked(job));
// PORT1.7 - TypeChecked will suffice for what used to require ConstantsChecked.
// Need ConstantsChecked in order to make sure that case statements have non-zero labels.
// addPrereq(scheduler.ConstantsChecked(job));
// Need to add an AscriptionGoal as a prereq to make sure that empty array initializers get a type ascribed.
addPrereq(new AscriptionGoal(job));
}
public Pass createPass(polyglot.frontend.ExtensionInfo extInfo) {
return new JavaIRPass(this, job(), new Java2IRTranslator(new PolyglotJava2CAstTranslator(fSourceLoader.getReference(), extInfo
.nodeFactory(), extInfo.typeSystem(), new PolyglotIdentityMapper(fSourceLoader.getReference(), this.job.extensionInfo()
.typeSystem())), fSourceLoader, ((IRTranslatorExtension) extInfo).getCAstRewriterFactory()));
@Override
public boolean runTask() {
ExtensionInfo extInfo= job.extensionInfo();
fTranslator= new Java2IRTranslator(
new PolyglotJava2CAstTranslator(
fSourceLoader.getReference(),
extInfo.nodeFactory(),
extInfo.typeSystem(),
new PolyglotIdentityMapper(fSourceLoader.getReference()),
((IRTranslatorExtension)extInfo).getReplicateForDoLoops()),
fSourceLoader,
((IRTranslatorExtension)extInfo).getCAstRewriterFactory());
ModuleSource src = (ModuleSource) job.source();
fTranslator.translate(src.getModule(),job.ast(), src.name());
return true;
}
public String name() {
return "<DOMO IR goal for " + job().source().path() + ">";
return "<WALA IR goal for " + job.source().path() + ">";
}
}

View File

@ -28,4 +28,6 @@ public interface IRTranslatorExtension {
*/
@SuppressWarnings("unchecked")
CAstRewriterFactory getCAstRewriterFactory();
boolean getReplicateForDoLoops();
}

View File

@ -1,42 +0,0 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
/*
* 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.Java2IRTranslator;
/**
* 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;
}
}

View File

@ -24,9 +24,8 @@ import polyglot.frontend.Scheduler;
import com.ibm.wala.cast.tree.impl.CAstRewriterFactory;
/**
* A Polyglot extension descriptor for a test harness extension that generates DOMO IR for the sources and class files in the
* classpath.
*
* A Polyglot extension descriptor for a test harness extension that generates WALA IR for
* the sources and class files in the classpath.
* @author rfuhrer
*/
public class JavaIRTranslatorExtension extends JLExtensionInfo implements IRTranslatorExtension {
@ -37,13 +36,26 @@ public class JavaIRTranslatorExtension extends JLExtensionInfo implements IRTran
@SuppressWarnings("unchecked")
protected CAstRewriterFactory rewriterFactory;
public void setSourceLoader(PolyglotSourceLoaderImpl sourceLoader) {
fSourceLoader = sourceLoader;
fMapper = new PolyglotIdentityMapper(sourceLoader.getReference(), typeSystem());
//PORT1.7 getCompileGoal() no longer exists; set the compile goal by manipulating the End goal for the job
@Override
protected Scheduler createScheduler() {
return new JLScheduler(this) {
@Override
public List<Goal> goals(Job job) {
List<Goal> goals= super.goals(job);
Goal endGoal = goals.get(goals.size()-1);
if (!(endGoal.name().equals("End"))) {
throw new IllegalStateException("Last goal is not an End goal?");
}
endGoal.addPrereq(new IRGoal(job, fSourceLoader));
return goals;
}
};
}
public Goal getCompileGoal(Job job) {
return new IRGoal(job, fSourceLoader);
public void setSourceLoader(PolyglotSourceLoaderImpl sourceLoader) {
fSourceLoader= sourceLoader;
fMapper= new PolyglotIdentityMapper(sourceLoader.getReference());
}
public PolyglotIdentityMapper getIdentityMapper() {
@ -59,4 +71,8 @@ public class JavaIRTranslatorExtension extends JLExtensionInfo implements IRTran
public CAstRewriterFactory getCAstRewriterFactory() {
return rewriterFactory;
}
public boolean getReplicateForDoLoops() {
return false;
}
}

View File

@ -1,101 +0,0 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
/*
* 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()));
}
@SuppressWarnings("unchecked")
public boolean compile(Collection/* <StreamSource> */sources) {
boolean okay = false;
try {
try {
Scheduler scheduler = sourceExtension().scheduler();
List<Job> jobs = new ArrayList<Job>();
// 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;
}
}

View File

@ -35,10 +35,10 @@ import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.strings.Atom;
/**
* Class responsible for mapping Polyglot type system objects representing types, methods and fields to the corresponding WALA
* TypeReferences, MethodReferences and FieldReferences. Used during translation and by clients to help correlate WALA analysis
* results to the various AST nodes.
*
* Class responsible for mapping Polyglot type system objects representing types,
* methods and fields to the corresponding WALA TypeReferences, MethodReferences
* and FieldReferences. Used during translation and by clients to help correlate
* WALA analysis results to the various AST nodes.
* @author rfuhrer
*/
public class PolyglotIdentityMapper implements IdentityMapper<Type, CodeInstance, FieldInstance> {
@ -50,24 +50,22 @@ public class PolyglotIdentityMapper implements IdentityMapper<Type, CodeInstance
/**
* Map from Polyglot local ClassTypes to their enclosing methods. Used by localTypeToTypeID().<br>
* Needed since Polyglot doesn't provide this information. (It doesn't need to, since it doesn't need to generate unambiguous
* names for such entities -- it hands the source off to javac to generate bytecode. It probably also wouldn't want to, since that
* would create back-pointers from Type objects in the TypeSystem to AST's.)
* Needed since Polyglot doesn't provide this information. (It doesn't need to, since it
* doesn't need to generate unambiguous names for such entities -- it hands the source
* off to javac to generate bytecode. It probably also wouldn't want to, since that would
* create back-pointers from Type objects in the TypeSystem to AST's.)
*/
protected Map<ClassType, CodeInstance> fLocalTypeMap = new LinkedHashMap<ClassType, CodeInstance>();
private final ClassLoaderReference fClassLoaderRef;
protected final ClassLoaderReference fClassLoaderRef;
private final TypeSystem fTypeSystem;
public PolyglotIdentityMapper(ClassLoaderReference clr, TypeSystem ts) {
fClassLoaderRef = clr;
fTypeSystem = ts;
public PolyglotIdentityMapper(ClassLoaderReference clr) {
fClassLoaderRef= clr;
}
public FieldReference getFieldRef(FieldInstance field) {
if (!fFieldMap.containsKey(field)) {
FieldReference ref = referenceForField(field);
FieldReference ref= referenceForField(field);
fFieldMap.put(field, ref);
return ref;
}
@ -76,7 +74,7 @@ public class PolyglotIdentityMapper implements IdentityMapper<Type, CodeInstance
public TypeReference getTypeRef(Type type) {
if (!fTypeMap.containsKey(type)) {
TypeReference ref = referenceForType(type);
TypeReference ref= referenceForType(type);
fTypeMap.put(type, ref);
return ref;
}
@ -85,7 +83,7 @@ public class PolyglotIdentityMapper implements IdentityMapper<Type, CodeInstance
public MethodReference getMethodRef(CodeInstance method) {
if (!fMethodMap.containsKey(method)) {
MethodReference sel = referenceForMethod(method);
MethodReference sel= referenceForMethod(method);
fMethodMap.put(method, sel);
return sel;
}
@ -98,124 +96,135 @@ public class PolyglotIdentityMapper implements IdentityMapper<Type, CodeInstance
/**
* Create a FieldReference for the given Polyglot FieldInstance.<br>
* N.B.: This method <b>does not canonicalize</b> the FieldReferences, but rather creates a new one for each call. You more likely
* want to call getFieldRef(). This method is exposed so that multiple Polyglot instances can use the translation services without
* having FieldInstances collide (producing the dreaded "we are TypeSystem_c but type Foo is from TypeSystem_c" exception).
* N.B.: This method <b>does not canonicalize</b> the FieldReferences,
* but rather creates a new one for each call.
* You more likely want to call getFieldRef(). This method is exposed
* so that multiple Polyglot instances can use the translation services
* without having FieldInstances collide (producing the dreaded "we are
* TypeSystem_c but type Foo is from TypeSystem_c" exception).
*/
public FieldReference referenceForField(FieldInstance field) {
Type targetType = field.container();
Type fieldType = field.type();
TypeReference targetTypeRef = TypeReference.findOrCreate(fClassLoaderRef, typeToTypeID(targetType));
TypeReference fieldTypeRef = TypeReference.findOrCreate(fClassLoaderRef, typeToTypeID(fieldType));
Atom fieldName = Atom.findOrCreateUnicodeAtom(field.name());
FieldReference fieldRef = FieldReference.findOrCreate(targetTypeRef, fieldName, fieldTypeRef);
Type targetType= field.container();
Type fieldType= field.type();
TypeReference targetTypeRef= TypeReference.findOrCreate(fClassLoaderRef, typeToTypeID(targetType));
TypeReference fieldTypeRef= TypeReference.findOrCreate(fClassLoaderRef, typeToTypeID(fieldType));
Atom fieldName= Atom.findOrCreateUnicodeAtom(field.name().toString());
FieldReference fieldRef= FieldReference.findOrCreate(targetTypeRef, fieldName, fieldTypeRef);
return fieldRef;
}
/**
* Create a TypeReference for the given Polyglot Type.<br>
* N.B.: This method <b>does not canonicalize</b> the TypeReferences, but rather creates a new one for each call. You more likely
* want to call getTypeRef(). This method is exposed so that multiple Polyglot instances can use the translation services without
* having Types collide (producing the dreaded "we are TypeSystem_c but type Foo is from TypeSystem_c" exception).
* N.B.: This method <b>does not canonicalize</b> the TypeReferences,
* but rather creates a new one for each call.
* You more likely want to call getTypeRef(). This method is exposed
* so that multiple Polyglot instances can use the translation services
* without having Types collide (producing the dreaded "we are
* TypeSystem_c but type Foo is from TypeSystem_c" exception).
*/
public TypeReference referenceForType(Type type) {
TypeName typeName = TypeName.string2TypeName(typeToTypeID(type));
TypeReference typeRef = TypeReference.findOrCreate(fClassLoaderRef, typeName);
TypeName typeName= TypeName.string2TypeName(typeToTypeID(type));
TypeReference typeRef= TypeReference.findOrCreate(fClassLoaderRef, typeName);
return typeRef;
}
@SuppressWarnings("unchecked")
private Selector selectorForMethod(CodeInstance procInstance) {
Atom name = (procInstance instanceof ConstructorInstance) ? MethodReference.initAtom
: (procInstance instanceof InitializerInstance) ? MethodReference.clinitName : Atom
.findOrCreateUnicodeAtom(((MethodInstance) procInstance).name());
Atom name=
(procInstance instanceof ConstructorInstance) ?
MethodReference.initAtom :
(procInstance instanceof InitializerInstance) ?
MethodReference.clinitName :
Atom.findOrCreateUnicodeAtom(((MethodInstance) procInstance).name().toString());
TypeName[] argTypeNames = null;
if (!(procInstance instanceof InitializerInstance)) {
List formalTypes = ((ProcedureInstance) procInstance).formalTypes();
if (! (procInstance instanceof InitializerInstance)) {
List formalTypes = ((ProcedureInstance)procInstance).formalTypes();
int numArgs = formalTypes.size();
// Descriptor prefers null to an empty array
if (numArgs > 0) {
argTypeNames = new TypeName[numArgs];
int i = 0;
for (Iterator iter = formalTypes.iterator(); iter.hasNext(); i++) {
Type argType = (Type) iter.next();
argTypeNames[i] = TypeName.string2TypeName(typeToTypeID(argType));
for(Iterator iter = formalTypes.iterator(); iter.hasNext(); i++) {
Type argType= (Type) iter.next();
argTypeNames[i]= TypeName.string2TypeName(typeToTypeID(argType));
}
}
}
Type retType = (procInstance instanceof MethodInstance) ? ((MethodInstance) procInstance).returnType() : fTypeSystem.Void();
TypeName retTypeName = TypeName.string2TypeName(typeToTypeID(retType));
Type retType=
(procInstance instanceof MethodInstance) ? ((MethodInstance) procInstance).returnType() : procInstance.typeSystem().Void();
TypeName retTypeName= TypeName.string2TypeName(typeToTypeID(retType));
Descriptor desc = Descriptor.findOrCreate(argTypeNames, retTypeName);
Descriptor desc= Descriptor.findOrCreate(argTypeNames, retTypeName);
return new Selector(name, desc);
return new Selector(name, desc);
}
/**
* Create a MethodReference for the given Polyglot MethodInstance.<br>
* N.B.: This method <b>does not canonicalize</b> the MethodReferences, but rather creates a new one for each call. You more
* likely want to call getMethodRef(). This method is exposed so that multiple Polyglot instances can use the translation services
* without having MethodInstances collide (producing the dreaded "we are TypeSystem_c but type Foo is from TypeSystem_c"
* exception).
* N.B.: This method <b>does not canonicalize</b> the MethodReferences,
* but rather creates a new one for each call.
* You more likely want to call getMethodRef(). This method is exposed
* so that multiple Polyglot instances can use the translation services
* without having MethodInstances collide (producing the dreaded "we are
* TypeSystem_c but type Foo is from TypeSystem_c" exception).
*/
public MethodReference referenceForMethod(CodeInstance procInstance) {
// Handles both ConstructorInstance's and MethodInstance's
TypeName ownerType = TypeName.string2TypeName(typeToTypeID(((MemberInstance) procInstance).container()));
TypeReference ownerTypeRef = TypeReference.findOrCreate(fClassLoaderRef, ownerType);
MethodReference methodRef = MethodReference.findOrCreate(ownerTypeRef, selectorForMethod(procInstance));
TypeName ownerType= TypeName.string2TypeName(typeToTypeID(((MemberDef) procInstance.def()).container().get()));
TypeReference ownerTypeRef= TypeReference.findOrCreate(fClassLoaderRef, ownerType);
MethodReference methodRef= MethodReference.findOrCreate(ownerTypeRef, selectorForMethod(procInstance));
return methodRef;
}
/**
* Translates the given Polyglot type to a name suitable for use in a DOMO TypeReference (i.e. a bytecode-compliant type name).
* Translates the given Polyglot type to a name suitable for use in a WALA TypeReference
* (i.e. a bytecode-compliant type name).
*/
public String typeToTypeID(Type type) {
if (type.isPrimitive()) {
PrimitiveType ptype = (PrimitiveType) type;
PrimitiveType ptype= (PrimitiveType) type;
return JavaPrimitiveTypeMap.getShortName(ptype.name());
return JavaPrimitiveTypeMap.getShortName(ptype.name().toString());
} else if (type.isArray()) {
ArrayType atype = (ArrayType) type;
ArrayType atype= (ArrayType) type;
return "[" + typeToTypeID(atype.base());
} else if (type.isNull()) {
Assertions.UNREACHABLE("typeToTypeID() encountered a null type!");
return null;
}
assert type.isClass() : "typeToTypeID() encountered the type " + type
+ " that is neither primitive, array, nor class!";
Assertions.productionAssertion(type.isClass(), "typeToTypeID() encountered the type " + type + " that is neither primitive, array, nor class!");
ClassType ctype = (ClassType) type;
ClassType ctype= (ClassType) type;
return (ctype.isLocal() || ctype.isAnonymous()) ? anonLocalTypeToTypeID(ctype) : composeDOMOTypeDescriptor(ctype);
return (ctype.isLocal() || ctype.isAnonymous()) ? anonLocalTypeToTypeID(ctype) : composeWALATypeDescriptor(ctype);
}
public String anonLocalTypeToTypeID(ClassType ctype) {
CodeInstance procInstance = (CodeInstance) fLocalTypeMap.get(ctype);
CodeInstance procInstance= (CodeInstance) fLocalTypeMap.get(ctype);
String outerTypeID = typeToTypeID(ctype.outer());
String shortName = (ctype.isAnonymous()) ? PolyglotJava2CAstTranslator.anonTypeName(ctype) : ctype.fullName();
String outerTypeID= typeToTypeID(ctype.outer());
String shortName= (ctype.isAnonymous()) ? PolyglotJava2CAstTranslator.anonTypeName(ctype) : ctype.fullName().name().toString();
return outerTypeID + '/' + getMethodRef(procInstance).getSelector() + '/' + shortName;
}
public String composeDOMOTypeDescriptor(ClassType ctype) {
return "L" + composeDOMOTypeName(ctype);
public String composeWALATypeDescriptor(ClassType ctype) {
return "L" + composeWALATypeName(ctype);
}
public String composeDOMOTypeName(ClassType ctype) {
public String composeWALATypeName(ClassType ctype) {
if (ctype.package_() != null) {
String packageName = ctype.package_().fullName();
String packageName = ctype.package_().fullName().toString();
assert ctype.fullName().startsWith(packageName);
return packageName.replace('.', '/') + "/" + ctype.fullName().substring(packageName.length() + 1).replace('.', '$');
Assertions.productionAssertion(ctype.fullName().toString().startsWith(packageName));
return packageName.replace('.','/') + "/" + ctype.fullName().toString().substring( packageName.length()+1 ).replace('.','$');
} else {
return ctype.fullName().replace('.', '$');
return ctype.fullName().toString().replace('.', '$');
}
}
}

View File

@ -34,7 +34,6 @@ import polyglot.ast.ArrayTypeNode;
import polyglot.ast.Assert;
import polyglot.ast.Assign;
import polyglot.ast.Binary;
import polyglot.ast.Binary.Operator;
import polyglot.ast.Block;
import polyglot.ast.BooleanLit;
import polyglot.ast.Branch;
@ -50,7 +49,6 @@ import polyglot.ast.ClassLit;
import polyglot.ast.ClassMember;
import polyglot.ast.Conditional;
import polyglot.ast.ConstructorCall;
import polyglot.ast.ConstructorCall.Kind;
import polyglot.ast.ConstructorDecl;
import polyglot.ast.Do;
import polyglot.ast.Empty;
@ -96,6 +94,8 @@ import polyglot.ast.TopLevelDecl;
import polyglot.ast.Try;
import polyglot.ast.Unary;
import polyglot.ast.While;
import polyglot.ast.Binary.Operator;
import polyglot.ast.ConstructorCall.Kind;
import polyglot.types.ArrayType;
import polyglot.types.ClassType;
import polyglot.types.CodeInstance;
@ -179,7 +179,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
protected PolyglotIdentityMapper fIdentityMapper;
protected boolean replicateForDoLoop = false;
protected boolean replicateForDoLoops = false;
protected final boolean DEBUG = true;
@ -308,7 +308,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
bodyNodes[idx++] = walkNodes(s, mc);
if (idx == 1) {
assert isSpecialCallStmt(s, ConstructorCall.SUPER);
Assertions.productionAssertion(isSpecialCallStmt(s, ConstructorCall.SUPER));
idx = insertInitializers(mc, bodyNodes, false, idx);
}
}
@ -406,11 +406,12 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
}
/*
* If we've handled all the parent cases, this should never be called -- visit(ArrayInit,WalkContext,Type) should be instead.
* If we've handled all the parent cases, this should never be called --
* visit(ArrayInit,WalkContext,Type) should be instead.
*/
public CAstNode visit(ArrayInit ai, WalkContext wc) {
if (((ArrayType) ai.type()).base().isNull()) {
assert false : "bad type " + ai.type() + " for " + ai + " at " + ai.position();
Assertions.productionAssertion(false, "bad type " + ai.type() + " for " + ai + " at " + ai.position());
}
TypeReference newTypeRef = fIdentityMapper.getTypeRef(ai.type());
@ -421,13 +422,13 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
.elements().size()));
for (Iterator iter = ai.elements().iterator(); iter.hasNext(); idx++) {
Expr element = (Expr) iter.next();
if (element instanceof ArrayInit) {
eltNodes[idx] = visit((ArrayInit) element, wc, ((ArrayType) ai.type()).base());
if ( element instanceof ArrayInit ) {
eltNodes[idx] = visit((ArrayInit)element, wc, ((ArrayType)ai.type()).base());
} else {
eltNodes[idx] = walkNodes(element, wc);
}
if (eltNodes[idx] == null) {
assert eltNodes[idx] != null : element.toString();
Assertions.productionAssertion(eltNodes[idx] != null, element.toString());
}
}
@ -435,8 +436,9 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
}
/*
* Workaround for the null array init bug: just in case ai.type().base() is null (e.g. "new Object[] {null}") we get the type
* from the parent (in this example, a NewArray of type Object[])
* Workaround for the null array init bug: just in case ai.type().base() is null (e.g.
* "new Object[] {null}") we get the type from the parent (in this example, a
* NewArray of type Object[])
*/
public CAstNode visit(ArrayInit ai, WalkContext wc, Type t) {
TypeReference newTypeRef = fIdentityMapper.getTypeRef(t);
@ -453,7 +455,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
eltNodes[idx] = walkNodes(element, wc);
}
if (eltNodes[idx] == null) {
assert eltNodes[idx] != null : element.toString();
Assertions.productionAssertion(eltNodes[idx] != null, element.toString());
}
}
@ -472,17 +474,23 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
return processAssign(la, wc);
}
private CAstNode processAssign(Assign la, WalkContext wc) {
WalkContext lvc = new AssignmentContext(wc);
if (la.operator() == Assign.ASSIGN) {
return makeNode(wc, fFactory, la, CAstNode.ASSIGN, walkNodes(la.left(), lvc), walkNodes(la.right(), wc));
protected CAstNode processAssign(Node assign, CAstNode lhsCAstNode, Assign.Operator operator, Expr rhs, WalkContext wc) {
if (operator == Assign.ASSIGN) {
return makeNode(wc, fFactory, assign, CAstNode.ASSIGN, lhsCAstNode, walkNodes(rhs, wc));
} else {
CAstNode op = makeNode(wc, fFactory, la, CAstNode.ASSIGN_PRE_OP, walkNodes(la.left(), lvc), walkNodes(la.right(), wc),
mapAssignOperator(la.operator()));
CAstNode op =
makeNode(wc,
fFactory,
assign,
CAstNode.ASSIGN_PRE_OP,
lhsCAstNode,
walkNodes(rhs, wc),
mapAssignOperator(operator));
if (la.type().isLongOrLess()
&& (mapAssignOperator(la.operator()) == CAstOperator.OP_DIV || mapAssignOperator(la.operator()) == CAstOperator.OP_MOD)) {
if (rhs.type().isLongOrLess() &&
(mapAssignOperator(operator)==CAstOperator.OP_DIV ||
mapAssignOperator(operator)==CAstOperator.OP_MOD))
{
Collection excTargets = wc.getCatchTargets(fDivByZeroType);
if (!excTargets.isEmpty()) {
for (Iterator iterator = excTargets.iterator(); iterator.hasNext();) {
@ -490,7 +498,9 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
wc.cfg().add(op, catchPair.snd, fDivByZeroType);
}
} else {
wc.cfg().add(op, CAstControlFlowMap.EXCEPTION_TO_EXIT, fDivByZeroType);
wc.cfg().add(op,
CAstControlFlowMap.EXCEPTION_TO_EXIT,
fDivByZeroType);
}
}
@ -542,52 +552,57 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
else if (operator.equals(Binary.COND_OR))
return makeNode(wc, fFactory, b, CAstNode.IF_EXPR, walkNodes(left, wc), fFactory.makeConstant(true), walkNodes(right, wc));
else {
Type leftType = left.type();
Type rightType = right.type();
if (leftType.isPrimitive() && rightType.isPrimitive()) {
CAstNode leftNode = walkNodes(left, wc);
CAstNode rightNode = walkNodes(right, wc);
Type leftType = left.type();
Type rightType = right.type();
if (leftType.isPrimitive() && rightType.isPrimitive()) {
CAstNode leftNode = walkNodes(left, wc);
CAstNode rightNode = walkNodes(right, wc);
try {
Type result = fTypeSystem.promote(leftType, rightType);
try {
Type result = fTypeSystem.promote(leftType, rightType);
if (! result.typeEquals(leftType, fTypeSystem.emptyContext())) {
leftNode = makeNode(wc, fFactory, b, CAstNode.CAST, fFactory.makeConstant(getTypeDict().getCAstTypeFor(result)), leftNode, fFactory.makeConstant(getTypeDict().getCAstTypeFor(leftType)));
}
if (!result.equals(leftType)) {
leftNode = makeNode(wc, fFactory, b, CAstNode.CAST, fFactory.makeConstant(getTypeDict().getCAstTypeFor(result)),
leftNode, fFactory.makeConstant(getTypeDict().getCAstTypeFor(leftType)));
}
if (! result.typeEquals(rightType, fTypeSystem.emptyContext())) {
rightNode = makeNode(wc, fFactory, b, CAstNode.CAST, fFactory.makeConstant(getTypeDict().getCAstTypeFor(result)), rightNode, fFactory.makeConstant(getTypeDict().getCAstTypeFor(rightType)));
}
} catch (SemanticException e) {
if (!result.equals(rightType)) {
rightNode = makeNode(wc, fFactory, b, CAstNode.CAST, fFactory.makeConstant(getTypeDict().getCAstTypeFor(result)),
rightNode, fFactory.makeConstant(getTypeDict().getCAstTypeFor(rightType)));
}
} catch (SemanticException e) {
}
}
CAstNode op = makeNode(wc, fFactory, b, CAstNode.BINARY_EXPR, mapBinaryOpcode(operator), leftNode, rightNode);
CAstNode op = makeNode(wc, fFactory, b, CAstNode.BINARY_EXPR, mapBinaryOpcode(operator), leftNode, rightNode);
if (leftType.isLongOrLess() &&
rightType.isLongOrLess() &&
(mapBinaryOpcode(operator)==CAstOperator.OP_DIV ||
mapBinaryOpcode(operator)==CAstOperator.OP_MOD))
{
Collection excTargets = wc.getCatchTargets(fDivByZeroType);
if (!excTargets.isEmpty()) {
for (Iterator iterator = excTargets.iterator();
iterator.hasNext();)
{
Pair catchPair = (Pair) iterator.next();
wc.cfg().add(op, catchPair.snd, fDivByZeroType);
}
} else {
wc.cfg().add(op,
CAstControlFlowMap.EXCEPTION_TO_EXIT,
fDivByZeroType);
}
}
if (leftType.isLongOrLess() && rightType.isLongOrLess()
&& (mapBinaryOpcode(operator) == CAstOperator.OP_DIV || mapBinaryOpcode(operator) == CAstOperator.OP_MOD)) {
Collection excTargets = wc.getCatchTargets(fDivByZeroType);
if (!excTargets.isEmpty()) {
for (Iterator iterator = excTargets.iterator(); iterator.hasNext();) {
Pair catchPair = (Pair) iterator.next();
wc.cfg().add(op, catchPair.snd, fDivByZeroType);
}
} else {
wc.cfg().add(op, CAstControlFlowMap.EXCEPTION_TO_EXIT, fDivByZeroType);
}
}
return op;
} else {
return makeNode(wc, fFactory, b, CAstNode.BINARY_EXPR, mapBinaryOpcode(operator), walkNodes(left, wc), walkNodes(right,
wc));
}
return op;
} else {
return makeNode(wc, fFactory, b, CAstNode.BINARY_EXPR, mapBinaryOpcode(operator), walkNodes(left, wc), walkNodes(right, wc));
}
}
}
@SuppressWarnings("unchecked")
private void handleThrowsFromCall(ProcedureInstance procedureInstance, Node callAstNode, WalkContext wc) {
List<Type> throwTypes = procedureInstance.throwTypes();
for (Iterator<Type> iter = IteratorPlusOne.make(throwTypes.iterator(), fREType); iter.hasNext();) {
@ -608,14 +623,14 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
StructType methodOwner = methodInstance.container();
if (methodOwner.isArray()) {
List realOne = methodInstance.overrides();
assert realOne.size() == 2 : "bad array method";
List realOne = methodInstance.overrides(fTypeSystem.emptyContext());
Assertions.productionAssertion(realOne.size() == 2, "bad array method");
methodInstance = (MethodInstance) realOne.get(1);
methodOwner = methodInstance.container();
}
if (!methodOwner.isClass()) {
assert false : "owner " + methodOwner + " of " + methodInstance + " is not a class";
Assertions.productionAssertion(false, "owner " + methodOwner + " of " + methodInstance + " is not a class");
}
boolean isIntf = ((ClassType) methodOwner).flags().isInterface();
@ -634,7 +649,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
children[i++] = makeNode(wc, fFactory, null, CAstNode.VOID);
if (children[0] == null) {
assert children[0] != null : "no receiver for " + methodInstance + " in " + wc.getEnclosingMethod();
Assertions.productionAssertion(children[0] != null, "no receiver for " + methodInstance + " in " + wc.getEnclosingMethod());
}
MethodReference methodRef = fIdentityMapper.getMethodRef(methodInstance);
@ -666,8 +681,8 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
public CAstNode visit(ConstructorCall cc, WalkContext wc) {
ConstructorInstance ctorInstance = cc.constructorInstance();
ReferenceType methodOwner = ctorInstance.container();
assert methodOwner.isClass();
StructType methodOwner = ctorInstance.container();
Assertions.productionAssertion(methodOwner.isClass());
MethodReference methodRef = fIdentityMapper.getMethodRef(ctorInstance);
int dummyPC = 0; // Just want to wrap the kind of call; the "rear end"
@ -703,12 +718,13 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
Type castedFrom = arg.type();
Type castedTo = c.castType().type();
// null can go into anything (e.g. in "((Foobar) null)" null can be assumed to be of type Foobar already)
// null can go into anything (e.g. in "((Foobar) null)" null can be assumed to be of type Foobar already)
if (castedFrom.isNull())
castedFrom = castedTo;
CAstNode ast = makeNode(wc, fFactory, c, CAstNode.CAST, fFactory.makeConstant(getTypeDict().getCAstTypeFor(castedTo)),
walkNodes(arg, wc), fFactory.makeConstant(getTypeDict().getCAstTypeFor(castedFrom)));
walkNodes(arg, wc),
fFactory.makeConstant(getTypeDict().getCAstTypeFor(castedFrom)));
Collection excTargets = wc.getCatchTargets(fCCEType);
if (!excTargets.isEmpty()) {
@ -792,14 +808,14 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
String tmpName = "ctor temp"; // this name is an illegal Java
// identifier
// new nodes with an explicit enclosing argument, e.g. "outer.new Inner()". They are mostly treated the same, except in
// JavaCAst2IRTranslator.doNewObject
// new nodes with an explicit enclosing argument, e.g. "outer.new Inner()". They are mostly treated the same, except in JavaCAst2IRTranslator.doNewObject
CAstNode newNode;
Expr enclosing = n.qualifier();
if (enclosing != null) {
CAstNode encNode = walkNodes(enclosing, wc);
newNode = makeNode(wc, fFactory, n, CAstNode.NEW_ENCLOSING, fFactory.makeConstant(newTypeRef), encNode);
} else
}
else
newNode = makeNode(wc, fFactory, n, CAstNode.NEW, fFactory.makeConstant(newTypeRef));
// end enclosing new stuff
@ -833,7 +849,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
public CAstNode visit(NewArray na, WalkContext wc) {
Type newType = na.type();
ArrayInit ai = na.init();
assert newType.isArray();
Assertions.productionAssertion(newType.isArray());
if (ai != null) {
return visit(ai, wc, newType);
@ -919,13 +935,6 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
// connect exception edge to exit
wc.cfg().add(n, CAstControlFlowMap.EXCEPTION_TO_EXIT, fNPEType);
}
CAstNode n = makeNode(wc, fFactory, aa, CAstNode.ARRAY_REF, walkNodes(aa.array(), wc), fFactory.makeConstant(eltTypeRef),
walkNodes(aa.index(), wc));
wc.cfg().map(aa, n);
return n;
}
public CAstNode visit(Field f, WalkContext wc) {
@ -933,7 +942,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
Type targetType = target.type();
if (targetType.isArray()) {
assert f.name().equals("length");
Assertions.productionAssertion(f.name().toString().equals("length"));
return makeNode(wc, fFactory, f, CAstNode.ARRAY_LENGTH, walkNodes(target, wc));
}
@ -949,10 +958,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
// "back-end"
// CAst -> IR translator interprets as a static ref).
if (fi.isConstant()) {
return makeNode(wc, fFactory, f, CAstNode.BLOCK_EXPR, targetNode, // can
// have
// side
// effects!
return makeNode(wc, fFactory, f, CAstNode.BLOCK_EXPR, targetNode, // can have side effects!
translateConstant(fi.constantValue()));
} else {
return makeNode(wc, fFactory, f, CAstNode.BLOCK_EXPR, targetNode, makeNode(wc, fFactory, f, CAstNode.OBJECT_REF,
@ -976,10 +982,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
wc.cfg().map(f, refNode);
if (fi.isConstant()) {
return makeNode(wc, fFactory, f, CAstNode.BLOCK_EXPR, refNode, // can
// have
// side
// effects!
return makeNode(wc, fFactory, f, CAstNode.BLOCK_EXPR, refNode, // can have side effects!
translateConstant(fi.constantValue()));
} else {
return refNode;
@ -1021,7 +1024,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
target = wc.getContinueFor(labelStr);
}
assert target != null;
Assertions.productionAssertion(target != null);
CAstNode result = makeNode(wc, fFactory, b, CAstNode.GOTO);
@ -1081,13 +1084,16 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
wc.getLabelMap().put(stmt, l.labelNode().id().toString());
CAstNode result;
if (!(l.statement() instanceof Empty)) {
WalkContext child = new BreakContext(wc, l.label(), breakTarget);
if (! (l.statement() instanceof Empty)) {
WalkContext child = new BreakContext(wc, l.labelNode().id().toString(), breakTarget);
result = makeNode(wc, fFactory, l, CAstNode.BLOCK_STMT, makeNode(wc, fFactory, l, CAstNode.LABEL_STMT, fFactory
.makeConstant(l.label()), walkNodes(l.statement(), child)), walkNodes(breakTarget, wc));
result =
makeNode(wc, fFactory, l, CAstNode.BLOCK_STMT,
makeNode(wc, fFactory, l, CAstNode.LABEL_STMT, fFactory.makeConstant(l.labelNode().id().toString()), walkNodes(l.statement(), child)),
walkNodes(breakTarget, wc));
} else {
result = makeNode(wc, fFactory, l, CAstNode.LABEL_STMT, fFactory.makeConstant(l.label()), walkNodes(l.statement(), wc));
result =
makeNode(wc, fFactory, l, CAstNode.LABEL_STMT, fFactory.makeConstant(l.labelNode().id().toString()), walkNodes(l.statement(), wc));
}
wc.cfg().map(l, result);
@ -1132,7 +1138,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
WalkContext lc = new LoopContext(wc, loopLabel, breakTarget, continueTarget);
CAstNode loopBody = walkNodes(d.body(), lc);
if (replicateForDoLoop) {
if (replicateForDoLoops) {
CAstRewriter.Rewrite x = (new CAstCloner(fFactory, false)).copy(loopBody, wc.cfg(), wc.pos(), wc.getNodeTypeMap(), null);
CAstNode otherBody = x.newRoot();
@ -1205,8 +1211,9 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
}
public CAstNode visit(Switch s, WalkContext wc) {
Node breakLabel = fNodeFactory.Labeled(s.position(), "switchBreakLabel" + s.position().toString().replace('.', '_'),
fNodeFactory.Empty(s.position()));
Node breakLabel = fNodeFactory.Labeled(s.position(),
fNodeFactory.Id(s.position(), "switchBreakLabel" + s.position().toString().replace('.', '_')),
fNodeFactory.Empty(s.position()));
CAstNode breakAst = walkNodes(breakLabel, wc);
String loopLabel = (String) wc.getLabelMap().get(s);
WalkContext child = new BreakContext(wc, loopLabel, breakLabel);
@ -1313,9 +1320,9 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
else
initNode = fFactory.makeConstant(null);
} else if (init instanceof ArrayInit)
initNode = visit((ArrayInit) init, wc, type);
initNode = visit((ArrayInit) init, wc, type);
else
initNode = walkNodes(init, wc);
initNode = walkNodes(init, wc);
Object defaultValue;
if (type.isLongOrLess())
@ -1629,7 +1636,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
public CAstType getNodeType(CAstNode node) {
throw new UnsupportedOperationException();
}
public Collection<CAstNode> getMappedNodes() {
throw new UnsupportedOperationException();
}
@ -1706,8 +1713,8 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
if (fPd instanceof InitializerInstance) {
return MethodReference.clinitName.toString();
} else {
assert fPd instanceof MethodInstance;
return ((MethodInstance) fPd).name();
Assertions.productionAssertion(fPd instanceof MethodInstance);
return ((MethodInstance) fPd).name().toString();
}
}
}
@ -2034,7 +2041,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
}
public void addScopedEntity(CAstNode node, CAstEntity e) {
assert node == null;
Assertions.productionAssertion(node == null);
fChildren.add(e);
}
@ -2159,8 +2166,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
}
public Collection<Pair<Type, Object>> getCatchTargets(Type label) {
Collection<Pair<Type, Object>> result = Collections.singleton(Pair.<Type, Object> make(fREType,
CAstControlFlowMap.EXCEPTION_TO_EXIT));
Collection<Pair<Type, Object>> result = Collections.singleton(Pair.<Type,Object>make(fREType, CAstControlFlowMap.EXCEPTION_TO_EXIT));
return result;
}
@ -2175,7 +2181,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
private final Context context;
Collection<Pair<Type, Object>> fCatchNodes = new ArrayList<Pair<Type, Object>>();
Collection<Pair<Type,Object>> fCatchNodes = new ArrayList<Pair<Type, Object>>();
TryCatchContext(WalkContext parent, Try tryNode, final Context context) {
super(parent);
@ -2184,7 +2190,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
for (Iterator catchIter = tryNode.catchBlocks().iterator(); catchIter.hasNext();) {
Catch c = (Catch) catchIter.next();
Pair<Type, Object> p = Pair.make(c.catchType(), (Object) c);
Pair<Type,Object> p = Pair.make(c.catchType(), (Object)c);
fCatchNodes.add(p);
}
@ -2388,7 +2394,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
public int getLastCol() {
return p.endColumn();
}
public int getFirstOffset() {
return p.offset();
}
@ -2530,9 +2536,8 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
/**
* Maps front-end-specific representations into WALA references of the appropriate kind.
*
* @author rfuhrer
*
*
* @param <T> The front-end-specific representation of a type (e.g., for Polyglot, a Type)
* @param <M> The front-end-specific representation of a procedure/method (e.g., for Polyglot, a CodeInstance)
* @param <F> The front-end-specific representation of a field (e.g., for Polyglot, a FieldInstance)
@ -2675,6 +2680,7 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst {
return ct.fullName() + "$" + pos.line() + "$" + pos.column();
}
@SuppressWarnings("unchecked")
protected CAstEntity walkEntity(Node rootNode, final WalkContext context) {
if (rootNode instanceof SourceFile) {
SourceFile file = (SourceFile) rootNode;

View File

@ -24,7 +24,7 @@ import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.types.ClassLoaderReference;
public class PolyglotSourceLoaderImpl extends JavaSourceLoaderImpl {
private final IRTranslatorExtension fExtInfo;
protected final IRTranslatorExtension fExtInfo;
public PolyglotSourceLoaderImpl(ClassLoaderReference loaderRef, IClassLoader parent, SetOfClasses exclusions,
IClassHierarchy cha, IRTranslatorExtension extInfo) throws IOException {
@ -37,6 +37,6 @@ public class PolyglotSourceLoaderImpl extends JavaSourceLoaderImpl {
}
protected SourceModuleTranslator getTranslator() {
return new PolyglotSourceModuleTranslator(cha.getScope(), fExtInfo, this);
return new PolyglotSourceModuleTranslator(cha.getScope(), fExtInfo, this, JavaSourceAnalysisScope.SOURCE);
}
}

View File

@ -39,112 +39,115 @@ import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.util.debug.Assertions;
/**
* A SourceModuleTranslator whose implementation of loadAllSources() uses the PolyglotFrontEnd pseudo-compiler to generate DOMO IR
* for the sources in the compile-time classpath.
*
* A SourceModuleTranslator whose implementation of loadAllSources() uses a suitably
* configured Polyglot-based compiler to generate WALA IR for the sources in the
* compile-time classpath.
* @author rfuhrer
*/
public class PolyglotSourceModuleTranslator implements SourceModuleTranslator {
private final ExtensionInfo fExtInfo;
private String fClassPath;
/**
* A client-supplied ClassLoaderReference to identify the innermost class loader
* to use when populating the classpath with loader Modules.
*/
private final ClassLoaderReference fSearchPathStart;
public PolyglotSourceModuleTranslator(AnalysisScope scope, IRTranslatorExtension extInfo, PolyglotSourceLoaderImpl sourceLoader) {
fExtInfo = (ExtensionInfo) extInfo;
computeClassPath(scope);
extInfo.setSourceLoader(sourceLoader);
protected String fClassPath;
protected String fSourcePath;
public PolyglotSourceModuleTranslator(AnalysisScope scope, IRTranslatorExtension extInfo,
PolyglotSourceLoaderImpl sourceLoader, ClassLoaderReference searchPathStart) {
fSearchPathStart = searchPathStart;
fExtInfo= (ExtensionInfo) extInfo;
computeClassPath(scope);
computeSourcePath(scope);
extInfo.setSourceLoader(sourceLoader);
}
private void computeClassPath(AnalysisScope scope) {
StringBuffer buf = new StringBuffer();
ClassLoaderReference cl = findInnermostClassLoader(scope);
protected void computeClassPath(AnalysisScope scope) {
StringBuilder sb= new StringBuilder();
ClassLoaderReference cl= fSearchPathStart;
while (cl != null) {
List<Module> modules = scope.getModules(cl);
for (Iterator<Module> 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 if (m instanceof FileModule) {
// do nothing
} else
Assertions.UNREACHABLE("Module entry is neither jar file nor directory: " + m);
}
cl = cl.getParent();
addModulesForLoader(scope, cl, sb);
cl= cl.getParent();
}
fClassPath = buf.toString();
fClassPath= sb.toString();
}
private ClassLoaderReference findInnermostClassLoader(AnalysisScope scope) {
Set<ClassLoaderReference> parentLoaders = new HashSet<ClassLoaderReference>();
protected void addModulesForLoader(AnalysisScope scope, ClassLoaderReference cl, StringBuilder sb) {
for(Module m: scope.getModules(cl)) {
if (sb.length() > 0)
sb.append(File.pathSeparator);
for (ClassLoaderReference loader : scope.getLoaders()) {
ClassLoaderReference parent = loader.getParent();
if (parent != null) {
parentLoaders.add(parent);
}
if (m instanceof JarFileModule) {
JarFileModule jarFileModule= (JarFileModule) m;
sb.append(jarFileModule.getAbsolutePath());
} else if (m instanceof DirectoryTreeModule) {
DirectoryTreeModule directoryTreeModule= (DirectoryTreeModule) m;
sb.append(directoryTreeModule.getPath());
} else if (m instanceof FileModule) {
// do nothing
} else
Assertions.UNREACHABLE("Module entry is neither jar file nor directory");
}
for (ClassLoaderReference child : scope.getLoaders()) {
if (!parentLoaders.contains(child)) {
return child;
}
}
throw new IllegalStateException("No innermost class loader???");
}
@SuppressWarnings("unchecked")
public void loadAllSources(Set modules) {
Options opts = fExtInfo.getOptions();
protected void computeSourcePath(AnalysisScope scope) {
// Ordinarily, the source files to process are specified using absolute paths (see
// loadAllSources()), so the source path won't be needed. However, derived classes
// may choose to place entries on the source path to resolve source entities that
// were not explicitly specified. E.g., the X10 1.7 runtime jar contains source
// code, since class files don't contain all of the necessary type information.
// Given all of the above, the following value will either be correct or do no
// harm (even if the source path isn't used).
fSourcePath = ".";
}
public void loadAllSources(Set<ModuleEntry> modules) {
Options opts= fExtInfo.getOptions();
opts.assertions = true;
Options.global = opts;
try {
opts.parseCommandLine(new String[] { "-cp", fClassPath }, new HashSet());
opts.parseCommandLine(new String[] { "-noserial", "-cp", fClassPath, "-sourcepath", fSourcePath }, new HashSet<String>());
} catch (UsageError e) {
// Assertions.UNREACHABLE("Error parsing classpath spec???");
}
Compiler compiler = new PolyglotFrontEnd(fExtInfo);
List<StreamSource> streams = new ArrayList<StreamSource>();
Compiler compiler= new Compiler(fExtInfo);
List<Source> streams= new ArrayList<Source>();
Globals.initialize(compiler);//PORT1.7 Must initialize before actually calling compiler
// N.B.: 'modules' is a flat set of source file ModuleEntry's.
for (Iterator it = modules.iterator(); it.hasNext();) {
SourceFileModule entry = (SourceFileModule) it.next();
for(Iterator<ModuleEntry> it= modules.iterator(); it.hasNext(); ) {
SourceFileModule entry= (SourceFileModule) it.next();
assert entry.isSourceFile();
Assertions.productionAssertion(entry.isSourceFile());
if (skipSourceFile(entry)) {
continue;
}
String filePath = entry.getAbsolutePath();
try {
StreamSource srcStream = new StreamSource(entry.getInputStream(), filePath);
ModuleSource srcStream= new ModuleSource(entry);
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.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
// At this point, WALA now "knows" about all the source-originated stuff
}
/**
* @return true if the given source file module should not be processed, e.g. because it is generated on behalf of some upstream
* source.
* @return true if the given source file module should not be processed,
* e.g. because it is generated on behalf of some upstream source.
*/
protected boolean skipSourceFile(SourceFileModule entry) {
return false;

View File

@ -59,8 +59,8 @@ public class PolyglotTypeDictionary extends CAstTypeDictionaryImpl {
public Collection getSupertypes() {
if (fEltPolyglotType.isPrimitive())
return Collections.singleton(getCAstTypeFor(fTypeSystem.Object()));
assert fEltPolyglotType.isReference() : "Non-primitive, non-reference array element type!";
ReferenceType baseRefType = (ReferenceType) fEltPolyglotType;
Assertions.productionAssertion(fEltPolyglotType.isReference(), "Non-primitive, non-reference array element type!");
ObjectType baseRefType = (ObjectType) fEltPolyglotType;
Collection<CAstType> supers = new ArrayList<CAstType>();
for (Iterator superIter = baseRefType.interfaces().iterator(); superIter.hasNext(); ) {
supers.add(getCAstTypeFor(superIter.next()));

View File

@ -1,45 +0,0 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
/*
* 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.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;
public StreamSource(InputStream s, String fullPath) throws IOException {
super(new File(fullPath), true);
fStream = s;
}
public Reader open() throws IOException {
if (reader == null) {
reader = createReader(fStream);
}
return reader;
}
}