refactor polyglot-based java code in its own projects
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@3163 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
fff6607a1d
commit
6d7fe4cc2c
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="source"/>
|
||||
<classpathentry kind="lib" path="lib/java_cup.jar"/>
|
||||
<classpathentry kind="lib" path="lib/polyglot.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.ibm.wala.cast.java.polyglot</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,82 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: WALA CAst Java Polyglot Plug-in
|
||||
Bundle-SymbolicName: com.ibm.wala.cast.java.polyglot
|
||||
Bundle-Version: 1.0.0
|
||||
Bundle-Activator: com.ibm.wala.cast.java.polyglot.Activator
|
||||
Bundle-Vendor: IBM
|
||||
Require-Bundle: com.ibm.wala.cast.java;bundle-version="1.0.0",
|
||||
com.ibm.wala.cast;bundle-version="1.0.0",
|
||||
com.ibm.wala.core;bundle-version="1.1.3",
|
||||
org.eclipse.core.runtime
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.ibm.wala.cast.java.polyglot;uses:="org.osgi.framework,org.eclipse.core.runtime",
|
||||
com.ibm.wala.cast.java.translator.polyglot;
|
||||
uses:="com.ibm.wala.types,
|
||||
polyglot.types,
|
||||
polyglot.util,
|
||||
polyglot.ast,
|
||||
com.ibm.wala.ipa.cha,
|
||||
com.ibm.wala.cast.java.client,
|
||||
com.ibm.wala.classLoader,
|
||||
com.ibm.wala.cast.tree,
|
||||
com.ibm.wala.cast.java.loader,
|
||||
com.ibm.wala.ipa.callgraph.impl,
|
||||
com.ibm.wala.ipa.callgraph,
|
||||
polyglot.frontend.goals,
|
||||
com.ibm.wala.cast.tree.impl,
|
||||
com.ibm.wala.cast.java.translator,
|
||||
polyglot.frontend,
|
||||
com.ibm.wala.cast.java.types",
|
||||
java_cup;uses:="java_cup.runtime",
|
||||
java_cup.runtime,
|
||||
polyglot.ast;
|
||||
uses:="polyglot.visit,
|
||||
polyglot.types,
|
||||
polyglot.util,
|
||||
polyglot.frontend",
|
||||
polyglot.ext.param;uses:="polyglot.frontend",
|
||||
polyglot.ext.param.types;uses:="polyglot.util,polyglot.types,polyglot.frontend",
|
||||
polyglot.frontend,
|
||||
polyglot.frontend.goals;
|
||||
uses:="polyglot.visit,
|
||||
polyglot.types,
|
||||
polyglot.ast,
|
||||
polyglot.frontend",
|
||||
polyglot.frontend.passes;
|
||||
uses:="polyglot.visit,
|
||||
polyglot.types,
|
||||
polyglot.frontend.goals,
|
||||
polyglot.frontend",
|
||||
polyglot.lex;uses:="polyglot.util,java_cup.runtime",
|
||||
polyglot.main;uses:="polyglot.util,polyglot.frontend",
|
||||
polyglot.parse;
|
||||
uses:="polyglot.util,
|
||||
polyglot.types,
|
||||
polyglot.ast,
|
||||
java_cup.runtime,
|
||||
polyglot.lex,
|
||||
polyglot.frontend",
|
||||
polyglot.qq;
|
||||
uses:="polyglot.util,
|
||||
polyglot.types,
|
||||
polyglot.ast,
|
||||
polyglot.parse,
|
||||
java_cup.runtime,
|
||||
polyglot.lex,
|
||||
polyglot.frontend",
|
||||
polyglot.types;
|
||||
uses:="polyglot.util,
|
||||
polyglot.main,
|
||||
polyglot.types.reflect,
|
||||
polyglot.frontend",
|
||||
polyglot.types.reflect;uses:="polyglot.util,polyglot.types,polyglot.frontend",
|
||||
polyglot.util;uses:="polyglot.types",
|
||||
polyglot.util.typedump;uses:="polyglot.util,polyglot.types",
|
||||
polyglot.visit;
|
||||
uses:="polyglot.util,
|
||||
polyglot.types,
|
||||
polyglot.main,
|
||||
polyglot.ast,
|
||||
polyglot.frontend"
|
|
@ -0,0 +1,4 @@
|
|||
source.. = source/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.
|
|
@ -0,0 +1,50 @@
|
|||
package com.ibm.wala.cast.java.polyglot;
|
||||
|
||||
import org.eclipse.core.runtime.Plugin;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
* The activator class controls the plug-in life cycle
|
||||
*/
|
||||
public class Activator extends Plugin {
|
||||
|
||||
// The plug-in ID
|
||||
public static final String PLUGIN_ID = "com.ibm.wala.cast.java.polyglot";
|
||||
|
||||
// The shared instance
|
||||
private static Activator plugin;
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*/
|
||||
public Activator() {
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void start(BundleContext context) throws Exception {
|
||||
super.start(context);
|
||||
plugin = this;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
plugin = null;
|
||||
super.stop(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shared instance
|
||||
*
|
||||
* @return the shared instance
|
||||
*/
|
||||
public static Activator getDefault() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,202 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Sep 1, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import polyglot.ast.ArrayAccess;
|
||||
import polyglot.ast.ArrayAccessAssign;
|
||||
import polyglot.ast.ArrayInit;
|
||||
import polyglot.ast.ArrayTypeNode;
|
||||
import polyglot.ast.Assert;
|
||||
import polyglot.ast.Binary;
|
||||
import polyglot.ast.Block;
|
||||
import polyglot.ast.BooleanLit;
|
||||
import polyglot.ast.Branch;
|
||||
import polyglot.ast.Call;
|
||||
import polyglot.ast.CanonicalTypeNode;
|
||||
import polyglot.ast.Case;
|
||||
import polyglot.ast.Cast;
|
||||
import polyglot.ast.Catch;
|
||||
import polyglot.ast.CharLit;
|
||||
import polyglot.ast.ClassBody;
|
||||
import polyglot.ast.ClassDecl;
|
||||
import polyglot.ast.ClassLit;
|
||||
import polyglot.ast.Conditional;
|
||||
import polyglot.ast.ConstructorCall;
|
||||
import polyglot.ast.ConstructorDecl;
|
||||
import polyglot.ast.Do;
|
||||
import polyglot.ast.Empty;
|
||||
import polyglot.ast.Eval;
|
||||
import polyglot.ast.Field;
|
||||
import polyglot.ast.FieldAssign;
|
||||
import polyglot.ast.FieldDecl;
|
||||
import polyglot.ast.FloatLit;
|
||||
import polyglot.ast.For;
|
||||
import polyglot.ast.Formal;
|
||||
import polyglot.ast.If;
|
||||
import polyglot.ast.Import;
|
||||
import polyglot.ast.Initializer;
|
||||
import polyglot.ast.Instanceof;
|
||||
import polyglot.ast.IntLit;
|
||||
import polyglot.ast.Labeled;
|
||||
import polyglot.ast.Local;
|
||||
import polyglot.ast.LocalAssign;
|
||||
import polyglot.ast.LocalClassDecl;
|
||||
import polyglot.ast.LocalDecl;
|
||||
import polyglot.ast.MethodDecl;
|
||||
import polyglot.ast.New;
|
||||
import polyglot.ast.NewArray;
|
||||
import polyglot.ast.Node;
|
||||
import polyglot.ast.NullLit;
|
||||
import polyglot.ast.PackageNode;
|
||||
import polyglot.ast.Return;
|
||||
import polyglot.ast.Special;
|
||||
import polyglot.ast.StringLit;
|
||||
import polyglot.ast.Switch;
|
||||
import polyglot.ast.SwitchBlock;
|
||||
import polyglot.ast.Synchronized;
|
||||
import polyglot.ast.Throw;
|
||||
import polyglot.ast.Try;
|
||||
import polyglot.ast.Unary;
|
||||
import polyglot.ast.While;
|
||||
|
||||
import com.ibm.wala.cast.java.translator.polyglot.PolyglotJava2CAstTranslator.MethodContext;
|
||||
import com.ibm.wala.cast.java.translator.polyglot.PolyglotJava2CAstTranslator.WalkContext;
|
||||
import com.ibm.wala.cast.tree.CAstNode;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
/**
|
||||
* Wrapper for the logic (nasty cascaded instanceof tests) necessary to visit a Polyglot AST
|
||||
* and dispatch to the appropriate TranslatingVisitor methods for each AST node type.
|
||||
* @author rfuhrer
|
||||
*/
|
||||
public class ASTTraverser {
|
||||
protected ASTTraverser() { }
|
||||
|
||||
public static CAstNode visit(Node n, TranslatingVisitor tv, WalkContext wc) {
|
||||
if (n instanceof MethodDecl) {
|
||||
return tv.visit((MethodDecl) n, (MethodContext) wc);
|
||||
} else if (n instanceof ConstructorDecl) {
|
||||
return tv.visit((ConstructorDecl) n, (MethodContext) wc);
|
||||
} else if (n instanceof FieldDecl) {
|
||||
return tv.visit((FieldDecl) n, (MethodContext) wc);
|
||||
} else if (n instanceof Import) {
|
||||
return tv.visit((Import) n, wc);
|
||||
} else if (n instanceof PackageNode) {
|
||||
return tv.visit((PackageNode) n, wc);
|
||||
} else if (n instanceof CanonicalTypeNode) {
|
||||
return tv.visit((CanonicalTypeNode) n, wc);
|
||||
} else if (n instanceof ArrayTypeNode) {
|
||||
return tv.visit((ArrayTypeNode) n, wc);
|
||||
} else if (n instanceof ArrayInit) {
|
||||
return tv.visit((ArrayInit) n, wc);
|
||||
} else if (n instanceof ArrayAccessAssign) {
|
||||
return tv.visit((ArrayAccessAssign) n, wc);
|
||||
} else if (n instanceof FieldAssign) {
|
||||
return tv.visit((FieldAssign) n, wc);
|
||||
} else if (n instanceof LocalAssign) {
|
||||
return tv.visit((LocalAssign) n, wc);
|
||||
} else if (n instanceof Binary) {
|
||||
return tv.visit((Binary) n, wc);
|
||||
} else if (n instanceof Call) {
|
||||
return tv.visit((Call) n, wc);
|
||||
} else if (n instanceof ConstructorCall) {
|
||||
return tv.visit((ConstructorCall) n, wc);
|
||||
} else if (n instanceof Cast) {
|
||||
return tv.visit((Cast) n, wc);
|
||||
} else if (n instanceof Conditional) {
|
||||
return tv.visit((Conditional) n, wc);
|
||||
} else if (n instanceof Instanceof) {
|
||||
return tv.visit((Instanceof) n, wc);
|
||||
} else if (n instanceof BooleanLit) {
|
||||
return tv.visit((BooleanLit) n, wc);
|
||||
} else if (n instanceof ClassLit) {
|
||||
return tv.visit((ClassLit) n, wc);
|
||||
} else if (n instanceof FloatLit) {
|
||||
return tv.visit((FloatLit) n, wc);
|
||||
} else if (n instanceof NullLit) {
|
||||
return tv.visit((NullLit) n, wc);
|
||||
} else if (n instanceof CharLit) {
|
||||
return tv.visit((CharLit) n, wc);
|
||||
} else if (n instanceof IntLit) {
|
||||
return tv.visit((IntLit) n, wc);
|
||||
} else if (n instanceof StringLit) {
|
||||
return tv.visit((StringLit) n, wc);
|
||||
} else if (n instanceof New) {
|
||||
return tv.visit((New) n, wc);
|
||||
} else if (n instanceof NewArray) {
|
||||
return tv.visit((NewArray) n, wc);
|
||||
} else if (n instanceof Special) {
|
||||
return tv.visit((Special) n, wc);
|
||||
} else if (n instanceof Unary) {
|
||||
return tv.visit((Unary) n, wc);
|
||||
} else if (n instanceof ArrayAccess) {
|
||||
return tv.visit((ArrayAccess) n, wc);
|
||||
} else if (n instanceof Field) {
|
||||
return tv.visit((Field) n, wc);
|
||||
} else if (n instanceof Local) {
|
||||
return tv.visit((Local) n, wc);
|
||||
} else if (n instanceof ClassBody) {
|
||||
return tv.visit((ClassBody) n, wc);
|
||||
} else if (n instanceof ClassDecl) {
|
||||
return tv.visit((ClassDecl) n, wc);
|
||||
} else if (n instanceof Initializer) {
|
||||
return tv.visit((Initializer) n, wc);
|
||||
} else if (n instanceof Assert) {
|
||||
return tv.visit((Assert) n, wc);
|
||||
} else if (n instanceof Branch) {
|
||||
return tv.visit((Branch) n, wc);
|
||||
} else if (n instanceof SwitchBlock) { // must test for this one before Block
|
||||
return tv.visit((SwitchBlock) n, wc);
|
||||
} else if (n instanceof Block) { // must test for this one before Block
|
||||
return tv.visit((Block) n, wc);
|
||||
} else if (n instanceof Catch) {
|
||||
return tv.visit((Catch) n, wc);
|
||||
} else if (n instanceof If) {
|
||||
return tv.visit((If) n, wc);
|
||||
} else if (n instanceof Labeled) {
|
||||
return tv.visit((Labeled) n, wc);
|
||||
} else if (n instanceof LocalClassDecl) {
|
||||
return tv.visit((LocalClassDecl) n, wc);
|
||||
} else if (n instanceof Do) {
|
||||
return tv.visit((Do) n, wc);
|
||||
} else if (n instanceof For) {
|
||||
return tv.visit((For) n, wc);
|
||||
} else if (n instanceof While) {
|
||||
return tv.visit((While) n, wc);
|
||||
} else if (n instanceof Switch) {
|
||||
return tv.visit((Switch) n, wc);
|
||||
} else if (n instanceof Synchronized) {
|
||||
return tv.visit((Synchronized) n, wc);
|
||||
} else if (n instanceof Try) {
|
||||
return tv.visit((Try) n, wc);
|
||||
} else if (n instanceof Empty) {
|
||||
return tv.visit((Empty) n, wc);
|
||||
} else if (n instanceof Eval) {
|
||||
return tv.visit((Eval) n, wc);
|
||||
} else if (n instanceof LocalDecl) {
|
||||
return tv.visit((LocalDecl) n, wc);
|
||||
} else if (n instanceof Return) {
|
||||
return tv.visit((Return) n, wc);
|
||||
} else if (n instanceof Case) {
|
||||
return tv.visit((Case) n, wc);
|
||||
} else if (n instanceof Throw) {
|
||||
return tv.visit((Throw) n, wc);
|
||||
} else if (n instanceof Formal) {
|
||||
return tv.visit((Formal) n, wc);
|
||||
} else {
|
||||
Assertions.UNREACHABLE("Unhandled node " + n + " of type " + n.getClass().getName() + " in ASTTraverser.visit().");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import polyglot.ast.ArrayInit;
|
||||
import polyglot.ast.Expr;
|
||||
import polyglot.frontend.CyclicDependencyException;
|
||||
import polyglot.frontend.ExtensionInfo;
|
||||
import polyglot.frontend.Job;
|
||||
import polyglot.frontend.Pass;
|
||||
import polyglot.frontend.Scheduler;
|
||||
import polyglot.frontend.VisitorPass;
|
||||
import polyglot.frontend.goals.AbstractGoal;
|
||||
import polyglot.types.SemanticException;
|
||||
import polyglot.types.Type;
|
||||
import polyglot.util.ErrorInfo;
|
||||
import polyglot.visit.AscriptionVisitor;
|
||||
|
||||
/**
|
||||
* Runs an AscriptionVisitor to make sure that empty array literals actually get a type.
|
||||
* @author rfuhrer
|
||||
*/
|
||||
public class AscriptionGoal extends AbstractGoal {
|
||||
public AscriptionGoal(Job job) {
|
||||
super(job);
|
||||
try {
|
||||
Scheduler scheduler= job.extensionInfo().scheduler();
|
||||
|
||||
addPrerequisiteGoal(scheduler.TypeChecked(job), scheduler);
|
||||
} catch (CyclicDependencyException e) {
|
||||
job.compiler().errorQueue().enqueue(ErrorInfo.INTERNAL_ERROR, "Cycle encountered in goal graph?");
|
||||
throw new IllegalStateException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public Pass createPass(ExtensionInfo extInfo) {
|
||||
return new VisitorPass(this,
|
||||
new AscriptionVisitor(job(), extInfo.typeSystem(), extInfo.nodeFactory()) {
|
||||
public Expr ascribe(Expr e, Type toType) throws SemanticException {
|
||||
if (e instanceof ArrayInit && e.type().isNull()) {
|
||||
return e.type(toType);
|
||||
}
|
||||
return super.ascribe(e, toType);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Oct 6, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import polyglot.frontend.CyclicDependencyException;
|
||||
import polyglot.frontend.Job;
|
||||
import polyglot.frontend.Pass;
|
||||
import polyglot.frontend.Scheduler;
|
||||
import polyglot.frontend.goals.AbstractGoal;
|
||||
import polyglot.frontend.goals.EndGoal;
|
||||
import polyglot.util.ErrorInfo;
|
||||
|
||||
import com.ibm.wala.cast.java.loader.JavaSourceLoaderImpl;
|
||||
import com.ibm.wala.cast.java.translator.Java2IRTranslator;
|
||||
|
||||
/**
|
||||
* A kind of EndGoal that indicates that DOMO IR has been generated for the given compilation unit.
|
||||
* @author rfuhrer
|
||||
*/
|
||||
public class IRGoal extends AbstractGoal implements EndGoal {
|
||||
private JavaSourceLoaderImpl fSourceLoader;
|
||||
|
||||
public IRGoal(Job job, JavaSourceLoaderImpl sourceLoader) {
|
||||
super(job);
|
||||
fSourceLoader = sourceLoader;
|
||||
try {
|
||||
Scheduler scheduler= job.extensionInfo().scheduler();
|
||||
|
||||
addPrerequisiteGoal(scheduler.TypeChecked(job), scheduler);
|
||||
// Need ConstantsChecked in order to make sure that case statements have non-zero labels.
|
||||
addPrerequisiteGoal(scheduler.ConstantsChecked(job), scheduler);
|
||||
// Need to add an AscriptionGoal as a prereq to make sure that empty array initializers get a type ascribed.
|
||||
addPrerequisiteGoal(new AscriptionGoal(job), scheduler);
|
||||
} catch (CyclicDependencyException e) {
|
||||
job.compiler().errorQueue().enqueue(ErrorInfo.INTERNAL_ERROR, "Cycle encountered in goal graph?");
|
||||
throw new IllegalStateException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public Pass createPass(polyglot.frontend.ExtensionInfo extInfo) {
|
||||
return new JavaIRPass(this, job(),
|
||||
new Java2IRTranslator(
|
||||
new PolyglotJava2CAstTranslator(
|
||||
fSourceLoader.getReference(),
|
||||
extInfo.nodeFactory(),
|
||||
extInfo.typeSystem(),
|
||||
new PolyglotIdentityMapper(fSourceLoader.getReference(), this.job.extensionInfo().typeSystem())),
|
||||
fSourceLoader,
|
||||
((IRTranslatorExtension)extInfo).getCAstRewriterFactory()));
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "<DOMO IR goal for " + job().source().path() + ">";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Oct 21, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import com.ibm.wala.cast.tree.impl.CAstRewriterFactory;
|
||||
|
||||
public interface IRTranslatorExtension {
|
||||
void setSourceLoader(PolyglotSourceLoaderImpl jsli);
|
||||
|
||||
/**
|
||||
* @return the identity mapper, for mapping AST nodes to WALA TypeReferences,
|
||||
* MethodReferences and FieldReferences. Helps clients to correlate analysis
|
||||
* results to AST nodes.
|
||||
*/
|
||||
PolyglotIdentityMapper getIdentityMapper();
|
||||
|
||||
/**
|
||||
* @return the CAstRewriterFactory.
|
||||
*/
|
||||
CAstRewriterFactory getCAstRewriterFactory();
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Oct 6, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import polyglot.frontend.AbstractPass;
|
||||
import polyglot.frontend.Job;
|
||||
import polyglot.frontend.goals.Goal;
|
||||
|
||||
import com.ibm.wala.cast.java.translator.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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/******************************************************************************
|
||||
* 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.JLExtensionInfo;
|
||||
import polyglot.frontend.Job;
|
||||
import polyglot.frontend.goals.Goal;
|
||||
|
||||
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.
|
||||
* @author rfuhrer
|
||||
*/
|
||||
public class JavaIRTranslatorExtension extends JLExtensionInfo implements IRTranslatorExtension {
|
||||
protected PolyglotSourceLoaderImpl fSourceLoader;
|
||||
protected PolyglotIdentityMapper fMapper;
|
||||
protected CAstRewriterFactory rewriterFactory;
|
||||
|
||||
public void setSourceLoader(PolyglotSourceLoaderImpl sourceLoader) {
|
||||
fSourceLoader= sourceLoader;
|
||||
fMapper= new PolyglotIdentityMapper(sourceLoader.getReference(), typeSystem());
|
||||
}
|
||||
|
||||
public Goal getCompileGoal(Job job) {
|
||||
return new IRGoal(job, fSourceLoader);
|
||||
}
|
||||
|
||||
public PolyglotIdentityMapper getIdentityMapper() {
|
||||
return fMapper;
|
||||
}
|
||||
|
||||
public void setCAstRewriterFactory(CAstRewriterFactory factory) {
|
||||
rewriterFactory = factory;
|
||||
}
|
||||
|
||||
public CAstRewriterFactory getCAstRewriterFactory() {
|
||||
return rewriterFactory;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Oct 7, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.ibm.wala.classLoader.ClassLoaderFactoryImpl;
|
||||
import com.ibm.wala.classLoader.ClassLoaderImpl;
|
||||
import com.ibm.wala.classLoader.IClassLoader;
|
||||
import com.ibm.wala.eclipse.util.EclipseProjectPath;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.ipa.callgraph.impl.SetOfClasses;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
|
||||
public class PolyglotClassLoaderFactory extends ClassLoaderFactoryImpl {
|
||||
|
||||
/**
|
||||
* A map from ClassLoaderReference to IRTranslatorExtension, so that source files
|
||||
* in different languages are processed by the right kind of IRTranslatorExtension.
|
||||
*/
|
||||
final protected Map<ClassLoaderReference,IRTranslatorExtension> fExtensionMap= new HashMap<ClassLoaderReference,IRTranslatorExtension>();
|
||||
|
||||
public PolyglotClassLoaderFactory(SetOfClasses exclusions, IRTranslatorExtension javaExtInfo) {
|
||||
super(exclusions);
|
||||
fExtensionMap.put(EclipseProjectPath.SOURCE_REF, javaExtInfo);
|
||||
}
|
||||
|
||||
protected IRTranslatorExtension getExtensionFor(ClassLoaderReference clr) {
|
||||
return fExtensionMap.get(clr);
|
||||
}
|
||||
|
||||
protected IClassLoader makeNewClassLoader(ClassLoaderReference classLoaderReference, IClassHierarchy cha, IClassLoader parent,
|
||||
AnalysisScope scope) throws IOException {
|
||||
if (classLoaderReference.equals(EclipseProjectPath.SOURCE_REF)) {
|
||||
ClassLoaderImpl cl = new PolyglotSourceLoaderImpl(classLoaderReference, parent, getExclusions(), cha, getExtensionFor(classLoaderReference));
|
||||
cl.init(scope.getModules(classLoaderReference));
|
||||
return cl;
|
||||
} else {
|
||||
return super.makeNewClassLoader(classLoaderReference, cha, parent, scope);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Oct 6, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import polyglot.frontend.Compiler;
|
||||
import polyglot.frontend.ExtensionInfo;
|
||||
import polyglot.frontend.Job;
|
||||
import polyglot.frontend.Scheduler;
|
||||
import polyglot.util.ErrorInfo;
|
||||
import polyglot.util.ErrorLimitError;
|
||||
import polyglot.util.ErrorQueue;
|
||||
import polyglot.util.InternalCompilerError;
|
||||
import polyglot.util.Position;
|
||||
import polyglot.util.StdErrorQueue;
|
||||
|
||||
/**
|
||||
* Enhancement of core Polyglot compiler that takes as input a Collection of StreamSources.
|
||||
* Identical to Compiler in all other respects.
|
||||
* @author rfuhrer
|
||||
*/
|
||||
public final class PolyglotFrontEnd extends Compiler {
|
||||
public PolyglotFrontEnd(ExtensionInfo info, ErrorQueue eq) {
|
||||
super(info, eq);
|
||||
}
|
||||
public PolyglotFrontEnd(ExtensionInfo info) {
|
||||
this(info, new StdErrorQueue(System.err, 1000 * 1000, info.compilerName()));
|
||||
}
|
||||
|
||||
public boolean compile(Collection/*<StreamSource>*/sources) {
|
||||
boolean okay= false;
|
||||
|
||||
try {
|
||||
try {
|
||||
Scheduler scheduler= sourceExtension().scheduler();
|
||||
List<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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,230 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import polyglot.types.ArrayType;
|
||||
import polyglot.types.ClassType;
|
||||
import polyglot.types.CodeInstance;
|
||||
import polyglot.types.ConstructorInstance;
|
||||
import polyglot.types.FieldInstance;
|
||||
import polyglot.types.InitializerInstance;
|
||||
import polyglot.types.MemberInstance;
|
||||
import polyglot.types.MethodInstance;
|
||||
import polyglot.types.PrimitiveType;
|
||||
import polyglot.types.ProcedureInstance;
|
||||
import polyglot.types.Type;
|
||||
import polyglot.types.TypeSystem;
|
||||
|
||||
import com.ibm.wala.cast.java.translator.polyglot.PolyglotJava2CAstTranslator.IdentityMapper;
|
||||
import com.ibm.wala.cast.java.types.JavaPrimitiveTypeMap;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.types.Descriptor;
|
||||
import com.ibm.wala.types.FieldReference;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.types.Selector;
|
||||
import com.ibm.wala.types.TypeName;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
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.
|
||||
* @author rfuhrer
|
||||
*/
|
||||
public class PolyglotIdentityMapper implements IdentityMapper<Type,CodeInstance,FieldInstance> {
|
||||
private final Map<Type,TypeReference> fTypeMap= HashMapFactory.make();
|
||||
private final Map<FieldInstance,FieldReference> fFieldMap= HashMapFactory.make();
|
||||
private final Map<CodeInstance,MethodReference> fMethodMap= HashMapFactory.make();
|
||||
|
||||
/**
|
||||
* 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.)
|
||||
*/
|
||||
protected Map<ClassType,CodeInstance> fLocalTypeMap= new LinkedHashMap<ClassType,CodeInstance>();
|
||||
|
||||
private final ClassLoaderReference fClassLoaderRef;
|
||||
private final TypeSystem fTypeSystem;
|
||||
|
||||
public PolyglotIdentityMapper(ClassLoaderReference clr, TypeSystem ts) {
|
||||
fClassLoaderRef= clr;
|
||||
fTypeSystem= ts;
|
||||
}
|
||||
|
||||
public FieldReference getFieldRef(FieldInstance field) {
|
||||
if (!fFieldMap.containsKey(field)) {
|
||||
FieldReference ref= referenceForField(field);
|
||||
fFieldMap.put(field, ref);
|
||||
return ref;
|
||||
}
|
||||
return fFieldMap.get(field);
|
||||
}
|
||||
|
||||
public TypeReference getTypeRef(Type type) {
|
||||
if (!fTypeMap.containsKey(type)) {
|
||||
TypeReference ref= referenceForType(type);
|
||||
fTypeMap.put(type, ref);
|
||||
return ref;
|
||||
}
|
||||
return fTypeMap.get(type);
|
||||
}
|
||||
|
||||
public MethodReference getMethodRef(CodeInstance method) {
|
||||
if (!fMethodMap.containsKey(method)) {
|
||||
MethodReference sel= referenceForMethod(method);
|
||||
fMethodMap.put(method, sel);
|
||||
return sel;
|
||||
}
|
||||
return fMethodMap.get(method);
|
||||
}
|
||||
|
||||
public void mapLocalAnonTypeToMethod(ClassType anonLocalType, CodeInstance owningProc) {
|
||||
fLocalTypeMap.put(anonLocalType, owningProc);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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).
|
||||
*/
|
||||
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);
|
||||
|
||||
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).
|
||||
*/
|
||||
public TypeReference referenceForType(Type type) {
|
||||
TypeName typeName= TypeName.string2TypeName(typeToTypeID(type));
|
||||
TypeReference typeRef= TypeReference.findOrCreate(fClassLoaderRef, typeName);
|
||||
|
||||
return typeRef;
|
||||
}
|
||||
|
||||
private Selector selectorForMethod(CodeInstance procInstance) {
|
||||
Atom name=
|
||||
(procInstance instanceof ConstructorInstance) ?
|
||||
MethodReference.initAtom :
|
||||
(procInstance instanceof InitializerInstance) ?
|
||||
MethodReference.clinitName :
|
||||
Atom.findOrCreateUnicodeAtom(((MethodInstance) procInstance).name());
|
||||
|
||||
TypeName[] argTypeNames = null;
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Type retType=
|
||||
(procInstance instanceof MethodInstance) ? ((MethodInstance) procInstance).returnType() : fTypeSystem.Void();
|
||||
TypeName retTypeName= TypeName.string2TypeName(typeToTypeID(retType));
|
||||
|
||||
Descriptor desc= Descriptor.findOrCreate(argTypeNames, retTypeName);
|
||||
|
||||
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).
|
||||
*/
|
||||
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));
|
||||
|
||||
return methodRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the given Polyglot type to a name suitable for use in a DOMO TypeReference
|
||||
* (i.e. a bytecode-compliant type name).
|
||||
*/
|
||||
public String typeToTypeID(Type type) {
|
||||
if (type.isPrimitive()) {
|
||||
PrimitiveType ptype= (PrimitiveType) type;
|
||||
|
||||
return JavaPrimitiveTypeMap.getShortName(ptype.name());
|
||||
} else if (type.isArray()) {
|
||||
ArrayType atype= (ArrayType) type;
|
||||
return "[" + typeToTypeID(atype.base());
|
||||
} else if (type.isNull()) {
|
||||
Assertions.UNREACHABLE("typeToTypeID() encountered a null type!");
|
||||
return null;
|
||||
}
|
||||
Assertions._assert(type.isClass(), "typeToTypeID() encountered the type " + type + " that is neither primitive, array, nor class!");
|
||||
|
||||
ClassType ctype= (ClassType) type;
|
||||
|
||||
return (ctype.isLocal() || ctype.isAnonymous()) ? anonLocalTypeToTypeID(ctype) : composeDOMOTypeDescriptor(ctype);
|
||||
}
|
||||
|
||||
public String anonLocalTypeToTypeID(ClassType ctype) {
|
||||
CodeInstance procInstance= (CodeInstance) fLocalTypeMap.get(ctype);
|
||||
|
||||
String outerTypeID= typeToTypeID(ctype.outer());
|
||||
String shortName= (ctype.isAnonymous()) ? PolyglotJava2CAstTranslator.anonTypeName(ctype) : ctype.fullName();
|
||||
|
||||
return outerTypeID + '/' + getMethodRef(procInstance).getSelector() + '/' + shortName;
|
||||
}
|
||||
|
||||
public String composeDOMOTypeDescriptor(ClassType ctype) {
|
||||
return "L" + composeDOMOTypeName(ctype);
|
||||
}
|
||||
|
||||
public String composeDOMOTypeName(ClassType ctype) {
|
||||
if (ctype.package_() != null) {
|
||||
String packageName = ctype.package_().fullName();
|
||||
|
||||
Assertions._assert( ctype.fullName().startsWith( packageName ) );
|
||||
return packageName.replace('.','/') + "/" + ctype.fullName().substring( packageName.length()+1 ).replace('.','$');
|
||||
} else {
|
||||
return ctype.fullName().replace('.', '$');
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,17 @@
|
|||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import com.ibm.wala.cast.java.client.JavaSourceAnalysisEngine;
|
||||
import com.ibm.wala.classLoader.ClassLoaderFactory;
|
||||
import com.ibm.wala.ipa.callgraph.impl.SetOfClasses;
|
||||
|
||||
public class PolyglotJavaSourceAnalysisEngine extends JavaSourceAnalysisEngine {
|
||||
|
||||
public IRTranslatorExtension getTranslatorExtension() {
|
||||
return new JavaIRTranslatorExtension();
|
||||
}
|
||||
|
||||
protected ClassLoaderFactory getClassLoaderFactory(SetOfClasses exclusions) {
|
||||
return new PolyglotClassLoaderFactory(exclusions, getTranslatorExtension());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Oct 7, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.ibm.wala.cast.java.loader.JavaSourceLoaderImpl;
|
||||
import com.ibm.wala.cast.java.translator.SourceModuleTranslator;
|
||||
import com.ibm.wala.classLoader.IClassLoader;
|
||||
import com.ibm.wala.ipa.callgraph.impl.SetOfClasses;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
|
||||
public class PolyglotSourceLoaderImpl extends JavaSourceLoaderImpl {
|
||||
private final IRTranslatorExtension fExtInfo;
|
||||
|
||||
public PolyglotSourceLoaderImpl(ClassLoaderReference loaderRef, IClassLoader parent, SetOfClasses exclusions,
|
||||
IClassHierarchy cha, IRTranslatorExtension extInfo) throws IOException {
|
||||
super(loaderRef, parent, exclusions, cha);
|
||||
this.fExtInfo = extInfo;
|
||||
}
|
||||
|
||||
public IRTranslatorExtension getTranslatorExtension() {
|
||||
return fExtInfo;
|
||||
}
|
||||
|
||||
protected SourceModuleTranslator getTranslator() {
|
||||
return new PolyglotSourceModuleTranslator(cha.getScope(), fExtInfo, this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Oct 6, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import polyglot.frontend.Compiler;
|
||||
import polyglot.frontend.ExtensionInfo;
|
||||
import polyglot.main.Options;
|
||||
import polyglot.main.UsageError;
|
||||
import polyglot.util.ErrorInfo;
|
||||
import polyglot.util.Position;
|
||||
|
||||
import com.ibm.wala.cast.java.translator.SourceModuleTranslator;
|
||||
import com.ibm.wala.classLoader.DirectoryTreeModule;
|
||||
import com.ibm.wala.classLoader.FileModule;
|
||||
import com.ibm.wala.classLoader.JarFileModule;
|
||||
import com.ibm.wala.classLoader.Module;
|
||||
import com.ibm.wala.classLoader.SourceFileModule;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
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.
|
||||
* @author rfuhrer
|
||||
*/
|
||||
public class PolyglotSourceModuleTranslator implements SourceModuleTranslator {
|
||||
private final ExtensionInfo fExtInfo;
|
||||
|
||||
private String fClassPath;
|
||||
|
||||
public PolyglotSourceModuleTranslator(AnalysisScope scope, IRTranslatorExtension extInfo, PolyglotSourceLoaderImpl sourceLoader) {
|
||||
fExtInfo= (ExtensionInfo) extInfo;
|
||||
computeClassPath(scope);
|
||||
extInfo.setSourceLoader(sourceLoader);
|
||||
}
|
||||
|
||||
private void computeClassPath(AnalysisScope scope) {
|
||||
StringBuffer buf= new StringBuffer();
|
||||
|
||||
ClassLoaderReference cl= findInnermostClassLoader(scope);
|
||||
|
||||
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");
|
||||
}
|
||||
cl= cl.getParent();
|
||||
}
|
||||
fClassPath= buf.toString();
|
||||
}
|
||||
|
||||
private ClassLoaderReference findInnermostClassLoader(AnalysisScope scope) {
|
||||
Set<ClassLoaderReference> parentLoaders= new HashSet<ClassLoaderReference>();
|
||||
|
||||
for(ClassLoaderReference loader: scope.getLoaders()) {
|
||||
parentLoaders.add(loader.getParent());
|
||||
}
|
||||
for (ClassLoaderReference child : scope.getLoaders()) {
|
||||
if (!parentLoaders.contains(child)) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("No innermost class loader???");
|
||||
}
|
||||
|
||||
public void loadAllSources(Set modules) {
|
||||
Options opts= fExtInfo.getOptions();
|
||||
opts.assertions = true;
|
||||
Options.global = opts;
|
||||
try {
|
||||
opts.parseCommandLine(new String[] { "-cp", fClassPath }, new HashSet());
|
||||
} catch (UsageError e) {
|
||||
// Assertions.UNREACHABLE("Error parsing classpath spec???");
|
||||
}
|
||||
|
||||
Compiler compiler= new PolyglotFrontEnd(fExtInfo);
|
||||
List<StreamSource> streams= new ArrayList<StreamSource>();
|
||||
|
||||
// N.B.: 'modules' is a flat set of source file ModuleEntry's.
|
||||
for(Iterator it= modules.iterator(); it.hasNext(); ) {
|
||||
SourceFileModule entry= (SourceFileModule) it.next();
|
||||
|
||||
Assertions._assert(entry.isSourceFile());
|
||||
|
||||
if (skipSourceFile(entry)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String filePath= entry.getAbsolutePath();
|
||||
|
||||
try {
|
||||
StreamSource srcStream= new StreamSource(entry.getInputStream(), filePath);
|
||||
|
||||
streams.add(srcStream);
|
||||
} catch (IOException e) {
|
||||
compiler.errorQueue().enqueue(new ErrorInfo(ErrorInfo.IO_ERROR, "Unable to open source file '" + entry.getName() + "'", Position.COMPILER_GENERATED));
|
||||
}
|
||||
}
|
||||
compiler.compile(streams);
|
||||
// At this point, DOMO now "knows" about all the source-originated stuff
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Sep 28, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
|
||||
import polyglot.types.ArrayType;
|
||||
import polyglot.types.ClassType;
|
||||
import polyglot.types.PrimitiveType;
|
||||
import polyglot.types.ReferenceType;
|
||||
import polyglot.types.Type;
|
||||
import polyglot.types.TypeSystem;
|
||||
|
||||
import com.ibm.wala.cast.java.types.JavaPrimitiveTypeMap;
|
||||
import com.ibm.wala.cast.tree.CAstType;
|
||||
import com.ibm.wala.cast.tree.impl.CAstTypeDictionaryImpl;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
public class PolyglotTypeDictionary extends CAstTypeDictionaryImpl {
|
||||
private final class PolyglotJavaArrayType implements CAstType.Array {
|
||||
private final Type fEltPolyglotType;
|
||||
|
||||
private final CAstType fEltCAstType;
|
||||
|
||||
private PolyglotJavaArrayType(ArrayType arrayType) {
|
||||
super();
|
||||
fEltPolyglotType = arrayType.base();
|
||||
fEltCAstType = getCAstTypeFor(fEltPolyglotType);
|
||||
}
|
||||
|
||||
public int getNumDimensions() {
|
||||
return 1; // always 1 for Java
|
||||
}
|
||||
|
||||
public CAstType getElementType() {
|
||||
return fEltCAstType;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "[" + fEltCAstType.getName();
|
||||
}
|
||||
|
||||
public Collection getSupertypes() {
|
||||
if (fEltPolyglotType.isPrimitive())
|
||||
return Collections.singleton(getCAstTypeFor(fTypeSystem.Object()));
|
||||
Assertions._assert(fEltPolyglotType.isReference(), "Non-primitive, non-reference array element type!");
|
||||
ReferenceType baseRefType = (ReferenceType) fEltPolyglotType;
|
||||
Collection<CAstType> supers = new ArrayList<CAstType>();
|
||||
for (Iterator superIter = baseRefType.interfaces().iterator(); superIter.hasNext();) {
|
||||
supers.add(getCAstTypeFor(superIter.next()));
|
||||
}
|
||||
if (baseRefType.superType() != null)
|
||||
supers.add(getCAstTypeFor(baseRefType.superType()));
|
||||
return supers;
|
||||
}
|
||||
}
|
||||
|
||||
protected final TypeSystem fTypeSystem;
|
||||
|
||||
private final PolyglotJava2CAstTranslator fTranslator;
|
||||
|
||||
public PolyglotTypeDictionary(TypeSystem typeSystem, PolyglotJava2CAstTranslator translator) {
|
||||
fTypeSystem = typeSystem;
|
||||
fTranslator = translator;
|
||||
}
|
||||
|
||||
public CAstType getCAstTypeFor(Object astType) {
|
||||
CAstType type = super.getCAstTypeFor(astType);
|
||||
// Handle the case where we haven't seen an AST decl for some type before
|
||||
// processing a reference. This can certainly happen with classes in byte-
|
||||
// code libraries, for which we never see an AST decl.
|
||||
// In this case, just create a new type and return that.
|
||||
if (type == null) {
|
||||
final Type polyglotType = (Type) astType;
|
||||
|
||||
if (polyglotType.isClass())
|
||||
type = fTranslator.new PolyglotJavaType((ClassType) astType, this, fTypeSystem);
|
||||
else if (polyglotType.isPrimitive()) {
|
||||
type = JavaPrimitiveTypeMap.lookupType(((PrimitiveType) polyglotType).name());
|
||||
} else if (polyglotType.isArray()) {
|
||||
type = new PolyglotJavaArrayType((ArrayType) polyglotType);
|
||||
} else
|
||||
Assertions.UNREACHABLE("getCAstTypeFor() passed type that is not primitive, array, or class?");
|
||||
super.map(astType, type);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/******************************************************************************
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Sep 1, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import polyglot.ast.ArrayAccess;
|
||||
import polyglot.ast.ArrayAccessAssign;
|
||||
import polyglot.ast.ArrayInit;
|
||||
import polyglot.ast.ArrayTypeNode;
|
||||
import polyglot.ast.Assert;
|
||||
import polyglot.ast.Binary;
|
||||
import polyglot.ast.Block;
|
||||
import polyglot.ast.BooleanLit;
|
||||
import polyglot.ast.Branch;
|
||||
import polyglot.ast.Call;
|
||||
import polyglot.ast.CanonicalTypeNode;
|
||||
import polyglot.ast.Case;
|
||||
import polyglot.ast.Cast;
|
||||
import polyglot.ast.Catch;
|
||||
import polyglot.ast.CharLit;
|
||||
import polyglot.ast.ClassBody;
|
||||
import polyglot.ast.ClassDecl;
|
||||
import polyglot.ast.ClassLit;
|
||||
import polyglot.ast.Conditional;
|
||||
import polyglot.ast.ConstructorCall;
|
||||
import polyglot.ast.ConstructorDecl;
|
||||
import polyglot.ast.Do;
|
||||
import polyglot.ast.Empty;
|
||||
import polyglot.ast.Eval;
|
||||
import polyglot.ast.Field;
|
||||
import polyglot.ast.FieldAssign;
|
||||
import polyglot.ast.FieldDecl;
|
||||
import polyglot.ast.FloatLit;
|
||||
import polyglot.ast.For;
|
||||
import polyglot.ast.Formal;
|
||||
import polyglot.ast.If;
|
||||
import polyglot.ast.Import;
|
||||
import polyglot.ast.Initializer;
|
||||
import polyglot.ast.Instanceof;
|
||||
import polyglot.ast.IntLit;
|
||||
import polyglot.ast.Labeled;
|
||||
import polyglot.ast.Local;
|
||||
import polyglot.ast.LocalAssign;
|
||||
import polyglot.ast.LocalClassDecl;
|
||||
import polyglot.ast.LocalDecl;
|
||||
import polyglot.ast.MethodDecl;
|
||||
import polyglot.ast.New;
|
||||
import polyglot.ast.NewArray;
|
||||
import polyglot.ast.NullLit;
|
||||
import polyglot.ast.PackageNode;
|
||||
import polyglot.ast.Return;
|
||||
import polyglot.ast.Special;
|
||||
import polyglot.ast.StringLit;
|
||||
import polyglot.ast.Switch;
|
||||
import polyglot.ast.SwitchBlock;
|
||||
import polyglot.ast.Synchronized;
|
||||
import polyglot.ast.Throw;
|
||||
import polyglot.ast.Try;
|
||||
import polyglot.ast.Unary;
|
||||
import polyglot.ast.While;
|
||||
|
||||
import com.ibm.wala.cast.java.translator.polyglot.PolyglotJava2CAstTranslator.MethodContext;
|
||||
import com.ibm.wala.cast.java.translator.polyglot.PolyglotJava2CAstTranslator.WalkContext;
|
||||
import com.ibm.wala.cast.tree.CAstNode;
|
||||
|
||||
/**
|
||||
* An alternative visitor API for Polyglot, whose API is somewhat brain-damaged...
|
||||
* @author rfuhrer
|
||||
*/
|
||||
public interface TranslatingVisitor {
|
||||
CAstNode visit(MethodDecl m, MethodContext context);
|
||||
CAstNode visit(ConstructorDecl cd, MethodContext cc);
|
||||
CAstNode visit(FieldDecl f, MethodContext mc); // yes, a MethodContext; we process FieldDecl's only to add their initializers to each constructor
|
||||
CAstNode visit(Import i, WalkContext wc);
|
||||
CAstNode visit(PackageNode p, WalkContext wc);
|
||||
CAstNode visit(CanonicalTypeNode ctn, WalkContext wc);
|
||||
CAstNode visit(ArrayTypeNode ctn, WalkContext wc);
|
||||
CAstNode visit(ArrayInit ai, WalkContext wc);
|
||||
CAstNode visit(ArrayAccessAssign aaa, WalkContext wc);
|
||||
CAstNode visit(FieldAssign fa, WalkContext wc);
|
||||
CAstNode visit(LocalAssign la, WalkContext wc);
|
||||
CAstNode visit(Binary b, WalkContext wc);
|
||||
CAstNode visit(Call c, WalkContext wc);
|
||||
CAstNode visit(ConstructorCall cc, WalkContext wc);
|
||||
CAstNode visit(Cast c, WalkContext wc);
|
||||
CAstNode visit(Conditional c, WalkContext wc);
|
||||
CAstNode visit(Instanceof io, WalkContext wc);
|
||||
CAstNode visit(BooleanLit bl, WalkContext wc);
|
||||
CAstNode visit(ClassLit cl, WalkContext wc);
|
||||
CAstNode visit(FloatLit fl, WalkContext wc);
|
||||
CAstNode visit(NullLit nl, WalkContext wc);
|
||||
CAstNode visit(CharLit cl, WalkContext wc);
|
||||
CAstNode visit(IntLit il, WalkContext wc);
|
||||
CAstNode visit(StringLit sl, WalkContext wc);
|
||||
CAstNode visit(New n, WalkContext wc);
|
||||
CAstNode visit(NewArray na, WalkContext wc);
|
||||
CAstNode visit(Special s, WalkContext wc);
|
||||
CAstNode visit(Unary u, WalkContext wc);
|
||||
CAstNode visit(ArrayAccess aa, WalkContext wc);
|
||||
CAstNode visit(Field f, WalkContext wc);
|
||||
CAstNode visit(Local l, WalkContext wc);
|
||||
CAstNode visit(ClassBody cb, WalkContext wc); // should never see this when producing CAstNodes
|
||||
CAstNode visit(ClassDecl cd, WalkContext wc); // should never see this when producing CAstNodes
|
||||
CAstNode visit(Initializer i, WalkContext wc); // should never see this when producing CAstNodes
|
||||
CAstNode visit(Assert a, WalkContext wc);
|
||||
CAstNode visit(Branch b, WalkContext wc);
|
||||
CAstNode visit(Block b, WalkContext wc);
|
||||
CAstNode visit(SwitchBlock sb, WalkContext wc);
|
||||
CAstNode visit(Catch c, WalkContext wc);
|
||||
CAstNode visit(If i, WalkContext wc);
|
||||
CAstNode visit(Labeled l, WalkContext wc);
|
||||
CAstNode visit(LocalClassDecl lcd, WalkContext wc);
|
||||
CAstNode visit(Do d, WalkContext wc);
|
||||
CAstNode visit(For f, WalkContext wc);
|
||||
CAstNode visit(While w, WalkContext wc);
|
||||
CAstNode visit(Switch s, WalkContext wc);
|
||||
CAstNode visit(Synchronized s, WalkContext wc);
|
||||
CAstNode visit(Try t, WalkContext wc);
|
||||
CAstNode visit(Empty e, WalkContext wc);
|
||||
CAstNode visit(Eval e, WalkContext wc);
|
||||
CAstNode visit(LocalDecl ld, WalkContext wc);
|
||||
CAstNode visit(Return r, WalkContext wc);
|
||||
CAstNode visit(Case c, WalkContext wc);
|
||||
CAstNode visit(Throw t, WalkContext wc);
|
||||
CAstNode visit(Formal f, WalkContext wc); // may not see these (might be handled by parent)
|
||||
}
|
Loading…
Reference in New Issue