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:
parent
41daeadbb8
commit
9e2c05f206
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() + ">";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,4 +28,6 @@ public interface IRTranslatorExtension {
|
|||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
CAstRewriterFactory getCAstRewriterFactory();
|
||||
|
||||
boolean getReplicateForDoLoops();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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('.', '$');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue