├── .gitignore ├── Data ├── JavaRepos │ ├── git-clone-repos.sh │ └── repos.txt ├── LiveStudy │ ├── AllPullRequests.txt │ └── RejectedPullRequests.txt ├── TestData │ ├── ParsedMethodNames.txt │ ├── TestLabels.txt │ ├── TestMethodBodyTokens.txt │ ├── TestMethodCode.java │ ├── TestMethodInfo.txt │ └── TestMethodNames.txt └── TrainingData │ ├── TrainingMethodBodyTokens.txt.zip │ └── TrainingMethodInfo.txt.zip ├── DebugMethodName ├── LICENSE ├── lib │ └── jaws-1.3.1.jar ├── pom.xml └── src │ ├── main │ ├── java │ │ └── edu │ │ │ └── lu │ │ │ └── uni │ │ │ └── serval │ │ │ ├── Configuration.java │ │ │ ├── DataFilter.java │ │ │ ├── Main.java │ │ │ ├── MainParser.java │ │ │ ├── akka │ │ │ ├── JavaFile │ │ │ │ └── getter │ │ │ │ │ ├── JavaFileGetActor.java │ │ │ │ │ ├── JavaFileGetWorker.java │ │ │ │ │ ├── JavaFileGetter.java │ │ │ │ │ ├── MultipleThreadsJavaFileGetter.java │ │ │ │ │ └── WorkerMessage.java │ │ │ └── method │ │ │ │ └── parser │ │ │ │ ├── MultipleShreadParser.java │ │ │ │ ├── ParseProjectActor.java │ │ │ │ ├── ParseProjectWorker.java │ │ │ │ └── ProjectsMessage.java │ │ │ ├── jdt │ │ │ ├── AST │ │ │ │ └── ASTGenerator.java │ │ │ ├── entity │ │ │ │ ├── EntityType.java │ │ │ │ └── Pair.java │ │ │ ├── generator │ │ │ │ ├── AbstractJdtTreeGenerator.java │ │ │ │ ├── AbstractRawTokenJdtTreeGenerator.java │ │ │ │ ├── ExpJdtTreeGenerator.java │ │ │ │ ├── RawTokenJdtTreeGenerator.java │ │ │ │ ├── Register.java │ │ │ │ ├── Registry.java │ │ │ │ └── TreeGenerator.java │ │ │ ├── method │ │ │ │ ├── AbstractMethod.java │ │ │ │ ├── IMethod.java │ │ │ │ └── Method.java │ │ │ ├── parser │ │ │ │ ├── JavaFileParser.java │ │ │ │ ├── SimpleTree.java │ │ │ │ ├── SimplifyTree.java │ │ │ │ ├── Tokenizer.java │ │ │ │ └── TypeReader.java │ │ │ ├── tree │ │ │ │ ├── AbstractTree.java │ │ │ │ ├── AssociationMap.java │ │ │ │ ├── ITree.java │ │ │ │ ├── Tree.java │ │ │ │ ├── TreeContext.java │ │ │ │ ├── TreeUtils.java │ │ │ │ └── hash │ │ │ │ │ ├── HashGenerator.java │ │ │ │ │ ├── HashUtils.java │ │ │ │ │ └── RollingHashGenerator.java │ │ │ └── visitor │ │ │ │ ├── AbstractJdtVisitor.java │ │ │ │ ├── AbstractRawTokenJdtVisitor.java │ │ │ │ ├── ExpJdtVisitor.java │ │ │ │ ├── JdtVisitor.java │ │ │ │ └── RawTokenJdtVisitor.java │ │ │ ├── method │ │ │ └── parser │ │ │ │ ├── MethodNameParser.java │ │ │ │ ├── MethodParser.java │ │ │ │ ├── Splitter.java │ │ │ │ └── util │ │ │ │ ├── Distribution.java │ │ │ │ ├── MethodBodiesExporter.java │ │ │ │ └── MethodExporter.java │ │ │ ├── sricmn │ │ │ ├── DetectMethodNames.java │ │ │ ├── TokenSuggestor.java │ │ │ ├── akka │ │ │ │ ├── EvaluateActor.java │ │ │ │ ├── EvaluateWorker.java │ │ │ │ ├── WorkerMessage.java │ │ │ │ └── WorkerReturnMessage.java │ │ │ ├── comparativeStudy │ │ │ │ ├── EvaluateJson.java │ │ │ │ ├── EvaluateNgram.java │ │ │ │ └── JsonInput.java │ │ │ ├── info │ │ │ │ ├── MethodInfo.java │ │ │ │ └── PredictToken.java │ │ │ └── liveStudy │ │ │ │ ├── AkkaEvaluation.java │ │ │ │ ├── EvaluateActor.java │ │ │ │ ├── EvaluateWorker.java │ │ │ │ ├── LiveStudyEvl.java │ │ │ │ └── Main.java │ │ │ └── utils │ │ │ ├── ASTNodeMap.java │ │ │ ├── Checker.java │ │ │ ├── DataReader.java │ │ │ ├── NamesStringSimilarity.java │ │ │ ├── Similarities.java │ │ │ └── SynonymsFinder.java │ └── resource │ │ └── logback.xml │ └── test │ └── java │ └── edu │ └── lu │ └── uni │ └── serval │ └── method │ └── TestMethodNameParser.java ├── GitTraveller ├── README.md ├── pom.xml └── src │ ├── main │ └── java │ │ └── edu │ │ └── lu │ │ └── uni │ │ └── serval │ │ ├── App.java │ │ ├── GitTravllerExample.java │ │ └── git │ │ ├── exception │ │ ├── GitRepositoryNotFoundException.java │ │ └── NotValidGitRepositoryException.java │ │ ├── filter │ │ ├── CommitFilter.java │ │ ├── DiffEntryFilter.java │ │ ├── LineDiffFilter.java │ │ └── RegExp.java │ │ └── travel │ │ ├── BugRelatedWords.java │ │ ├── CommitDiffEntry.java │ │ ├── CommitFile.java │ │ ├── GitRepository.java │ │ ├── ModifiedDetails.java │ │ └── MyDiffEntry.java │ └── test │ └── java │ └── edu │ └── lu │ └── uni │ └── serval │ └── AppTest.java ├── LearningModel ├── pom.xml └── src │ └── main │ ├── java │ └── edu │ │ └── lu │ │ └── uni │ │ ├── Configuration.java │ │ ├── deeplearning │ │ └── extractor │ │ │ ├── CNNFeatureExtractor.java │ │ │ └── FeatureExtractor.java │ │ ├── feature │ │ └── exporter │ │ │ └── FeatureExporter.java │ │ └── serval │ │ ├── MethodName │ │ └── detector │ │ │ ├── App1.java │ │ │ ├── MethodNameFeatureLearner.java │ │ │ ├── MethodNameFeatureLearner2.java │ │ │ └── T1.java │ │ ├── deeplearner │ │ ├── MyTokenPreprocessor.java │ │ ├── SentenceEncoder.java │ │ └── Word2VecEncoder.java │ │ └── dlMethods │ │ ├── DataInitializer.java │ │ ├── DataMerger.java │ │ ├── DataPrepare │ │ ├── CommonFirstTokens.java │ │ └── RenamedMethodSelector.java │ │ ├── DataPreparer.java │ │ ├── EmbedCodeTokens.java │ │ ├── MethodBodyCodeLearner.java │ │ ├── MethodNameLearner.java │ │ ├── RenamedMethods.java │ │ ├── TokensEmbedder.java │ │ └── liveStudy │ │ ├── DataInitializer.java │ │ ├── Step1.java │ │ ├── Step2.java │ │ ├── Step3.java │ │ ├── Step4.java │ │ └── Step5.java │ └── resources │ └── logback.xml ├── README.md ├── RenamedMethodsCollector ├── pom.xml └── src │ ├── main │ ├── java │ │ └── edu │ │ │ └── lu │ │ │ └── uni │ │ │ └── serval │ │ │ ├── diffentry │ │ │ ├── DiffEntryHunk.java │ │ │ ├── DiffEntryReader.java │ │ │ └── RegExp.java │ │ │ ├── gumtree │ │ │ └── regroup │ │ │ │ ├── HierarchicalActionSet.java │ │ │ │ ├── HierarchicalRegrouper.java │ │ │ │ ├── SimpleTree.java │ │ │ │ └── SimplifyTree.java │ │ │ ├── renamed │ │ │ └── methods │ │ │ │ ├── CodeChangeParser.java │ │ │ │ ├── CommitDiffs.java │ │ │ │ ├── Configuration.java │ │ │ │ ├── Main.java │ │ │ │ ├── Main2.java │ │ │ │ ├── Main3.java │ │ │ │ ├── MessageFiles.java │ │ │ │ ├── ParseActor.java │ │ │ │ ├── ParseWorker.java │ │ │ │ ├── RenamedMethodsCollector.java │ │ │ │ ├── RenamedMethodsCollector2.java │ │ │ │ ├── RenamedMethodsFilter.java │ │ │ │ └── RunnableParser.java │ │ │ └── utils │ │ │ ├── ASTNodeMap.java │ │ │ ├── CUCreator.java │ │ │ ├── Checker.java │ │ │ └── Tokenizer.java │ └── resource │ │ └── logback.xml │ └── test │ └── java │ └── edu │ └── lu │ └── uni │ └── serval │ └── AppTest.java ├── gumtree ├── .travis.yml ├── LICENSE ├── checkstyle_ignore.xml ├── core │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── github │ │ │ └── gumtreediff │ │ │ ├── actions │ │ │ ├── ActionGenerator.java │ │ │ ├── ActionUtil.java │ │ │ ├── LeavesClassifier.java │ │ │ ├── RootAndLeavesClassifier.java │ │ │ ├── RootsClassifier.java │ │ │ ├── TreeClassifier.java │ │ │ └── model │ │ │ │ ├── Action.java │ │ │ │ ├── Addition.java │ │ │ │ ├── Delete.java │ │ │ │ ├── Insert.java │ │ │ │ ├── Move.java │ │ │ │ └── Update.java │ │ │ ├── gen │ │ │ ├── Generators.java │ │ │ ├── Register.java │ │ │ ├── Registry.java │ │ │ └── TreeGenerator.java │ │ │ ├── io │ │ │ ├── ActionsIoUtils.java │ │ │ ├── DirectoryComparator.java │ │ │ ├── Indentation.java │ │ │ ├── IndentingXMLStreamWriter.java │ │ │ ├── LineReader.java │ │ │ ├── MatrixDebugger.java │ │ │ ├── StreamWriterDelegate.java │ │ │ └── TreeIoUtils.java │ │ │ ├── matchers │ │ │ ├── CompositeMatcher.java │ │ │ ├── CompositeMatchers.java │ │ │ ├── Mapping.java │ │ │ ├── MappingStore.java │ │ │ ├── Matcher.java │ │ │ ├── Matchers.java │ │ │ ├── MultiMappingStore.java │ │ │ ├── Register.java │ │ │ ├── heuristic │ │ │ │ ├── LcsMatcher.java │ │ │ │ ├── XyBottomUpMatcher.java │ │ │ │ ├── cd │ │ │ │ │ ├── ChangeDistillerBottomUpMatcher.java │ │ │ │ │ └── ChangeDistillerLeavesMatcher.java │ │ │ │ └── gt │ │ │ │ │ ├── AbstractBottomUpMatcher.java │ │ │ │ │ ├── AbstractMappingComparator.java │ │ │ │ │ ├── AbstractSubtreeMatcher.java │ │ │ │ │ ├── CliqueSubtreeMatcher.java │ │ │ │ │ ├── CompleteBottomUpMatcher.java │ │ │ │ │ ├── FirstMatchBottomUpMatcher.java │ │ │ │ │ ├── GreedyBottomUpMatcher.java │ │ │ │ │ ├── GreedySubtreeMatcher.java │ │ │ │ │ ├── HungarianSubtreeMatcher.java │ │ │ │ │ ├── ParentsMappingComparator.java │ │ │ │ │ └── SiblingsMappingComparator.java │ │ │ └── optimal │ │ │ │ ├── rted │ │ │ │ ├── InfoTree.java │ │ │ │ ├── LabelDictionary.java │ │ │ │ ├── RtedAlgorithm.java │ │ │ │ └── RtedMatcher.java │ │ │ │ └── zs │ │ │ │ └── ZsMatcher.java │ │ │ ├── tree │ │ │ ├── AbstractTree.java │ │ │ ├── AssociationMap.java │ │ │ ├── ITree.java │ │ │ ├── IterableEnumeration.java │ │ │ ├── Tree.java │ │ │ ├── TreeContext.java │ │ │ ├── TreeMap.java │ │ │ ├── TreeUtils.java │ │ │ └── hash │ │ │ │ ├── HashGenerator.java │ │ │ │ ├── HashUtils.java │ │ │ │ ├── RollingHashGenerator.java │ │ │ │ └── StaticHashGenerator.java │ │ │ └── utils │ │ │ ├── HungarianAlgorithm.java │ │ │ ├── Pair.java │ │ │ └── StringAlgorithms.java │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── github │ │ │ └── gumtreediff │ │ │ └── test │ │ │ ├── TestActionGenerator.java │ │ │ ├── TestActionIo.java │ │ │ ├── TestAlgorithms.java │ │ │ ├── TestCoreSuite.java │ │ │ ├── TestGumtreeMatcher.java │ │ │ ├── TestHash.java │ │ │ ├── TestMetadata.java │ │ │ ├── TestPair.java │ │ │ ├── TestRtedMatcher.java │ │ │ ├── TestTree.java │ │ │ ├── TestTreeIoUtils.java │ │ │ ├── TestTreeUtils.java │ │ │ ├── TestZsMatcher.java │ │ │ └── TreeLoader.java │ │ └── resources │ │ ├── Dummy_big.xml │ │ ├── Dummy_v0.xml │ │ ├── Dummy_v1.xml │ │ ├── action_v0.xml │ │ ├── action_v1.xml │ │ ├── gumtree_v0.xml │ │ ├── gumtree_v1.xml │ │ ├── zs_slide_v0.xml │ │ ├── zs_slide_v1.xml │ │ ├── zs_v0.xml │ │ └── zs_v1.xml ├── gen.jdt │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ ├── com │ │ │ └── github │ │ │ │ └── gumtreediff │ │ │ │ └── gen │ │ │ │ └── jdt │ │ │ │ ├── AbstractJdtTreeGenerator.java │ │ │ │ ├── AbstractJdtVisitor.java │ │ │ │ ├── JdtTreeGenerator.java │ │ │ │ ├── JdtVisitor.java │ │ │ │ └── cd │ │ │ │ ├── CdJdtTreeGenerator.java │ │ │ │ ├── CdJdtVisitor.java │ │ │ │ └── EntityType.java │ │ │ └── edu │ │ │ └── lu │ │ │ └── uni │ │ │ └── serval │ │ │ ├── gen │ │ │ └── jdt │ │ │ │ ├── exp │ │ │ │ ├── ExpJdtTreeGenerator.java │ │ │ │ └── ExpJdtVisitor.java │ │ │ │ └── rawToken │ │ │ │ ├── AbstractRawTokenJdtTreeGenerator.java │ │ │ │ ├── AbstractRawTokenJdtVisitor.java │ │ │ │ ├── RawTokenJdtTreeGenerator.java │ │ │ │ └── RawTokenJdtVisitor.java │ │ │ └── gumtree │ │ │ ├── GumTreeComparer.java │ │ │ └── GumTreeGenerator.java │ │ └── test │ │ └── java │ │ └── com │ │ └── github │ │ └── gumtreediff │ │ └── gen │ │ └── jdt │ │ └── TestJdtGenerator.java ├── gumtree_checkstyle.xml └── pom.xml └── simple-utils ├── pom.xml └── src └── main └── java └── edu └── lu └── uni └── serval └── utils ├── DistanceCalculator.java ├── Distribution.java ├── Evaluation.java ├── Exporter.java ├── FeatureReader.java ├── FileHelper.java ├── LevenshteinDistance.java ├── ListSorter.java ├── MapSorter.java ├── ReturnType.java └── similarity ├── DamerauLevenshteinDistance.java ├── Jaccard.java ├── JaroWinkler.java ├── LevenshteinDistance.java ├── LongestCommonSubsequence.java ├── MetricLCS.java ├── MostFreqKDistance.java ├── NGram.java ├── NormalizedLevenshteinDistance.java ├── NormalizedSimilarity.java ├── OptimalStringAlignment.java ├── Overlap.java ├── QGram.java ├── Sift4.java ├── Similarity.java ├── SimilarityCalculator.java ├── SorensenDice.java ├── StringMetrics.java └── Tversky.java /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.R 3 | .classpath 4 | .project 5 | .settings 6 | target/ 7 | -------------------------------------------------------------------------------- /Data/LiveStudy/AllPullRequests.txt: -------------------------------------------------------------------------------- 1 | cannot https://github.com/apache/directory-studio/pull/2/files ignore https://github.com/apache/batik/pull/14 ignore https://github.com/apache/cocoon/pull/5/files ignore https://github.com/apache/flex-blazeds/pull/4 ignore https://github.com/apache/fop/pull/10 ignore https://github.com/apache/fop/pull/7/files ignore https://github.com/apache/fop/pull/6 ignore https://github.com/apache/geronimo/pull/2/files ignore https://github.com/apache/kafka/pull/4899/files ignore https://github.com/apache/lucene-solr/pull/354 ignore https://github.com/apache/river/pull/1 ignore https://github.com/spring-projects/spring-data-commons/pull/288 merged https://github.com/spring-projects/spring-batch/pull/600 merged https://github.com/apache/activemq-artemis/pull/2037/files merged https://github.com/apache/asterixdb/pull/7 merged https://github.com/apache/cloudstack/pull/2601/files merged https://github.com/apache/cloudstack/pull/2600/files merged https://github.com/apache/cloudstack/pull/2599/files merged https://github.com/apache/cloudstack/pull/2598/files merged https://github.com/apache/cloudstack/pull/2591 merged https://github.com/apache/drill/pull/1236/files merged https://github.com/apache/eagle/pull/991/files merged https://github.com/apache/james-project/pull/110/files merged https://github.com/apache/ode/pull/7/files merged https://github.com/apache/rocketmq-externals/pull/65 merged https://github.com/apache/sis/pull/7/files merged https://github.com/apache/cloudstack/pull/2847 merged https://github.com/eclipse/org.aspectj/pull/8 rejected https://github.com/apache/stanbol/pull/7 rejected https://github.com/apache/xerces2-j/pull/3 rejected https://github.com/apache/drill/pull/1235/files rejected https://github.com/apache/ambari/pull/1024/files rejected https://github.com/apache/ambari/pull/1022/files rejected https://github.com/apache/ambari/pull/1020 rejected https://github.com/apache/fop/pull/9 rejected https://github.com/apache/fop/pull/8 rejected https://github.com/apache/jackrabbit-oak/pull/85 rejected https://github.com/apache/uima-uimaj/pull/2 won't fix https://github.com/apache/openmeetings/pull/5/files won't fix https://github.com/spring-projects/spring-data-gemfire/pull/94/files -------------------------------------------------------------------------------- /Data/TrainingData/TrainingMethodBodyTokens.txt.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TruX-DTF/debug-method-name/fb1f87ffd923ef987aad8521ab9be8b747ca50c5/Data/TrainingData/TrainingMethodBodyTokens.txt.zip -------------------------------------------------------------------------------- /Data/TrainingData/TrainingMethodInfo.txt.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TruX-DTF/debug-method-name/fb1f87ffd923ef987aad8521ab9be8b747ca50c5/Data/TrainingData/TrainingMethodInfo.txt.zip -------------------------------------------------------------------------------- /DebugMethodName/lib/jaws-1.3.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TruX-DTF/debug-method-name/fb1f87ffd923ef987aad8521ab9be8b747ca50c5/DebugMethodName/lib/jaws-1.3.1.jar -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/Configuration.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval; 2 | 3 | import java.io.File; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public class Configuration { 8 | 9 | private static final String ROOT_PATH = "../Data/"; 10 | // Data paths of Java method parsing. 11 | public static final String JAVA_REPOS_PATH = ROOT_PATH + "JavaRepos/"; 12 | public static final String JAVA_REPO_NAMES_FILE = JAVA_REPOS_PATH + "repos.txt"; 13 | public static final List PROJECTS = new ArrayList<>(); // input 14 | static { 15 | File trainingDataFile = new File(JAVA_REPOS_PATH); 16 | File[] files = trainingDataFile.listFiles(); 17 | for (File file : files) { 18 | if (file.isDirectory() && !file.getName().startsWith(".")) { 19 | PROJECTS.add(JAVA_REPOS_PATH + file.getName() + "/.git"); 20 | } 21 | } 22 | } 23 | public static final String OUTPUT_PATH = ROOT_PATH + "Output/"; 24 | public static final String TOKENIZED_METHODS_PATH = OUTPUT_PATH + "tokenization/"; 25 | public static final String JAVA_FILES_PATH = OUTPUT_PATH + "JavaFiles/"; 26 | public static final String JAVA_FILES_FILE = OUTPUT_PATH + "JavaFiles.txt"; 27 | 28 | public static final String WORDNET_PATH = "/usr/local/Cellar/wordnet/3.1/dict"; 29 | public static final String DL_DATA_PATH = OUTPUT_PATH + "DL_Data/"; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/Main.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval; 2 | 3 | import akka.actor.ActorRef; 4 | import akka.actor.ActorSystem; 5 | import edu.lu.uni.serval.sricmn.akka.EvaluateActor; 6 | 7 | /** 8 | * Sport and refactor inconsistent method names. 9 | * 10 | * @author kui.liu 11 | * 12 | */ 13 | public class Main { 14 | 15 | public static void main(String[] args) { 16 | int nEpochs = 1;// 1, 10, 20. 17 | int topNum = 100; 18 | boolean considerReturnType = false;// true or false: method body with return types or not. 19 | int fileId = 2; // 1 or 2. 1: method names without return types. 2: method names with return types. 20 | String inputPath = Configuration.OUTPUT_PATH; 21 | int numberOfTestingWorkers = 50; 22 | int numberOfRenamedWorkers = 100; 23 | int similarityType = 0; // 0-15. 24 | boolean isSubToken = false; // true or false. 25 | boolean considerSynonyms = false; 26 | boolean needAllSynonyms = false; 27 | Main akkaEval = new Main(); 28 | akkaEval.evaluate(nEpochs, topNum, considerReturnType, fileId, inputPath, numberOfTestingWorkers, numberOfRenamedWorkers, 29 | similarityType, isSubToken, considerSynonyms, needAllSynonyms); 30 | } 31 | 32 | @SuppressWarnings("deprecation") 33 | public void evaluate(int nEpochs, int topNum, boolean considerReturnType, int fileId, String inputPath, int numberOfTestingWorkers, 34 | int numberOfRenamedWorkers, int similarityType, boolean isSubToken, boolean considerSynonyms, boolean needAllSynonyms) { 35 | ActorSystem system = null; 36 | ActorRef parsingActor = null; 37 | String[] inputPaths = {inputPath + "/DL_Data/", inputPath + "/Detect_Data/"}; 38 | 39 | try { 40 | system = ActorSystem.create("Evaluation-System"); 41 | parsingActor = system.actorOf(EvaluateActor.props(numberOfTestingWorkers, numberOfRenamedWorkers, inputPaths, nEpochs, topNum, considerReturnType, 42 | fileId, similarityType, isSubToken, considerSynonyms, needAllSynonyms), "evaluate-actor"); 43 | parsingActor.tell("BEGIN", ActorRef.noSender()); 44 | } catch (Exception e) { 45 | system.shutdown(); 46 | e.printStackTrace(); 47 | } 48 | 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/akka/JavaFile/getter/JavaFileGetter.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.akka.JavaFile.getter; 2 | 3 | import edu.lu.uni.serval.Configuration; 4 | 5 | /** 6 | * Get all Java files to accelerate the process of parsing Java methods. 7 | * 8 | * @author kui.liu 9 | * 10 | */ 11 | public class JavaFileGetter { 12 | 13 | public static void main(String[] args) { 14 | int numberOfWorkers = 430; 15 | MultipleThreadsJavaFileGetter getter = new MultipleThreadsJavaFileGetter(Configuration.JAVA_REPOS_PATH, numberOfWorkers); 16 | getter.getJavaFiles(); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/akka/JavaFile/getter/MultipleThreadsJavaFileGetter.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.akka.JavaFile.getter; 2 | 3 | import akka.actor.ActorRef; 4 | import akka.actor.ActorSystem; 5 | 6 | /** 7 | * Use multiple threads to get all java files to improve the efficiency of parsing Java methods. 8 | * 9 | * @author kui.liu 10 | * 11 | */ 12 | public class MultipleThreadsJavaFileGetter { 13 | 14 | private String projectsPath; 15 | private int numberOfWorkers; 16 | 17 | public MultipleThreadsJavaFileGetter(String projectsPath, int numberOfWorkers) { 18 | this.projectsPath = projectsPath; 19 | this.numberOfWorkers = numberOfWorkers; 20 | } 21 | 22 | 23 | @SuppressWarnings("deprecation") 24 | public void getJavaFiles() { 25 | ActorSystem system = null; 26 | ActorRef parsingActor = null; 27 | 28 | try { 29 | system = ActorSystem.create("Parsing-Method-System"); 30 | parsingActor = system.actorOf(JavaFileGetActor.props(numberOfWorkers), "parse-method-actor"); 31 | parsingActor.tell(projectsPath, ActorRef.noSender()); 32 | } catch (Exception e) { 33 | system.shutdown(); 34 | e.printStackTrace(); 35 | } 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/akka/JavaFile/getter/WorkerMessage.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.akka.JavaFile.getter; 2 | 3 | import java.io.File; 4 | import java.util.List; 5 | 6 | public class WorkerMessage { 7 | private int workderId; 8 | private List javaProjects; 9 | 10 | public WorkerMessage(int workderId, List javaProjects) { 11 | super(); 12 | this.workderId = workderId; 13 | this.javaProjects = javaProjects; 14 | } 15 | 16 | public int getWorkderId() { 17 | return workderId; 18 | } 19 | 20 | public List getJavaProjects() { 21 | return javaProjects; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/akka/method/parser/MultipleShreadParser.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.akka.method.parser; 2 | 3 | import java.util.List; 4 | 5 | import akka.actor.ActorRef; 6 | import akka.actor.ActorSystem; 7 | 8 | public class MultipleShreadParser { 9 | 10 | private ProjectsMessage msg; 11 | private int numberOfWorkers; 12 | 13 | public MultipleShreadParser(List projectList, String outputPath, int numberOfWorkers) { 14 | this.msg = new ProjectsMessage(projectList, 0, outputPath); 15 | this.numberOfWorkers = numberOfWorkers; 16 | } 17 | 18 | public MultipleShreadParser(String project, String outputPath, int numberOfWorkers) { 19 | this.msg = new ProjectsMessage(project, 0, outputPath); 20 | this.numberOfWorkers = numberOfWorkers; 21 | } 22 | 23 | @SuppressWarnings("deprecation") 24 | public void parseMethods() { 25 | ActorSystem system = null; 26 | ActorRef parsingActor = null; 27 | 28 | try { 29 | system = ActorSystem.create("Parsing-Method-System"); 30 | parsingActor = system.actorOf(ParseProjectActor.props(numberOfWorkers), "parse-method-actor"); 31 | parsingActor.tell(msg, ActorRef.noSender()); 32 | } catch (Exception e) { 33 | system.shutdown(); 34 | e.printStackTrace(); 35 | } 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/akka/method/parser/ProjectsMessage.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.akka.method.parser; 2 | 3 | import java.io.File; 4 | import java.util.List; 5 | 6 | public class ProjectsMessage { 7 | private List projects = null; 8 | private String project = null; 9 | private List javaFiles = null; 10 | private List javaFilePathes = null; 11 | private int workerID; 12 | private String outputPath; 13 | 14 | public ProjectsMessage(List projects, int workerID, String outputPath) { 15 | super(); 16 | this.projects = projects; 17 | this.workerID = workerID; 18 | this.outputPath = outputPath; 19 | } 20 | 21 | public ProjectsMessage(String project, int workerID, String outputPath) { 22 | super(); 23 | this.project = project; 24 | this.workerID = workerID; 25 | this.outputPath = outputPath; 26 | } 27 | 28 | public void setJavaFiles(List javaFiles) { 29 | this.javaFiles = javaFiles; 30 | } 31 | 32 | public List getJavaFiles() { 33 | return javaFiles; 34 | } 35 | 36 | public List getJavaFilePathes() { 37 | return javaFilePathes; 38 | } 39 | 40 | public void setJavaFilePathes(List javaFilePathes) { 41 | this.javaFilePathes = javaFilePathes; 42 | } 43 | 44 | public List getProjects() { 45 | return projects; 46 | } 47 | 48 | public String getProject() { 49 | return project; 50 | } 51 | 52 | public int getWorkerID() { 53 | return workerID; 54 | } 55 | 56 | public String getOutputPath() { 57 | return outputPath; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/jdt/entity/Pair.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.jdt.entity; 2 | 3 | public class Pair { 4 | 5 | public final E1 firstElement; 6 | 7 | public final E2 secondElement; 8 | 9 | public Pair(E1 e1, E2 e2) { 10 | this.firstElement = e1; 11 | this.secondElement = e2; 12 | } 13 | 14 | public E1 getFirst() { 15 | return firstElement; 16 | } 17 | 18 | public E2 getSecond() { 19 | return secondElement; 20 | } 21 | 22 | @Override 23 | public boolean equals(Object o) { 24 | if (this == o) return true; 25 | if (o == null || getClass() != o.getClass()) return false; 26 | 27 | Pair pair = (Pair) o; 28 | 29 | if (!firstElement.equals(pair.firstElement)) return false; 30 | return secondElement.equals(pair.secondElement); 31 | 32 | } 33 | 34 | @Override 35 | public int hashCode() { 36 | int result = firstElement.hashCode(); 37 | result = 31 * result + secondElement.hashCode(); 38 | return result; 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return "(" + getFirst().toString() + "," + getSecond().toString() + ")"; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/jdt/generator/AbstractJdtTreeGenerator.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.jdt.generator; 2 | 3 | import org.eclipse.jdt.core.JavaCore; 4 | import org.eclipse.jdt.core.dom.AST; 5 | import org.eclipse.jdt.core.dom.ASTParser; 6 | 7 | import edu.lu.uni.serval.jdt.tree.TreeContext; 8 | import edu.lu.uni.serval.jdt.visitor.AbstractJdtVisitor; 9 | 10 | import java.io.BufferedReader; 11 | import java.io.IOException; 12 | import java.io.Reader; 13 | import java.util.Map; 14 | 15 | public abstract class AbstractJdtTreeGenerator extends TreeGenerator { 16 | 17 | private static char[] readerToCharArray(Reader r) throws IOException { 18 | StringBuilder fileData = new StringBuilder(); 19 | try (BufferedReader br = new BufferedReader(r)) { 20 | char[] buf = new char[10]; 21 | int numRead = 0; 22 | while ((numRead = br.read(buf)) != -1) { 23 | String readData = String.valueOf(buf, 0, numRead); 24 | fileData.append(readData); 25 | buf = new char[1024]; 26 | } 27 | } 28 | return fileData.toString().toCharArray(); 29 | } 30 | 31 | @Override 32 | public TreeContext generate(Reader r) throws IOException { 33 | return generate(r, ASTParser.K_COMPILATION_UNIT); 34 | } 35 | 36 | @Override 37 | public TreeContext generate(Reader r, int astParserType) throws IOException { 38 | ASTParser parser = ASTParser.newParser(AST.JLS8); 39 | parser.setKind(astParserType); 40 | Map pOptions = JavaCore.getOptions(); 41 | pOptions.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8); 42 | pOptions.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8); 43 | pOptions.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8); 44 | pOptions.put(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.ENABLED); 45 | parser.setCompilerOptions(pOptions); 46 | parser.setSource(readerToCharArray(r)); 47 | AbstractJdtVisitor v = createVisitor(); 48 | parser.createAST(null).accept(v); 49 | return v.getTreeContext(); 50 | } 51 | 52 | protected abstract AbstractJdtVisitor createVisitor(); 53 | } 54 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/jdt/generator/AbstractRawTokenJdtTreeGenerator.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.jdt.generator; 2 | 3 | import org.eclipse.jdt.core.JavaCore; 4 | import org.eclipse.jdt.core.dom.AST; 5 | import org.eclipse.jdt.core.dom.ASTParser; 6 | 7 | import edu.lu.uni.serval.jdt.tree.TreeContext; 8 | import edu.lu.uni.serval.jdt.visitor.AbstractRawTokenJdtVisitor; 9 | 10 | import java.io.BufferedReader; 11 | import java.io.IOException; 12 | import java.io.Reader; 13 | import java.util.Map; 14 | 15 | public abstract class AbstractRawTokenJdtTreeGenerator extends TreeGenerator { 16 | 17 | private static char[] readerToCharArray(Reader r) throws IOException { 18 | StringBuilder fileData = new StringBuilder(); 19 | try (BufferedReader br = new BufferedReader(r)) { 20 | char[] buf = new char[10]; 21 | int numRead = 0; 22 | while ((numRead = br.read(buf)) != -1) { 23 | String readData = String.valueOf(buf, 0, numRead); 24 | fileData.append(readData); 25 | buf = new char[1024]; 26 | } 27 | } 28 | return fileData.toString().toCharArray(); 29 | } 30 | 31 | @Override 32 | public TreeContext generate(Reader r) throws IOException { 33 | return generate(r, ASTParser.K_COMPILATION_UNIT); 34 | } 35 | 36 | @Override 37 | public TreeContext generate(Reader r, int astParserType) throws IOException { 38 | ASTParser parser = ASTParser.newParser(AST.JLS8); 39 | parser.setKind(astParserType); 40 | Map pOptions = JavaCore.getOptions(); 41 | pOptions.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8); 42 | pOptions.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8); 43 | pOptions.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8); 44 | pOptions.put(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.ENABLED); 45 | parser.setCompilerOptions(pOptions); 46 | parser.setSource(readerToCharArray(r)); 47 | AbstractRawTokenJdtVisitor v = createVisitor(); 48 | parser.createAST(null).accept(v); 49 | return v.getTreeContext(); 50 | } 51 | 52 | protected abstract AbstractRawTokenJdtVisitor createVisitor(); 53 | } 54 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/jdt/generator/ExpJdtTreeGenerator.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.jdt.generator; 2 | 3 | import edu.lu.uni.serval.jdt.visitor.AbstractJdtVisitor; 4 | import edu.lu.uni.serval.jdt.visitor.ExpJdtVisitor; 5 | 6 | @Register(id = "java-jdt-exp") 7 | public class ExpJdtTreeGenerator extends AbstractJdtTreeGenerator { 8 | @Override 9 | protected AbstractJdtVisitor createVisitor() { 10 | return new ExpJdtVisitor(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/jdt/generator/RawTokenJdtTreeGenerator.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.jdt.generator; 2 | 3 | import edu.lu.uni.serval.jdt.visitor.AbstractRawTokenJdtVisitor; 4 | import edu.lu.uni.serval.jdt.visitor.RawTokenJdtVisitor; 5 | 6 | @Register(id = "java-jdt", accept = "\\.java$", priority = Registry.Priority.MAXIMUM) 7 | public class RawTokenJdtTreeGenerator extends AbstractRawTokenJdtTreeGenerator { 8 | 9 | @Override 10 | protected AbstractRawTokenJdtVisitor createVisitor() { 11 | return new RawTokenJdtVisitor(); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/jdt/generator/Register.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.jdt.generator; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.TYPE) 10 | public @interface Register { 11 | String id(); 12 | String[] accept() default { }; 13 | int priority() default Registry.Priority.MEDIUM; 14 | } 15 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/jdt/method/IMethod.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.jdt.method; 2 | 3 | import java.util.Map; 4 | 5 | import org.eclipse.jdt.core.dom.Type; 6 | 7 | public interface IMethod { 8 | 9 | public String getKey(); 10 | 11 | public Type getReturnType(); 12 | 13 | public String getReturnTypeString(); 14 | 15 | public String getName(); 16 | 17 | public Map getParameters(); 18 | 19 | public String getBody(); 20 | 21 | public boolean isConstructor(); 22 | } 23 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/jdt/parser/SimpleTree.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.jdt.parser; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class SimpleTree { 7 | 8 | private String nodeType; 9 | private String label; 10 | private SimpleTree parent; 11 | private List children = new ArrayList<>(); 12 | 13 | public String getNodeType() { 14 | return nodeType; 15 | } 16 | 17 | public void setNodeType(String nodeType) { 18 | this.nodeType = nodeType; 19 | } 20 | 21 | public String getLabel() { 22 | return label; 23 | } 24 | 25 | public void setLabel(String label) { 26 | this.label = label; 27 | } 28 | 29 | public SimpleTree getParent() { 30 | return parent; 31 | } 32 | 33 | public void setParent(SimpleTree parent) { 34 | this.parent = parent; 35 | } 36 | 37 | public List getChildren() { 38 | return children; 39 | } 40 | 41 | public void setChildren(List children) { 42 | this.children = children; 43 | } 44 | 45 | private List strList = new ArrayList<>(); 46 | 47 | @Override 48 | public String toString() { 49 | String str = this.nodeType + "@@" + this.label; 50 | if (strList.size() == 0) { 51 | strList.add(str); 52 | for (SimpleTree child : children) { 53 | child.toString(); 54 | List strList1 = child.strList; 55 | for (String str1 : strList1) { 56 | strList.add("------" + str1); 57 | } 58 | } 59 | } 60 | 61 | str = ""; 62 | for (String str1 : strList) { 63 | str += str1 + "\n"; 64 | } 65 | 66 | return str; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/jdt/parser/TypeReader.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.jdt.parser; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | import edu.lu.uni.serval.utils.ListSorter; 8 | 9 | public class TypeReader { 10 | 11 | public static String readArgumentTypes(String arguments) { 12 | List argumentTypesList = new ArrayList<>(); 13 | List argumentsList = Arrays.asList(arguments.split("#")); 14 | int size = argumentsList.size(); 15 | if (argumentsList.size() == 1) { 16 | return "null"; 17 | } 18 | 19 | for (int i = 0; i < size; i = i + 2) { 20 | argumentTypesList.add(canonicalType(argumentsList.get(i))); 21 | } 22 | 23 | if (argumentTypesList.size() > 1) { 24 | ListSorter sorter = new ListSorter<>(argumentTypesList); 25 | argumentTypesList = sorter.sortAscending(); 26 | } 27 | 28 | String argumentTypesStr = ""; 29 | size = argumentTypesList.size() - 1; 30 | for (int i = 0; i < size; i ++) { 31 | argumentTypesStr += argumentTypesList.get(i) + "#"; 32 | } 33 | argumentTypesStr += argumentTypesList.get(size); 34 | return argumentTypesStr; 35 | } 36 | 37 | public static String canonicalType(String returnType) { 38 | String arrays = ""; 39 | if (returnType.endsWith("[]")) { 40 | arrays = "[]"; 41 | returnType = returnType.substring(0, returnType.length() - 2); 42 | } 43 | 44 | int index = returnType.indexOf("<"); 45 | if (index != -1) { 46 | if (index == 0) { 47 | while (index == 0) { 48 | returnType = returnType.substring(returnType.indexOf(">") + 1).trim(); 49 | index = returnType.indexOf(">"); 50 | } 51 | index = returnType.indexOf("<"); 52 | if (index == -1) index = returnType.length(); 53 | } 54 | returnType = returnType.substring(0, index); 55 | } 56 | index = returnType.lastIndexOf("."); 57 | if (index != -1) { // && returnType.startsWith("java.")) { 58 | returnType = returnType.substring(index + 1); 59 | } 60 | 61 | return returnType + arrays; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/jdt/tree/AssociationMap.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.jdt.tree; 2 | 3 | import java.util.AbstractMap; 4 | import java.util.ArrayList; 5 | import java.util.Iterator; 6 | import java.util.Map.Entry; 7 | 8 | /** 9 | * Meta-data. 10 | */ 11 | public class AssociationMap { 12 | // FIXME or not, should we inline this class ? or use Entry to only have one list ? ... or both 13 | ArrayList values = new ArrayList<>(); 14 | ArrayList keys = new ArrayList<>(); 15 | 16 | public Object get(String key) { 17 | int idx = keys.indexOf(key); 18 | if (idx == -1) 19 | return null; 20 | return values.get(idx); 21 | } 22 | 23 | /** 24 | * set meta-data `key` with `value` and returns the previous value 25 | * This method won't remove if value == null 26 | */ 27 | public Object set(String key, Object value) { 28 | int idx = keys.indexOf(key); 29 | if (idx == -1) { 30 | keys.add(key); 31 | values.add(value); 32 | return null; 33 | } 34 | return values.set(idx, value); 35 | } 36 | 37 | public Object remove(String key) { 38 | int idx = keys.indexOf(key); 39 | if (idx == -1) 40 | return null; 41 | if (idx == keys.size() - 1) { 42 | keys.remove(idx); 43 | return values.remove(idx); 44 | } 45 | keys.set(idx, keys.remove(keys.size() - 1)); 46 | return values.set(idx, values.remove(values.size() - 1)); 47 | } 48 | 49 | public Iterator> iterator() { 50 | return new Iterator>() { 51 | int currentPos = 0; 52 | @Override 53 | public boolean hasNext() { 54 | return currentPos < keys.size(); 55 | } 56 | 57 | @Override 58 | public Entry next() { 59 | Entry e = new AbstractMap.SimpleEntry<>(keys.get(currentPos), values.get(currentPos)); 60 | currentPos++; 61 | return e; 62 | } 63 | 64 | @Override 65 | public void remove() { 66 | // TODO Auto-generated method stub 67 | 68 | } 69 | }; 70 | } 71 | } -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/jdt/tree/hash/HashGenerator.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.jdt.tree.hash; 2 | 3 | import edu.lu.uni.serval.jdt.tree.ITree; 4 | 5 | public interface HashGenerator { 6 | 7 | public void hash(ITree t); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/jdt/tree/hash/HashUtils.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.jdt.tree.hash; 2 | 3 | import java.security.MessageDigest; 4 | import java.security.NoSuchAlgorithmException; 5 | 6 | import edu.lu.uni.serval.jdt.tree.ITree; 7 | 8 | public class HashUtils { 9 | 10 | private HashUtils() {} 11 | 12 | public static final int BASE = 33; 13 | 14 | public static final HashGenerator DEFAULT_HASH_GENERATOR = new RollingHashGenerator.Md5RollingHashGenerator(); 15 | 16 | public static int byteArrayToInt(byte[] b) { 17 | return b[3] & 0xFF | (b[2] & 0xFF) << 8 | (b[1] & 0xFF) << 16 | (b[0] & 0xFF) << 24; 18 | } 19 | 20 | public static int standardHash(ITree t) { 21 | return Integer.valueOf(t.getType()).hashCode() + HashUtils.BASE * t.getLabel().hashCode(); 22 | } 23 | 24 | public static String inSeed(ITree t) { 25 | return ITree.OPEN_SYMBOL + t.getLabel() + ITree.SEPARATE_SYMBOL + t.getType(); 26 | } 27 | 28 | public static String outSeed(ITree t) { 29 | return t.getType() + ITree.SEPARATE_SYMBOL + t.getLabel() + ITree.CLOSE_SYMBOL; 30 | } 31 | 32 | public static int md5(String s) { 33 | try { 34 | MessageDigest md = MessageDigest.getInstance("MD5"); 35 | byte[] digest = md.digest(s.getBytes()); 36 | return byteArrayToInt(digest); 37 | } catch (NoSuchAlgorithmException e) { 38 | e.printStackTrace(); 39 | } 40 | return ITree.NO_VALUE; 41 | } 42 | 43 | public static int fpow(int a, int b) { 44 | if (b == 1) 45 | return a; 46 | int result = 1; 47 | while (b > 0) { 48 | if ((b & 1) != 0) 49 | result *= a; 50 | b >>= 1; 51 | a *= a; 52 | } 53 | return result; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/jdt/tree/hash/RollingHashGenerator.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.jdt.tree.hash; 2 | 3 | import static edu.lu.uni.serval.jdt.tree.hash.HashUtils.BASE; 4 | import static edu.lu.uni.serval.jdt.tree.hash.HashUtils.fpow; 5 | import static edu.lu.uni.serval.jdt.tree.hash.HashUtils.md5; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | import edu.lu.uni.serval.jdt.tree.ITree; 11 | import edu.lu.uni.serval.jdt.tree.hash.HashUtils; 12 | 13 | public abstract class RollingHashGenerator implements HashGenerator { 14 | 15 | public void hash(ITree t) { 16 | for (ITree n: t.postOrder()) 17 | if (n.isLeaf()) 18 | n.setHash(leafHash(n)); 19 | else 20 | n.setHash(innerNodeHash(n)); 21 | } 22 | 23 | public abstract int hashFunction(String s); 24 | 25 | public int leafHash(ITree t) { 26 | return BASE * hashFunction(HashUtils.inSeed(t)) + hashFunction(HashUtils.outSeed(t)); 27 | } 28 | 29 | public int innerNodeHash(ITree t) { 30 | int size = t.getSize() * 2 - 1; 31 | int hash = hashFunction(HashUtils.inSeed(t)) * fpow(BASE, size); 32 | 33 | for (ITree c: t.getChildren()) { 34 | size = size - c.getSize() * 2; 35 | hash += c.getHash() * fpow(BASE, size); 36 | } 37 | 38 | hash += hashFunction(HashUtils.outSeed(t)); 39 | return hash; 40 | } 41 | 42 | public static class JavaRollingHashGenerator extends RollingHashGenerator { 43 | 44 | @Override 45 | public int hashFunction(String s) { 46 | return s.hashCode(); 47 | } 48 | 49 | } 50 | 51 | public static class Md5RollingHashGenerator extends RollingHashGenerator { 52 | 53 | @Override 54 | public int hashFunction(String s) { 55 | return md5(s); 56 | } 57 | 58 | } 59 | 60 | public static class RandomRollingHashGenerator extends RollingHashGenerator { 61 | 62 | private static final Map digests = new HashMap<>(); 63 | 64 | @Override 65 | public int hashFunction(String s) { 66 | return rdmHash(s); 67 | } 68 | 69 | public static int rdmHash(String s) { 70 | if (!digests.containsKey(s)) { 71 | int digest = (int) (Math.random() * (Integer.MAX_VALUE - 1)); 72 | digests.put(s, digest); 73 | return digest; 74 | } else return digests.get(s); 75 | } 76 | 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/jdt/visitor/AbstractJdtVisitor.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.jdt.visitor; 2 | 3 | import java.util.ArrayDeque; 4 | import java.util.Deque; 5 | 6 | import org.eclipse.jdt.core.dom.ASTNode; 7 | import org.eclipse.jdt.core.dom.ASTVisitor; 8 | 9 | import edu.lu.uni.serval.jdt.entity.EntityType; 10 | import edu.lu.uni.serval.jdt.tree.ITree; 11 | import edu.lu.uni.serval.jdt.tree.TreeContext; 12 | 13 | public abstract class AbstractJdtVisitor extends ASTVisitor { 14 | 15 | protected TreeContext context = new TreeContext(); 16 | 17 | private Deque trees = new ArrayDeque<>(); 18 | 19 | public AbstractJdtVisitor() { 20 | super(true); 21 | } 22 | 23 | public TreeContext getTreeContext() { 24 | return context; 25 | } 26 | 27 | protected void pushNode(ASTNode n, String label) { 28 | int type = n.getNodeType(); 29 | String typeName = n.getClass().getSimpleName(); 30 | push(type, typeName, label, n.getStartPosition(), n.getLength()); 31 | } 32 | 33 | protected void pushFakeNode(EntityType n, int startPosition, int length) { 34 | int type = -n.ordinal(); // Fake types have negative types (but does it matter ?) 35 | String typeName = n.name(); 36 | push(type, typeName, "", startPosition, length); 37 | } 38 | 39 | protected void push(int type, String typeName, String label, int startPosition, int length) { 40 | ITree t = context.createTree(type, label, typeName); 41 | t.setPos(startPosition); 42 | t.setLength(length); 43 | 44 | if (trees.isEmpty()) 45 | context.setRoot(t); 46 | else { 47 | ITree parent = trees.peek(); 48 | t.setParentAndUpdateChildren(parent); 49 | } 50 | 51 | trees.push(t); 52 | } 53 | 54 | protected ITree getCurrentParent() { 55 | return trees.peek(); 56 | } 57 | 58 | protected void popNode() { 59 | trees.pop(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/jdt/visitor/AbstractRawTokenJdtVisitor.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.jdt.visitor; 2 | 3 | 4 | import org.eclipse.jdt.core.dom.ASTNode; 5 | 6 | /** 7 | * Create AbstractRowTokenJdtVisitor by extending AbstractJdtVisitor and overriding pushNode method. 8 | * 9 | * Remove the ASTNode type in trees. 10 | * 11 | * @author kui.liu 12 | * 13 | */ 14 | public abstract class AbstractRawTokenJdtVisitor extends AbstractJdtVisitor { 15 | 16 | public AbstractRawTokenJdtVisitor() { 17 | super(); 18 | } 19 | 20 | @Override 21 | protected void pushNode(ASTNode n, String label) { 22 | push(0, "", label, n.getStartPosition(), n.getLength()); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/sricmn/akka/WorkerReturnMessage.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.sricmn.akka; 2 | 3 | import java.util.Map; 4 | 5 | public class WorkerReturnMessage { 6 | 7 | private String type; 8 | private Map> topPredictedTokens; 9 | 10 | public String getType() { 11 | return type; 12 | } 13 | 14 | public void setType(String type) { 15 | this.type = type; 16 | } 17 | 18 | public Map> getTopPredictedTokens() { 19 | return topPredictedTokens; 20 | } 21 | 22 | public void setTopPredictedTokens(Map> topPredictedTokens) { 23 | this.topPredictedTokens = topPredictedTokens; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/sricmn/comparativeStudy/EvaluateNgram.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.sricmn.comparativeStudy; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.StringReader; 6 | 7 | import edu.lu.uni.serval.utils.FileHelper; 8 | 9 | public class EvaluateNgram { 10 | 11 | public static void main(String[] args) throws IOException { 12 | int size = 0; 13 | int falseNegatives = 0; 14 | int trueNegatives = 0; 15 | int falsePositives = 0; 16 | int truePositives = 0; 17 | 18 | String content = FileHelper.readFile("OUTPUT/N-gram.results"); 19 | BufferedReader reader = new BufferedReader(new StringReader(content)); 20 | String line = reader.readLine(); 21 | while ((line = reader.readLine()) != null) { 22 | String[] elements = line.split(","); 23 | int predictedResult = Integer.parseInt(elements[0]); 24 | int realResult = Integer.parseInt(elements[1]); 25 | if (realResult == 0) { // inconsistent name 26 | if (predictedResult == 0) { 27 | truePositives ++; 28 | } else { 29 | falseNegatives ++; 30 | } 31 | } else { 32 | if (predictedResult == 1) { 33 | trueNegatives ++; 34 | } else { 35 | falsePositives ++; 36 | } 37 | } 38 | size++; 39 | } 40 | reader.close(); 41 | System.out.println(size); 42 | System.out.println("=======Identify inconsistent methods======"); 43 | System.out.println(" Positives Negative "); 44 | System.out.println("True " + truePositives + " " + trueNegatives + " " + (truePositives + trueNegatives)); 45 | System.out.println("False " + falsePositives + " " + falseNegatives); 46 | edu.lu.uni.serval.utils.Evaluation eval = new edu.lu.uni.serval.utils.Evaluation(truePositives, trueNegatives, falsePositives, falseNegatives); 47 | eval.evaluate(); 48 | System.out.println("------------------------------------------"); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/sricmn/info/MethodInfo.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.sricmn.info; 2 | 3 | import java.io.Serializable; 4 | import java.util.List; 5 | 6 | public class MethodInfo implements Serializable { 7 | 8 | /** 9 | * 10 | */ 11 | private static final long serialVersionUID = 1L; 12 | 13 | private int index; 14 | // private String projectName; 15 | // private String packageName; 16 | // private String className; 17 | private String methodName; 18 | private String info; 19 | private String returnType; 20 | private List methodNameTokens; 21 | private String methodBody; 22 | private Double[] bodyFeatures; 23 | private int listIndex; 24 | 25 | public MethodInfo(int index, String returnType, List methodNameTokens) { 26 | super(); 27 | this.index = index; 28 | this.returnType = returnType; 29 | this.methodNameTokens = methodNameTokens; 30 | 31 | for (String token : methodNameTokens) { 32 | methodName += token; 33 | } 34 | } 35 | 36 | public int getIndex() { 37 | return index; 38 | } 39 | 40 | public String getInfo() { 41 | return info; 42 | } 43 | 44 | public void setInfo(String info) { 45 | this.info = info; 46 | } 47 | 48 | public String getMethodName() { 49 | return methodName; 50 | } 51 | 52 | public String getReturnType() { 53 | return returnType; 54 | } 55 | 56 | public List getMethodNameTokens() { 57 | return methodNameTokens; 58 | } 59 | 60 | public String getMethodBody() { 61 | return methodBody; 62 | } 63 | 64 | public void setMethodBody(String methodBody) { 65 | this.methodBody = methodBody; 66 | } 67 | 68 | public Double[] getBodyFeatures() { 69 | return bodyFeatures; 70 | } 71 | 72 | public void setBodyFeatures(Double[] bodyFeatures) { 73 | this.bodyFeatures = bodyFeatures; 74 | } 75 | 76 | public void setListIndex(int listIndex) { 77 | this.listIndex = listIndex; 78 | } 79 | 80 | public int getListIndex() { 81 | return listIndex; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/sricmn/info/PredictToken.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.sricmn.info; 2 | 3 | public class PredictToken implements Comparable { 4 | 5 | private String token; 6 | private Integer times = 0; 7 | private Double similarity = 0.0; 8 | 9 | public PredictToken(String token) { 10 | this.token = token; 11 | } 12 | 13 | public String getToken() { 14 | return token; 15 | } 16 | 17 | public void setToken(String token) { 18 | this.token = token; 19 | } 20 | 21 | public int getTimes() { 22 | return times; 23 | } 24 | 25 | public void setTimes(int times) { 26 | this.times = times; 27 | } 28 | 29 | public Double getSimilarity() { 30 | return similarity; 31 | } 32 | 33 | public void setSimilarity(Double similarity) { 34 | this.similarity = similarity; 35 | } 36 | 37 | @Override 38 | public boolean equals(Object obj) { 39 | if (obj instanceof PredictToken) { 40 | PredictToken pt = (PredictToken) obj; 41 | return this.token.equals(pt.token); 42 | } 43 | return false; 44 | } 45 | 46 | @Override 47 | public int compareTo(PredictToken pt) { 48 | int compareResult = this.similarity.compareTo(pt.similarity); 49 | if (compareResult == 0) { 50 | compareResult = this.times.compareTo(pt.times); 51 | } 52 | return compareResult; 53 | } 54 | 55 | 56 | } 57 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/java/edu/lu/uni/serval/sricmn/liveStudy/AkkaEvaluation.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.sricmn.liveStudy; 2 | 3 | import akka.actor.ActorRef; 4 | import akka.actor.ActorSystem; 5 | 6 | public class AkkaEvaluation { 7 | 8 | public static void main(String[] args) { 9 | if (args.length != 9) { 10 | System.out.println("Arguments: , , , <1/2>, , , "); 11 | System.exit(0); 12 | } 13 | 14 | int nEpochs = Integer.valueOf(args[0]);//1, 10, 20 15 | int topNum = Integer.valueOf(args[1]); //100 16 | boolean considerReturnType = Boolean.valueOf(args[2]);// true or false. 17 | int fileId = Integer.valueOf(args[3]); // 1 or 2. 18 | String inputPath = args[4]; 19 | int numberOfBodyFeatureWorkers = Integer.valueOf(args[5]);// 50. 20 | int numberOfNameFeatureWorkers = Integer.valueOf(args[6]);// 100. 21 | int startIndex = Integer.valueOf(args[7]); 22 | int endIndex = Integer.valueOf(args[8]); 23 | AkkaEvaluation akkaEval = new AkkaEvaluation(); 24 | akkaEval.evaluate(nEpochs, topNum, considerReturnType, fileId, inputPath, numberOfBodyFeatureWorkers, numberOfNameFeatureWorkers, startIndex, endIndex); 25 | } 26 | 27 | @SuppressWarnings("deprecation") 28 | public void evaluate(int nEpochs, int topNum, boolean considerReturnType, int fileId, String inputPath, int numberOfBodyFeatureWorkers, int numberOfNameFeatureWorkers, int startIndex, int endIndex) { 29 | ActorSystem system = null; 30 | ActorRef parsingActor = null; 31 | try { 32 | system = ActorSystem.create("Evaluation-System"); 33 | parsingActor = system.actorOf(EvaluateActor.props(numberOfBodyFeatureWorkers, numberOfNameFeatureWorkers, inputPath, nEpochs, topNum, considerReturnType, fileId, startIndex, endIndex), "evaluate-actor"); 34 | parsingActor.tell("BEGIN", ActorRef.noSender()); 35 | } catch (Exception e) { 36 | system.shutdown(); 37 | e.printStackTrace(); 38 | } 39 | 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /DebugMethodName/src/main/resource/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ${APP_NAME} 5 | 6 | 7 | 8 | 9 | 10 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n 11 | 12 | 13 | 14 | 15 | ${LOG_HOME}/myLog.log 16 | 17 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n 18 | 19 | 20 | 21 | 22 | 23 | ${LOG_HOME}/%d{yyyy-MM-dd}.log 24 | 30 25 | 26 | 27 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n 28 | 29 | 30 | 10MB 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /DebugMethodName/src/test/java/edu/lu/uni/serval/method/TestMethodNameParser.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.method; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.fail; 5 | 6 | import java.io.IOException; 7 | 8 | import org.junit.Test; 9 | 10 | import edu.lu.uni.serval.method.parser.MethodNameParser; 11 | 12 | public class TestMethodNameParser { 13 | 14 | private MethodNameParser parser = new MethodNameParser(); 15 | 16 | @Test 17 | public void testParseMethodName() { 18 | assertEquals("get,id", parser.parseMethodName("getId")); 19 | assertEquals("get,id", parser.parseMethodName("get_Id")); 20 | assertEquals("get,id", parser.parseMethodName("get_Id0")); 21 | } 22 | 23 | @Test public void testParseWithGenTest() { 24 | try { 25 | assertEquals("get,id,", parser.parseWithGenTest("getId").toString()); 26 | assertEquals("get,id,", parser.parseWithGenTest("get_Id").toString()); 27 | assertEquals("get,id,", parser.parseWithGenTest("get_Id0").toString()); 28 | } catch (IOException e) { 29 | fail("Failed to parse method name with GenTest."); 30 | } 31 | } 32 | 33 | @Test 34 | public void testParseWithCamelCase() { 35 | assertEquals("get,id", parser.parseWithCamelCase("getId")); 36 | assertEquals("get,id", parser.parseWithCamelCase("get_Id")); 37 | assertEquals("get,id", parser.parseWithCamelCase("get_Id0")); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /GitTraveller/README.md: -------------------------------------------------------------------------------- 1 | Git Traveller 2 | --------------- 3 | 4 | Travel a specific git repository to obtain the contains of specific commit(s). 5 | -------------------------------------------------------------------------------- /GitTraveller/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | edu.lu.uni.serval 6 | GitTraveller 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | GitTraveller 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | 16 | 17 | 18 | 19 | 20 | edu.lu.uni 21 | simple-utils 22 | 0.0.1-SNAPSHOT 23 | 24 | 25 | 26 | 27 | org.apache.commons 28 | commons-lang3 29 | 3.7 30 | 31 | 32 | 33 | 34 | org.jsoup 35 | jsoup 36 | 1.11.2 37 | 38 | 39 | 40 | 41 | org.eclipse.jgit 42 | org.eclipse.jgit 43 | 4.7.0.201704051617-r 44 | 45 | 46 | 47 | 48 | org.slf4j 49 | slf4j-api 50 | 1.7.21 51 | 52 | 53 | ch.qos.logback 54 | logback-core 55 | 1.1.7 56 | 57 | 58 | ch.qos.logback 59 | logback-classic 60 | 1.1.7 61 | 62 | 63 | 64 | junit 65 | junit 66 | 4.12 67 | test 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | org.apache.maven.plugins 76 | maven-compiler-plugin 77 | 3.2 78 | 79 | 1.8 80 | 1.8 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /GitTraveller/src/main/java/edu/lu/uni/serval/git/exception/GitRepositoryNotFoundException.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.git.exception; 2 | 3 | public class GitRepositoryNotFoundException extends Exception { 4 | 5 | /** 6 | * 7 | */ 8 | private static final long serialVersionUID = 8060210508833740142L; 9 | 10 | public GitRepositoryNotFoundException() { 11 | 12 | } 13 | 14 | public GitRepositoryNotFoundException(String message) { 15 | super(message); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /GitTraveller/src/main/java/edu/lu/uni/serval/git/exception/NotValidGitRepositoryException.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.git.exception; 2 | 3 | public class NotValidGitRepositoryException extends Exception { 4 | 5 | /** 6 | * 7 | */ 8 | private static final long serialVersionUID = 1187015266656167209L; 9 | 10 | public NotValidGitRepositoryException() { 11 | 12 | } 13 | 14 | public NotValidGitRepositoryException(String message) { 15 | super(message); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /GitTraveller/src/main/java/edu/lu/uni/serval/git/filter/CommitFilter.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.git.filter; 2 | 3 | import org.eclipse.jgit.revwalk.RevCommit; 4 | 5 | public class CommitFilter { 6 | 7 | public static boolean filterInitializeCommit(RevCommit revCommit) { 8 | boolean initializeCommit = false; 9 | if (revCommit.getParentCount() == 0) { 10 | initializeCommit = true; 11 | } 12 | return initializeCommit; 13 | } 14 | 15 | public static boolean filterMergeCommit(RevCommit revCommit) { 16 | boolean mergeCommit = false; 17 | if (revCommit.getParentCount() > 1 || revCommit.getShortMessage().toLowerCase().startsWith("merge ") 18 | || revCommit.getShortMessage().toLowerCase().startsWith("merged ")) { 19 | mergeCommit = true; 20 | } 21 | return mergeCommit; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /GitTraveller/src/main/java/edu/lu/uni/serval/git/filter/DiffEntryFilter.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.git.filter; 2 | 3 | import org.eclipse.jgit.diff.DiffEntry; 4 | 5 | public class DiffEntryFilter { 6 | 7 | public static boolean filterJavaFile(DiffEntry diffentry) { 8 | boolean isJava = false; 9 | 10 | if (diffentry.getNewPath().toString().endsWith(".java")) { 11 | isJava = true; 12 | } 13 | 14 | return isJava; 15 | } 16 | 17 | public static boolean filterModifyType(DiffEntry diffentry) { 18 | boolean isModify = false; 19 | 20 | if (diffentry.getChangeType().equals(DiffEntry.ChangeType.MODIFY)) { 21 | isModify = true; 22 | } 23 | 24 | return isModify; 25 | } 26 | 27 | public static boolean filterAddType(DiffEntry diffentry) { 28 | boolean isAdd = false; 29 | 30 | if (diffentry.getChangeType().equals(DiffEntry.ChangeType.ADD)) { 31 | isAdd = true; 32 | } 33 | 34 | return isAdd; 35 | } 36 | 37 | public static boolean filterDeleteType(DiffEntry diffentry) { 38 | boolean isDelete = false; 39 | 40 | if (diffentry.getChangeType().equals(DiffEntry.ChangeType.DELETE)) { 41 | isDelete = true; 42 | } 43 | 44 | return isDelete; 45 | } 46 | 47 | public static boolean filterRenameType(DiffEntry diffentry) { 48 | boolean isRename = false; 49 | 50 | if (diffentry.getChangeType().equals(DiffEntry.ChangeType.RENAME)) { 51 | isRename = true; 52 | } 53 | 54 | return isRename; 55 | } 56 | 57 | public static boolean filterCopyType(DiffEntry diffentry) { 58 | boolean isCopy = false; 59 | 60 | if (diffentry.getChangeType().equals(DiffEntry.ChangeType.COPY)) { 61 | isCopy = true; 62 | } 63 | 64 | return isCopy; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /GitTraveller/src/main/java/edu/lu/uni/serval/git/filter/LineDiffFilter.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.git.filter; 2 | 3 | import java.util.regex.Matcher; 4 | import java.util.regex.Pattern; 5 | 6 | public class LineDiffFilter { 7 | private static final String REGULAR_EXPRESSION = "^@@\\s\\-\\d+,*\\d*\\s\\+\\d+,*\\d*\\s@@$"; //@@ -21,0 +22,2 @@ 8 | private static Pattern pattern = Pattern.compile(REGULAR_EXPRESSION); 9 | 10 | public static boolean filterSignal(String string) { 11 | boolean flag = false; 12 | 13 | Matcher res = pattern.matcher(string); 14 | if (res.matches()) { 15 | flag = true; 16 | } 17 | 18 | return flag; 19 | } 20 | 21 | public static boolean filterString(String string) { 22 | boolean flag = false; 23 | 24 | if (string.startsWith("@@") && string.endsWith("@@") && 25 | string.contains("-") && string.contains("+")) { 26 | flag = true; 27 | } 28 | 29 | return flag; 30 | } 31 | 32 | public static boolean filterImport(String string) { 33 | boolean flag = false; 34 | 35 | if (string.substring(1).trim().startsWith("import")) { 36 | flag = true; 37 | } 38 | 39 | return flag; 40 | } 41 | 42 | public static boolean filterComment(String string) { 43 | boolean flag = false; 44 | String s = string.substring(1).trim(); 45 | /* 46 | * startsWith("*") is not very accurate, if the previous statement not endsWith(";") and is a statement, this predicate is OK. 47 | */ 48 | // startsWith("*/"). 49 | if (s.startsWith("/*") || s.startsWith("*") || s.startsWith("//")) { 50 | flag = true; 51 | } 52 | return flag; 53 | } 54 | 55 | public static boolean filterAnnotation(String string) { 56 | if (string.substring(1).trim().startsWith("@")){ 57 | return true; 58 | } 59 | return false; 60 | } 61 | 62 | public static void main(String[] args) { 63 | System.out.println(filterSignal("@@ -895,0 +896 @@")); 64 | //@@ -209 +209 @@ 65 | //@@ -3513 +3513,19 @@ 66 | //@@ -895,0 +896,6 @@ 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /GitTraveller/src/main/java/edu/lu/uni/serval/git/travel/BugRelatedWords.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.git.travel; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | public class BugRelatedWords { 8 | 9 | public enum CommitMessageKeyWords { 10 | bug, 11 | error, 12 | fault, 13 | fix, 14 | patch, 15 | repair 16 | } 17 | 18 | public static final List BUG_RELATED_KEY_WORDS = new ArrayList<>(); 19 | 20 | static { 21 | List tokens = Arrays.asList(CommitMessageKeyWords.values()); 22 | for (Object obj : tokens) { 23 | BUG_RELATED_KEY_WORDS.add(obj.toString()); 24 | } 25 | } 26 | 27 | public static void main(String[] args) { 28 | System.out.println(BUG_RELATED_KEY_WORDS); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /GitTraveller/src/main/java/edu/lu/uni/serval/git/travel/CommitDiffEntry.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.git.travel; 2 | 3 | import org.eclipse.jgit.diff.DiffEntry; 4 | import org.eclipse.jgit.revwalk.RevCommit; 5 | 6 | public class CommitDiffEntry { 7 | 8 | private RevCommit commit; 9 | private RevCommit parentCommit; 10 | private DiffEntry diffentry; 11 | 12 | public RevCommit getCommit() { 13 | return commit; 14 | } 15 | 16 | public DiffEntry getDiffentry() { 17 | return diffentry; 18 | } 19 | 20 | public RevCommit getParentCommit() { 21 | return parentCommit; 22 | } 23 | 24 | public CommitDiffEntry(RevCommit commit, RevCommit parentCommit, DiffEntry diffentry) { 25 | this.commit = commit; 26 | this.parentCommit = parentCommit; 27 | this.diffentry = diffentry; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /GitTraveller/src/main/java/edu/lu/uni/serval/git/travel/CommitFile.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.git.travel; 2 | 3 | public class CommitFile implements Comparable { 4 | 5 | private String fileName; 6 | private String commitId; 7 | private Integer commitTime; 8 | 9 | public String getFileName() { 10 | return fileName; 11 | } 12 | 13 | public void setFileName(String fileName) { 14 | this.fileName = fileName; 15 | } 16 | 17 | public String getCommitId() { 18 | return commitId; 19 | } 20 | 21 | public void setCommitId(String commitId) { 22 | this.commitId = commitId; 23 | } 24 | 25 | public Integer getCommitTime() { 26 | return commitTime; 27 | } 28 | 29 | public void setCommitTime(Integer commitTime) { 30 | this.commitTime = commitTime; 31 | } 32 | 33 | @Override 34 | public int compareTo(CommitFile cf) { 35 | return this.commitTime.compareTo(cf.commitTime); 36 | } 37 | 38 | @Override 39 | public boolean equals(Object obj) { 40 | if (obj instanceof CommitFile) { 41 | CommitFile cf = (CommitFile) obj; 42 | if (cf.fileName.equals(this.fileName) && cf.commitId.equals(this.commitId)) { 43 | return true; 44 | } 45 | } 46 | return false; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /GitTraveller/src/main/java/edu/lu/uni/serval/git/travel/MyDiffEntry.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.git.travel; 2 | 3 | import java.util.List; 4 | 5 | public class MyDiffEntry { 6 | 7 | private String revFile; //commitId + file_path + file_name. 8 | private String prevFile;//prev_ + commitId + file_path + file_name. 9 | private List modifiedDetails; 10 | private String commitId; 11 | private String prevCommitId; // parent commit id. 12 | 13 | public MyDiffEntry() { 14 | 15 | } 16 | 17 | public MyDiffEntry(String revFile, String prevFile, List modifiedDetails) { 18 | this.revFile = revFile; 19 | this.prevFile = prevFile; 20 | this.modifiedDetails = modifiedDetails; 21 | } 22 | 23 | public String getCommitId() { 24 | return commitId; 25 | } 26 | 27 | public void setCommitId(String commitId) { 28 | this.commitId = commitId; 29 | } 30 | 31 | public String getPrevCommitId() { 32 | return prevCommitId; 33 | } 34 | 35 | public void setPrevCommitId(String prevCommitId) { 36 | this.prevCommitId = prevCommitId; 37 | } 38 | 39 | public String getRevFile() { 40 | return revFile; 41 | } 42 | 43 | public void setRevFile(String revFile) { 44 | this.revFile = revFile; 45 | } 46 | 47 | public String getPrevFile() { 48 | return prevFile; 49 | } 50 | 51 | public void setPrevFile(String prevFile) { 52 | this.prevFile = prevFile; 53 | } 54 | 55 | public List getModifiedDetails() { 56 | return modifiedDetails; 57 | } 58 | 59 | public void setModifiedDetails(List modifiedDetails) { 60 | this.modifiedDetails = modifiedDetails; 61 | } 62 | 63 | @Override 64 | public String toString() { 65 | String delAddLines = ""; 66 | for (ModifiedDetails md : modifiedDetails) { 67 | delAddLines += md.toString(); 68 | } 69 | return "======Previous File:" + prevFile + "======\n" + 70 | "======Revised File:" + revFile + "======\n" + delAddLines + "\n"; 71 | } 72 | 73 | public boolean onlyContainsDelLines() { 74 | int addCounts = 0; 75 | 76 | for (ModifiedDetails md : modifiedDetails) { 77 | if (md.getAddLines() == null || md.getAddLines().equals("")) 78 | addCounts ++; 79 | } 80 | 81 | if (addCounts == modifiedDetails.size()) { 82 | return true; 83 | } 84 | return false; 85 | } 86 | 87 | public boolean onlyContainsAddLines() { 88 | int delCounts = 0; 89 | 90 | for (ModifiedDetails md : modifiedDetails) { 91 | if (md.getDelLines() == null || md.getDelLines().equals("")) 92 | delCounts ++; 93 | } 94 | 95 | if (delCounts == modifiedDetails.size()) { 96 | return true; 97 | } 98 | return false; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /GitTraveller/src/test/java/edu/lu/uni/serval/AppTest.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval; 2 | 3 | import junit.framework.Test; 4 | import junit.framework.TestCase; 5 | import junit.framework.TestSuite; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest 11 | extends TestCase 12 | { 13 | /** 14 | * Create the test case 15 | * 16 | * @param testName name of the test case 17 | */ 18 | public AppTest( String testName ) 19 | { 20 | super( testName ); 21 | } 22 | 23 | /** 24 | * @return the suite of tests being tested 25 | */ 26 | public static Test suite() 27 | { 28 | return new TestSuite( AppTest.class ); 29 | } 30 | 31 | /** 32 | * Rigourous Test :-) 33 | */ 34 | public void testApp() 35 | { 36 | assertTrue( true ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /LearningModel/src/main/java/edu/lu/uni/Configuration.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni; 2 | 3 | public class Configuration { 4 | public static final String ROOT_PATH = "../Data/Output/"; 5 | 6 | public static final String TOKENIZED_METHODS_PATH = ROOT_PATH + "tokenization/"; 7 | public static final String RENAMED_METHODS_PATH = ROOT_PATH + "RenamedMethods/"; 8 | public static final String JAVA_REPO_NAMES_FILE = "../Data/JavaRepos/repos.txt"; 9 | 10 | public static final String DL_DATA_PATH = ROOT_PATH + "DL_Data/"; 11 | public static final String SELECTED_DATA_PATH = DL_DATA_PATH + "SelectedData/"; 12 | public static final String SELECTED_RENAMED_DATA_PATH = DL_DATA_PATH + "RenamedMethods/"; 13 | 14 | public static final String DL_INPUT_DATA_PATH = DL_DATA_PATH + "DLinput/"; 15 | 16 | public static final String ENCODED_METHOD_BODY_FILE_PATH = DL_DATA_PATH + "encoding/encoded_method_bodies.txt"; // output 17 | 18 | // token embedding with word2vec 19 | public static final int SIZE_OF_EMBEDDED_VECTOR = 300; 20 | public static final String EMBEDDED_DATA_FILE_PATH = DL_DATA_PATH + "data_for_CNN/vectorized_tokens.csv"; 21 | 22 | 23 | /** 24 | * Configuration of the third step: extract features of method bodies by deep learning with the CNN algorithm. 25 | */ 26 | public static final int BATCH_SIZE = 1024; 27 | public static final int SIZE_OF_FEATURE_VECTOR = 300; // size of extracted feature vectors 28 | public static final String DATA_APPZENDED_ZERO = DL_DATA_PATH + "data_for_CNN/append_zero/"; // file path of output 29 | public static final String DATA_STANDARDIZED = DL_DATA_PATH + "data_for_CNN/standardized_data/"; // file path of output 30 | public static final String DATA_EXTRACTED_FEATURE = DL_DATA_PATH + "CNN_extracted_feature/"; // file path of output 31 | public static final String DATA_EXTRACTED_FEATURE_BY_PROJECTS = DL_DATA_PATH + "extracted_features_by_project/"; 32 | public static final int N_EPOCHS = 10; 33 | 34 | public static final String EVALUATION_DATA_PATH = ROOT_PATH + "Eva/"; 35 | 36 | } 37 | -------------------------------------------------------------------------------- /LearningModel/src/main/java/edu/lu/uni/serval/deeplearner/MyTokenPreprocessor.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.deeplearner; 2 | 3 | import org.deeplearning4j.text.tokenization.tokenizer.TokenPreProcess; 4 | 5 | public class MyTokenPreprocessor implements TokenPreProcess { 6 | 7 | @Override 8 | public String preProcess(String token) { 9 | return token; 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /LearningModel/src/main/java/edu/lu/uni/serval/dlMethods/DataPreparer.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.dlMethods; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.StringReader; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import edu.lu.uni.Configuration; 10 | import edu.lu.uni.serval.utils.FileHelper; 11 | 12 | /** 13 | * Prepare data for deep learning of methods. 14 | * @author kui.liu 15 | * 16 | */ 17 | public class DataPreparer { 18 | private static final int QUANTITY = 1; // the number of methods of which names start with the same token. 19 | private static final int MIN_SIZE = 0; // The minimum size of vectors. 20 | 21 | public static void main(String[] args) throws IOException { 22 | List projects = readProjects(); 23 | for (String project : projects) { 24 | String inputPath = Configuration.TOKENIZED_METHODS_PATH + project + "/"; 25 | String renamedMethodsPath = Configuration.RENAMED_METHODS_PATH + project + "/ActualRenamed/"; 26 | String outputPath1 = Configuration.SELECTED_DATA_PATH + project + "/"; 27 | String outputPath2 = Configuration.SELECTED_RENAMED_DATA_PATH + project + "/"; 28 | 29 | /** 30 | * Prepare data: 31 | * 32 | * Figure out the common first tokens of all method names. Select the methods of 33 | * which method names start with these common first tokens. 34 | */ 35 | DataInitializer dataInit = new DataInitializer(); 36 | dataInit.QUANTITY = QUANTITY; 37 | dataInit.MIN_SIZE = MIN_SIZE; 38 | dataInit.inputPath = inputPath; 39 | dataInit.outputPath1 = outputPath1; 40 | dataInit.outputPath2 = outputPath2; 41 | dataInit.renamedMethodsPath = renamedMethodsPath; 42 | dataInit.initializeData(); 43 | dataInit.selectMethod(); 44 | } 45 | 46 | DataMerger.merge(); 47 | } 48 | 49 | public static List readProjects() { 50 | List projects = new ArrayList<>(); 51 | String content = FileHelper.readFile(Configuration.JAVA_REPO_NAMES_FILE); 52 | BufferedReader reader = new BufferedReader(new StringReader(content)); 53 | try { 54 | String line = null; 55 | while ((line = reader.readLine()) != null) { 56 | projects.add(line); 57 | } 58 | } catch (IOException e) { 59 | e.printStackTrace(); 60 | } finally { 61 | try { 62 | if (reader != null) { 63 | reader.close(); 64 | reader = null; 65 | } 66 | } catch (IOException e) { 67 | e.printStackTrace(); 68 | } 69 | } 70 | return projects; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /LearningModel/src/main/java/edu/lu/uni/serval/dlMethods/EmbedCodeTokens.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.dlMethods; 2 | 3 | import java.io.IOException; 4 | 5 | import edu.lu.uni.Configuration; 6 | import edu.lu.uni.serval.utils.FileHelper; 7 | 8 | /** 9 | * Embedding tokens and vectorize method bodies. 10 | * 11 | * @author kui.liu 12 | * 13 | */ 14 | public class EmbedCodeTokens { 15 | 16 | public static void main(String[] args) throws IOException { 17 | String inputPath = Configuration.DL_DATA_PATH; 18 | String outputPath = Configuration.DL_INPUT_DATA_PATH; 19 | FileHelper.deleteDirectory(outputPath); 20 | 21 | TokensEmbedder embedder = new TokensEmbedder(); 22 | embedder.inputPath = inputPath; 23 | embedder.outputPath = outputPath; 24 | embedder.mergeData(false); 25 | embedder.embedTokens(); 26 | embedder.vectorizedData(true); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /LearningModel/src/main/java/edu/lu/uni/serval/dlMethods/MethodNameLearner.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.dlMethods; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | import edu.lu.uni.Configuration; 7 | import edu.lu.uni.serval.MethodName.detector.MethodNameFeatureLearner; 8 | 9 | /** 10 | * Learn features of method names with ParagraphVectors. 11 | * 12 | * @author kui.liu 13 | * 14 | */ 15 | public class MethodNameLearner { 16 | 17 | public static void main(String[] args) throws IOException { 18 | MethodNameFeatureLearner learner = new MethodNameFeatureLearner(); 19 | String testingData = Configuration.SELECTED_RENAMED_DATA_PATH + "ParsedMethodNames.txt"; 20 | String outputPath = Configuration.EVALUATION_DATA_PATH; 21 | 22 | // Selecting data for method name feature learning. 23 | String testingMethodNamesFile = outputPath + "TestingMethodNames.txt"; 24 | learner.prepareData(testingData, testingMethodNamesFile, outputPath + "TestingLabels.txt"); 25 | 26 | String trainingData = Configuration.SELECTED_DATA_PATH + "SelectedMethodInfo.txt"; 27 | String featureLearningData1 = outputPath + "FeatureLearningData1.txt"; // without return type. 28 | String featureLearningData2 = outputPath + "FeatureLearningData2.txt"; // with return type. 29 | String returnTypeOfTestingFile = Configuration.SELECTED_RENAMED_DATA_PATH + "MethodInfo.txt"; 30 | 31 | learner.prepareFeatureLearningData(trainingData, testingMethodNamesFile, featureLearningData1, featureLearningData2, returnTypeOfTestingFile); 32 | 33 | learner.learnFeatures(new File(featureLearningData1), outputPath + "MethodNameFeatures_1_Size=" + learner.SIZE + ".txt"); 34 | learner.learnFeatures(new File(featureLearningData2), outputPath + "MethodNameFeatures_2_Size=" + learner.SIZE + ".txt"); 35 | learner.learnFeatures(new File(featureLearningData1 + ".bak"), outputPath + "MethodNameFeatures_1_Size=" + learner.SIZE + ".txt.bak"); 36 | learner.learnFeatures(new File(featureLearningData2 + ".bak"), outputPath + "MethodNameFeatures_2_Size=" + learner.SIZE + ".txt.bak"); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /LearningModel/src/main/java/edu/lu/uni/serval/dlMethods/liveStudy/Step1.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.dlMethods.liveStudy; 2 | 3 | import java.io.IOException; 4 | 5 | import edu.lu.uni.Configuration; 6 | import edu.lu.uni.serval.utils.FileHelper; 7 | 8 | /** 9 | * Prepare data for deep learning of methods. 10 | * @author kui.liu 11 | * 12 | */ 13 | public class Step1 { 14 | 15 | private static final int QUANTITY = 1;// or 500, the number of methods of which names start with the same token. 16 | private static final int MIN_SIZE = 0;// The minimum size of vectors. 17 | 18 | public static void main(String[] args) throws IOException { 19 | String inputPath = Configuration.TOKENIZED_METHODS_PATH; 20 | String outputPath = Configuration.ROOT_PATH + "LiveStudy/"; 21 | FileHelper.deleteDirectory(outputPath); 22 | 23 | /** 24 | * Prepare data: 25 | * 26 | * Figure out the common first tokens of all method names. 27 | * Select the methods of which method names start with these common first tokens. 28 | * Training data: 90%. 29 | * Testing data: 10%. 30 | */ 31 | DataInitializer dataInit = new DataInitializer(); 32 | dataInit.QUANTITY = QUANTITY; 33 | dataInit.MIN_SIZE = MIN_SIZE; 34 | dataInit.inputPath = inputPath; 35 | dataInit.outputPath = outputPath; 36 | dataInit.selectTrainingAndTestingData(); 37 | dataInit.exportTrainingAndTestingMethodBodies(); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /LearningModel/src/main/java/edu/lu/uni/serval/dlMethods/liveStudy/Step2.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.dlMethods.liveStudy; 2 | 3 | import java.io.IOException; 4 | 5 | import edu.lu.uni.serval.dlMethods.TokensEmbedder; 6 | import edu.lu.uni.serval.utils.FileHelper; 7 | 8 | /** 9 | * Embedding tokens and vectorize method bodies. 10 | * 11 | * @author kui.liu 12 | * 13 | */ 14 | public class Step2 { 15 | 16 | public static void main(String[] args) throws IOException { 17 | String inputPath = args[0];//"../OUTPUT_4/DL_Data/"; 18 | String outputPath = args[1];//"../OUTPUT_4/DL_Data/DLinput/"; 19 | boolean mergeData = Boolean.valueOf(args[2]); 20 | FileHelper.deleteDirectory(outputPath); 21 | TokensEmbedder embedder = new TokensEmbedder(); 22 | embedder.inputPath = inputPath; 23 | embedder.outputPath = outputPath; 24 | embedder.mergeData(mergeData); 25 | embedder.embedTokens(); 26 | embedder.vectorizedData(mergeData); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /LearningModel/src/main/java/edu/lu/uni/serval/dlMethods/liveStudy/Step3.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.dlMethods.liveStudy; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.io.IOException; 6 | 7 | import edu.lu.uni.Configuration; 8 | import edu.lu.uni.deeplearning.extractor.CNNFeatureExtractor; 9 | import edu.lu.uni.serval.utils.FileHelper; 10 | 11 | /** 12 | * Feature learning. 13 | * 14 | * @author kui.liu 15 | * 16 | */ 17 | public class Step3 { 18 | 19 | public static void main(String[] args) throws FileNotFoundException, IOException, InterruptedException { 20 | String rootPath = args[0];//"../OUTPUT_3/DL_Data/"; 21 | String inputPath = rootPath + "DLinput/"; 22 | File[] files = new File(inputPath).listFiles(); 23 | File trainingDataFile = null; 24 | File testingDataFile = null; 25 | // File renamedDataFile = null; 26 | int maxSize = 0; 27 | 28 | for (File file : files) { 29 | String fileName = file.getName(); 30 | if (fileName.startsWith("TrainingData_")) { 31 | trainingDataFile = file; 32 | maxSize = Integer.parseInt(fileName.substring("TrainingData_Tokens_MaxSize=".length(), fileName.lastIndexOf(".csv"))); 33 | } else if (fileName.startsWith("TestingData_")) { 34 | testingDataFile = file; 35 | } 36 | } 37 | 38 | int nEpochs = Integer.valueOf(args[1]);//1, 10, 20 39 | String outputPath = rootPath + "DLoutput_" + nEpochs + "/"; 40 | FileHelper.deleteDirectory(outputPath); 41 | 42 | int sizeOfTokensVector = maxSize; 43 | int sizeOfEmbeddedVector = 300; 44 | int batchSize = Configuration.BATCH_SIZE; 45 | int sizeOfFeatureVector = Configuration.SIZE_OF_FEATURE_VECTOR; 46 | 47 | 48 | CNNFeatureExtractor learner = new CNNFeatureExtractor(trainingDataFile, sizeOfTokensVector, sizeOfEmbeddedVector, batchSize, sizeOfFeatureVector); 49 | learner.setNumberOfEpochs(nEpochs); 50 | learner.setSeed(123); 51 | learner.setNumOfOutOfLayer1(20); 52 | learner.setNumOfOutOfLayer2(50); 53 | learner.setOutputPath(outputPath); 54 | 55 | learner.extracteFeaturesWithCNN(); 56 | 57 | File modelFile = new File(outputPath + "CNNoutput.zip"); 58 | learner.setModelFile(modelFile); 59 | learner.setTestingData(testingDataFile); 60 | learner.extracteFeaturesWithCNNByLoadingModel(); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /LearningModel/src/main/java/edu/lu/uni/serval/dlMethods/liveStudy/Step4.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.dlMethods.liveStudy; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | import edu.lu.uni.serval.MethodName.detector.MethodNameFeatureLearner; 7 | 8 | /** 9 | * Learn features of method names with ParagraphVectors. 10 | * 11 | * @author kui.liu 12 | * 13 | */ 14 | public class Step4 { 15 | 16 | public static void main(String[] args) throws IOException { 17 | MethodNameFeatureLearner learner = new MethodNameFeatureLearner(); 18 | String inputPath = args[0]; // "../OUTPUT_4/LiveStudy/"; 19 | String outputPath = args[1]; // "../OUTPUT_4/LiveStudy/NameFeatures/"; 20 | String trainingData = inputPath + "TrainingData/MethodsInfo.txt"; 21 | String testingData = inputPath + "TestingData/MethodsInfo.txt"; 22 | String featureLearningData1 = outputPath + "FeatureLearningData1.txt"; // without return type. 23 | String featureLearningData2 = outputPath + "FeatureLearningData2.txt"; // with return type. 24 | learner.prepareFeatureLearningData(trainingData, featureLearningData1, featureLearningData2, false); 25 | learner.prepareFeatureLearningData(testingData, featureLearningData1, featureLearningData2, true); 26 | learner.learnFeatures(new File(featureLearningData1), outputPath + "MethodNameFeatures_1_Size=" + learner.SIZE + ".txt"); 27 | learner.learnFeatures(new File(featureLearningData2), outputPath + "MethodNameFeatures_2_Size=" + learner.SIZE + ".txt"); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /LearningModel/src/main/java/edu/lu/uni/serval/dlMethods/liveStudy/Step5.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.dlMethods.liveStudy; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.FileInputStream; 5 | import java.io.FileReader; 6 | import java.io.IOException; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import java.util.Scanner; 10 | 11 | import edu.lu.uni.serval.utils.FileHelper; 12 | 13 | public class Step5 { 14 | 15 | public static void main(String[] args) throws IOException { 16 | String inputFile = args[0];//../OUTPUT_4/LiveStudy/TestingData/MethodsInfo.txt 17 | String outputFile = args[1];//../OUTPUT_4/LiveStudy/TestingData/method_bodies.txt 18 | String methodBodiesFile = "../OUTPUT/tokenization/method_bodies.txt"; 19 | List selectedIndexes = readIndexes(inputFile); 20 | FileInputStream fis = new FileInputStream(methodBodiesFile); 21 | Scanner scanner = new Scanner(fis); 22 | StringBuilder methods = new StringBuilder(); 23 | int index = -1; 24 | StringBuilder singleMethod = new StringBuilder(); 25 | while (scanner.hasNextLine()) { 26 | String line = scanner.nextLine(); 27 | if ("#METHOD_BODY#========================".equals(line)) { 28 | if (singleMethod.length() > 0) { 29 | if (selectedIndexes.contains(index)) { 30 | methods.append(singleMethod).append("\n"); 31 | } 32 | } 33 | singleMethod.setLength(0); 34 | index ++; 35 | } 36 | singleMethod.append(line).append("\n"); 37 | } 38 | scanner.close(); 39 | fis.close(); 40 | 41 | if (selectedIndexes.contains(index)) { 42 | methods.append(singleMethod).append("\n"); 43 | } 44 | 45 | FileHelper.outputToFile(outputFile, methods, false); 46 | } 47 | 48 | private static List readIndexes(String inputFile) throws IOException { 49 | List indexes = new ArrayList<>(); 50 | FileReader fileReader = new FileReader(inputFile); 51 | BufferedReader reader = new BufferedReader(fileReader); 52 | String line = null; 53 | while ((line = reader.readLine()) != null) { 54 | int index = Integer.valueOf(line.substring(0, line.indexOf("@"))); 55 | indexes.add(index); 56 | } 57 | reader.close(); 58 | fileReader.close(); 59 | return indexes; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /LearningModel/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ${APP_NAME} 5 | 6 | 7 | 8 | 9 | 10 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n 11 | 12 | 13 | 14 | 15 | ${LOG_HOME}/myLog.log 16 | 17 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n 18 | 19 | 20 | 21 | 22 | 23 | ${LOG_HOME}/%d{yyyy-MM-dd}.log 24 | 30 25 | 26 | 27 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n 28 | 29 | 30 | 10MB 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # debug-method-name 2 | 3 | Description 4 | ------------ 5 | A tool of spotting and refactoring inconsistent method names learned from real-world code bases. 6 | This work will be presented at ICSE 2019. 7 | 8 | Requirement 9 | ------------ 10 | - Java 1.8 11 | - Maven 3.3.9 12 | 13 | 14 | How to run debug-method-name 15 | ----------------------------- 16 | 1. Clone the repo: 17 | - `git clone https://github.com/TruX-DTF/debug-method-name.git` 18 | 19 | 2. Preparing process: 20 | - `cd debug-method-name/simple-utils` 21 | - `mvn install` 22 | - `cd ../GitTraveller` 23 | - `mvn install` 24 | - `cd ../gumtree` 25 | - `mvn install -DskipTests=true` 26 | 27 | 3. Prepare data: clone Java repositories from GitHub. 28 | - `cd ../Data/JavaRepos/` 29 | - `./git-clone-repos.sh` 30 | 31 | 4. Prepare data: Collect the renamed methods from the commit history of Java programs. 32 | - `cd ../../RenamedMethodsCollector` 33 | - `mvn dependency:copy-dependencies` 34 | - `mvn package` 35 | - `mv target/RenamedMethodsCollector-0.0.1-SNAPSHOT.jar target/dependency` 36 | - `java -cp "target/dependency/*" -Xmx8g edu.lu.uni.serval.renamed.methods.Main` 37 | 38 | 5. Prepare data: Parse methods in Java projects. 39 | **Note that:** it will take **a long time and a big space** to prepare the data for this experiment, we recommend to use the data we already have to proceed the following steps. 40 | - `cd ../DebugMethodName` 41 | - `mvn dependency:copy-dependencies` 42 | - `mvn package` 43 | - `mv target/DebugMethodName-0.0.1-SNAPSHOT.jar target/dependency` 44 | - `java -cp "target/dependency/*" -Xmx8g edu.lu.uni.serval.MainParser `, `` is the index of a Java project in the Java project list (`repos.txt`). 45 | 46 | 6. Prepare data: Prepare data for deep learning of methods. 47 | - `cd ../LearningModel` 48 | - `mvn dependency:copy-dependencies` 49 | - `mvn package` 50 | - `mv target/LearningModel-0.0.1-SNAPSHOT.jar target/dependency` 51 | - `java -cp "target/dependency/*" -Xmx8g edu.lu.uni.serval.dlMethods.DataPreparer` Prepare data for learning process. 52 | 53 | 7. Model Learning: 54 | **Note that:** it will take **a long time and a huge space** to finish the learning process. 55 | - `java -cp "target/dependency/*" -Xmx256g edu.lu.uni.serval.dlMethods.EmbedCodeTokens` Embed method body code tokens. 56 | - `java -cp "target/dependency/*" -Xmx1024g edu.lu.uni.serval.dlMethods.MethodBodyCodeLearner` Learn method body features with CNNs. 57 | - `java -cp "target/dependency/*" -Xmx1024g edu.lu.uni.serval.dlMethods.MethodNameLearner` Learn method name features with ParagraphVectors. 58 | 59 | 8. Spot and Refactor inconsistent method names: 60 | - `cd ../DebugMethodName` 61 | - `java -cp "target/dependency/*" -Xmx8g edu.lu.uni.serval.Main` 62 | -------------------------------------------------------------------------------- /RenamedMethodsCollector/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | edu.lu.uni.serval 6 | RenamedMethodsCollector 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | RenamedMethodsCollector 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | 2.4.11 16 | 2.0.0-SNAPSHOT 17 | 18 | 19 | 20 | 21 | 22 | org.apache.commons 23 | commons-lang3 24 | 3.7 25 | 26 | 27 | 28 | 29 | com.typesafe.akka 30 | akka-actor_2.11 31 | ${akka.version} 32 | 33 | 34 | 35 | edu.lu.uni.serval 36 | GitTraveller 37 | 0.0.1-SNAPSHOT 38 | 39 | 40 | 41 | com.github.gumtreediff 42 | core 43 | 2.0.0-MethodParser 44 | 45 | 46 | 47 | com.github.gumtreediff 48 | gen.jdt 49 | 2.0.0-MethodParser 50 | 51 | 52 | 53 | junit 54 | junit 55 | 4.12 56 | test 57 | 58 | 59 | 60 | 61 | 62 | 63 | org.apache.maven.plugins 64 | maven-compiler-plugin 65 | 3.2 66 | 67 | 1.8 68 | 1.8 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /RenamedMethodsCollector/src/main/java/edu/lu/uni/serval/diffentry/DiffEntryHunk.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.diffentry; 2 | 3 | public class DiffEntryHunk { 4 | 5 | private int bugLineStartNum; 6 | private int fixLineStartNum; 7 | private int bugRange; 8 | private int fixRange; 9 | private String hunk; 10 | 11 | public DiffEntryHunk(int bugLineStartNum, int fixLineStartNum, int bugRange, int fixRange) { 12 | super(); 13 | this.bugLineStartNum = bugLineStartNum; 14 | this.fixLineStartNum = fixLineStartNum; 15 | this.bugRange = bugRange; 16 | this.fixRange = fixRange; 17 | } 18 | 19 | public int getBugLineStartNum() { 20 | return bugLineStartNum; 21 | } 22 | 23 | public int getFixLineStartNum() { 24 | return fixLineStartNum; 25 | } 26 | 27 | public int getBugRange() { 28 | return bugRange; 29 | } 30 | 31 | public int getFixRange() { 32 | return fixRange; 33 | } 34 | 35 | public String getHunk() { 36 | return hunk; 37 | } 38 | 39 | public void setHunk(String hunk) { 40 | this.hunk = hunk; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "@@ -" + this.bugLineStartNum + ", " + this.bugRange + " +" + this.fixLineStartNum + ", " + this.fixRange + "\n" + this.hunk; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /RenamedMethodsCollector/src/main/java/edu/lu/uni/serval/diffentry/RegExp.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.diffentry; 2 | 3 | import java.util.regex.Matcher; 4 | import java.util.regex.Pattern; 5 | 6 | public class RegExp { 7 | private static final String REGULAR_EXPRESSION = "^@@\\s\\-\\d+,*\\d*\\s\\+\\d+,*\\d*\\s@@$"; //@@ -21,0 +22,2 @@ 8 | private static Pattern pattern = Pattern.compile(REGULAR_EXPRESSION); 9 | 10 | public static boolean filterSignal(String string) { 11 | boolean flag = false; 12 | 13 | Matcher res = pattern.matcher(string); 14 | if (res.matches()) { 15 | flag = true; 16 | } 17 | 18 | return flag; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /RenamedMethodsCollector/src/main/java/edu/lu/uni/serval/gumtree/regroup/SimpleTree.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.gumtree.regroup; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class SimpleTree { 7 | 8 | private String nodeType; 9 | private String label; 10 | private SimpleTree parent; 11 | private List children = new ArrayList<>(); 12 | 13 | public String getNodeType() { 14 | return nodeType; 15 | } 16 | 17 | public void setNodeType(String nodeType) { 18 | this.nodeType = nodeType; 19 | } 20 | 21 | public String getLabel() { 22 | return label; 23 | } 24 | 25 | public void setLabel(String label) { 26 | this.label = label; 27 | } 28 | 29 | public SimpleTree getParent() { 30 | return parent; 31 | } 32 | 33 | public void setParent(SimpleTree parent) { 34 | this.parent = parent; 35 | } 36 | 37 | public List getChildren() { 38 | return children; 39 | } 40 | 41 | public void setChildren(List children) { 42 | this.children = children; 43 | } 44 | 45 | private List strList = new ArrayList<>(); 46 | 47 | @Override 48 | public String toString() { 49 | String str = this.nodeType + "@@" + this.label; 50 | if (strList.size() == 0) { 51 | strList.add(str); 52 | for (SimpleTree child : children) { 53 | child.toString(); 54 | List strList1 = child.strList; 55 | for (String str1 : strList1) { 56 | strList.add("------" + str1); 57 | } 58 | } 59 | } 60 | 61 | str = ""; 62 | for (String str1 : strList) { 63 | str += str1 + "\n"; 64 | } 65 | 66 | return str; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /RenamedMethodsCollector/src/main/java/edu/lu/uni/serval/renamed/methods/Configuration.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.renamed.methods; 2 | 3 | public class Configuration { 4 | public static final String JAVA_REPOS_PATH = "../Data/JavaRepos/"; 5 | public static final String JAVA_REPO_NAMES_FILE = JAVA_REPOS_PATH + "repos.txt"; 6 | public static final String OUTPUT_PATH = "../Data/Output/"; 7 | public static final String COMMIT_DIFF_PATH = OUTPUT_PATH + "Commit_Diffs/"; 8 | public static final String RENAMED_METHODS_PATH = OUTPUT_PATH + "RenamedMethods/"; 9 | public static final Long Timeout = 300L; 10 | } 11 | -------------------------------------------------------------------------------- /RenamedMethodsCollector/src/main/java/edu/lu/uni/serval/renamed/methods/Main.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.renamed.methods; 2 | 3 | import java.util.List; 4 | 5 | public class Main { 6 | /** 7 | * Collect renamed methods for all project. 8 | * @param args 9 | */ 10 | public static void main(String[] args) { 11 | CommitDiffs.main(null); // Collect all commits and generate previous java files and revised java files from Java repositories. 12 | List projects = CommitDiffs.readList(Configuration.JAVA_REPO_NAMES_FILE); 13 | for (int i = 0; i < projects.size(); i ++) { 14 | args = new String[] {"" + i}; 15 | RenamedMethodsCollector.main(args); // Collect renamed methods. 16 | } 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /RenamedMethodsCollector/src/main/java/edu/lu/uni/serval/renamed/methods/Main2.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.renamed.methods; 2 | 3 | import java.util.List; 4 | 5 | public class Main2 { 6 | /** 7 | * Collect commits for one single project. 8 | * @param args 9 | */ 10 | public static void main(String[] args) { 11 | List projectList = CommitDiffs.readList(Configuration.JAVA_REPO_NAMES_FILE); 12 | int index = Integer.parseInt(args[0]); 13 | String project = projectList.get(index); 14 | CommitDiffs.traverseGitRepos(project, Configuration.JAVA_REPOS_PATH + project + "/.git"); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /RenamedMethodsCollector/src/main/java/edu/lu/uni/serval/renamed/methods/Main3.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.renamed.methods; 2 | 3 | public class Main3 { 4 | /** 5 | * Collect renamed methods for one single project. 6 | * @param args 7 | */ 8 | public static void main(String[] args) { 9 | // RenamedMethodsCollector.main(args); // Collect renamed methods. 10 | int start = 0; 11 | int end = 1; 12 | for (int i = start; start < end; start ++) { 13 | String[] argss = {"" + i}; 14 | RenamedMethodsCollector.main(argss); // Collect renamed methods. 15 | } 16 | 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /RenamedMethodsCollector/src/main/java/edu/lu/uni/serval/renamed/methods/MessageFiles.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.renamed.methods; 2 | 3 | import java.io.File; 4 | import java.util.List; 5 | 6 | public class MessageFiles { 7 | private int id; 8 | private List revFiles; 9 | 10 | public MessageFiles(int id) { 11 | this.id = id; 12 | } 13 | 14 | public List getRevFiles() { 15 | return revFiles; 16 | } 17 | 18 | public void setRevFiles(List revFiles) { 19 | this.revFiles = revFiles; 20 | } 21 | 22 | public int getId() { 23 | return id; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /RenamedMethodsCollector/src/main/java/edu/lu/uni/serval/renamed/methods/RenamedMethodsCollector.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.renamed.methods; 2 | 3 | import java.io.File; 4 | import java.util.List; 5 | 6 | import akka.actor.ActorRef; 7 | import akka.actor.ActorSystem; 8 | 9 | /** 10 | * Collect renamed methods from the commit history of a Java repo. 11 | * 12 | * @author kui.liu 13 | * 14 | */ 15 | public class RenamedMethodsCollector { 16 | 17 | private static final String INPUT_DATA_PATH = Configuration.COMMIT_DIFF_PATH; 18 | private static final String OUTPUT_DATA_PATH = Configuration.RENAMED_METHODS_PATH; 19 | 20 | public static void main(String[] args) { 21 | System.out.println("Argus: " + args[0]); 22 | List projectList = CommitDiffs.readList(Configuration.JAVA_REPO_NAMES_FILE); 23 | int index; 24 | try { 25 | index = Integer.valueOf(args[0]); 26 | } catch (NumberFormatException e1) { 27 | System.err.println("Wrong parameter: " + args[0]); 28 | return; 29 | } 30 | if (index >= projectList.size()) { 31 | System.err.println("The value of index is out of bound: " + args[0]); 32 | return; 33 | } 34 | 35 | String projectName = projectList.get(index);// projectPath.getName(); 36 | String filePath = INPUT_DATA_PATH + projectName; 37 | if (!new File(filePath).exists()) { 38 | File projectPath = new File(Configuration.JAVA_REPOS_PATH + projectName); 39 | if (!projectPath.exists()) return; 40 | File[] projectFiles = projectPath.listFiles(); 41 | if (projectFiles.length == 0) { 42 | projectPath.delete(); 43 | return; 44 | } 45 | 46 | File projectFile = projectFiles[0]; 47 | String projectGit = projectFile.getPath() + "/.git"; 48 | filePath = INPUT_DATA_PATH + projectName; 49 | 50 | if (!new File(filePath).exists()) { 51 | CommitDiffs.traverseGitRepos(projectName, projectGit); 52 | } 53 | 54 | String outputPath = OUTPUT_DATA_PATH + projectName + "/"; 55 | parseRenamedMethods(filePath, outputPath); 56 | } else { 57 | String outputPath = OUTPUT_DATA_PATH + projectName + "/"; 58 | parseRenamedMethods(filePath, outputPath); 59 | } 60 | } 61 | 62 | private static void parseRenamedMethods(String inputProject, String outputPath) { 63 | ActorSystem system = null; 64 | ActorRef gitTravelActor = null; 65 | try { 66 | system = ActorSystem.create("methodNames-system"); 67 | gitTravelActor = system.actorOf(ParseActor.props(inputProject, outputPath), "parse-actor"); 68 | gitTravelActor.tell("BEGIN", ActorRef.noSender()); 69 | } catch (Exception e) { 70 | e.printStackTrace(); 71 | } 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /RenamedMethodsCollector/src/main/java/edu/lu/uni/serval/renamed/methods/RenamedMethodsCollector2.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.renamed.methods; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import akka.actor.ActorRef; 9 | import akka.actor.ActorSystem; 10 | 11 | /** 12 | * Collect renamed methods from the commit history of a Java repo. 13 | * 14 | * @author kui.liu 15 | * 16 | */ 17 | @Deprecated 18 | public class RenamedMethodsCollector2 { 19 | 20 | private static final String INPUT_DATA_PATH = Configuration.COMMIT_DIFF_PATH; 21 | private static final String OUTPUT_DATA_PATH = Configuration.RENAMED_METHODS_PATH; 22 | 23 | public static void main(String[] args) throws IOException { 24 | System.out.println("========Argus: " + args[0]); 25 | List projectList = readProjects(); 26 | int index; 27 | try { 28 | index = Integer.valueOf(args[0]); 29 | } catch (NumberFormatException e1) { 30 | System.out.println("Wrong parameter: " + args[0]); 31 | return; 32 | } 33 | if (index >= projectList.size()) { 34 | System.out.println("The value of index is out of bound: " + args[0]); 35 | return; 36 | } 37 | 38 | String projectName = projectList.get(index); 39 | String filePath = INPUT_DATA_PATH + projectName; 40 | String outputPath = OUTPUT_DATA_PATH + projectName + "/"; 41 | int startIndex = Integer.valueOf(args[1]); 42 | int endIndex = Integer.valueOf(args[2]); 43 | System.out.println(startIndex + " --- " + endIndex); 44 | parseRenamedMethods(filePath, outputPath, startIndex, endIndex); 45 | } 46 | 47 | private static List readProjects() throws IOException { 48 | List projectList = new ArrayList<>(); 49 | 50 | File projectsFile = new File(Configuration.JAVA_REPOS_PATH); 51 | File[] files = projectsFile.listFiles(); 52 | for (File file : files) { 53 | if (file.isDirectory() && !file.getName().startsWith(".")) { 54 | projectList.add(file.getName()); 55 | } 56 | } 57 | return projectList; 58 | } 59 | 60 | private static void parseRenamedMethods(String inputProject, String outputPath, int startIndex, int endIndex) { 61 | ActorSystem system = null; 62 | ActorRef gitTravelActor = null; 63 | try { 64 | system = ActorSystem.create("methodNames-system"); 65 | gitTravelActor = system.actorOf(ParseActor.props(inputProject, outputPath, startIndex, endIndex), "parse-actor"); 66 | gitTravelActor.tell("BEGIN", ActorRef.noSender()); 67 | } catch (Exception e) { 68 | e.printStackTrace(); 69 | } 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /RenamedMethodsCollector/src/main/java/edu/lu/uni/serval/renamed/methods/RunnableParser.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.renamed.methods; 2 | 3 | import java.io.File; 4 | 5 | public class RunnableParser implements Runnable { 6 | 7 | private File prevFile; 8 | private File revFile; 9 | private File diffentryFile; 10 | private CodeChangeParser parser; 11 | 12 | public RunnableParser(File prevFile, File revFile, File diffentryFile, CodeChangeParser parser) { 13 | this.prevFile = prevFile; 14 | this.revFile = revFile; 15 | this.diffentryFile = diffentryFile; 16 | this.parser = parser; 17 | } 18 | 19 | @Override 20 | public void run() { 21 | parser.parse(revFile, prevFile, diffentryFile); 22 | } 23 | } -------------------------------------------------------------------------------- /RenamedMethodsCollector/src/main/java/edu/lu/uni/serval/utils/CUCreator.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.utils; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.File; 5 | import java.io.FileNotFoundException; 6 | import java.io.FileReader; 7 | import java.io.IOException; 8 | 9 | import org.eclipse.jdt.core.dom.AST; 10 | import org.eclipse.jdt.core.dom.ASTParser; 11 | import org.eclipse.jdt.core.dom.CompilationUnit; 12 | 13 | /** 14 | * Creator of a CompilationUnit. 15 | * 16 | * @author kui.liu 17 | * 18 | */ 19 | public class CUCreator { 20 | 21 | public CompilationUnit createCompilationUnit(File javaFile) { 22 | CompilationUnit unit = null; 23 | try { 24 | char[] sourceCode = readFileToCharArray(new FileReader(javaFile)); 25 | ASTParser parser = createASTParser(sourceCode); 26 | parser.setKind(ASTParser.K_COMPILATION_UNIT); 27 | unit = (CompilationUnit) parser.createAST(null); 28 | } catch (FileNotFoundException e) { 29 | e.printStackTrace(); 30 | } catch (IOException e) { 31 | e.printStackTrace(); 32 | } 33 | return unit; 34 | } 35 | 36 | private ASTParser createASTParser(char[] javaCode) { 37 | ASTParser parser = ASTParser.newParser(AST.JLS8); 38 | parser.setSource(javaCode); 39 | return parser; 40 | } 41 | 42 | private char[] readFileToCharArray(FileReader fileReader) throws IOException { 43 | StringBuilder fileData = new StringBuilder(); 44 | BufferedReader br = new BufferedReader(fileReader); 45 | 46 | char[] buf = new char[10]; 47 | int numRead = 0; 48 | while ((numRead = br.read(buf)) != -1) { 49 | String readData = String.valueOf(buf, 0, numRead); 50 | fileData.append(readData); 51 | buf = new char[1024]; 52 | } 53 | br.close(); 54 | 55 | return fileData.toString().toCharArray(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /RenamedMethodsCollector/src/main/resource/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ${APP_NAME} 5 | 6 | 7 | 8 | 9 | 10 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n 11 | 12 | 13 | 14 | 15 | ${LOG_HOME}/myLog.log 16 | 17 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n 18 | 19 | 20 | 21 | 22 | 23 | ${LOG_HOME}/%d{yyyy-MM-dd}.log 24 | 30 25 | 26 | 27 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n 28 | 29 | 30 | 10MB 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /RenamedMethodsCollector/src/test/java/edu/lu/uni/serval/AppTest.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval; 2 | 3 | import junit.framework.Test; 4 | import junit.framework.TestCase; 5 | import junit.framework.TestSuite; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest 11 | extends TestCase 12 | { 13 | /** 14 | * Create the test case 15 | * 16 | * @param testName name of the test case 17 | */ 18 | public AppTest( String testName ) 19 | { 20 | super( testName ); 21 | } 22 | 23 | /** 24 | * @return the suite of tests being tested 25 | */ 26 | public static Test suite() 27 | { 28 | return new TestSuite( AppTest.class ); 29 | } 30 | 31 | /** 32 | * Rigourous Test :-) 33 | */ 34 | public void testApp() 35 | { 36 | assertTrue( true ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /gumtree/.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk8 4 | after_success: 5 | - mvn clean test jacoco:report coveralls:report -------------------------------------------------------------------------------- /gumtree/checkstyle_ignore.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /gumtree/core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | gumtree 5 | com.github.gumtreediff 6 | 2.0.0-MethodParser 7 | 8 | core 9 | GumTree Core Module 10 | 11 | 12 | com.github.mpkorstanje 13 | simmetrics-core 14 | 3.0.3 15 | 16 | 17 | net.sf.trove4j 18 | trove4j 19 | 3.0.3 20 | 21 | 22 | com.google.code.gson 23 | gson 24 | 2.3 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/actions/ActionUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.actions; 22 | 23 | import com.github.gumtreediff.actions.model.*; 24 | import com.github.gumtreediff.tree.TreeContext; 25 | 26 | import java.util.List; 27 | 28 | public class ActionUtil { 29 | private ActionUtil() {} 30 | 31 | public static TreeContext apply(TreeContext context, List actions) { 32 | for (Action a: actions) { 33 | if (a instanceof Insert) { 34 | Insert action = ((Insert) a); 35 | action.getParent().insertChild(action.getNode(), action.getPosition()); 36 | } else if (a instanceof Update) { 37 | Update action = ((Update) a); 38 | action.getNode().setLabel(action.getValue()); 39 | } else if (a instanceof Move) { 40 | Move action = ((Move) a); 41 | action.getNode().getParent().getChildren().remove(action.getNode()); 42 | action.getParent().insertChild(action.getNode(), action.getPosition()); 43 | } else if (a instanceof Delete) { 44 | Delete action = ((Delete) a); 45 | action.getNode().getParent().getChildren().remove(action.getNode()); 46 | } else throw new RuntimeException("No such action: " + a ); 47 | } 48 | return context; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/actions/RootsClassifier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.actions; 22 | 23 | import java.util.List; 24 | import java.util.Set; 25 | 26 | import com.github.gumtreediff.actions.model.Delete; 27 | import com.github.gumtreediff.actions.model.Move; 28 | import com.github.gumtreediff.actions.model.Update; 29 | import com.github.gumtreediff.actions.model.Action; 30 | import com.github.gumtreediff.actions.model.Insert; 31 | import com.github.gumtreediff.matchers.Mapping; 32 | import com.github.gumtreediff.matchers.Matcher; 33 | import com.github.gumtreediff.tree.TreeContext; 34 | 35 | public class RootsClassifier extends TreeClassifier { 36 | 37 | public RootsClassifier(TreeContext src, TreeContext dst, Set rawMappings, List script) { 38 | super(src, dst, rawMappings, script); 39 | } 40 | 41 | public RootsClassifier(TreeContext src, TreeContext dst, Matcher m) { 42 | super(src, dst, m); 43 | } 44 | 45 | public void classify() { 46 | for (Action a: actions) { 47 | if (a instanceof Delete) srcDelTrees.add(a.getNode()); 48 | else if (a instanceof Insert) 49 | dstAddTrees.add(a.getNode()); 50 | else if (a instanceof Update) { 51 | srcUpdTrees.add(a.getNode()); 52 | dstUpdTrees.add(mappings.getDst(a.getNode())); 53 | } else if (a instanceof Move) { 54 | srcMvTrees.add(a.getNode()); 55 | dstMvTrees.add(mappings.getDst(a.getNode())); 56 | } 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/actions/model/Action.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.actions.model; 22 | 23 | import com.github.gumtreediff.tree.ITree; 24 | 25 | public abstract class Action implements Comparable { 26 | 27 | protected ITree node; 28 | protected Integer position; 29 | protected int length = 0; 30 | 31 | public Action(ITree node, int pos, int length) { 32 | this.node = node; 33 | this.length = length; 34 | this.position = pos; 35 | } 36 | 37 | public ITree getNode() { 38 | return node; 39 | } 40 | 41 | public void setNode(ITree node) { 42 | this.node = node; 43 | } 44 | 45 | public int getPosition() { 46 | return position; 47 | } 48 | 49 | public int getLength() { 50 | return length; 51 | } 52 | 53 | public abstract String getName(); 54 | 55 | @Override 56 | public abstract String toString(); 57 | 58 | @Override 59 | public int compareTo(Action o) { 60 | int result = this.position.compareTo(o.position); 61 | if (result == 0) { 62 | result = this.length >= o.length ? -1 : 1; 63 | } 64 | return result; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/actions/model/Addition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.actions.model; 22 | 23 | import com.github.gumtreediff.tree.ITree; 24 | 25 | public abstract class Addition extends Action { 26 | 27 | protected ITree parent; 28 | 29 | public Addition(ITree node, ITree parent, int pos) { 30 | super(node, node.getPos(), node.getLength()); 31 | this.parent = parent; 32 | } 33 | 34 | public ITree getParent() { 35 | return parent; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | // boolean newParent = false; 41 | // if (!parent.isRoot() && (parent.toShortString().startsWith("8@@") || parent.toShortString().startsWith("0@@Block:"))) { 42 | // newParent = true; 43 | // } 44 | // return getName() + " " + node.toShortString() + " @TO@ " + (newParent ? parent.getParent().toShortString() : parent.toShortString()) + " @AT@ " + position + " @LENGTH@ " + length; 45 | return getName() + " " + node.toShortString() + " @TO@ " + parent.toShortString() + " @AT@ " + position + " @LENGTH@ " + length; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/actions/model/Delete.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.actions.model; 22 | 23 | import com.github.gumtreediff.tree.ITree; 24 | 25 | public class Delete extends Action { 26 | 27 | public Delete(ITree node) { 28 | super(node, node.getPos(), node.getLength()); 29 | } 30 | 31 | @Override 32 | public String getName() { 33 | return "DEL"; 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | // node.toShortString: getType()@@getLabel() 39 | // return getName() + " " + node.toShortString() + " / "+node.getChildrenLabels() + " at " + node.getPos(); 40 | return getName() + " " + node.toShortString() + " @AT@ " + position + " @LENGTH@ " + length; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/actions/model/Insert.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.actions.model; 22 | 23 | import com.github.gumtreediff.tree.ITree; 24 | 25 | public class Insert extends Addition { 26 | 27 | public Insert(ITree node, ITree parent, int pos) { 28 | super(node, parent, pos); 29 | } 30 | 31 | @Override 32 | public String getName() { 33 | return "INS"; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/actions/model/Move.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.actions.model; 22 | 23 | import com.github.gumtreediff.tree.ITree; 24 | 25 | public class Move extends Addition { 26 | 27 | public Move(ITree node, ITree parent, int pos) { 28 | super(node, parent, pos); 29 | } 30 | 31 | @Override 32 | public String getName() { 33 | return "MOV"; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/actions/model/Update.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.actions.model; 22 | 23 | import com.github.gumtreediff.tree.ITree; 24 | 25 | public class Update extends Action { 26 | 27 | private String value; 28 | private ITree newNode; 29 | 30 | public Update(ITree node, ITree newNode) { 31 | super(node, node.getPos(), node.getLength()); 32 | this.value = newNode.getLabel(); 33 | this.newNode = newNode; 34 | } 35 | 36 | @Override 37 | public String getName() { 38 | return "UPD"; 39 | } 40 | 41 | public String getValue() { 42 | return this.value; 43 | } 44 | 45 | public ITree getNewNode() { 46 | return this.newNode; 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | // node.toShortString: getType()@@getLabel() 52 | return getName() + " " + node.toShortString() + " @TO@ " + value + " @AT@ " + position + " @LENGTH@ " + length; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/gen/Register.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.gen; 22 | 23 | import java.lang.annotation.ElementType; 24 | import java.lang.annotation.Retention; 25 | import java.lang.annotation.RetentionPolicy; 26 | import java.lang.annotation.Target; 27 | 28 | @Retention(RetentionPolicy.RUNTIME) 29 | @Target(ElementType.TYPE) 30 | public @interface Register { 31 | String id(); 32 | String[] accept() default { }; 33 | int priority() default Registry.Priority.MEDIUM; 34 | } 35 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/io/LineReader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.io; 22 | 23 | import java.io.IOException; 24 | import java.io.Reader; 25 | import java.util.ArrayList; 26 | import java.util.Arrays; 27 | 28 | public class LineReader extends Reader { 29 | private Reader reader; 30 | 31 | private int currentPos = 0; 32 | 33 | private ArrayList lines = new ArrayList<>(Arrays.asList(0)); 34 | 35 | public LineReader(Reader parent) { 36 | reader = parent; 37 | } 38 | 39 | @Override 40 | public int read(char[] cbuf, int off, int len) throws IOException { 41 | int r = reader.read(cbuf, off, len); 42 | for (int i = 0; i < len; i ++) 43 | if (cbuf[off + i] == '\n') 44 | lines.add(currentPos + i); 45 | currentPos += len; 46 | return r; 47 | } 48 | 49 | // Line and column starts at 1 50 | public int positionFor(int line, int column) { 51 | return lines.get(line - 1) + column - 1; 52 | } 53 | 54 | // public int[] positionFor(int offset) { // TODO write this method 55 | // Arrays.binarySearch(lines., null, null) 56 | // } 57 | 58 | @Override 59 | public void close() throws IOException { 60 | reader.close(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/io/MatrixDebugger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.io; 22 | 23 | public final class MatrixDebugger { 24 | 25 | private MatrixDebugger() { 26 | } 27 | 28 | public static void dump(Object[][] mat) { 29 | for (Object[] r : mat) { 30 | for (Object l: r) System.out.print(l + "\t"); 31 | System.out.println(); 32 | } 33 | } 34 | 35 | public static void dump(boolean[][] mat) { 36 | for (boolean[] r : mat) { 37 | for (boolean l: r) System.out.print(l + "\t"); 38 | System.out.println(); 39 | } 40 | } 41 | 42 | public static void dump(double[][] mat) { 43 | System.out.println("---"); 44 | for (double[] r : mat) { 45 | for (double l: r) System.out.print(l + "\t"); 46 | System.out.println(); 47 | } 48 | System.out.println("---"); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/matchers/CompositeMatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.matchers; 22 | 23 | import com.github.gumtreediff.tree.ITree; 24 | 25 | public class CompositeMatcher extends Matcher { 26 | 27 | protected final Matcher[] matchers; 28 | 29 | public CompositeMatcher(ITree src, ITree dst, MappingStore store, Matcher[] matchers) { 30 | super(src, dst, store); 31 | this.matchers = matchers; 32 | } 33 | 34 | public void match() { 35 | for (Matcher matcher : matchers) { 36 | matcher.match(); 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/matchers/Mapping.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.matchers; 22 | 23 | import com.github.gumtreediff.tree.ITree; 24 | import com.github.gumtreediff.utils.Pair; 25 | 26 | public class Mapping extends Pair { 27 | 28 | public Mapping(ITree a, ITree b) { 29 | super(a, b); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/matchers/Register.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.matchers; 22 | 23 | import com.github.gumtreediff.gen.Registry; 24 | 25 | import java.lang.annotation.ElementType; 26 | import java.lang.annotation.Retention; 27 | import java.lang.annotation.RetentionPolicy; 28 | import java.lang.annotation.Target; 29 | 30 | @Retention(RetentionPolicy.RUNTIME) 31 | @Target(ElementType.TYPE) 32 | public @interface Register { 33 | String id(); 34 | 35 | int priority() default Registry.Priority.MEDIUM; 36 | 37 | boolean defaultMatcher() default false; 38 | } 39 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/matchers/heuristic/LcsMatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.matchers.heuristic; 22 | 23 | import com.github.gumtreediff.utils.StringAlgorithms; 24 | import com.github.gumtreediff.matchers.MappingStore; 25 | import com.github.gumtreediff.matchers.Matcher; 26 | import com.github.gumtreediff.matchers.Register; 27 | import com.github.gumtreediff.tree.ITree; 28 | import com.github.gumtreediff.tree.TreeUtils; 29 | 30 | import java.util.List; 31 | 32 | @Register(id = "lcs") 33 | public class LcsMatcher extends Matcher { 34 | 35 | public LcsMatcher(ITree src, ITree dst, MappingStore store) { 36 | super(src, dst, store); 37 | } 38 | 39 | @Override 40 | public void match() { 41 | List srcSeq = TreeUtils.preOrder(src); 42 | List dstSeq = TreeUtils.preOrder(dst); 43 | List lcs = StringAlgorithms.lcss(srcSeq, dstSeq); 44 | System.out.println(lcs.size()); 45 | for (int[] x: lcs) { 46 | 47 | ITree t1 = srcSeq.get(x[0]); 48 | ITree t2 = dstSeq.get(x[1]); 49 | addMapping(t1, t2); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/matchers/heuristic/cd/ChangeDistillerBottomUpMatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.matchers.heuristic.cd; 22 | 23 | import com.github.gumtreediff.matchers.MappingStore; 24 | import com.github.gumtreediff.matchers.Matcher; 25 | import com.github.gumtreediff.tree.ITree; 26 | import com.github.gumtreediff.tree.TreeUtils; 27 | 28 | import java.util.List; 29 | 30 | public class ChangeDistillerBottomUpMatcher extends Matcher { 31 | 32 | public static final double STRUCT_SIM_THRESHOLD_1 = 0.6D; 33 | 34 | public static final double STRUCT_SIM_THRESHOLD_2 = 0.4D; 35 | 36 | public ChangeDistillerBottomUpMatcher(ITree src, ITree dst, MappingStore store) { 37 | super(src, dst, store); 38 | } 39 | 40 | @Override 41 | public void match() { 42 | List poDst = TreeUtils.postOrder(dst); 43 | for (ITree src: this.src.postOrder()) { 44 | int l = numberOfLeafs(src); 45 | for (ITree dst: poDst) { 46 | if (isMappingAllowed(src, dst) && !(src.isLeaf() || dst.isLeaf())) { 47 | double sim = chawatheSimilarity(src, dst); 48 | if ((l > 4 && sim >= STRUCT_SIM_THRESHOLD_1) || (l <= 4 && sim >= STRUCT_SIM_THRESHOLD_2)) { 49 | addMapping(src, dst); 50 | break; 51 | } 52 | } 53 | } 54 | } 55 | } 56 | 57 | private int numberOfLeafs(ITree root) { 58 | int l = 0; 59 | for (ITree t : root.getDescendants()) 60 | if (t.isLeaf()) 61 | l++; 62 | return l; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/matchers/heuristic/gt/ParentsMappingComparator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2016 Jean-Rémy Falleri 18 | */ 19 | 20 | package com.github.gumtreediff.matchers.heuristic.gt; 21 | 22 | import com.github.gumtreediff.matchers.Mapping; 23 | import com.github.gumtreediff.matchers.MappingStore; 24 | import com.github.gumtreediff.tree.ITree; 25 | import com.github.gumtreediff.utils.StringAlgorithms; 26 | 27 | import java.util.*; 28 | 29 | public final class ParentsMappingComparator extends AbstractMappingComparator { 30 | 31 | public ParentsMappingComparator(List ambiguousMappings, MappingStore mappings, int maxTreeSize) { 32 | super(ambiguousMappings, mappings, maxTreeSize); 33 | for (Mapping ambiguousMapping: ambiguousMappings) 34 | similarities.put(ambiguousMapping, similarity(ambiguousMapping.getFirst(), ambiguousMapping.getSecond())); 35 | } 36 | 37 | protected double similarity(ITree src, ITree dst) { 38 | return 100D * parentsJaccardSimilarity(src, dst) 39 | + 10D * posInParentSimilarity(src, dst) + numberingSimilarity(src , dst); 40 | } 41 | 42 | protected double parentsJaccardSimilarity(ITree src, ITree dst) { 43 | List srcParents = src.getParents(); 44 | List dstParents = dst.getParents(); 45 | double numerator = (double) StringAlgorithms.lcss(srcParents, dstParents).size(); 46 | double denominator = (double) srcParents.size() + (double) dstParents.size() - numerator; 47 | return numerator / denominator; 48 | } 49 | 50 | } -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/matchers/optimal/rted/RtedMatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.matchers.optimal.rted; 22 | 23 | import com.github.gumtreediff.matchers.MappingStore; 24 | import com.github.gumtreediff.matchers.Matcher; 25 | import com.github.gumtreediff.tree.ITree; 26 | import com.github.gumtreediff.tree.TreeUtils; 27 | 28 | import java.util.List; 29 | 30 | public class RtedMatcher extends Matcher { 31 | 32 | public RtedMatcher(ITree src, ITree dst, MappingStore store) { 33 | super(src, dst, store); 34 | } 35 | 36 | @Override 37 | public void match() { 38 | RtedAlgorithm a = new RtedAlgorithm(1D, 1D, 1D); 39 | a.init(src, dst); 40 | a.computeOptimalStrategy(); 41 | a.nonNormalizedTreeDist(); 42 | List arrayMappings = a.computeEditMapping(); 43 | List srcs = TreeUtils.postOrder(src); 44 | List dsts = TreeUtils.postOrder(dst); 45 | for (int[] m: arrayMappings) { 46 | if (m[0] != 0 && m[1] != 0) { 47 | ITree src = srcs.get(m[0] - 1); 48 | ITree dst = dsts.get(m[1] - 1); 49 | if (isMappingAllowed(src, dst)) 50 | addMapping(src, dst); 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/tree/IterableEnumeration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.tree; 22 | 23 | import java.util.Enumeration; 24 | import java.util.Iterator; 25 | 26 | public abstract class IterableEnumeration implements Iterable { 27 | 28 | public static Iterable make(Enumeration en) { 29 | return new Iterable() { 30 | public Iterator iterator() { 31 | return new Iterator() { 32 | @Override 33 | public boolean hasNext() { 34 | return en.hasMoreElements(); 35 | } 36 | 37 | @Override 38 | public T next() { 39 | return en.nextElement(); 40 | } 41 | 42 | @Override 43 | public void remove() { 44 | throw new UnsupportedOperationException(); 45 | } 46 | }; 47 | } 48 | }; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/tree/TreeMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.tree; 22 | 23 | import gnu.trove.map.TIntObjectMap; 24 | import gnu.trove.map.hash.TIntObjectHashMap; 25 | 26 | public final class TreeMap { 27 | 28 | private TIntObjectMap trees; 29 | 30 | public TreeMap(ITree tree) { 31 | this(); 32 | putTrees(tree); 33 | } 34 | 35 | public TreeMap() { 36 | trees = new TIntObjectHashMap<>(); 37 | } 38 | 39 | public ITree getTree(int id) { 40 | return trees.get(id); 41 | } 42 | 43 | public boolean contains(ITree tree) { 44 | return contains(tree.getId()); 45 | } 46 | 47 | public boolean contains(int id) { 48 | return trees.containsKey(id); 49 | } 50 | 51 | public void putTrees(ITree tree) { 52 | for (ITree t: tree.getTrees()) 53 | trees.put(t.getId(), t); 54 | } 55 | 56 | public void putTree(ITree t) { 57 | trees.put(t.getId(), t); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/tree/hash/HashGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.tree.hash; 22 | 23 | import com.github.gumtreediff.tree.ITree; 24 | 25 | public interface HashGenerator { 26 | 27 | public void hash(ITree t); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/tree/hash/HashUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.tree.hash; 22 | 23 | import java.security.MessageDigest; 24 | import java.security.NoSuchAlgorithmException; 25 | 26 | import com.github.gumtreediff.tree.ITree; 27 | 28 | public class HashUtils { 29 | 30 | private HashUtils() {} 31 | 32 | public static final int BASE = 33; 33 | 34 | public static final HashGenerator DEFAULT_HASH_GENERATOR = new RollingHashGenerator.Md5RollingHashGenerator(); 35 | 36 | public static int byteArrayToInt(byte[] b) { 37 | return b[3] & 0xFF | (b[2] & 0xFF) << 8 | (b[1] & 0xFF) << 16 | (b[0] & 0xFF) << 24; 38 | } 39 | 40 | public static int standardHash(ITree t) { 41 | return Integer.hashCode(t.getType()) + HashUtils.BASE * t.getLabel().hashCode(); 42 | } 43 | 44 | public static String inSeed(ITree t) { 45 | return ITree.OPEN_SYMBOL + t.getLabel() + ITree.SEPARATE_SYMBOL + t.getType(); 46 | } 47 | 48 | public static String outSeed(ITree t) { 49 | return t.getType() + ITree.SEPARATE_SYMBOL + t.getLabel() + ITree.CLOSE_SYMBOL; 50 | } 51 | 52 | public static int md5(String s) { 53 | try { 54 | MessageDigest md = MessageDigest.getInstance("MD5"); 55 | byte[] digest = md.digest(s.getBytes()); 56 | return byteArrayToInt(digest); 57 | } catch (NoSuchAlgorithmException e) { 58 | e.printStackTrace(); 59 | } 60 | return ITree.NO_VALUE; 61 | } 62 | 63 | public static int fpow(int a, int b) { 64 | if (b == 1) 65 | return a; 66 | int result = 1; 67 | while (b > 0) { 68 | if ((b & 1) != 0) 69 | result *= a; 70 | b >>= 1; 71 | a *= a; 72 | } 73 | return result; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/tree/hash/StaticHashGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.tree.hash; 22 | 23 | import com.github.gumtreediff.tree.ITree; 24 | 25 | public abstract class StaticHashGenerator implements HashGenerator { 26 | 27 | public void hash(ITree t) { 28 | for (ITree n: t.postOrder()) 29 | n.setHash(nodeHash(n)); 30 | } 31 | 32 | public abstract int nodeHash(ITree t); 33 | 34 | public static class StdHashGenerator extends StaticHashGenerator { 35 | 36 | @Override 37 | public int nodeHash(ITree t) { 38 | return t.toStaticHashString().hashCode(); 39 | } 40 | 41 | } 42 | 43 | public static class Md5HashGenerator extends StaticHashGenerator { 44 | 45 | @Override 46 | public int nodeHash(ITree t) { 47 | return HashUtils.md5(t.toStaticHashString()); 48 | } 49 | 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /gumtree/core/src/main/java/com/github/gumtreediff/utils/Pair.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.utils; 22 | 23 | public class Pair { 24 | 25 | public final T1 first; 26 | 27 | public final T2 second; 28 | 29 | public Pair(T1 a, T2 b) { 30 | this.first = a; 31 | this.second = b; 32 | } 33 | 34 | public T1 getFirst() { 35 | return first; 36 | } 37 | 38 | public T2 getSecond() { 39 | return second; 40 | } 41 | 42 | @Override 43 | public boolean equals(Object o) { 44 | if (this == o) return true; 45 | if (o == null || getClass() != o.getClass()) return false; 46 | 47 | Pair pair = (Pair) o; 48 | 49 | if (!first.equals(pair.first)) return false; 50 | return second.equals(pair.second); 51 | 52 | } 53 | 54 | @Override 55 | public int hashCode() { 56 | int result = first.hashCode(); 57 | result = 31 * result + second.hashCode(); 58 | return result; 59 | } 60 | 61 | @Override 62 | public String toString() { 63 | return "(" + getFirst().toString() + "," + getSecond().toString() + ")"; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /gumtree/core/src/test/java/com/github/gumtreediff/test/TestAlgorithms.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2016 Jean-Rémy Falleri 18 | */ 19 | 20 | package com.github.gumtreediff.test; 21 | 22 | import com.github.gumtreediff.utils.HungarianAlgorithm; 23 | import com.github.gumtreediff.utils.StringAlgorithms; 24 | import org.junit.Test; 25 | import static org.junit.Assert.assertThat; 26 | import static org.hamcrest.CoreMatchers.*; 27 | 28 | import java.util.List; 29 | 30 | public class TestAlgorithms { 31 | 32 | @Test 33 | public void testLcss() { 34 | // Exemple coming from: 35 | // http://www.geeksforgeeks.org/dynamic-programming-set-4-longest-common-subsequence/ 36 | List indexes = StringAlgorithms.lcss("ABCDGH", "AEDFHR"); 37 | assertThat(indexes.size(), is(3)); 38 | assertThat(indexes, hasItem(new int[] {0, 0})); 39 | assertThat(indexes, hasItem(new int[] {3, 2})); 40 | assertThat(indexes, hasItem(new int[] {5, 4})); 41 | } 42 | 43 | @Test 44 | public void testLcs() { 45 | String lcs = StringAlgorithms.lcs("FUTUR", "CHUTE"); 46 | assertThat(lcs, is("UT")); 47 | } 48 | 49 | @Test 50 | public void testHungarianAlgorithm() { 51 | // Exemple coming from https://en.wikipedia.org/wiki/Hungarian_algorithm 52 | double[][] costMatrix = new double[3][]; 53 | costMatrix[0] = new double[] {2F, 3F, 3F}; 54 | costMatrix[1] = new double[] {3F, 2F, 3F}; 55 | costMatrix[2] = new double[] {3F, 3F, 2F}; 56 | HungarianAlgorithm a = new HungarianAlgorithm(costMatrix); 57 | int[] result = a.execute(); 58 | assertThat(result[0], is(0)); 59 | assertThat(result[1], is(1)); 60 | assertThat(result[2], is(2)); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /gumtree/core/src/test/java/com/github/gumtreediff/test/TestCoreSuite.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.test; 22 | import org.junit.runner.RunWith; 23 | import org.junit.runners.Suite; 24 | @RunWith(Suite.class) 25 | @Suite.SuiteClasses({ 26 | TestTree.class, 27 | TestTreeUtils.class, 28 | TestTreeIoUtils.class, 29 | TestHash.class, 30 | TestZsMatcher.class, 31 | TestRtedMatcher.class }) 32 | public class TestCoreSuite {} 33 | -------------------------------------------------------------------------------- /gumtree/core/src/test/java/com/github/gumtreediff/test/TestHash.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.test; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | 25 | import com.github.gumtreediff.tree.ITree; 26 | import com.github.gumtreediff.tree.hash.RollingHashGenerator; 27 | import org.junit.Before; 28 | import org.junit.Test; 29 | 30 | public class TestHash { 31 | 32 | ITree root; 33 | 34 | @Before // FIXME Could it be before class ? 35 | public void init() { 36 | 37 | } 38 | 39 | @Test 40 | public void testRollingJavaHash() { 41 | ITree root = TreeLoader.getDummySrc(); 42 | new RollingHashGenerator.JavaRollingHashGenerator().hash(root); 43 | assertEquals(-1381305887, root.getChild(0).getChild(0).getHash()); // for c 44 | assertEquals(-1380321823, root.getChild(0).getChild(1).getHash()); // for d 45 | assertEquals(-1762812253, root.getChild(0).getHash()); // for b 46 | assertEquals(-1407966943, root.getChild(1).getHash()); // for e 47 | assertEquals(-295599963, root.getHash()); // for a 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /gumtree/core/src/test/java/com/github/gumtreediff/test/TestPair.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2016 Jean-Rémy Falleri 18 | */ 19 | 20 | package com.github.gumtreediff.test; 21 | 22 | 23 | import com.github.gumtreediff.utils.Pair; 24 | import org.junit.Test; 25 | import static org.junit.Assert.assertTrue; 26 | 27 | public class TestPair { 28 | 29 | @Test 30 | public void testEquals() { 31 | Pair p1 = new Pair<>(new String("a"), new String("b")); 32 | Pair p2 = new Pair<>(new String("a"), new String("b")); 33 | Pair p3 = new Pair<>(new String("b"), new String("a")); 34 | assertTrue(p1.equals(p2)); 35 | assertTrue(!p1.equals(p3)); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /gumtree/core/src/test/java/com/github/gumtreediff/test/TestRtedMatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.test; 22 | 23 | import com.github.gumtreediff.matchers.MappingStore; 24 | import com.github.gumtreediff.matchers.Matcher; 25 | import com.github.gumtreediff.matchers.optimal.rted.RtedMatcher; 26 | import com.github.gumtreediff.tree.ITree; 27 | import com.github.gumtreediff.utils.Pair; 28 | import com.github.gumtreediff.tree.TreeContext; 29 | import org.junit.Test; 30 | 31 | import static org.junit.Assert.assertEquals; 32 | import static org.junit.Assert.assertTrue; 33 | 34 | public class TestRtedMatcher { 35 | 36 | @Test 37 | public void testRtedMatcher() { 38 | Pair trees = TreeLoader.getZsSlidePair(); 39 | ITree src = trees.getFirst().getRoot(); 40 | ITree dst = trees.getSecond().getRoot(); 41 | Matcher matcher = new RtedMatcher(src, dst, new MappingStore()); 42 | matcher.match(); 43 | assertEquals(5, matcher.getMappingSet().size()); 44 | assertTrue(matcher.getMappings().has(src, dst)); 45 | assertTrue(matcher.getMappings().has(src.getChild(0).getChild(0), dst.getChild(0))); 46 | assertTrue(matcher.getMappings().has(src.getChild(0).getChild(0).getChild(0), dst.getChild(0).getChild(0))); 47 | assertTrue(matcher.getMappings().has(src.getChild(0).getChild(1), dst.getChild(1).getChild(0))); 48 | assertTrue(matcher.getMappings().has(src.getChild(0).getChild(2), dst.getChild(2))); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /gumtree/core/src/test/resources/Dummy_big.xml: -------------------------------------------------------------------------------- 1 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /gumtree/core/src/test/resources/Dummy_v0.xml: -------------------------------------------------------------------------------- 1 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /gumtree/core/src/test/resources/Dummy_v1.xml: -------------------------------------------------------------------------------- 1 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /gumtree/core/src/test/resources/action_v0.xml: -------------------------------------------------------------------------------- 1 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /gumtree/core/src/test/resources/action_v1.xml: -------------------------------------------------------------------------------- 1 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /gumtree/core/src/test/resources/gumtree_v0.xml: -------------------------------------------------------------------------------- 1 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /gumtree/core/src/test/resources/gumtree_v1.xml: -------------------------------------------------------------------------------- 1 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /gumtree/core/src/test/resources/zs_slide_v0.xml: -------------------------------------------------------------------------------- 1 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /gumtree/core/src/test/resources/zs_slide_v1.xml: -------------------------------------------------------------------------------- 1 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /gumtree/core/src/test/resources/zs_v0.xml: -------------------------------------------------------------------------------- 1 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /gumtree/core/src/test/resources/zs_v1.xml: -------------------------------------------------------------------------------- 1 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /gumtree/gen.jdt/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | com.github.gumtreediff 5 | gumtree 6 | 2.0.0-MethodParser 7 | 8 | gen.jdt 9 | jar 10 | Gumtree JDT Tree Generator 11 | 12 | 13 | edu.lu.uni 14 | simple-utils 15 | 0.0.1-SNAPSHOT 16 | 17 | 18 | com.github.gumtreediff 19 | core 20 | 2.0.0-MethodParser 21 | 22 | 23 | 24 | 25 | org.slf4j 26 | slf4j-api 27 | 1.7.21 28 | 29 | 30 | ch.qos.logback 31 | logback-core 32 | 1.1.7 33 | 34 | 35 | ch.qos.logback 36 | logback-classic 37 | 1.1.7 38 | 39 | 40 | 41 | org.eclipse.core 42 | runtime 43 | 3.10.0-v20140318-2214 44 | 45 | 46 | org.eclipse.birt.runtime 47 | org.eclipse.core.resources 48 | 3.10.0.v20150423-0755 49 | 50 | 51 | 52 | 53 | org.eclipse.tycho 54 | org.eclipse.jdt.core 55 | 3.12.2.v20161117-1814 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /gumtree/gen.jdt/src/main/java/com/github/gumtreediff/gen/jdt/JdtTreeGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.gen.jdt; 22 | 23 | 24 | import com.github.gumtreediff.gen.Register; 25 | import com.github.gumtreediff.gen.Registry; 26 | 27 | @Register(id = "java-jdt", accept = "\\.java$", priority = Registry.Priority.MAXIMUM) 28 | public class JdtTreeGenerator extends AbstractJdtTreeGenerator { 29 | 30 | @Override 31 | protected AbstractJdtVisitor createVisitor() { 32 | return new JdtVisitor(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /gumtree/gen.jdt/src/main/java/com/github/gumtreediff/gen/jdt/cd/CdJdtTreeGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.gen.jdt.cd; 22 | 23 | import com.github.gumtreediff.gen.Register; 24 | import com.github.gumtreediff.gen.jdt.AbstractJdtVisitor; 25 | import com.github.gumtreediff.gen.jdt.AbstractJdtTreeGenerator; 26 | 27 | @Register(id = "java-jdt-cd") 28 | public class CdJdtTreeGenerator extends AbstractJdtTreeGenerator { 29 | @Override 30 | protected AbstractJdtVisitor createVisitor() { 31 | return new CdJdtVisitor(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /gumtree/gen.jdt/src/main/java/edu/lu/uni/serval/gen/jdt/exp/ExpJdtTreeGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package edu.lu.uni.serval.gen.jdt.exp; 22 | 23 | import com.github.gumtreediff.gen.Register; 24 | import com.github.gumtreediff.gen.jdt.AbstractJdtVisitor; 25 | import com.github.gumtreediff.gen.jdt.AbstractJdtTreeGenerator; 26 | 27 | @Register(id = "java-jdt-cd") 28 | public class ExpJdtTreeGenerator extends AbstractJdtTreeGenerator { 29 | @Override 30 | protected AbstractJdtVisitor createVisitor() { 31 | return new ExpJdtVisitor(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /gumtree/gen.jdt/src/main/java/edu/lu/uni/serval/gen/jdt/rawToken/AbstractRawTokenJdtVisitor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package edu.lu.uni.serval.gen.jdt.rawToken; 22 | 23 | 24 | import com.github.gumtreediff.gen.jdt.AbstractJdtVisitor; 25 | import org.eclipse.jdt.core.dom.ASTNode; 26 | 27 | /** 28 | * Create AbstractRowTokenJdtVisitor by extending AbstractJdtVisitor and overriding pushNode method. 29 | * 30 | * Remove the ASTNode type in trees. 31 | * 32 | * @author kui.liu 33 | * 34 | */ 35 | public abstract class AbstractRawTokenJdtVisitor extends AbstractJdtVisitor { 36 | 37 | public AbstractRawTokenJdtVisitor() { 38 | super(); 39 | } 40 | 41 | @Override 42 | protected void pushNode(ASTNode n, String label) { 43 | push(0, "", label, n.getStartPosition(), n.getLength()); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /gumtree/gen.jdt/src/main/java/edu/lu/uni/serval/gen/jdt/rawToken/RawTokenJdtTreeGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package edu.lu.uni.serval.gen.jdt.rawToken; 22 | 23 | 24 | import com.github.gumtreediff.gen.Register; 25 | import com.github.gumtreediff.gen.Registry; 26 | 27 | @Register(id = "java-jdt", accept = "\\.java$", priority = Registry.Priority.MAXIMUM) 28 | public class RawTokenJdtTreeGenerator extends AbstractRawTokenJdtTreeGenerator { 29 | 30 | @Override 31 | protected AbstractRawTokenJdtVisitor createVisitor() { 32 | return new RawTokenJdtVisitor(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /gumtree/gen.jdt/src/main/java/edu/lu/uni/serval/gumtree/GumTreeComparer.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.gumtree; 2 | 3 | import java.io.File; 4 | import java.util.List; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import com.github.gumtreediff.actions.ActionGenerator; 10 | import com.github.gumtreediff.actions.model.Action; 11 | import com.github.gumtreediff.matchers.Matcher; 12 | import com.github.gumtreediff.matchers.Matchers; 13 | import com.github.gumtreediff.tree.ITree; 14 | 15 | import edu.lu.uni.serval.gumtree.GumTreeGenerator.GumTreeType; 16 | 17 | public class GumTreeComparer { 18 | 19 | private static Logger log = LoggerFactory.getLogger(GumTreeComparer.class); 20 | 21 | public List compareTwoCodeBlocksWithGumTree(String oldCodeBlock, String newCodeBlock) { 22 | // Generate GumTree. 23 | ITree oldTree = new GumTreeGenerator().generateITreeForCodeBlock(oldCodeBlock, GumTreeType.EXP_JDT); 24 | ITree newTree = new GumTreeGenerator().generateITreeForCodeBlock(newCodeBlock, GumTreeType.EXP_JDT); 25 | if (oldTree != null && newTree != null) { 26 | if (oldTree.isIsomorphicTo(newTree)) { // TODO: this method should be improved. 27 | System.out.println(true); 28 | } 29 | 30 | Matcher m = Matchers.getInstance().getMatcher(oldTree, newTree); 31 | m.match(); 32 | ActionGenerator ag = new ActionGenerator(oldTree, newTree, m.getMappings()); 33 | ag.generate(); 34 | List actions = ag.getActions(); // change actions from bug to patch 35 | return actions; 36 | } 37 | 38 | return null; 39 | } 40 | 41 | public List compareTwoFilesWithGumTree(File prevFile, File revFile) { 42 | // Generate GumTree. 43 | ITree oldTree = null; 44 | ITree newTree = null; 45 | try { 46 | oldTree = new GumTreeGenerator().generateITreeForJavaFile(prevFile, GumTreeType.EXP_JDT); 47 | newTree = new GumTreeGenerator().generateITreeForJavaFile(revFile, GumTreeType.EXP_JDT); 48 | } catch (Exception e) { 49 | if (oldTree == null) { 50 | log.info("Null GumTree of Previous File: " + prevFile.getPath()); 51 | } else if (newTree == null) { 52 | log.info("Null GumTree of Revised File: " + revFile.getPath()); 53 | } 54 | } 55 | if (oldTree != null && newTree != null) { 56 | Matcher m = Matchers.getInstance().getMatcher(oldTree, newTree); 57 | m.match(); 58 | ActionGenerator ag = new ActionGenerator(oldTree, newTree, m.getMappings()); 59 | ag.generate(); 60 | List actions = ag.getActions(); // change actions from bug to patch 61 | return actions; 62 | } 63 | 64 | return null; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /gumtree/gen.jdt/src/main/java/edu/lu/uni/serval/gumtree/GumTreeGenerator.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.gumtree; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | import org.eclipse.jdt.core.dom.ASTParser; 7 | 8 | import com.github.gumtreediff.tree.ITree; 9 | import com.github.gumtreediff.tree.TreeContext; 10 | 11 | import edu.lu.uni.serval.gen.jdt.exp.ExpJdtTreeGenerator; 12 | import edu.lu.uni.serval.gen.jdt.rawToken.RawTokenJdtTreeGenerator; 13 | 14 | public class GumTreeGenerator { 15 | 16 | public enum GumTreeType { 17 | EXP_JDT, 18 | RAW_TOKEN, 19 | } 20 | 21 | public ITree generateITreeForJavaFile(File javaFile, GumTreeType type) { 22 | ITree gumTree = null; 23 | try { 24 | TreeContext tc = null; 25 | switch (type) { 26 | case EXP_JDT: 27 | tc = new ExpJdtTreeGenerator().generateFromFile(javaFile); 28 | break; 29 | case RAW_TOKEN: 30 | tc = new RawTokenJdtTreeGenerator().generateFromFile(javaFile); 31 | break; 32 | default: 33 | break; 34 | } 35 | 36 | if (tc != null){ 37 | gumTree = tc.getRoot(); 38 | } 39 | } catch (IOException e) { 40 | e.printStackTrace(); 41 | } 42 | return gumTree; 43 | } 44 | 45 | public ITree generateITreeForJavaFile(String javaFile, GumTreeType type) { 46 | ITree gumTree = null; 47 | try { 48 | TreeContext tc = null; 49 | switch (type) { 50 | case EXP_JDT: 51 | tc = new ExpJdtTreeGenerator().generateFromFile(javaFile); 52 | break; 53 | case RAW_TOKEN: 54 | tc = new RawTokenJdtTreeGenerator().generateFromFile(javaFile); 55 | break; 56 | default: 57 | break; 58 | } 59 | 60 | if (tc != null){ 61 | gumTree = tc.getRoot(); 62 | } 63 | } catch (IOException e) { 64 | e.printStackTrace(); 65 | } 66 | return gumTree; 67 | } 68 | 69 | public ITree generateITreeForCodeBlock(String codeBlock, GumTreeType type) { 70 | ITree gumTree = null; 71 | try { 72 | TreeContext tc = null; 73 | switch (type) { 74 | case EXP_JDT: 75 | tc = new ExpJdtTreeGenerator().generateFromString(codeBlock, ASTParser.K_STATEMENTS); 76 | break; 77 | case RAW_TOKEN: 78 | tc = new RawTokenJdtTreeGenerator().generateFromString(codeBlock, ASTParser.K_STATEMENTS); 79 | break; 80 | default: 81 | break; 82 | } 83 | 84 | if (tc != null){ 85 | gumTree = tc.getRoot(); 86 | } 87 | } catch (IOException e) { 88 | e.printStackTrace(); 89 | } 90 | return gumTree; 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /gumtree/gen.jdt/src/test/java/com/github/gumtreediff/gen/jdt/TestJdtGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GumTree. 3 | * 4 | * GumTree is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GumTree is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with GumTree. If not, see . 16 | * 17 | * Copyright 2011-2015 Jean-Rémy Falleri 18 | * Copyright 2011-2015 Floréal Morandat 19 | */ 20 | 21 | package com.github.gumtreediff.gen.jdt; 22 | 23 | import java.io.IOException; 24 | 25 | import org.junit.Test; 26 | 27 | import com.github.gumtreediff.tree.ITree; 28 | import static org.junit.Assert.*; 29 | 30 | public class TestJdtGenerator { 31 | 32 | @Test 33 | public void testSimpleSyntax() throws IOException { 34 | String input = "public class Foo { public int foo; }"; 35 | ITree tree = new JdtTreeGenerator().generateFromString(input).getRoot(); 36 | assertEquals(15, tree.getType()); 37 | assertEquals(9, tree.getSize()); 38 | } 39 | 40 | @Test 41 | public void testJava5Syntax() throws IOException { 42 | String input = "public class Foo { public List foo; public void foo() " 43 | + "{ for (A f : foo) { System.out.println(f); } } }"; 44 | ITree tree = new JdtTreeGenerator().generateFromString(input).getRoot(); 45 | assertEquals(15, tree.getType()); 46 | assertEquals(32, tree.getSize()); 47 | } 48 | 49 | @Test 50 | public void testJava8Syntax() throws IOException { 51 | String input = "public class Foo { public void foo(){ new ArrayList().stream().forEach(a -> {}); } }"; 52 | ITree tree = new JdtTreeGenerator().generateFromString(input).getRoot(); 53 | assertEquals(15, tree.getType()); 54 | assertEquals(24, tree.getSize()); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /simple-utils/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | edu.lu.uni 6 | simple-utils 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | simple-utils 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | 3.12 16 | 17 | 18 | 19 | 20 | 21 | org.apache.poi 22 | poi 23 | ${poi.version} 24 | 25 | 26 | org.apache.poi 27 | poi-ooxml 28 | ${poi.version} 29 | 30 | 31 | org.apache.poi 32 | poi-ooxml-schemas 33 | ${poi.version} 34 | 35 | 36 | 37 | 38 | net.sourceforge.jexcelapi 39 | jxl 40 | 2.6.12 41 | 42 | 43 | 44 | 45 | org.slf4j 46 | slf4j-api 47 | 1.7.25 48 | 49 | 50 | ch.qos.logback 51 | logback-core 52 | 1.2.3 53 | 54 | 55 | ch.qos.logback 56 | logback-classic 57 | 1.2.3 58 | 59 | 60 | 61 | junit 62 | junit 63 | 3.8.1 64 | test 65 | 66 | 67 | 68 | 69 | 70 | 71 | org.apache.maven.plugins 72 | maven-compiler-plugin 73 | 3.2 74 | 75 | 1.8 76 | 1.8 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /simple-utils/src/main/java/edu/lu/uni/serval/utils/DistanceCalculator.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.utils; 2 | 3 | public class DistanceCalculator { 4 | 5 | public enum DistanceFunction { 6 | EUCLIDEAN, COSINESIMILARITY, MANHATTAN 7 | } 8 | 9 | public Double calculateDistance(DistanceFunction distanceType, Double[] targetPoint, Double[] selfPoint) { 10 | double distance = 0; 11 | switch (distanceType) { 12 | case EUCLIDEAN: 13 | distance = euclideanDistance(targetPoint, selfPoint); 14 | break; 15 | case COSINESIMILARITY: 16 | distance = cosineSimilarityDistance(targetPoint, selfPoint); 17 | break; 18 | case MANHATTAN: 19 | distance = manhattanDistance(targetPoint, selfPoint); 20 | break; 21 | default: 22 | distance = euclideanDistance(targetPoint, selfPoint); 23 | break; 24 | } 25 | return distance; 26 | } 27 | 28 | public Double euclideanDistance(Double[] targetPoint, Double[] selfPoint) { 29 | double sum = 0.0; 30 | 31 | for (int i = 0, length = targetPoint.length; i < length; i++) { 32 | double diff = targetPoint[i].doubleValue() - selfPoint[i].doubleValue(); 33 | sum += diff * diff; 34 | } 35 | return Double.valueOf(Math.sqrt(sum)); 36 | } 37 | 38 | public Double cosineSimilarityDistance(Double[] targetPoint, Double[] selfPoint) { 39 | double sim = 0.0d; 40 | int length = targetPoint.length; 41 | double dot = 0.0d; 42 | double mag1 = 0.0d; 43 | double mag2 = 0.0d; 44 | 45 | for (int i = 0; i < length; i ++) { 46 | dot += targetPoint[i].doubleValue() * selfPoint[i].doubleValue(); 47 | mag1 += Math.pow(targetPoint[i], 2); 48 | mag2 += Math.pow(selfPoint[i], 2); 49 | } 50 | Double divisor = Double.valueOf((Math.sqrt(mag1) * Math.sqrt(mag2))); 51 | if (Math.abs(divisor) < 2 * Double.MIN_VALUE) { 52 | return Double.NaN; 53 | } 54 | sim = dot / divisor; 55 | return Double.valueOf(sim); 56 | } 57 | 58 | public Double manhattanDistance(Double[] targetPoint, Double[] selfPoint) { 59 | double result = 0.0; 60 | for (int i = 0; i < targetPoint.length; i++) { 61 | result += Math.abs(selfPoint[i].doubleValue() - targetPoint[i].doubleValue()); 62 | } 63 | return Double.valueOf(result); 64 | } 65 | 66 | public Double minkowskiDistance(Double[] targetPoint, Double[] selfPoint) { 67 | return null; 68 | } 69 | 70 | public Double jaccardSimilarity(Double[] targetPoint, Double[] selfPoint) { 71 | return null; 72 | } 73 | 74 | } 75 | 76 | -------------------------------------------------------------------------------- /simple-utils/src/main/java/edu/lu/uni/serval/utils/Evaluation.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.utils; 2 | 3 | import java.text.DecimalFormat; 4 | 5 | public class Evaluation { 6 | 7 | private static final DecimalFormat FORMAT = new DecimalFormat("0.000"); 8 | 9 | private int truePositives; 10 | private int trueNegatives; 11 | private int falsePositives; 12 | private int falseNegatives; 13 | 14 | private double accuracy; 15 | private double precision; 16 | private double recall; 17 | private double f1_measure; 18 | 19 | public Evaluation(int truePositives, int trueNegatives, int falsePositives, int falseNegatives) { 20 | super(); 21 | this.truePositives = truePositives; 22 | this.trueNegatives = trueNegatives; 23 | this.falsePositives = falsePositives; 24 | this.falseNegatives = falseNegatives; 25 | } 26 | 27 | public void evaluate() { 28 | accuracy = (double) (this.truePositives + this.trueNegatives) / (this.truePositives + this.trueNegatives + this.falsePositives + this.falseNegatives); 29 | precision = (double) this.truePositives / (this.truePositives + this.falsePositives); 30 | recall = (double) this.truePositives / (this.truePositives + this.falseNegatives); 31 | f1_measure = (double) 2 * this.truePositives / (2 * this.truePositives + this.falsePositives + this.falseNegatives); 32 | outputResults(); 33 | } 34 | 35 | private void outputResults() { 36 | System.out.println("=========================================="); 37 | System.out.println("Accuracy: " + FORMAT.format(accuracy * 100) + "%"); 38 | System.out.println("Precision: " + FORMAT.format(precision * 100) + "%"); 39 | System.out.println("Recall: " + FORMAT.format(recall * 100) + "%"); 40 | System.out.println("F1-measure: " + FORMAT.format(f1_measure * 100) + "%"); 41 | System.out.println("=========================================="); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /simple-utils/src/main/java/edu/lu/uni/serval/utils/Exporter.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.utils; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.util.Map; 6 | 7 | import jxl.CellView; 8 | import jxl.Workbook; 9 | import jxl.write.Label; 10 | import jxl.write.WritableSheet; 11 | import jxl.write.WritableWorkbook; 12 | 13 | public class Exporter { 14 | 15 | 16 | public static void exportOutliers(Map map, File file, int sheetNo, String[] columns) { 17 | if (!file.exists()) { 18 | try { 19 | file.createNewFile(); 20 | } catch (IOException e) { 21 | e.printStackTrace(); 22 | } 23 | } 24 | try { 25 | Workbook wb = null; 26 | // new excel file. 27 | WritableWorkbook book = null; 28 | WritableSheet sheet = null; 29 | if (sheetNo == 1) { 30 | book = Workbook.createWorkbook(file); 31 | sheet = book.createSheet("sheet ", sheetNo - 1); 32 | } else { 33 | wb = Workbook.getWorkbook(file); 34 | book = Workbook.createWorkbook(file, wb); 35 | sheet = book.createSheet("sheet ", sheetNo - 1); 36 | } 37 | 38 | // Setting cell width according to the length of content automatically. 39 | CellView cellView = new CellView(); 40 | cellView.setAutosize(true); 41 | for (int i = 0; i < columns.length; i++) { 42 | sheet.setColumnView(i, cellView); 43 | } 44 | 45 | int rowIndex = 0; 46 | // Adding the names of sub column. 47 | for (int i = 0; i < columns.length; i++) { 48 | sheet.addCell(new Label(i, rowIndex, columns[i])); 49 | } 50 | rowIndex ++; 51 | 52 | for (Map.Entry entry : map.entrySet()) { 53 | sheet.addCell(new Label(0, rowIndex, entry.getKey())); 54 | sheet.addCell(new Label(1, rowIndex, entry.getValue() + "")); 55 | rowIndex++; 56 | } 57 | 58 | book.write(); 59 | book.close(); 60 | } catch (Exception e) { 61 | e.printStackTrace(); 62 | } 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /simple-utils/src/main/java/edu/lu/uni/serval/utils/FeatureReader.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.utils; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileNotFoundException; 6 | import java.io.IOException; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import java.util.Scanner; 10 | 11 | public class FeatureReader { 12 | 13 | private File featureFile; 14 | private List features ; 15 | 16 | public void setFeatureFile(File featureFile) { 17 | this.featureFile = featureFile; 18 | } 19 | 20 | public List getFeatures() { 21 | return features; 22 | } 23 | 24 | public void readFeatures() { 25 | features = new ArrayList<>(); 26 | FileInputStream fis = null; 27 | Scanner scanner = null; 28 | 29 | try { 30 | fis = new FileInputStream(featureFile); 31 | scanner = new Scanner(fis); 32 | 33 | while (scanner.hasNextLine()) { 34 | String line = scanner.nextLine(); 35 | if ("".equals(line)) { 36 | features.add(null); 37 | } else { 38 | Double[] feature = doubleParseFeature(line); 39 | features.add(feature); 40 | } 41 | } 42 | } catch (FileNotFoundException e) { 43 | e.printStackTrace(); 44 | } finally { 45 | try { 46 | scanner.close(); 47 | fis.close(); 48 | } catch (IOException e) { 49 | e.printStackTrace(); 50 | } 51 | } 52 | } 53 | 54 | private Double[] doubleParseFeature(String feature) { 55 | String[] features = feature.split(","); 56 | int length = features.length; 57 | Double[] doubleFeatures = new Double[length]; 58 | for (int i = 0; i < length; i ++) { 59 | doubleFeatures[i] = Double.parseDouble(features[i]); 60 | } 61 | return doubleFeatures; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /simple-utils/src/main/java/edu/lu/uni/serval/utils/ListSorter.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.utils; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.Comparator; 6 | import java.util.List; 7 | 8 | public class ListSorter> { 9 | 10 | private List list; 11 | 12 | public ListSorter(List list) { 13 | this.list = new ArrayList<>(); 14 | this.list.addAll(list); 15 | } 16 | 17 | public List getList() { 18 | return this.list; 19 | } 20 | 21 | public List sortAscending() { 22 | try { 23 | if (list != null && list.size() > 0) { 24 | Collections.sort(this.list, new Comparator() { 25 | 26 | @Override 27 | public int compare(T t1, T t2) { 28 | return t1.compareTo(t2); 29 | } 30 | 31 | }); 32 | } 33 | } catch (Exception e) { 34 | return null; 35 | } 36 | return this.list; 37 | } 38 | 39 | public List sortDescending() { 40 | if (list != null && list.size() > 0) { 41 | Collections.sort(this.list, Collections.reverseOrder()); 42 | } 43 | return this.list; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /simple-utils/src/main/java/edu/lu/uni/serval/utils/similarity/Jaccard.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.utils.similarity; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | /** 8 | * Calculate the similarities between two strings or two lists of data with the Jaccard similarity coefficient. 9 | * https://en.wikipedia.org/wiki/Jaccard_index 10 | * 11 | * S(V1, V2) = |V1 intersect V2| / |V1 union V2|. 12 | * 13 | * The similarity between V1 and V2 is proportional to the value of S(V1, V2). 14 | * 15 | * @author kui.liu 16 | * 17 | */ 18 | public class Jaccard implements Similarity { 19 | 20 | @Override 21 | public Double similarity(final List l1, final List l2) { 22 | 23 | if (l1 == null || l2 == null) return Double.NaN; 24 | if (l1.containsAll(l2) && l2.containsAll(l1)) return 1d; 25 | /* 26 | * FIXME: if there are several same objects in one list, what should we do? 27 | * If so, it is preferred to use Kulczynski-2 algorithm. 28 | */ 29 | List intersectionList = l1.stream().filter(t -> l2.contains(t)).distinct().collect(Collectors.toList()); 30 | List unionList = new ArrayList(); 31 | unionList.addAll(l1); 32 | unionList.addAll(l2); 33 | unionList = unionList.stream().distinct().collect(Collectors.toList()); 34 | 35 | int intersectionNum = intersectionList.size(); 36 | int unionNum = unionList.size(); 37 | 38 | return Double.valueOf((double) intersectionNum / unionNum); 39 | } 40 | 41 | @Override 42 | public Double similarity(final String str1, final String str2) { 43 | if (str1 == null || str2 == null) return Double.NaN; 44 | if (str1.equals(str2)) return 1d; 45 | 46 | List l1 = toStringList(str1); 47 | List l2 = toStringList(str2); 48 | return similarity(l1, l2); 49 | } 50 | 51 | protected List toStringList(final String str) { 52 | char[] charArray = str.toCharArray(); 53 | List strList = new ArrayList<>(charArray.length); 54 | for (int i = 0, length = charArray.length; i < length; i ++) { 55 | strList.add(String.valueOf(charArray[i])); 56 | } 57 | return strList; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /simple-utils/src/main/java/edu/lu/uni/serval/utils/similarity/LongestCommonSubsequence.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.utils.similarity; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * https://en.wikipedia.org/wiki/Longest_common_subsequence_problem 7 | * 8 | * The similarity between two strings is inversely proportional to the similarity value. 9 | * 10 | * @author kui.liu 11 | * 12 | */ 13 | public class LongestCommonSubsequence implements Similarity { 14 | 15 | @Override 16 | public Double similarity(String str1, String str2) { 17 | if (str1 == null || str2 == null) { 18 | return Double.NaN; 19 | } 20 | 21 | if (str1.equals(str2)) { 22 | return 1d; // 0d 23 | } 24 | 25 | // str1.length() + str2.length() - 2 * lcs(str1, str2) 26 | return NormalizedSimilarity.normalize(lcs(str1, str2), str1.length(), str2.length()); 27 | } 28 | 29 | int lcs(String s1, String s2) { 30 | int lengthOfS1 = s1.length(); 31 | int lengthOfS2 = s2.length(); 32 | char[] x = s1.toCharArray(); 33 | char[] y = s2.toCharArray(); 34 | 35 | int[][] c = new int[lengthOfS1 + 1][lengthOfS2 + 1]; 36 | 37 | for (int i = 1; i <= lengthOfS1; i++) { 38 | for (int j = 1; j <= lengthOfS2; j++) { 39 | if (x[i - 1] == y[j - 1]) { 40 | c[i][j] = c[i - 1][j - 1] + 1; 41 | 42 | } else { 43 | c[i][j] = Math.max(c[i][j - 1], c[i - 1][j]); 44 | } 45 | } 46 | } 47 | 48 | return c[lengthOfS1][lengthOfS2]; 49 | } 50 | 51 | @Override 52 | public Double similarity(List l1, List l2) { 53 | if (l1 == null || l2 == null) { 54 | return Double.NaN; 55 | } 56 | 57 | if (l1.containsAll(l2) && l2.containsAll(l1)) { 58 | return 1d; 59 | } 60 | 61 | return NormalizedSimilarity.normalize(lcs(l1, l2), l1.size(), l2.size());//Double.valueOf(2d * lcs(l1, l2) / (l1.size() + l2.size())); 62 | } 63 | 64 | int lcs(List l1, List l2) { 65 | int sizeOfL1 = l1.size(); 66 | int sizeOfL2 = l2.size(); 67 | 68 | int[][] c = new int[sizeOfL1 + 1][sizeOfL2 + 1]; 69 | 70 | for (int i = 1; i <= sizeOfL1; i++) { 71 | for (int j = 1; j <= sizeOfL2; j++) { 72 | if (l1.get(i - 1).equals(l2.get(j - 1))) { 73 | c[i][j] = c[i - 1][j - 1] + 1; 74 | 75 | } else { 76 | c[i][j] = Math.max(c[i][j - 1], c[i - 1][j]); 77 | } 78 | } 79 | } 80 | 81 | return c[sizeOfL1][sizeOfL2]; 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /simple-utils/src/main/java/edu/lu/uni/serval/utils/similarity/MetricLCS.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.utils.similarity; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Distance metric based on Longest Common Subsequence, 7 | * from the notes "An LCS-based string metric" by Daniel Bakkelund. 8 | * 9 | * The similarity between two strings is inversely proportional to the similarity value. 10 | * 11 | * @author kui.liu 12 | * 13 | */ 14 | public class MetricLCS implements Similarity { 15 | 16 | private final LongestCommonSubsequence lcs = new LongestCommonSubsequence(); 17 | 18 | /** 19 | * Distance metric based on Longest Common Subsequence, computed as 20 | * 1 - |LCS(str1, str2)| / max(|str1|, |str2|). 21 | * 22 | * @param s1 The first string to compare. 23 | * @param s2 The second string to compare. 24 | * @return The computed distance metric value. 25 | * @throws NullPointerException if s1 or s2 is null. 26 | */ 27 | @Override 28 | public Double similarity(String str1, String str2) { 29 | if (str1 == null || str2 == null) { 30 | return Double.NaN; 31 | } 32 | 33 | if (str1.equals(str2)) { 34 | return 1d; 35 | } 36 | 37 | int maxLength = Math.max(str1.length(), str2.length()); 38 | if (maxLength == 0) { 39 | return 0d; 40 | } 41 | return (double) lcs.lcs(str1, str2) / maxLength;//1.0 - (1.0 * lcs.similarity(str1, str2)) / maxLength; 42 | } 43 | 44 | @Override 45 | public Double similarity(List l1, List l2) { 46 | if (l1 == null || l2 == null) { 47 | return Double.NaN; 48 | } 49 | 50 | if (l1.containsAll(l2) && l2.containsAll(l1)) { 51 | return 1d; 52 | } 53 | 54 | int maxSize = Math.max(l1.size(), l2.size()); 55 | if (maxSize == 0) { 56 | return 0d; 57 | } 58 | return (double) lcs.lcs(l1, l2) / maxSize;//1.0 - (1.0 * lcs.similarity(l1, l2)) / maxSize; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /simple-utils/src/main/java/edu/lu/uni/serval/utils/similarity/NormalizedLevenshteinDistance.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.utils.similarity; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * The similarity between two strings is inversely proportional to the similarity value. 7 | * @author kui.liu 8 | * 9 | */ 10 | public class NormalizedLevenshteinDistance implements Similarity { 11 | 12 | private LevenshteinDistance ld = new LevenshteinDistance(); 13 | 14 | @Override 15 | public Double similarity(String str1, String str2) { 16 | if (str1 == null || str2 == null) { 17 | return Double.NaN; 18 | } 19 | 20 | if (str1.equals(str2)) { 21 | return 1d; 22 | } 23 | 24 | int m_len = Math.max(str1.length(), str2.length()); 25 | 26 | if (m_len == 0) { 27 | return 0d; 28 | } 29 | return 1 - (double) ld.ld(str1, str2) / m_len; 30 | } 31 | 32 | @Override 33 | public Double similarity(List l1, List l2) { 34 | if (l1 == null || l2 == null) { 35 | return Double.NaN; 36 | } 37 | 38 | if (l1.containsAll(l2) && l2.containsAll(l1)) { 39 | return 1d; 40 | } 41 | 42 | int m_len = Math.max(l1.size(), l2.size()); 43 | 44 | if (m_len == 0) { 45 | return 0d; 46 | } 47 | return 1 - (double) ld.ld(l1, l2) / m_len; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /simple-utils/src/main/java/edu/lu/uni/serval/utils/similarity/NormalizedSimilarity.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.utils.similarity; 2 | 3 | public class NormalizedSimilarity { 4 | 5 | public static Double normalize(int distance, int length1, int length2) { 6 | return 2d * distance / (length1 + length2); 7 | } 8 | 9 | public static Double normalize(int distance, int length) { 10 | return (double) distance / length; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /simple-utils/src/main/java/edu/lu/uni/serval/utils/similarity/Overlap.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.utils.similarity; 2 | 3 | import java.util.List; 4 | import java.util.stream.Collectors; 5 | 6 | /** 7 | * Calculate similarities between two strings or two lists of data with the Overlap coefficient. 8 | * https://en.wikipedia.org/wiki/Overlap_coefficient 9 | * 10 | * S(V1, V2) = |V1 intersect V2| / min(|V1|,|V2|) 11 | * 12 | * The similarity between V1 and V2 is proportional to the value of S(V1, V2). 13 | * 14 | * @author kui.liu 15 | * 16 | */ 17 | public class Overlap extends Jaccard { 18 | 19 | @Override 20 | public Double similarity(String str1, String str2) { 21 | if (str1 == null || str2 == null) return Double.NaN; 22 | 23 | List l1 = toStringList(str1); 24 | List l2 = toStringList(str2); 25 | return similarity(l1, l2); 26 | } 27 | 28 | @Override 29 | public Double similarity(List l1, List l2) { 30 | if(l1 == null || l2 == null) return Double.NaN; 31 | 32 | List intersectionList = l1.stream().filter(t -> l2.contains(t)).distinct().collect(Collectors.toList()); 33 | int intersectionNum = intersectionList.size(); 34 | int minNum = l1.size() > l2.size() ? l2.size() : l1.size(); 35 | 36 | return Double.valueOf((double) intersectionNum / minNum); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /simple-utils/src/main/java/edu/lu/uni/serval/utils/similarity/Similarity.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.utils.similarity; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Interface of calculating similarities between two strings or two lists of data with the string metric algorithms. 7 | * https://en.wikipedia.org/wiki/String_metric 8 | * 9 | * @author kui.liu 10 | * 11 | */ 12 | public interface Similarity { 13 | 14 | /** 15 | * Calculate the similarity between two strings. 16 | * 17 | * @param str1 18 | * @param str2 19 | * @return 20 | */ 21 | Double similarity(final String str1, final String str2); 22 | 23 | /** 24 | * Calculate the similarity between two lists of data. 25 | * 26 | * @param l1 27 | * @param l2 28 | * @return 29 | */ 30 | Double similarity(final List l1, final List l2); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /simple-utils/src/main/java/edu/lu/uni/serval/utils/similarity/SimilarityCalculator.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.utils.similarity; 2 | 3 | import java.util.List; 4 | 5 | public class SimilarityCalculator { 6 | 7 | public Double calculateSimilarity(String str1, String str2, StringMetrics sm) { 8 | Similarity sim = createSimilarityCalculatorInstance(sm); 9 | 10 | if (sim == null) return null; 11 | 12 | return sim.similarity(str1, str2); 13 | } 14 | 15 | public Double calculateSimilarity(List l1, List l2, StringMetrics sm) { 16 | Similarity sim = createSimilarityCalculatorInstance(sm); 17 | 18 | if (sim == null) return null; 19 | 20 | return sim.similarity(l1, l2); 21 | } 22 | 23 | private Similarity createSimilarityCalculatorInstance(StringMetrics sm) { 24 | if (sm == StringMetrics.DamerauLevenshtein) { 25 | return new DamerauLevenshteinDistance(); 26 | } else if (sm == StringMetrics.Jaccard) { 27 | return new Jaccard(); 28 | } else if (sm == StringMetrics.JaroWinkler) { 29 | return new JaroWinkler(); 30 | } else if (sm == StringMetrics.LevenshteinDistance) { 31 | return new LevenshteinDistance(); 32 | } else if (sm == StringMetrics.LongestCommonSubsequence) { 33 | return new LongestCommonSubsequence(); 34 | } else if (sm == StringMetrics.MetricLCS) { 35 | return new MetricLCS(); 36 | } else if (sm == StringMetrics.MostFreqKDistance) { 37 | return new MostFreqKDistance(); 38 | } else if (sm == StringMetrics.NGram) { 39 | return new NGram(); 40 | } else if (sm == StringMetrics.NormalizedLevenshteinDistance) { 41 | return new NormalizedLevenshteinDistance(); 42 | } else if (sm == StringMetrics.OptimalStringAlignment) { 43 | return new OptimalStringAlignment(); 44 | } else if (sm == StringMetrics.Overlap) { 45 | return new Overlap(); 46 | } else if (sm == StringMetrics.QGram) { 47 | return new QGram(); 48 | } else if (sm == StringMetrics.Sift4) { 49 | return new Sift4(); 50 | } else if (sm == StringMetrics.SorensenDice) { 51 | return new SorensenDice(); 52 | } else if (sm == StringMetrics.Tversky) { 53 | return new Tversky(); 54 | } 55 | return null; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /simple-utils/src/main/java/edu/lu/uni/serval/utils/similarity/SorensenDice.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.utils.similarity; 2 | 3 | import java.util.List; 4 | import java.util.stream.Collectors; 5 | 6 | /** 7 | * Calculate similarities between two strings or two lists of data with the Sorensen-Dice coefficient. 8 | * https://en.wikipedia.org/wiki/S%C3%B8rensen%E2%80%93Dice_coefficient 9 | * 10 | * S(V1, V2) = 2 * |V1 intersect V2| / (|V1| + |V2|) 11 | * 12 | * The similarity between V1 and V2 is proportional to the value of S(V1, V2). 13 | * 14 | * @author kui.liu 15 | * 16 | */ 17 | public class SorensenDice extends Jaccard { 18 | 19 | @Override 20 | public Double similarity(final String str1, final String str2) { 21 | if (str1 == null || str2 == null) return Double.NaN; 22 | 23 | List l1 = toStringList(str1); 24 | List l2 = toStringList(str2); 25 | return similarity(l1, l2); 26 | } 27 | 28 | @Override 29 | public Double similarity(final List l1, final List l2) { 30 | if (l1 == null || l2 == null) return Double.NaN; 31 | 32 | List intersectionList = l1.stream().filter(t -> l2.contains(t)).collect(Collectors.toList()); 33 | int intersectionNum = intersectionList.size(); 34 | 35 | return Double.valueOf(2d * intersectionNum / (l1.size() + l2.size())); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /simple-utils/src/main/java/edu/lu/uni/serval/utils/similarity/StringMetrics.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.utils.similarity; 2 | 3 | /** 4 | * A string metric (also known as a string similarity metric or string distance function) 5 | * is a metric that measures distance ("inverse similarity") between two text strings 6 | * for approximate string matching or comparison and in fuzzy string searching. 7 | * 8 | * https://en.wikipedia.org/wiki/String_metric 9 | * 10 | * @author kui.liu 11 | * 12 | */ 13 | public enum StringMetrics { 14 | DamerauLevenshtein, // https://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance 15 | Jaccard, // https://en.wikipedia.org/wiki/Jaccard_index 16 | JaroWinkler, // https://en.wikipedia.org/wiki/Jaro%E2%80%93Winkler_distance 17 | LevenshteinDistance, // https://en.wikipedia.org/wiki/Levenshtein_distance 18 | LongestCommonSubsequence, // 19 | MetricLCS, // https://pdfs.semanticscholar.org/03eb/b47423f23c70608ce4d6995f6d773ffa3348.pdf 20 | MostFreqKDistance, // https://en.wikipedia.org/wiki/Most_frequent_k_characters 21 | NGram, // http://webdocs.cs.ualberta.ca/~kondrak/papers/spire05.pdf 22 | NormalizedLevenshteinDistance, // 23 | OptimalStringAlignment, // 24 | Overlap, // https://en.wikipedia.org/wiki/Overlap_coefficient 25 | QGram, // https://www-sciencedirect-com.proxy.bnl.lu/science/article/pii/0304397592901434?pds=107201810203393151758490735537587 26 | Sift4, // https://siderite.blogspot.com/2014/11/super-fast-and-accurate-string-distance.html 27 | SorensenDice, // https://en.wikipedia.org/wiki/S%C3%B8rensen%E2%80%93Dice_coefficient 28 | Tversky, // https://en.wikipedia.org/wiki/Tversky_index 29 | } 30 | -------------------------------------------------------------------------------- /simple-utils/src/main/java/edu/lu/uni/serval/utils/similarity/Tversky.java: -------------------------------------------------------------------------------- 1 | package edu.lu.uni.serval.utils.similarity; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * https://en.wikipedia.org/wiki/Tversky_index 7 | * @author kui.liu 8 | * 9 | */ 10 | public class Tversky implements Similarity { 11 | 12 | @Override 13 | public Double similarity(String str1, String str2) { 14 | // TODO Auto-generated method stub 15 | return null; 16 | } 17 | 18 | @Override 19 | public Double similarity(List l1, List l2) { 20 | // TODO Auto-generated method stub 21 | return null; 22 | } 23 | 24 | } 25 | --------------------------------------------------------------------------------