add some new classes from wala
This commit is contained in:
parent
a76f93a28c
commit
b84657d1a9
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* This file is a derivative of code released by the University of
|
||||
* California under the terms listed below.
|
||||
*
|
||||
* WALA JDT Frontend is Copyright (c) 2008 The Regents of the
|
||||
* University of California (Regents). Provided that this notice and
|
||||
* the following two paragraphs are included in any distribution of
|
||||
* Refinement Analysis Tools or its derivative work, Regents agrees
|
||||
* not to assert any of Regents' copyright rights in Refinement
|
||||
* Analysis Tools against recipient for recipient's reproduction,
|
||||
* preparation of derivative works, public display, public
|
||||
* performance, distribution or sublicensing of Refinement Analysis
|
||||
* Tools and derivative works, in source code and object code form.
|
||||
* This agreement not to assert does not confer, by implication,
|
||||
* estoppel, or otherwise any license or rights in any intellectual
|
||||
* property of Regents, including, but not limited to, any patents
|
||||
* of Regents or Regents' employees.
|
||||
*
|
||||
* IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT,
|
||||
* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
|
||||
* INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE
|
||||
* AND ITS DOCUMENTATION, EVEN IF REGENTS HAS BEEN ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND FURTHER DISCLAIMS ANY STATUTORY
|
||||
* WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE AND ACCOMPANYING
|
||||
* DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS
|
||||
* IS". REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
|
||||
* UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*/
|
||||
package com.ibm.wala.cast.java.client;
|
||||
|
||||
import org.eclipse.core.resources.IFolder;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
|
||||
import com.ibm.wala.cast.java.translator.jdt.JDTClassLoaderFactory;
|
||||
import com.ibm.wala.classLoader.ClassLoaderFactory;
|
||||
import com.ibm.wala.ide.classloader.EclipseSourceFileModule;
|
||||
import com.ibm.wala.ide.util.JdtUtil;
|
||||
import com.ibm.wala.ipa.callgraph.impl.SetOfClasses;
|
||||
|
||||
public class JDTJavaSourceAnalysisEngine extends JavaSourceAnalysisEngine {
|
||||
protected final IJavaProject project;
|
||||
|
||||
public JDTJavaSourceAnalysisEngine(IJavaProject project) {
|
||||
super();
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
public JDTJavaSourceAnalysisEngine(String projectName) {
|
||||
this(JdtUtil.getNamedProject(projectName));
|
||||
}
|
||||
|
||||
protected ClassLoaderFactory getClassLoaderFactory(SetOfClasses exclusions) {
|
||||
return new JDTClassLoaderFactory(exclusions);
|
||||
}
|
||||
|
||||
public void addSourceModule(IResource file) {
|
||||
IProject proj = project.getProject();
|
||||
IPath path = file.getProjectRelativePath();
|
||||
if (file.getType() == IResource.FILE) {
|
||||
addSourceModule(EclipseSourceFileModule.createEclipseSourceFileModule(proj.getFile(path)));
|
||||
} else {
|
||||
assert file.getType() == IResource.FOLDER;
|
||||
IFolder dir = proj.getFolder(path);
|
||||
try {
|
||||
for(IResource x : dir.members()) {
|
||||
assert x.getType() == IResource.FILE || x.getType() == IResource.FOLDER;
|
||||
addSourceModule(x);
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
throw new RuntimeException("trouble with " + file, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addSourceModule(String fileName) {
|
||||
IResource file = project.getProject().findMember(fileName);
|
||||
assert file != null;
|
||||
addSourceModule(file);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/******************************************************************************
|
||||
* 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 com.ibm.wala.classLoader.SourceModule;
|
||||
|
||||
import polyglot.frontend.FileSource;
|
||||
import polyglot.frontend.Resource;
|
||||
|
||||
/**
|
||||
* 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 ModuleSource extends FileSource {
|
||||
private final SourceModule module;
|
||||
|
||||
SourceModule getModule() {
|
||||
return module;
|
||||
}
|
||||
|
||||
public ModuleSource(final SourceModule module) throws IOException {
|
||||
super(new Resource() {
|
||||
public File file() {
|
||||
return new File(module.getURL().getFile());
|
||||
}
|
||||
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return module.getInputStream();
|
||||
}
|
||||
|
||||
public String name() {
|
||||
String fullPath = module.getURL().getFile();
|
||||
int idx= fullPath.lastIndexOf(File.separatorChar);
|
||||
return (idx > 0) ? fullPath.substring(idx+1) : fullPath;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return module.getName();
|
||||
}
|
||||
}, true);
|
||||
this.module = module;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.ibm.wala.cast.js.test;
|
||||
|
||||
import org.junit.Before;
|
||||
|
||||
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
|
||||
|
||||
public class TestForInLoopHackRhino extends TestForInLoopHack {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
com.ibm.wala.cast.js.ipa.callgraph.Util.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.ibm.wala.cast.js.test;
|
||||
|
||||
import org.junit.Before;
|
||||
|
||||
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
|
||||
|
||||
public class TestMozillaBugPagesRhino extends TestMozillaBugPages {
|
||||
|
||||
public static void main(String[] args) {
|
||||
justThisTest(TestMozillaBugPagesRhino.class);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
com.ibm.wala.cast.js.ipa.callgraph.Util.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.ibm.wala.cast.js.test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.ibm.wala.cast.js.html.IHtmlParser;
|
||||
import com.ibm.wala.cast.js.html.jericho.JerichoHtmlParser;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
|
||||
public class TestSimplePageCallGraphShapeRhinoJericho extends TestSimplePageCallGraphShapeRhino {
|
||||
|
||||
@Test public void testCrawl() throws IOException, IllegalArgumentException, CancelException {
|
||||
URL url = getClass().getClassLoader().getResource("pages/crawl.html");
|
||||
CallGraph CG = Util.makeHTMLCG(url);
|
||||
verifyGraphAssertions(CG, null);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
justThisTest(TestSimplePageCallGraphShapeRhinoJericho.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IHtmlParser getParser() {
|
||||
return new JerichoHtmlParser();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
package com.ibm.wala.cast.js.test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.ibm.wala.cast.js.html.JSSourceExtractor;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JSCFABuilder;
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.Context;
|
||||
import com.ibm.wala.ipa.callgraph.ContextItem;
|
||||
import com.ibm.wala.ipa.callgraph.ContextKey;
|
||||
import com.ibm.wala.ipa.callgraph.ContextSelector;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.FilteredPointerKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
import com.ibm.wala.util.intset.IntSetUtil;
|
||||
|
||||
public class TestForInLoopHack extends TestJSCallGraphShape {
|
||||
|
||||
@Before
|
||||
public void config() {
|
||||
JSSourceExtractor.USE_TEMP_NAME = false;
|
||||
JSSourceExtractor.DELETE_UPON_EXIT = false;
|
||||
}
|
||||
|
||||
@Test public void testPage3WithoutHack() throws IOException, IllegalArgumentException, CancelException {
|
||||
URL url = getClass().getClassLoader().getResource("pages/page3.html");
|
||||
JSCFABuilder builder = Util.makeHTMLCGBuilder(url);
|
||||
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||
Util.dumpCG(builder.getPointerAnalysis(), CG);
|
||||
}
|
||||
|
||||
@Test public void testPage3WithHack() throws IOException, IllegalArgumentException, CancelException {
|
||||
URL url = getClass().getClassLoader().getResource("pages/page3.html");
|
||||
JSCFABuilder builder = Util.makeHTMLCGBuilder(url);
|
||||
addHackedForInLoopSensitivity(builder);
|
||||
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||
Util.dumpCG(builder.getPointerAnalysis(), CG);
|
||||
}
|
||||
|
||||
private static final Object[][] assertionsForBadForin = new Object[][] {
|
||||
new Object[] { ROOT,
|
||||
new String[] { "tests/badforin.js" } },
|
||||
new Object[] { "tests/badforin.js",
|
||||
new String[] { "tests/badforin.js/testForIn", "tests/badforin.js/_check_obj_foo", "tests/badforin.js/_check_obj_bar", "tests/badforin.js/_check_copy_foo", "tests/badforin.js/_check_copy_bar"} },
|
||||
new Object[] { "tests/badforin.js/testForIn",
|
||||
new String[] { "tests/badforin.js/testForIn1", "tests/badforin.js/testForIn2" } },
|
||||
new Object[] { "tests/badforin.js/_check_obj_foo",
|
||||
new String[] { "tests/badforin.js/testForIn1" } },
|
||||
new Object[] { "tests/badforin.js/_check_copy_foo",
|
||||
new String[] { "tests/badforin.js/testForIn1" } },
|
||||
new Object[] { "tests/badforin.js/_check_obj_bar",
|
||||
new String[] { "tests/badforin.js/testForIn2" } },
|
||||
new Object[] { "tests/badforin.js/_check_copy_bar",
|
||||
new String[] { "tests/badforin.js/testForIn2" } }
|
||||
};
|
||||
|
||||
@Test public void testBadForInWithoutHack() throws IOException, IllegalArgumentException, CancelException {
|
||||
JSCFABuilder B = Util.makeScriptCGBuilder("tests", "badforin.js");
|
||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||
Util.dumpCG(B.getPointerAnalysis(), CG);
|
||||
verifyGraphAssertions(CG, assertionsForBadForin);
|
||||
}
|
||||
|
||||
private static final Object[][] assertionsForBadForinHackPrecision = new Object[][] {
|
||||
new Object[] { "tests/badforin.js/_check_obj_foo",
|
||||
new String[] { "!tests/badforin.js/testForIn2" } },
|
||||
new Object[] { "tests/badforin.js/_check_copy_foo",
|
||||
new String[] { "!tests/badforin.js/testForIn2" } },
|
||||
new Object[] { "tests/badforin.js/_check_obj_bar",
|
||||
new String[] { "!tests/badforin.js/testForIn1" } },
|
||||
new Object[] { "tests/badforin.js/_check_copy_bar",
|
||||
new String[] { "!tests/badforin.js/testForIn1" } }
|
||||
};
|
||||
|
||||
@Test public void testBadForInWithHack() throws IOException, IllegalArgumentException, CancelException {
|
||||
JSCFABuilder B = Util.makeScriptCGBuilder("tests", "badforin.js");
|
||||
addHackedForInLoopSensitivity(B);
|
||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||
Util.dumpCG(B.getPointerAnalysis(), CG);
|
||||
verifyGraphAssertions(CG, assertionsForBadForin);
|
||||
verifyGraphAssertions(CG, assertionsForBadForinHackPrecision);
|
||||
}
|
||||
|
||||
private void addHackedForInLoopSensitivity(JSCFABuilder builder) {
|
||||
final ContextSelector orig = builder.getContextSelector();
|
||||
builder.setContextSelector(new ContextSelector() {
|
||||
public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, final InstanceKey[] receiver) {
|
||||
final Context origContext = orig.getCalleeTarget(caller, site, callee, receiver);
|
||||
if (callee.getDeclaringClass().getName().toString().contains("_forin_body")) {
|
||||
class ForInContext implements Context {
|
||||
private final InstanceKey obj = receiver[2];
|
||||
public ContextItem get(ContextKey name) {
|
||||
if (name.equals(ContextKey.PARAMETERS[2])) {
|
||||
return new FilteredPointerKey.SingleInstanceFilter(obj);
|
||||
} else {
|
||||
return origContext.get(name);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return obj.hashCode();
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return other != null &&
|
||||
getClass().equals(other.getClass()) &&
|
||||
obj.equals(((ForInContext)other).obj);
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "for in hack filter for " + obj;
|
||||
}
|
||||
};
|
||||
return new ForInContext();
|
||||
} else {
|
||||
return origContext;
|
||||
}
|
||||
}
|
||||
public IntSet getRelevantParameters(CGNode caller, CallSiteReference site) {
|
||||
if (caller.getIR().getCalls(site)[0].getNumberOfUses() > 2) {
|
||||
return IntSetUtil.make(new int[]{2}).union(orig.getRelevantParameters(caller, site));
|
||||
} else {
|
||||
return orig.getRelevantParameters(caller, site);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package com.ibm.wala.cast.js.test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.ibm.wala.cast.js.html.JSSourceExtractor;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JSCFABuilder;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
public class TestMozillaBugPages extends TestJSCallGraphShape {
|
||||
|
||||
public static void main(String[] args) {
|
||||
justThisTest(TestMozillaBugPages.class);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void config() {
|
||||
JSSourceExtractor.USE_TEMP_NAME = false;
|
||||
JSSourceExtractor.DELETE_UPON_EXIT = false;
|
||||
}
|
||||
|
||||
@Test public void testMozilla439164() throws IOException, IllegalArgumentException, CancelException {
|
||||
URL url = getClass().getClassLoader().getResource("pages/mochitest/mozillaBug439164.html");
|
||||
JSCFABuilder builder = Util.makeHTMLCGBuilder(url);
|
||||
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||
Util.dumpCG(builder.getPointerAnalysis(), CG);
|
||||
}
|
||||
|
||||
@Test public void testMozilla488233() throws IOException, IllegalArgumentException, CancelException {
|
||||
URL url = getClass().getClassLoader().getResource("pages/mochitest/mozillaBug488233NoExtJS.html");
|
||||
JSCFABuilder builder = Util.makeHTMLCGBuilder(url);
|
||||
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||
Util.dumpCG(builder.getPointerAnalysis(), CG);
|
||||
}
|
||||
|
||||
@Test public void testMozilla490152() throws IOException, IllegalArgumentException, CancelException {
|
||||
URL url = getClass().getClassLoader().getResource("pages/mochitest/mozillaBug490152NoExtJS.html");
|
||||
JSCFABuilder builder = Util.makeHTMLCGBuilder(url);
|
||||
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||
Util.dumpCG(builder.getPointerAnalysis(), CG);
|
||||
}
|
||||
|
||||
@Test public void testMozilla625562() throws IOException, IllegalArgumentException, CancelException {
|
||||
URL url = getClass().getClassLoader().getResource("pages/mochitest/mozillaBug625562NoExtJS.html");
|
||||
JSCFABuilder builder = Util.makeHTMLCGBuilder(url);
|
||||
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||
Util.dumpCG(builder.getPointerAnalysis(), CG);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.ibm.wala.cast.test;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import com.ibm.wala.cast.loader.CAstAbstractLoader;
|
||||
import com.ibm.wala.classLoader.IClassLoader;
|
||||
import com.ibm.wala.classLoader.ModuleEntry;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.util.warnings.Warning;
|
||||
|
||||
public class Util {
|
||||
|
||||
public static void checkForFrontEndErrors(IClassHierarchy cha) {
|
||||
StringBuffer message = null;
|
||||
for(IClassLoader loader : cha.getLoaders()) {
|
||||
if (loader instanceof CAstAbstractLoader) {
|
||||
Iterator<ModuleEntry> errors = ((CAstAbstractLoader)loader).getModulesWithParseErrors();
|
||||
if (errors.hasNext()) {
|
||||
if (message == null) {
|
||||
message = new StringBuffer("front end errors:\n");
|
||||
}
|
||||
while (errors.hasNext()) {
|
||||
ModuleEntry errorModule = errors.next();
|
||||
for(Warning w : (((CAstAbstractLoader)loader).getMessages(errorModule))) {
|
||||
message.append("error in ").append(errorModule.getName()).append(":\n");
|
||||
message.append(w.toString()).append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (message != null) {
|
||||
message.append("end of front end errors\n");
|
||||
}
|
||||
Assert.assertTrue(String.valueOf(message), message == null);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 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.classLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import com.ibm.wala.util.collections.NonNullSingletonIterator;
|
||||
import com.ibm.wala.util.collections.Pair;
|
||||
|
||||
public class CompoundModule implements ModuleEntry, Module, SourceModule {
|
||||
private final SourceModule[] constituents;
|
||||
private final URL name;
|
||||
|
||||
public CompoundModule(URL name, SourceModule[] constituents) {
|
||||
this.name = name;
|
||||
this.constituents = constituents;
|
||||
}
|
||||
|
||||
public SourceModule[] getConstituents() {
|
||||
SourceModule[] stuff = new SourceModule[ constituents.length ];
|
||||
System.arraycopy(constituents, 0, stuff, 0, constituents.length);
|
||||
return stuff;
|
||||
}
|
||||
|
||||
public Iterator<ModuleEntry> getEntries() {
|
||||
return new NonNullSingletonIterator<ModuleEntry>(this);
|
||||
}
|
||||
|
||||
public boolean isModuleFile() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Module asModule() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name.toString();
|
||||
}
|
||||
|
||||
public URL getURL() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean isClassFile() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isSourceFile() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return new InputStream() {
|
||||
private int index = 0;
|
||||
private InputStream currentStream;
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
if (currentStream == null) {
|
||||
if (index < constituents.length) {
|
||||
currentStream = constituents[index++].getInputStream();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
int b = currentStream.read();
|
||||
if (b == -1) {
|
||||
currentStream = null;
|
||||
return read();
|
||||
}
|
||||
return b;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public class Reader extends java.io.Reader {
|
||||
private final List<Pair<Integer,URL>> locations = new ArrayList<Pair<Integer,URL>>();
|
||||
private int line = 0;
|
||||
private int index = 0;
|
||||
private LineNumberReader currentReader;
|
||||
private URL currentName;
|
||||
|
||||
@Override
|
||||
public int read(char[] cbuf, int off, int len) throws IOException {
|
||||
if (currentReader == null) {
|
||||
if (index < constituents.length) {
|
||||
currentName = constituents[index].getURL();
|
||||
currentReader = new LineNumberReader(new InputStreamReader(constituents[index++].getInputStream()));
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int x;
|
||||
if ((x = currentReader.read(cbuf, off, len)) == -1) {
|
||||
line += currentReader.getLineNumber();
|
||||
locations.add(Pair.make(line, currentName));
|
||||
|
||||
currentReader.close();
|
||||
currentReader = null;
|
||||
|
||||
return read(cbuf, off, len);
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (currentReader!= null) {
|
||||
currentReader.close();
|
||||
currentReader = null;
|
||||
}
|
||||
}
|
||||
|
||||
public Pair<Integer,URL> getOriginalPosition(int lineNumber) {
|
||||
int start = 0;
|
||||
for(int i = 0; i < locations.size(); i++) {
|
||||
if (locations.get(i).fst >= lineNumber) {
|
||||
return Pair.make(lineNumber - start, locations.get(i).snd);
|
||||
} else {
|
||||
start = locations.get(i).fst;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("line number " + lineNumber + " too high");
|
||||
}
|
||||
}
|
||||
|
||||
public Reader getInputReader() {
|
||||
return new Reader();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.ibm.wala.util.functions;
|
||||
|
||||
public interface VoidFunction<T> {
|
||||
|
||||
void apply(T v);
|
||||
|
||||
}
|
Loading…
Reference in New Issue