Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for analyzing multiple local modules (multi-module projects) by using PYTHONPATH #176

Merged
merged 41 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
4e1f622
Add `PYTHONPATH` to the analysis (#91)
khatchad Mar 26, 2024
6a8e718
Remove copy and paste error.
khatchad Mar 26, 2024
eb9975b
Merge branch 'master' into contrib_PYTHONPATH
khatchad Mar 27, 2024
7506af2
Remove redundant logs.
khatchad Mar 27, 2024
5bf8bd2
Fix logs.
khatchad Mar 27, 2024
c11f394
Guard against files that don't exist.
khatchad Mar 27, 2024
11dd298
Move variable.
khatchad Mar 27, 2024
57b1680
Use the filename if it's a source file module.
khatchad Mar 27, 2024
f9af063
Revert "Use the filename if it's a source file module."
khatchad Mar 28, 2024
b44526c
Add launch configuration.
khatchad Mar 29, 2024
c423159
Revert "Guard against files that don't exist."
khatchad Mar 29, 2024
a9bb846
Merge branch 'master' into contrib_PYTHONPATH
khatchad Mar 29, 2024
f8f3a04
Class tests for PYTHONPATH (#93)
khatchad Apr 1, 2024
2ec5e9d
Modify launch config.
khatchad Apr 2, 2024
ee55339
Fix build.
khatchad Apr 2, 2024
5b1e9fc
Pull up `PYTHONPATH` from `PythonLoader` subclasses refactoring.
khatchad Apr 3, 2024
544499d
Enhancements to PYTHONPATH.
khatchad Apr 8, 2024
9fbd8d1
Capitalize constant.
khatchad Apr 3, 2024
ce556df
Make more robust.
khatchad Apr 4, 2024
ad59ac0
Simplify lambda.
khatchad Apr 4, 2024
a23b4ad
Extract local variable refactoring.
khatchad Apr 2, 2024
d35b1dc
Revert "Extract local variable refactoring."
khatchad Apr 2, 2024
6cc6742
Localize log.
khatchad Apr 2, 2024
c5f1e13
Add log.
khatchad Apr 2, 2024
3794eb0
Use method references.
khatchad Apr 2, 2024
55e5ee8
Enhancements to PYTHONPATH.
khatchad Apr 8, 2024
0906a55
Fix merge error.
khatchad Apr 8, 2024
4353a2d
Update tests.
khatchad Apr 8, 2024
9bd0088
Merge branch 'master' into contrib_PYTHONPATH
khatchad Apr 9, 2024
696aa85
Remove added whitespace.
khatchad Apr 9, 2024
3d9856b
Handle relative imports (#97)
khatchad Apr 12, 2024
3a1551e
Modify tests for Jython3 only.
khatchad Apr 12, 2024
5329f4f
Merge branch 'master' into contrib_PYTHONPATH
khatchad Apr 12, 2024
b77e8ff
Merge branch 'master' into contrib_PYTHONPATH
khatchad Apr 16, 2024
c24fd94
Use method reference.
khatchad Apr 16, 2024
cf8775f
Rename method.
khatchad Apr 25, 2024
8560264
Merge branch 'master' into contrib_PYTHONPATH
khatchad Apr 25, 2024
e369a23
Extract method.
khatchad Apr 25, 2024
745970c
Extract method.
khatchad Apr 25, 2024
019cd40
Fix refactoring.
khatchad Apr 25, 2024
22260cf
Add javadoc.
khatchad Apr 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ protected TranslatorToCAst getTranslatorToCAst(CAst ast, ModuleEntry M, List<Mod
RewritingTranslatorToCAst x =
new RewritingTranslatorToCAst(
M,
new PythonModuleParser((SourceModule) M, typeDictionary, allModules) {
new PythonModuleParser(
(SourceModule) M, typeDictionary, allModules, this.getPythonPath()) {
@Override
public CAstEntity translateToCAst() throws Error, IOException {
CAstEntity ce = super.translateToCAst();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*****************************************************************************/
package com.ibm.wala.cast.python.parser;

import com.ibm.wala.cast.python.util.Util;
import com.ibm.wala.cast.tree.CAstEntity;
import com.ibm.wala.cast.tree.impl.CAstTypeDictionaryImpl;
import com.ibm.wala.cast.util.CAstPrinter;
Expand All @@ -18,13 +19,15 @@
import java.io.IOException;
import java.io.Reader;
import java.net.URL;
import java.util.List;

public class PythonFileParser extends PythonParser<File> {

private final File fileName;

public PythonFileParser(File fileName, CAstTypeDictionaryImpl<String> types) {
super(types);
public PythonFileParser(
File fileName, CAstTypeDictionaryImpl<String> types, List<File> pythonPath) {
super(types, pythonPath);
this.fileName = fileName;
}

Expand All @@ -43,8 +46,10 @@ protected WalaPythonParser makeParser() throws IOException {
}

public static void main(String[] args) throws Exception {
List<File> pythonPath = Util.getPathFiles(args[1]);

PythonParser<File> p =
new PythonFileParser(new File(args[0]), new CAstTypeDictionaryImpl<String>());
new PythonFileParser(new File(args[0]), new CAstTypeDictionaryImpl<String>(), pythonPath);
CAstEntity script = p.translateToCAst();
System.err.println(script);
System.err.println(CAstPrinter.print(script));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
*****************************************************************************/
package com.ibm.wala.cast.python.parser;

import com.ibm.wala.cast.python.util.Util;
import com.ibm.wala.cast.tree.CAstEntity;
import com.ibm.wala.cast.tree.impl.CAstTypeDictionaryImpl;
import com.ibm.wala.cast.util.CAstPrinter;
import com.ibm.wala.classLoader.Module;
import com.ibm.wala.classLoader.ModuleEntry;
import com.ibm.wala.classLoader.SourceModule;
import com.ibm.wala.classLoader.SourceURLModule;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
Expand All @@ -40,8 +42,11 @@ protected WalaPythonParser makeParser() throws IOException {
}

public PythonModuleParser(
SourceModule fileName, CAstTypeDictionaryImpl<String> types, List<Module> allModules) {
super(types);
SourceModule fileName,
CAstTypeDictionaryImpl<String> types,
List<Module> allModules,
List<File> pythonPath) {
super(types, pythonPath);
this.fileName = fileName;
}

Expand All @@ -52,11 +57,14 @@ protected String scriptName() {

public static void main(String[] args) throws Exception {
URL url = new URL(args[0]);
List<File> pythonPath = Util.getPathFiles(args[1]);

PythonParser<ModuleEntry> p =
new PythonModuleParser(
new SourceURLModule(url),
new CAstTypeDictionaryImpl<String>(),
Collections.singletonList(new SourceURLModule(url)));
Collections.singletonList(new SourceURLModule(url)),
pythonPath);
CAstEntity script = p.translateToCAst();
System.err.println(script);
System.err.println(CAstPrinter.print(script));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,12 @@
import com.ibm.wala.util.collections.HashMapFactory;
import com.ibm.wala.util.collections.HashSetFactory;
import com.ibm.wala.util.collections.ReverseIterator;
import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
Expand Down Expand Up @@ -1821,8 +1824,18 @@ public CAstNode visitYield(Yield arg0) throws Exception {

private final CAstTypeDictionaryImpl<String> types;

protected PythonParser(CAstTypeDictionaryImpl<String> types) {
/**
* The <a href="https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPATH">PYTHONPATH</a> to
* use in the analysis.
*
* @apiNote PYTHONPATH is currently only supported for Python 3.
* @see https://docs.python.org/3/tutorial/modules.html#the-module-search-path.
*/
protected java.util.List<File> pythonPath;

protected PythonParser(CAstTypeDictionaryImpl<String> types, java.util.List<File> pythonPath) {
this.types = types;
this.pythonPath = pythonPath;
}

@Override
Expand Down Expand Up @@ -1906,6 +1919,35 @@ public Position getPosition(int arg) {
public Position getNamePosition() {
return null;
}

@Override
public String getSignature() {
File file = this.getFile();
java.util.List<File> pythonPath = getPythonPath();

// If the PYTHONPATH isn't specified.
if (pythonPath.isEmpty())
// Revert to just the name.
return this.getName();

for (File pathEntry : pythonPath) {
String pathEntryAbsolutePath = pathEntry.getAbsoluteFile().getPath();
// Remove protocol.
pathEntryAbsolutePath = pathEntryAbsolutePath.replaceFirst("file:.*!/", "");

String fileAbsolutePath = file.getAbsolutePath();

if (fileAbsolutePath.startsWith(pathEntryAbsolutePath)) {
// Found it.
Path filePath = Paths.get(fileAbsolutePath);
Path pathEntryPath = Paths.get(pathEntryAbsolutePath);

Path scriptRelativePath = pathEntryPath.relativize(filePath);
return "script " + scriptRelativePath.toString();
}
}
return null; // Not found.
}
};

return script;
Expand All @@ -1924,4 +1966,16 @@ public String getMsg() {
public void print(PyObject ast) {
System.err.println(ast.getClass());
}

/**
* Gets the <a
* href="https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPATH">PYTHONPATH</a> to use in
* the analysis.
*
* @apiNote PYTHONPATH is currently only supported for Python 3.
* @see https://docs.python.org/3/tutorial/modules.html#the-module-search-path.
*/
public java.util.List<File> getPythonPath() {
return pythonPath;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.ibm.wala.cast.python.client;

import static java.util.Collections.emptyList;

import com.ibm.wala.cast.python.loader.PytestLoader;
import com.ibm.wala.cast.python.loader.PytestLoaderFactory;
import com.ibm.wala.classLoader.CallSiteReference;
Expand All @@ -18,6 +20,8 @@
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
import com.ibm.wala.util.CancelException;
import com.ibm.wala.util.intset.OrdinalSet;
import java.io.File;
import java.util.List;

public class PytestAnalysisEngine<T> extends PythonAnalysisEngine<T> {

Expand Down Expand Up @@ -72,8 +76,11 @@ public IMethod getCalleeTarget(CGNode caller, CallSiteReference site, IClass rec
}

public PytestAnalysisEngine() {
super();
loader = new PytestLoaderFactory();
loader = new PytestLoaderFactory(emptyList());
}

public PytestAnalysisEngine(List<File> pythonPath) {
loader = new PytestLoaderFactory(pythonPath);
}

protected void addBypassLogic(IClassHierarchy cha, AnalysisOptions options) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.collections.HashMapFactory;
import com.ibm.wala.util.collections.Pair;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
Expand All @@ -33,8 +35,8 @@ public class PytestLoader extends Python3Loader {

private final Map<String, Map<String, Integer>> testParams = HashMapFactory.make();

public PytestLoader(IClassHierarchy cha) {
super(cha);
public PytestLoader(IClassHierarchy cha, List<File> pythonPath) {
super(cha, pythonPath);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,37 @@

import com.ibm.wala.classLoader.IClassLoader;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import java.io.File;
import java.util.List;

public class PytestLoaderFactory extends PythonLoaderFactory {

/**
* The <a
* href="https://docs.python.org/3/tutorial/modules.html#the-module-search-path">PYTHONPATH</a> to
* use in the analysis.
*
* @apiNote PYTHONPATH is currently only supported for Python 3.
*/
protected List<File> pythonPath;

public PytestLoaderFactory(List<File> pythonPath) {
this.pythonPath = pythonPath;
}

@Override
protected IClassLoader makeTheLoader(IClassHierarchy cha) {
return new PytestLoader(cha);
return new PytestLoader(cha, this.getPythonPath());
}

/**
* Gets the <a
* href="https://docs.python.org/3/tutorial/modules.html#the-module-search-path">PYTHONPATH</a> to
* use in the analysis.
*
* @apiNote PYTHONPATH is currently only supported for Python 3.
*/
public List<File> getPythonPath() {
return pythonPath;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,19 @@
import com.ibm.wala.classLoader.ModuleEntry;
import com.ibm.wala.classLoader.SourceModule;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.python.core.PyObject;

public class Python3Loader extends PythonLoader {
public Python3Loader(IClassHierarchy cha, IClassLoader parent) {
super(cha, parent);

public Python3Loader(IClassHierarchy cha, IClassLoader parent, List<File> pythonPath) {
super(cha, parent, pythonPath);
}

public Python3Loader(IClassHierarchy cha) {
super(cha);
public Python3Loader(IClassHierarchy cha, List<File> pythonPath) {
super(cha, pythonPath);
}

@Override
Expand All @@ -48,7 +50,8 @@ protected TranslatorToCAst getTranslatorToCAst(CAst ast, ModuleEntry M, List<Mod
RewritingTranslatorToCAst x =
new RewritingTranslatorToCAst(
M,
new PythonModuleParser((SourceModule) M, typeDictionary, allModules) {
new PythonModuleParser(
(SourceModule) M, typeDictionary, allModules, this.getPythonPath()) {
@Override
public CAstEntity translateToCAst() throws Error, IOException {
CAstEntity ce = super.translateToCAst();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,38 @@

import com.ibm.wala.classLoader.IClassLoader;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import java.io.File;
import java.util.List;

public class Python3LoaderFactory extends PythonLoaderFactory {

/**
* The <a href="https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPATH">PYTHONPATH</a> to
* use in the analysis.
*
* @apiNote PYTHONPATH is currently only supported for Python 3.
* @see https://docs.python.org/3/tutorial/modules.html#the-module-search-path.
*/
protected List<File> pythonPath;

public Python3LoaderFactory(List<File> pythonPath) {
this.pythonPath = pythonPath;
}

@Override
protected IClassLoader makeTheLoader(IClassHierarchy cha) {
return new Python3Loader(cha);
return new Python3Loader(cha, this.getPythonPath());
}

/**
* Gets the <a
* href="https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPATH">PYTHONPATH</a> to use in
* the analysis.
*
* @apiNote PYTHONPATH is currently only supported for Python 3.
* @see https://docs.python.org/3/tutorial/modules.html#the-module-search-path.
*/
public List<File> getPythonPath() {
return pythonPath;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*****************************************************************************/
package com.ibm.wala.cast.python.parser;

import com.ibm.wala.cast.python.util.Util;
import com.ibm.wala.cast.tree.CAstEntity;
import com.ibm.wala.cast.tree.impl.CAstTypeDictionaryImpl;
import com.ibm.wala.cast.util.CAstPrinter;
Expand All @@ -18,13 +19,15 @@
import java.io.IOException;
import java.io.Reader;
import java.net.URL;
import java.util.List;

public class PythonFileParser extends PythonParser<File> {

private final File fileName;

public PythonFileParser(File fileName, CAstTypeDictionaryImpl<String> types) {
super(types);
public PythonFileParser(
File fileName, CAstTypeDictionaryImpl<String> types, List<File> pythonPath) {
super(types, pythonPath);
this.fileName = fileName;
}

Expand All @@ -43,8 +46,10 @@ protected WalaPythonParser makeParser() throws IOException {
}

public static void main(String[] args) throws Exception {
List<File> pythonPath = Util.getPathFiles(args[1]);

PythonParser<File> p =
new PythonFileParser(new File(args[0]), new CAstTypeDictionaryImpl<String>());
new PythonFileParser(new File(args[0]), new CAstTypeDictionaryImpl<String>(), pythonPath);
CAstEntity script = p.translateToCAst();
System.err.println(script);
System.err.println(CAstPrinter.print(script));
Expand Down
Loading
Loading