├── src
├── main
│ ├── java
│ │ ├── utils
│ │ │ ├── sacha
│ │ │ │ ├── finder
│ │ │ │ │ ├── classes
│ │ │ │ │ │ ├── ClassFinder.java
│ │ │ │ │ │ └── impl
│ │ │ │ │ │ │ ├── ClassloaderFinder.java
│ │ │ │ │ │ │ ├── ProjectFinder.java
│ │ │ │ │ │ │ ├── ClasspathFinder.java
│ │ │ │ │ │ │ └── SourceFolderFinder.java
│ │ │ │ │ ├── filters
│ │ │ │ │ │ ├── utils
│ │ │ │ │ │ │ └── TestType.java
│ │ │ │ │ │ ├── ClassFilter.java
│ │ │ │ │ │ └── impl
│ │ │ │ │ │ │ ├── AcceptAllFilter.java
│ │ │ │ │ │ │ └── TestFilter.java
│ │ │ │ │ ├── main
│ │ │ │ │ │ ├── TestInClasspath.java
│ │ │ │ │ │ ├── TestInFolder.java
│ │ │ │ │ │ ├── TestMain.java
│ │ │ │ │ │ ├── Main.java
│ │ │ │ │ │ ├── TestInURLClassloader.java
│ │ │ │ │ │ └── TestClassFinder.java
│ │ │ │ │ └── processor
│ │ │ │ │ │ └── Processor.java
│ │ │ │ ├── project
│ │ │ │ │ └── utils
│ │ │ │ │ │ └── IMavenMerger.java
│ │ │ │ ├── interfaces
│ │ │ │ │ ├── IGeneralToJava.java
│ │ │ │ │ ├── IEclipseConfigurable.java
│ │ │ │ │ ├── ITestResult.java
│ │ │ │ │ ├── IRunner.java
│ │ │ │ │ └── ISpooner.java
│ │ │ │ ├── mains
│ │ │ │ │ ├── RepairLoop1.java
│ │ │ │ │ ├── MergeMavenProjects.java
│ │ │ │ │ ├── EclipseGeneralToJavaProject.java
│ │ │ │ │ ├── TestFinderMain.java
│ │ │ │ │ ├── TestRunnerMain.java
│ │ │ │ │ ├── RunSpoonWithClasspath.java
│ │ │ │ │ ├── TestSuiteGeneratorMain.java
│ │ │ │ │ └── CheckLoopMain.java
│ │ │ │ ├── impl
│ │ │ │ │ ├── TestFinderCore.java
│ │ │ │ │ ├── TestRunnerCore.java
│ │ │ │ │ ├── TestSuiteCreatorCore.java
│ │ │ │ │ ├── DefaultSpooner.java
│ │ │ │ │ └── AbstractConfigurator.java
│ │ │ │ ├── classloader
│ │ │ │ │ └── factory
│ │ │ │ │ │ └── ClassloaderFactory.java
│ │ │ │ ├── utils
│ │ │ │ │ └── SachaDocumentationGenerator.java
│ │ │ │ └── runner
│ │ │ │ │ └── utils
│ │ │ │ │ └── TestInfo.java
│ │ │ └── org
│ │ │ │ └── eclipse
│ │ │ │ └── core
│ │ │ │ └── internal
│ │ │ │ └── localstore
│ │ │ │ └── ILocalStoreConstants.java
│ │ └── fr
│ │ │ └── inria
│ │ │ └── spirals
│ │ │ └── npefix
│ │ │ ├── resi
│ │ │ ├── strategies
│ │ │ │ ├── ReturnType.java
│ │ │ │ ├── Strat1A.java
│ │ │ │ ├── Strat1B.java
│ │ │ │ ├── Strat2A.java
│ │ │ │ ├── Strat2B.java
│ │ │ │ ├── NoStrat.java
│ │ │ │ ├── Strategy.java
│ │ │ │ ├── Strat3.java
│ │ │ │ ├── Strat2.java
│ │ │ │ ├── ArrayReadFirst.java
│ │ │ │ ├── ArrayReadLast.java
│ │ │ │ ├── ArrayReadReturnNull.java
│ │ │ │ ├── Strat1.java
│ │ │ │ └── Strat4.java
│ │ │ ├── oracle
│ │ │ │ ├── ExceptionOracle.java
│ │ │ │ ├── Oracle.java
│ │ │ │ ├── TestOracle.java
│ │ │ │ └── AbstractOracle.java
│ │ │ ├── context
│ │ │ │ ├── ConstructorContext.java
│ │ │ │ ├── instance
│ │ │ │ │ ├── Instance.java
│ │ │ │ │ ├── PrimitiveInstance.java
│ │ │ │ │ ├── ArrayReadInstance.java
│ │ │ │ │ ├── VariableInstance.java
│ │ │ │ │ ├── AbstractInstance.java
│ │ │ │ │ ├── InstanceFactory.java
│ │ │ │ │ └── StaticVariableInstance.java
│ │ │ │ ├── TryContext.java
│ │ │ │ ├── MethodContext.java
│ │ │ │ ├── Location.java
│ │ │ │ └── NPEOutput.java
│ │ │ ├── selector
│ │ │ │ ├── NoMoreDecisionException.java
│ │ │ │ ├── RegressionSelector.java
│ │ │ │ ├── Selector.java
│ │ │ │ ├── SafeMonoSelector.java
│ │ │ │ ├── DomSelector.java
│ │ │ │ ├── RandomSelector.java
│ │ │ │ ├── AbstractSelector.java
│ │ │ │ └── MonoExplorerSelector.java
│ │ │ ├── exception
│ │ │ │ ├── AbnormalExecutionError.java
│ │ │ │ ├── VarNotFound.java
│ │ │ │ ├── NoMoreDecision.java
│ │ │ │ ├── NPEFixError.java
│ │ │ │ ├── ReturnNotSupported.java
│ │ │ │ ├── ForceReturn.java
│ │ │ │ └── ErrorInitClass.java
│ │ │ ├── RandomGenerator.java
│ │ │ └── ExceptionStack.java
│ │ │ ├── patch
│ │ │ ├── sorter
│ │ │ │ ├── tokenizer
│ │ │ │ │ ├── Tokenizer.java
│ │ │ │ │ ├── AbstractTokenizer.java
│ │ │ │ │ ├── FullTokenizer.java
│ │ │ │ │ ├── TokenTypeTokenizer.java
│ │ │ │ │ ├── BinaryTokenizer.java
│ │ │ │ │ ├── RenameOperatorTokenizer.java
│ │ │ │ │ ├── RenameSyntaxTokenizer.java
│ │ │ │ │ ├── RenameLiteralTokenizer.java
│ │ │ │ │ ├── RenameIdentifierLiteralTokenizer.java
│ │ │ │ │ ├── RenameIdentifierTokenizer.java
│ │ │ │ │ └── RenameSyntaxKeywordTokenizer.java
│ │ │ │ ├── Token.java
│ │ │ │ ├── SingleFileTokenIterator.java
│ │ │ │ ├── StringTokensCreator.java
│ │ │ │ ├── algorithm
│ │ │ │ │ ├── Laplace.java
│ │ │ │ │ ├── Algorithm.java
│ │ │ │ │ ├── NGram.java
│ │ │ │ │ └── KneserNey.java
│ │ │ │ ├── FileTokensCreator.java
│ │ │ │ ├── TokenImpl.java
│ │ │ │ └── Experiment.java
│ │ │ ├── DecisionElement.java
│ │ │ ├── PositionScanner.java
│ │ │ └── generator
│ │ │ │ └── Writer.java
│ │ │ ├── transformer
│ │ │ ├── utils
│ │ │ │ ├── CtTryGenerated.java
│ │ │ │ └── CtThrowGenerated.java
│ │ │ └── processors
│ │ │ │ ├── ArrayRead.java
│ │ │ │ ├── IfSplitter.java
│ │ │ │ ├── ConstructorTryCatchRepair.java
│ │ │ │ ├── ForceNullInit.java
│ │ │ │ ├── TryCatchRepair.java
│ │ │ │ └── VariableFor.java
│ │ │ ├── patchTemplate
│ │ │ ├── template
│ │ │ │ ├── PatchTemplate.java
│ │ │ │ ├── SkipLine.java
│ │ │ │ ├── ReplaceGlobal.java
│ │ │ │ ├── ReplaceLocal.java
│ │ │ │ └── SkipMethodReturn.java
│ │ │ └── ThisFinder.java
│ │ │ └── main
│ │ │ ├── all
│ │ │ ├── RepairStrategy.java
│ │ │ └── TryCatchRepairStrategy.java
│ │ │ ├── DecisionServer.java
│ │ │ ├── spoon
│ │ │ └── MainSpoon.java
│ │ │ └── ExecutionClient.java
│ └── resources
│ │ └── config.ini
├── test
│ ├── java
│ │ └── fr
│ │ │ └── inria
│ │ │ └── spirals
│ │ │ └── npefix
│ │ │ ├── patchTemplate
│ │ │ ├── testClasses
│ │ │ │ ├── ParentClass.java
│ │ │ │ └── ChildClassSamePackage.java
│ │ │ ├── SkipLineTest.java
│ │ │ ├── ReplaceGlobalTest.java
│ │ │ ├── SkipMethodReturnTest.java
│ │ │ └── ReplaceLocalTest.java
│ │ │ ├── transformer
│ │ │ └── processors
│ │ │ │ ├── ArrayAccessTest.java
│ │ │ │ ├── CheckNotNullTest.java
│ │ │ │ ├── TernarySplitterTest.java
│ │ │ │ ├── ImplicitCastCheckerTest.java
│ │ │ │ ├── ConstructorEncapsulationTest.java
│ │ │ │ ├── TargetModifierTest.java
│ │ │ │ └── BeforeDerefAdderTest.java
│ │ │ └── main
│ │ │ └── all
│ │ │ └── End2EndTest.java
│ └── resources
│ │ ├── foo
│ │ └── src
│ │ │ ├── main
│ │ │ └── java
│ │ │ │ ├── Foo2.java
│ │ │ │ ├── FooArrayAccess.java
│ │ │ │ ├── FooTernary.java
│ │ │ │ ├── ImplicitCast.java
│ │ │ │ └── Foo.java
│ │ │ └── test
│ │ │ └── java
│ │ │ ├── FooArrayAccessTest.java
│ │ │ └── FooClassTest.java
│ │ └── bar
│ │ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── Coneflower.java
│ │ └── test
│ │ └── java
│ │ └── ConeflowerTest.java
└── evaluation
│ └── java
│ └── fr
│ └── inria
│ └── spirals
│ └── npefix
│ ├── resi
│ └── selector
│ │ ├── ExplorationSelectorEvaluation.java
│ │ ├── GreedySelectorEvaluation.java
│ │ ├── RandomSelectorEvaluation.java
│ │ ├── MonoExplorationEvaluation.java
│ │ └── DomSelectorEvaluation.java
│ └── SafeMonoEvaluation.java
├── .travis-settings.xml
├── .gitignore
├── .github
└── workflows
│ └── maven.yml
├── CITATION.cff
├── targets
├── .travis.yml
└── count.py
/src/main/java/utils/sacha/finder/classes/ClassFinder.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.finder.classes;
2 |
3 | public interface ClassFinder {
4 |
5 | String[] getClasses();
6 | }
7 |
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/project/utils/IMavenMerger.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.project.utils;
2 |
3 | public interface IMavenMerger {
4 |
5 | public void merge();
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/resi/strategies/ReturnType.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.strategies;
2 |
3 | public enum ReturnType {
4 | NULL, NEW, VAR, VOID
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/interfaces/IGeneralToJava.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.interfaces;
2 |
3 | public interface IGeneralToJava {
4 |
5 | public void changeToJava();
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/.travis-settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | github
5 | ${env.GITHUB_PASSWORD}
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/finder/filters/utils/TestType.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.finder.filters.utils;
2 |
3 | public enum TestType {
4 | TEST_CLASSES, RUN_WITH_CLASSES, JUNIT38_TEST_CLASSES
5 | }
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/interfaces/IEclipseConfigurable.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.interfaces;
2 |
3 | public interface IEclipseConfigurable {
4 |
5 | void setEclipseMetadataFolder(String folderName);
6 |
7 | void setEclipseProject(String projectName);
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/patch/sorter/tokenizer/Tokenizer.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.patch.sorter.tokenizer;
2 |
3 | import fr.inria.spirals.npefix.patch.sorter.Token;
4 |
5 | public interface Tokenizer {
6 |
7 | String computeRepresentation(Token token);
8 | }
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/interfaces/ITestResult.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.interfaces;
2 |
3 | import org.junit.runner.Result;
4 |
5 | public interface ITestResult {
6 |
7 | int getNbRunTests();
8 |
9 | int getNbFailedTests();
10 |
11 | Result getResult();
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/finder/filters/ClassFilter.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.finder.filters;
2 |
3 | public interface ClassFilter {
4 | boolean acceptClass(Class> clazz);
5 | boolean acceptClassName(String className);
6 | boolean acceptInnerClass();
7 | boolean searchInJars();
8 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | output/
3 | gh-pages
4 | pom.xml.tag
5 | pom.xml.releaseBackup
6 | pom.xml.versionsBackup
7 | pom.xml.next
8 | release.properties
9 | dependency-reduced-pom.xml
10 | buildNumber.properties
11 | .mvn/timing.properties
12 |
13 | bin
14 | target
15 | *.iml
16 | .idea
17 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/resi/oracle/ExceptionOracle.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.oracle;
2 |
3 | public class ExceptionOracle extends AbstractOracle {
4 |
5 | public ExceptionOracle(Exception e) {
6 | super("exception", false);
7 | setError(printException(e));
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/resi/context/ConstructorContext.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.context;
2 |
3 | public class ConstructorContext extends MethodContext {
4 | public ConstructorContext(Class c, int line, int sourceStart, int sourceEnd) {
5 | super(c, line, sourceStart, sourceEnd);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/resi/oracle/Oracle.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.oracle;
2 |
3 | import org.json.JSONObject;
4 |
5 | import java.io.Serializable;
6 |
7 | public interface Oracle extends Serializable {
8 | boolean isValid();
9 |
10 | String getError();
11 |
12 | JSONObject toJSON();
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/resi/selector/NoMoreDecisionException.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.selector;
2 |
3 | /**
4 | * Created by thomas on 11/10/16.
5 | */
6 | public class NoMoreDecisionException extends RuntimeException {
7 | public NoMoreDecisionException(String s) {
8 | super(s);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/mains/RepairLoop1.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.mains;
2 |
3 | /** Is a basic example on how having the repair loop modification -> test suite (TODO Matias) */
4 | public class RepairLoop1 {
5 |
6 | public static void main(String[] args) {
7 | throw new UnsupportedOperationException();
8 | }
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/src/test/java/fr/inria/spirals/npefix/patchTemplate/testClasses/ParentClass.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.patchTemplate.testClasses;
2 |
3 | public class ParentClass {
4 | public String publicParentField;
5 | private String privateParentField;
6 | protected String protectedParentField;
7 | String defaultParentField;
8 | }
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/transformer/utils/CtTryGenerated.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.transformer.utils;
2 |
3 | import spoon.support.reflect.code.CtTryImpl;
4 |
5 | public class CtTryGenerated extends CtTryImpl {
6 |
7 | /**
8 | *
9 | */
10 | private static final long serialVersionUID = 1L;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/resi/selector/RegressionSelector.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.selector;
2 |
3 | import fr.inria.spirals.npefix.resi.context.Lapse;
4 |
5 | import java.rmi.RemoteException;
6 |
7 | public interface RegressionSelector extends Selector {
8 | void setLapse(Lapse lapse) throws RemoteException;
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/resi/strategies/Strat1A.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.strategies;
2 |
3 | /**
4 | * b.foo
5 | * @author bcornu
6 | *
7 | */
8 | public class Strat1A extends Strat1 {
9 | @Override
10 | public boolean isCompatibleAction(ACTION action) {
11 | return action.equals(ACTION.isCalled);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/resi/exception/AbnormalExecutionError.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.exception;
2 |
3 | public class AbnormalExecutionError extends NPEFixError {
4 |
5 | public AbnormalExecutionError(){
6 | super();
7 | }
8 |
9 | public AbnormalExecutionError(String string) {
10 | super(string);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/resi/strategies/Strat1B.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.strategies;
2 |
3 | /**
4 | * a=b
5 | * @author bcornu
6 | *
7 | */
8 | public class Strat1B extends Strat1 {
9 |
10 | @Override
11 | public boolean isCompatibleAction(ACTION action) {
12 | return action.equals(ACTION.beforeCalled);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/resi/strategies/Strat2A.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.strategies;
2 |
3 | /**
4 | * new A.foo
5 | * @author bcornu
6 | *
7 | */
8 | public class Strat2A extends Strat2 {
9 |
10 | @Override
11 | public boolean isCompatibleAction(ACTION action) {
12 | return action.equals(ACTION.isCalled);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/resi/strategies/Strat2B.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.strategies;
2 |
3 | /**
4 | * a=new A
5 | * @author bcornu
6 | *
7 | */
8 | public class Strat2B extends Strat2 {
9 |
10 | @Override
11 | public boolean isCompatibleAction(ACTION action) {
12 | return action.equals(ACTION.beforeCalled);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/resources/config.ini:
--------------------------------------------------------------------------------
1 | # in sec
2 | iteration.timeout = 5
3 | iteration.count = 10000
4 |
5 | server.port = 10000
6 | server.host = 127.0.0.1
7 | server.name = Selector
8 |
9 | evaluation.datasetRoot = ../npedataset/
10 | evaluation.workingDirectory = /tmp/npefix/
11 | evaluation.m2Root = ~/.m2/
12 |
13 | selector.greedy.epsilon = 0.2
14 |
15 | random.seed = 10
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/transformer/utils/CtThrowGenerated.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.transformer.utils;
2 |
3 | import spoon.support.reflect.code.CtThrowImpl;
4 |
5 | public class CtThrowGenerated extends CtThrowImpl{
6 |
7 | /**
8 | * generated
9 | */
10 | private static final long serialVersionUID = 5737541619010329164L;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/src/test/resources/foo/src/main/java/Foo2.java:
--------------------------------------------------------------------------------
1 | import java.util.ArrayList;
2 | import java.util.Arrays;
3 | import java.util.List;
4 |
5 | public class Foo2 {
6 | public String field = null;
7 | public String[] array = null;
8 |
9 | public Foo2() {
10 | super();
11 | field.toString();
12 | field = null;
13 | array = null;
14 | }
15 | }
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/resi/exception/VarNotFound.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.exception;
2 |
3 | /**
4 | * Created by thomas on 15/10/15.
5 | */
6 | public class VarNotFound extends NPEFixError {
7 | public VarNotFound(){
8 | super();
9 | }
10 |
11 | public VarNotFound(String string) {
12 | super(string);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/interfaces/IRunner.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.interfaces;
2 |
3 | public interface IRunner {
4 |
5 | /** setEclipseClassPath must have been called before */
6 | utils.sacha.interfaces.ITestResult runAllTestsInClasspath();
7 |
8 | /** dir must be valid source folder */
9 | utils.sacha.interfaces.ITestResult runAllTestsInDirectory(String dir);
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/patch/sorter/tokenizer/AbstractTokenizer.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.patch.sorter.tokenizer;
2 |
3 | public abstract class AbstractTokenizer implements Tokenizer {
4 |
5 |
6 | public AbstractTokenizer() {
7 | }
8 |
9 | @Override
10 | public String toString() {
11 | return getClass().getSimpleName().replace("Tokenizer", "");
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/resi/exception/NoMoreDecision.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.exception;
2 |
3 | /**
4 | * Created by thomas on 15/10/15.
5 | */
6 | public class NoMoreDecision extends NPEFixError {
7 | public NoMoreDecision(){
8 | super();
9 | }
10 |
11 | public NoMoreDecision(String string) {
12 | super(string);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/resi/exception/NPEFixError.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.exception;
2 |
3 | public class NPEFixError extends Error {
4 |
5 | public NPEFixError(){
6 | super();
7 | }
8 |
9 | public NPEFixError(String string) {
10 | super(string);
11 | }
12 |
13 | public NPEFixError(String string, Throwable t) {
14 | super(string, t);
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/resi/exception/ReturnNotSupported.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.exception;
2 |
3 | /**
4 | * Created by thomas on 15/10/15.
5 | */
6 | public class ReturnNotSupported extends NPEFixError {
7 | public ReturnNotSupported(){
8 | super();
9 | }
10 |
11 | public ReturnNotSupported(String string) {
12 | super(string);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/finder/main/TestInClasspath.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.finder.main;
2 |
3 | import utils.sacha.finder.classes.impl.ClasspathFinder;
4 | import utils.sacha.finder.filters.impl.TestFilter;
5 | import utils.sacha.finder.processor.Processor;
6 |
7 | public class TestInClasspath{
8 |
9 | public Class>[] find(){
10 | return new Processor(new ClasspathFinder(), new TestFilter()).process();
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/patch/sorter/tokenizer/FullTokenizer.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.patch.sorter.tokenizer;
2 |
3 | import fr.inria.spirals.npefix.patch.sorter.Token;
4 |
5 | /**
6 | * the unmodified list of token
7 | */
8 | public class FullTokenizer extends AbstractTokenizer {
9 |
10 | @Override
11 | public String computeRepresentation(Token token) {
12 | return token.getValue();
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/resi/exception/ForceReturn.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.exception;
2 |
3 | import fr.inria.spirals.npefix.resi.context.Decision;
4 |
5 | public class ForceReturn extends RuntimeException {
6 | private Decision decision;
7 |
8 | public ForceReturn(Decision decision) {
9 | this.decision = decision;
10 | }
11 |
12 | public Decision getDecision() {
13 | return decision;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/patch/sorter/tokenizer/TokenTypeTokenizer.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.patch.sorter.tokenizer;
2 |
3 | import fr.inria.spirals.npefix.patch.sorter.Token;
4 |
5 | /**
6 | * a list of token types, ect PAREN, ID, OPERATOR
7 | */
8 | public class TokenTypeTokenizer extends AbstractTokenizer {
9 |
10 | @Override
11 | public String computeRepresentation(Token token) {
12 | return token.getType() + "";
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/resi/context/instance/Instance.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.context.instance;
2 |
3 | import org.json.JSONObject;
4 | import spoon.reflect.code.CtExpression;
5 | import spoon.reflect.factory.Factory;
6 |
7 | import java.io.Serializable;
8 |
9 | public interface Instance extends Serializable, Comparable {
10 | T getValue();
11 |
12 | CtExpression toCtExpression(Factory factory);
13 |
14 | JSONObject toJSON();
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/interfaces/ISpooner.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.interfaces;
2 |
3 | public interface ISpooner extends IEclipseConfigurable {
4 |
5 | void spoon();
6 |
7 | void setOutputFolder(String folderPath);
8 |
9 | void setProcessors(String... processorNames);
10 |
11 | void setProcessors(Class... processor);
12 |
13 | /** must be set before spooning */
14 | void setSourceFolder(String... sources);
15 |
16 | void setGraphicalOutput(boolean b);
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/resi/exception/ErrorInitClass.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.exception;
2 |
3 | /**
4 | * Created by thomas on 15/10/15.
5 | */
6 | public class ErrorInitClass extends NPEFixError {
7 | public ErrorInitClass(){
8 | super();
9 | }
10 |
11 | public ErrorInitClass(String string) {
12 | super(string);
13 | }
14 | public ErrorInitClass(String string, Throwable t) {
15 | super(string, t);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/patch/sorter/tokenizer/BinaryTokenizer.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.patch.sorter.tokenizer;
2 |
3 | import fr.inria.spirals.npefix.patch.sorter.Token;
4 |
5 | /**
6 | * a suite of IDs or Java keywords
7 | */
8 | public class BinaryTokenizer extends AbstractTokenizer {
9 |
10 | @Override
11 | public String computeRepresentation(Token token) {
12 | if (token.isOperator() || token.isKeyword()) {
13 | return "JAVA$";
14 | }
15 | return "ID$";
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/mains/MergeMavenProjects.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.mains;
2 |
3 | import utils.sacha.project.utils.MavenModulesMerger;
4 |
5 | /** Merges Maven projects in one single Eclipse project */
6 | public class MergeMavenProjects {
7 |
8 | public static void main(String[] args) {
9 | MavenModulesMerger merger = new MavenModulesMerger();
10 | merger.setEclipseMetadataFolder("/home/bcornu/workspace/.metadata");
11 | merger.setEclipseProject("find-sec-bugs");
12 | merger.merge();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/patch/sorter/tokenizer/RenameOperatorTokenizer.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.patch.sorter.tokenizer;
2 |
3 | import fr.inria.spirals.npefix.patch.sorter.Token;
4 | /**
5 | * literals are abstracted as LIT$1,LIT$2, etc
6 | */
7 | public class RenameOperatorTokenizer extends AbstractTokenizer {
8 |
9 | @Override
10 | public String computeRepresentation(Token token) {
11 | if (token.isOperator()) {
12 | return ("OP");
13 | }
14 | return token.getValue();
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/patch/sorter/tokenizer/RenameSyntaxTokenizer.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.patch.sorter.tokenizer;
2 |
3 | import fr.inria.spirals.npefix.patch.sorter.Token;
4 |
5 | /**
6 | * literals are abstracted as LIT$1,LIT$2, etc
7 | */
8 | public class RenameSyntaxTokenizer extends AbstractTokenizer {
9 |
10 | @Override
11 | public String computeRepresentation(Token token) {
12 | if (token.isSyntax()) {
13 | return ("SYN$");
14 | }
15 | return token.getValue();
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/test/java/fr/inria/spirals/npefix/transformer/processors/ArrayAccessTest.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.transformer.processors;
2 |
3 | import org.junit.Test;
4 | import spoon.Launcher;
5 |
6 | public class ArrayAccessTest {
7 |
8 | @Test
9 | public void test() {
10 | Launcher spoon = new Launcher();
11 | spoon.addInputResource("src/test/resources/foo/src/main/java/");
12 | spoon.addProcessor(new ArrayRead());
13 | spoon.setSourceOutputDirectory("target/instrumented");
14 |
15 | spoon.run();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/.github/workflows/maven.yml:
--------------------------------------------------------------------------------
1 | name: CI with Maven
2 |
3 | on:
4 | push:
5 | branches: [ "master" ]
6 | pull_request:
7 | branches: [ "master" ]
8 |
9 | jobs:
10 | build:
11 |
12 | runs-on: ubuntu-latest
13 |
14 | steps:
15 | - uses: actions/checkout@v4
16 | - name: Set up Java
17 | uses: actions/setup-java@v4
18 | with:
19 | java-version: '17'
20 | distribution: 'temurin'
21 | cache: maven
22 | - name: Build with Maven
23 | run: mvn -B package --file pom.xml
24 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/patch/sorter/tokenizer/RenameLiteralTokenizer.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.patch.sorter.tokenizer;
2 |
3 | import fr.inria.spirals.npefix.patch.sorter.Token;
4 |
5 | /**
6 | * literals are abstracted as LIT$1,LIT$2, etc
7 | */
8 | public class RenameLiteralTokenizer extends AbstractTokenizer {
9 |
10 | @Override
11 | public String computeRepresentation(Token token) {
12 | if (token.isLiteral()) {
13 | return ("LIT$");
14 | }
15 | return token.getValue();
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/test/java/fr/inria/spirals/npefix/transformer/processors/CheckNotNullTest.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.transformer.processors;
2 |
3 | import org.junit.Test;
4 | import spoon.Launcher;
5 |
6 | public class CheckNotNullTest {
7 |
8 | @Test
9 | public void test() {
10 | Launcher spoon = new Launcher();
11 | spoon.addInputResource("src/test/resources/foo/src/main/java/");
12 | spoon.addProcessor(new CheckNotNull());
13 | spoon.setSourceOutputDirectory("target/instrumented");
14 |
15 | spoon.run();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/mains/EclipseGeneralToJavaProject.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.mains;
2 |
3 | import utils.sacha.impl.GeneralToJavaCore;
4 |
5 |
6 | /** Manipulates Eclipse projects (nature, classpath, etc. **/
7 | public class EclipseGeneralToJavaProject {
8 |
9 | public static void main(String[] args) {
10 | GeneralToJavaCore core = new GeneralToJavaCore();
11 | core.setEclipseMetadataFolder("/home/bcornu/workspace/.metadata");
12 | core.setEclipseProject("jmeter-maven-plugin");
13 | core.changeToJava();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/impl/TestFinderCore.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.impl;
2 |
3 | import utils.sacha.classloader.enrich.EnrichableClassloader;
4 | import utils.sacha.finder.main.TestClassFinder;
5 |
6 | public class TestFinderCore extends AbstractConfigurator {
7 |
8 | public Class>[] findTestClasses() {
9 | EnrichableClassloader eClassloader = getEnrichableClassloader();
10 |
11 | Thread.currentThread().setContextClassLoader(eClassloader);
12 |
13 | return new TestClassFinder(eClassloader).findTestClasses();
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/evaluation/java/fr/inria/spirals/npefix/resi/selector/ExplorationSelectorEvaluation.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.selector;
2 |
3 | import fr.inria.spirals.npefix.resi.CallChecker;
4 | import fr.inria.spirals.npefix.resi.RandomGenerator;
5 | import org.junit.Before;
6 |
7 | public class ExplorationSelectorEvaluation extends AbstractSelectorEvaluation {
8 |
9 | @Before
10 | public void setup() {
11 | RandomGenerator.reset();
12 | CallChecker.clear();
13 | setSelector(new ExplorerSelector());
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/patch/sorter/tokenizer/RenameIdentifierLiteralTokenizer.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.patch.sorter.tokenizer;
2 |
3 | import fr.inria.spirals.npefix.patch.sorter.Token;
4 |
5 | /**
6 | * identifiers and literals are abstracted as ID$1,ID$2, etc
7 | */
8 | public class RenameIdentifierLiteralTokenizer extends AbstractTokenizer {
9 |
10 |
11 | @Override
12 | public String computeRepresentation(Token token) {
13 | if (token.isText()) {
14 | return ("ID$");
15 | }
16 | return token.getValue();
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/test/resources/bar/src/main/java/Coneflower.java:
--------------------------------------------------------------------------------
1 |
2 | public class Coneflower {
3 |
4 | private String nullString = null;
5 | private int i = 0;
6 |
7 | public String methodThrowingNPE() {
8 | return nullString.toString();
9 | }
10 |
11 | public String intermediateMethod() {
12 | return "Brilliant coneflower," + methodThrowingNPE();
13 | }
14 |
15 | public String method() {
16 | return "Cutleaf coneflower," + intermediateMethod();
17 | }
18 |
19 | public int throwingException() {
20 | return Integer.parseInt("thisIsNotAnInteger");
21 | }
22 |
23 | }
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/patchTemplate/template/PatchTemplate.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.patchTemplate.template;
2 |
3 | import spoon.reflect.code.CtExpression;
4 | import spoon.reflect.declaration.CtElement;
5 |
6 | public interface PatchTemplate {
7 |
8 | /**
9 | * Apply a patch template on the null element nullElement.
10 | *
11 | * @param nullElement the null element to patch
12 | * @return the modified element
13 | * @throws RuntimeException when the patch cannot be applied
14 | */
15 | CtElement apply(CtExpression nullElement);
16 | }
17 |
--------------------------------------------------------------------------------
/src/test/resources/foo/src/main/java/FooArrayAccess.java:
--------------------------------------------------------------------------------
1 | import java.util.ArrayList;
2 | import java.util.Arrays;
3 | import java.util.List;
4 |
5 | public class FooArrayAccess {
6 |
7 | public String emtpyArray() {
8 | String[] array = new String[0];
9 | return array[0];
10 | }
11 |
12 | public String indexToSmall() {
13 | String[] array = new String[]{"Test"};
14 | return array[-1];
15 | }
16 |
17 | public String indexToBig() {
18 | String[] array = new String[]{"Test"};
19 | return array[1];
20 | }
21 |
22 | }
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/finder/main/TestInFolder.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.finder.main;
2 |
3 | import utils.sacha.finder.classes.impl.SourceFolderFinder;
4 | import utils.sacha.finder.filters.impl.TestFilter;
5 | import utils.sacha.finder.processor.Processor;
6 |
7 | public class TestInFolder{
8 |
9 | private String testFolder = null;
10 |
11 | public TestInFolder(String testFolder) {
12 | this.testFolder=testFolder;
13 | }
14 |
15 | public Class>[] find(){
16 | return new Processor(new SourceFolderFinder(testFolder), new TestFilter()).process();
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/CITATION.cff:
--------------------------------------------------------------------------------
1 | cff-version: 1.2.0
2 | preferred-citation:
3 | title: "Dynamic Patch Generation for Null Pointer Exceptions Using Metaprogramming"
4 | doi: "10.1109/SANER.2017.7884635"
5 | year: "2017"
6 | type: conference-paper
7 | conference: "IEEE International Conference on Software Analysis, Evolution and Reengineering"
8 | authors:
9 | - family-names: Durieux
10 | given-names: Thomas
11 | - family-names: Cornu
12 | given-names: Benoit
13 | - family-names: Seinturier
14 | given-names: Lionel
15 | - family-names: Monperrus
16 | given-names: Martin
17 |
--------------------------------------------------------------------------------
/src/evaluation/java/fr/inria/spirals/npefix/resi/selector/GreedySelectorEvaluation.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.selector;
2 |
3 | import fr.inria.spirals.npefix.resi.CallChecker;
4 | import fr.inria.spirals.npefix.resi.RandomGenerator;
5 | import org.junit.Before;
6 |
7 | /**
8 | * Created by thomas on 13/10/15.
9 | */
10 | public class GreedySelectorEvaluation extends AbstractSelectorEvaluation {
11 |
12 | @Before
13 | public void setup() {
14 | RandomGenerator.reset();
15 | CallChecker.clear();
16 | setSelector(new GreedySelector());
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/evaluation/java/fr/inria/spirals/npefix/resi/selector/RandomSelectorEvaluation.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.selector;
2 |
3 | import fr.inria.spirals.npefix.resi.CallChecker;
4 | import fr.inria.spirals.npefix.resi.RandomGenerator;
5 | import org.junit.Before;
6 |
7 | /**
8 | * Created by thomas on 13/10/15.
9 | */
10 | public class RandomSelectorEvaluation extends AbstractSelectorEvaluation {
11 |
12 | @Before
13 | public void setup() {
14 | RandomGenerator.reset();
15 | CallChecker.clear();
16 | setSelector(new RandomSelector());
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/main/all/RepairStrategy.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.main.all;
2 |
3 | import fr.inria.spirals.npefix.resi.context.NPEOutput;
4 | import fr.inria.spirals.npefix.resi.selector.Selector;
5 | import spoon.processing.AbstractProcessor;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * Created by Benjamin DANGLOT
11 | * benjamin.danglot@inria.fr
12 | * on 11/07/17
13 | */
14 | public interface RepairStrategy {
15 |
16 | List getListOfProcessors();
17 |
18 | NPEOutput run(Selector selector, List methodTests);
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/mains/TestFinderMain.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.mains;
2 |
3 | import utils.sacha.impl.TestFinderCore;
4 |
5 | /** Runs all tests of an Eclipse project */
6 | public class TestFinderMain {
7 |
8 | public static void main(String[] args) {
9 | TestFinderCore finder = new TestFinderCore();
10 | finder.setEclipseMetadataFolder("/home/bcornu/workspace/.metadata/");
11 | finder.setEclipseProject("joda-time");
12 |
13 | Class>[] tests = finder.findTestClasses();
14 | for (Class> clazz : tests) {
15 | System.out.println(clazz);;
16 | }
17 |
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/test/resources/foo/src/test/java/FooArrayAccessTest.java:
--------------------------------------------------------------------------------
1 | import org.junit.Assert;
2 | import org.junit.Test;
3 |
4 | public class FooArrayAccessTest {
5 |
6 | @Test
7 | public void fooTest() {
8 | FooArrayAccess foo = new FooArrayAccess();
9 | foo.emtpyArray();
10 | }
11 |
12 | @Test
13 | public void fooTest1() {
14 | FooArrayAccess foo = new FooArrayAccess();
15 | foo.indexToSmall();
16 | }
17 |
18 |
19 | @Test
20 | public void fooTest2() {
21 | FooArrayAccess foo = new FooArrayAccess();
22 | foo.indexToBig();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/finder/main/TestMain.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.finder.main;
2 |
3 | import utils.sacha.finder.classes.impl.SourceFolderFinder;
4 | import utils.sacha.finder.filters.impl.TestFilter;
5 | import utils.sacha.finder.processor.Processor;
6 |
7 | public class TestMain extends Main{
8 |
9 | public static Class>[] findTest(String testFolder){
10 | return getTestsClasses(checkFolder(testFolder));
11 | }
12 |
13 | private static Class>[] getTestsClasses(String testFolder) {
14 | return new Processor(new SourceFolderFinder(testFolder), new TestFilter()).process();
15 | }
16 |
17 |
18 |
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/test/resources/foo/src/main/java/FooTernary.java:
--------------------------------------------------------------------------------
1 | public class FooTernary {
2 |
3 | String field;
4 |
5 | public String m1() {
6 | String local = (field == null?"": field);
7 | if(field == null) {
8 | System.out.println("test");
9 | }
10 | return (field == null?"": field);
11 | }
12 |
13 | public void m2(String parm) {
14 | field = (parm == null?"": parm);
15 | }
16 |
17 | public static void add(Object[] array, Object element) {
18 | Class type = array != null ? array.getClass() : element != null ? element.getClass() : Object.class;
19 | }
20 | }
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/patch/sorter/Token.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.patch.sorter;
2 |
3 | public interface Token {
4 | /**
5 | * the value of the token, e.g. "{"
6 | */
7 | String getValue();
8 |
9 | /**
10 | * the type the token, from JDT
11 | */
12 | int getType();
13 |
14 | /**
15 | * returns true if the token is a literal or an identifier (e.g. a class name
16 | */
17 | boolean isText();
18 |
19 | /**
20 | * returns true if the token is a literal
21 | */
22 | boolean isLiteral();
23 |
24 | boolean isSyntax();
25 |
26 | boolean isKeyword();
27 |
28 | boolean isOperator();
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/patch/sorter/tokenizer/RenameIdentifierTokenizer.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.patch.sorter.tokenizer;
2 |
3 | import fr.inria.spirals.npefix.patch.sorter.Token;
4 | import org.eclipse.jdt.core.compiler.ITerminalSymbols;
5 |
6 | /**
7 | * identifiers are abstracted as ID$1,ID$2, etc
8 | */
9 | public class RenameIdentifierTokenizer extends AbstractTokenizer {
10 |
11 | @Override
12 | public String computeRepresentation(Token token) {
13 | if (token.getType() == ITerminalSymbols.TokenNameIdentifier) {
14 | return ("ID$");
15 | }
16 | return token.getValue();
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/patch/sorter/SingleFileTokenIterator.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.patch.sorter;
2 |
3 | import org.apache.commons.io.FileUtils;
4 |
5 | import java.io.File;
6 | import java.io.IOException;
7 |
8 | /**
9 | * iterates over the probabilityPatch of size n in a given file
10 | */
11 | public class SingleFileTokenIterator extends StringTokenIterator {
12 | public SingleFileTokenIterator(File f, int n) throws IOException {
13 | super(FileUtils.readFileToString(f), n);
14 | if (f.isDirectory()) {
15 | throw new RuntimeException("oops,should be a regular file");
16 | }
17 | }
18 |
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/evaluation/java/fr/inria/spirals/npefix/resi/selector/MonoExplorationEvaluation.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.selector;
2 |
3 | import fr.inria.spirals.npefix.config.Config;
4 | import fr.inria.spirals.npefix.resi.CallChecker;
5 | import fr.inria.spirals.npefix.resi.RandomGenerator;
6 | import org.junit.Before;
7 |
8 | public class MonoExplorationEvaluation extends AbstractSelectorEvaluation {
9 |
10 | @Before
11 | public void setup() {
12 | RandomGenerator.reset();
13 | CallChecker.clear();
14 | Config.CONFIG.setMultiPoints(false);
15 | setSelector(new MonoExplorerSelector());
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/finder/main/Main.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.finder.main;
2 |
3 | import java.io.File;
4 |
5 | public abstract class Main {
6 |
7 | protected static String checkFolder(String testFolder) {
8 | if(testFolder.endsWith("/")||testFolder.endsWith("\\"))
9 | testFolder=testFolder.substring(0, testFolder.length());
10 |
11 | File testSrcFolder = new File(testFolder);
12 | if(!testSrcFolder.exists() || !testSrcFolder.isDirectory() || !testSrcFolder.canRead())
13 | throw new IllegalArgumentException("cannot found "+testFolder+" or is not a directory or is not readable");
14 |
15 | return testFolder;
16 |
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/patch/sorter/tokenizer/RenameSyntaxKeywordTokenizer.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.patch.sorter.tokenizer;
2 |
3 | import fr.inria.spirals.npefix.patch.sorter.Token;
4 |
5 | /**
6 | * literals are abstracted as LIT$1,LIT$2, etc
7 | */
8 | public class RenameSyntaxKeywordTokenizer extends AbstractTokenizer {
9 |
10 | @Override
11 | public String computeRepresentation(Token token) {
12 | if (token.isSyntax()) {
13 | return "SYN$";
14 | }
15 | if (token.isKeyword()) {
16 | return "KEY$";
17 | }
18 | if (token.isOperator()) {
19 | return "OP$";
20 | }
21 | return token.getValue();
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/finder/main/TestInURLClassloader.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.finder.main;
2 |
3 | import utils.sacha.finder.classes.impl.ClassloaderFinder;
4 | import utils.sacha.finder.filters.impl.TestFilter;
5 | import utils.sacha.finder.processor.Processor;
6 |
7 | import java.net.URLClassLoader;
8 |
9 | public class TestInURLClassloader{
10 |
11 | private URLClassLoader urlClassloader;
12 |
13 | public TestInURLClassloader(URLClassLoader classloader) {
14 | this.urlClassloader=classloader;
15 | }
16 |
17 | public Class>[] find(){
18 | return new Processor(new ClassloaderFinder(urlClassloader), new TestFilter()).process();
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/finder/main/TestClassFinder.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.finder.main;
2 |
3 | import utils.sacha.classloader.enrich.EnrichableClassloader;
4 | import utils.sacha.finder.classes.impl.ProjectFinder;
5 | import utils.sacha.finder.filters.impl.TestFilter;
6 | import utils.sacha.finder.processor.Processor;
7 |
8 | public class TestClassFinder{
9 |
10 | private EnrichableClassloader urlClassloader;
11 |
12 | public TestClassFinder(EnrichableClassloader classloader) {
13 | this.urlClassloader=classloader;
14 | }
15 |
16 | public Class>[] findTestClasses(){
17 | return new Processor(new ProjectFinder(urlClassloader), new TestFilter()).process();
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/mains/TestRunnerMain.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.mains;
2 |
3 | import utils.sacha.impl.TestRunnerCore;
4 | import utils.sacha.interfaces.ITestResult;
5 |
6 | /** Runs all tests of an Eclipse project */
7 | public class TestRunnerMain {
8 |
9 | public static void main(String[] args) {
10 | TestRunnerCore runner = new TestRunnerCore();
11 | runner.setEclipseMetadataFolder("/home/bcornu/workspace/.metadata/");
12 | runner.setEclipseProject("joda-time");
13 | // runs the test folder
14 | ITestResult res = runner.runAllTestsInClasspath();
15 | System.out.println(res.getNbRunTests());
16 | System.out.println(res.getNbFailedTests());
17 |
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/evaluation/java/fr/inria/spirals/npefix/SafeMonoEvaluation.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.selector;
2 |
3 | import org.junit.Before;
4 |
5 | import fr.inria.spirals.npefix.config.Config;
6 | import fr.inria.spirals.npefix.resi.CallChecker;
7 | import fr.inria.spirals.npefix.resi.RandomGenerator;
8 |
9 | // safe mode for NpeFix, see https://github.com/Spirals-Team/npefix/issues/10
10 | public class SafeMonoEvaluation extends AbstractSelectorEvaluation {
11 |
12 | @Before
13 | public void setup() {
14 | RandomGenerator.reset();
15 | CallChecker.clear();
16 | Config.CONFIG.setMultiPoints(false);
17 | setSelector(new SafeMonoSelector());
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/evaluation/java/fr/inria/spirals/npefix/resi/selector/DomSelectorEvaluation.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.selector;
2 |
3 | import fr.inria.spirals.npefix.resi.CallChecker;
4 | import fr.inria.spirals.npefix.resi.RandomGenerator;
5 | import fr.inria.spirals.npefix.resi.strategies.ReturnType;
6 | import fr.inria.spirals.npefix.resi.strategies.Strat4;
7 | import org.junit.Before;
8 |
9 | public class DomSelectorEvaluation extends AbstractSelectorEvaluation {
10 |
11 | @Before
12 | public void setup() {
13 | RandomGenerator.reset();
14 | CallChecker.clear();
15 | setSelector(new DomSelector());
16 | DomSelector.strategy = new Strat4(ReturnType.VAR);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/patch/sorter/StringTokensCreator.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.patch.sorter;
2 |
3 | import fr.inria.spirals.npefix.patch.sorter.tokenizer.Tokenizer;
4 |
5 | /**
6 | * recursively iterates over a directory and enumerates all probabilityPatch of size n
7 | */
8 | public class StringTokensCreator {
9 | StringTokenIterator it;
10 | int n;
11 | Tokens tokens;
12 |
13 | public StringTokensCreator(String f, int n, Tokenizer tokenizer) {
14 | this.n = n;
15 | it = new StringTokenIterator(f, n);
16 | tokens = new Tokens(tokenizer);
17 | }
18 |
19 | public Tokens getTokens() {
20 | while (it.hasNext()) {
21 | tokens.add(it.next());
22 | }
23 | return tokens;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/resi/strategies/NoStrat.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.resi.strategies;
2 |
3 | import fr.inria.spirals.npefix.resi.context.Decision;
4 | import fr.inria.spirals.npefix.resi.context.Location;
5 | import fr.inria.spirals.npefix.resi.context.MethodContext;
6 |
7 | import java.util.Collections;
8 | import java.util.List;
9 |
10 | public class NoStrat extends AbstractStrategy {
11 |
12 | @Override
13 | public boolean isCompatibleAction(ACTION action) {
14 | return false;
15 | }
16 |
17 | @Override
18 | public List> getSearchSpace(Object value,
19 | Class clazz,
20 | Location location,
21 | MethodContext context) {
22 | return Collections.EMPTY_LIST;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/finder/filters/impl/AcceptAllFilter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * @author Johannes Link (business@johanneslink.net)
3 | *
4 | * Published under GNU General Public License 2.0 (http://www.gnu.org/licenses/gpl.html)
5 | */
6 | package utils.sacha.finder.filters.impl;
7 |
8 | import utils.sacha.finder.filters.ClassFilter;
9 |
10 | public class AcceptAllFilter implements ClassFilter {
11 |
12 | public boolean acceptClassName(String className) {
13 | return true;
14 | }
15 |
16 | public boolean acceptInnerClass() {
17 | return true;
18 | }
19 |
20 | public boolean acceptClass(Class> clazz) {
21 | return true;
22 | }
23 |
24 | public boolean searchInJars() {
25 | return true;
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/patch/sorter/algorithm/Laplace.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.patch.sorter.algorithm;
2 |
3 | import fr.inria.spirals.npefix.patch.sorter.Token;
4 | import fr.inria.spirals.npefix.patch.sorter.Tokens;
5 |
6 | public class Laplace extends Algorithm {
7 | public Laplace(Token token, Tokens predicate, Tokens corpus) {
8 | super(token, predicate, corpus);
9 | }
10 |
11 | public double perform() {
12 | int countWithPredicate = getCorpus().count(getToken(), getPredicate());
13 | int countTotal = countWithPredicate;
14 | if (!getPredicate().isEmpty()) {
15 | countTotal = getCorpus().nbWordCanFollow(getPredicate()) + getCorpus().size();
16 | }
17 | return (countWithPredicate + 1) / (double) countTotal;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/patch/sorter/algorithm/Algorithm.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.patch.sorter.algorithm;
2 |
3 | import fr.inria.spirals.npefix.patch.sorter.Token;
4 | import fr.inria.spirals.npefix.patch.sorter.Tokens;
5 |
6 | public abstract class Algorithm {
7 | private final Token token;
8 | private final Tokens predicate;
9 | private final Tokens corpus;
10 |
11 | public Algorithm(Token token, Tokens predicate, Tokens corpus) {
12 | this.token = token;
13 | this.predicate = predicate;
14 | this.corpus = corpus;
15 | }
16 |
17 | public Token getToken() {
18 | return token;
19 | }
20 |
21 | public Tokens getPredicate() {
22 | return predicate;
23 | }
24 |
25 | public Tokens getCorpus() {
26 | return corpus;
27 | }
28 |
29 | public abstract double perform();
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/utils/sacha/mains/RunSpoonWithClasspath.java:
--------------------------------------------------------------------------------
1 | package utils.sacha.mains;
2 |
3 | import utils.sacha.impl.DefaultSpooner;
4 | import utils.sacha.interfaces.ISpooner;
5 |
6 | /** Runs spoon in an easy manner */
7 | public class RunSpoonWithClasspath {
8 |
9 | public static void main(String[] args) {
10 |
11 | ISpooner spooner = new DefaultSpooner();
12 | //project config
13 | spooner.setEclipseProject("test");
14 | spooner.setEclipseMetadataFolder("/home/bcornu/workspace/.metadata");
15 | //spoon config
16 | spooner.setSourceFolder("src");
17 | // spooner.setProcessors("bcu.transformer.processors.ClassAnnotation","bcu.transformer.processors.TryEncapsulation");
18 | spooner.setOutputFolder("/home/bcornu/workspace/test-spooned/src");
19 |
20 | spooner.setGraphicalOutput(true);
21 |
22 | spooner.spoon();
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/fr/inria/spirals/npefix/patch/sorter/algorithm/NGram.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.patch.sorter.algorithm;
2 |
3 | import fr.inria.spirals.npefix.patch.sorter.Token;
4 | import fr.inria.spirals.npefix.patch.sorter.Tokens;
5 |
6 | public class NGram extends Algorithm {
7 | public NGram(Token token, Tokens predicate, Tokens corpus) {
8 | super(token, predicate, corpus);
9 | }
10 |
11 | public double perform() {
12 | int countWithPredicate = getCorpus().count(getToken(), getPredicate());
13 | int countTotal = countWithPredicate;
14 | if (!getPredicate().isEmpty()) {
15 | countTotal = getCorpus().count(getPredicate().get(getPredicate().fullSize() - 1), getPredicate().subList(0, getPredicate().fullSize() - 1));
16 | }
17 | if (countTotal == 0) {
18 | return 0.0;
19 | }
20 | return countWithPredicate / (double) countTotal;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/test/resources/foo/src/main/java/ImplicitCast.java:
--------------------------------------------------------------------------------
1 | import java.util.ArrayList;
2 | import java.util.List;
3 | import java.util.Objects;
4 |
5 | public class ImplicitCast {
6 |
7 | private int field;
8 |
9 | public int implicitCastReturn() {
10 | return new Integer(null);
11 | }
12 |
13 | public void implicitLocalVariable() {
14 | int i = new Integer(null);
15 | }
16 |
17 | public void implicitAssignment() {
18 | field = new Integer(null);
19 | }
20 |
21 | public void implicitAssignmentVariable() {
22 | Integer value = new Integer(null);
23 | field = value;
24 | }
25 |
26 | public void implicitInvocation() {
27 | List>> list = new ArrayList<>();
28 | if(!list.get(0).isEmpty()) {
29 | List objects = list.get(0);
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/src/test/java/fr/inria/spirals/npefix/transformer/processors/TernarySplitterTest.java:
--------------------------------------------------------------------------------
1 | package fr.inria.spirals.npefix.transformer.processors;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 | import spoon.Launcher;
6 | import spoon.reflect.declaration.CtClass;
7 |
8 | /**
9 | * Split if condition into several if in order to add check not null before each section of the condition
10 | */
11 | public class TernarySplitterTest {
12 |
13 | @Test
14 | public void test() {
15 | Launcher spoon = new Launcher();
16 | spoon.addInputResource("src/test/resources/foo/src/main/java/");
17 | spoon.addProcessor(TernarySplitter.class.getCanonicalName());
18 | spoon.setSourceOutputDirectory("target/instrumented");
19 |
20 | spoon.run();
21 |
22 | CtClass