Skip to content

Commit d4a6d02

Browse files
yaronskayaanatolystansler
authored andcommitted
feat: python list comprehension fact (#117) (#158)
* feat: python list comprehesion fact * feat: syntax stats facts * wip: fix pr
1 parent 74fd2db commit d4a6d02

File tree

5 files changed

+98
-1
lines changed

5 files changed

+98
-1
lines changed

src/main/kotlin/app/extractors/Extractor.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class Extractor : ExtractorInterface {
1212
val TYPE_LANGUAGE = 1
1313
val TYPE_LIBRARY = 2
1414
val TYPE_KEYWORD = 3
15+
val TYPE_SYNTAX = 4
1516
val SEPARATOR = ">"
1617
}
1718

src/main/kotlin/app/extractors/PythonExtractor.kt

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,42 @@ class PythonExtractor : ExtractorInterface {
1616
}
1717
val MULTI_IMPORT_TO_LIB =
1818
ExtractorInterface.getMultipleImportsToLibraryMap(LANGUAGE_NAME)
19+
val COMPREHENSION_MAP = "map"
20+
val COMPREHENSION_LIST = "list"
1921
}
2022

2123
override fun extract(files: List<DiffFile>): List<CommitStats> {
2224
files.map { file -> file.language = LANGUAGE_NAME }
23-
return super.extract(files)
25+
val stats = super.extract(files).toMutableList()
26+
27+
// List comprehension fun fact.
28+
val allAdded = files.map{ file -> file.getAllAdded() }.flatten()
29+
val allDeleted = files.map{ file -> file.getAllDeleted() }.flatten()
30+
31+
val mapRegex = Regex("""(map\([^,]+?,)""")
32+
val mapAllAdded = allAdded.fold(0) { total, line ->
33+
total + mapRegex.findAll(line).toList().size }
34+
val mapAllDeleted = allDeleted.fold(0) { total, line ->
35+
total + mapRegex.findAll(line).toList().size }
36+
37+
val listAllAdded = allAdded.fold(0) { total, line ->
38+
total + line.count { c -> c == '[' } }
39+
val listAllDeleted = allDeleted.fold(0) { total, line ->
40+
total + line.count { c -> c == '[' } }
41+
42+
if (mapAllAdded > 0 || mapAllDeleted > 0) {
43+
stats.add(CommitStats(
44+
mapAllAdded, mapAllDeleted, Extractor.TYPE_SYNTAX,
45+
tech = LANGUAGE_NAME + Extractor.SEPARATOR + COMPREHENSION_MAP))
46+
}
47+
48+
if (listAllAdded > 0 || listAllDeleted > 0) {
49+
stats.add(CommitStats(
50+
listAllAdded, listAllDeleted, Extractor.TYPE_SYNTAX,
51+
tech = LANGUAGE_NAME + Extractor.SEPARATOR + COMPREHENSION_LIST))
52+
}
53+
54+
return stats
2455
}
2556

2657
override fun extractImports(fileContent: List<String>): List<String> {

src/main/kotlin/app/hashers/FactHasher.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import app.FactCodes
88
import app.Logger
99
import app.api.Api
1010
import app.extractors.Extractor
11+
import app.extractors.PythonExtractor
1112
import app.model.Author
1213
import app.model.Commit
1314
import app.model.Fact
@@ -109,6 +110,7 @@ class FactHasher(private val serverRepo: Repo = Repo(),
109110

110111
fsLinesPerCommits[email]!![numCommits - 1] += lines.size
111112

113+
// Variable naming.
112114
lines.forEach { line ->
113115
val tokens = Extractor().tokenize(line)
114116
val underscores = tokens.count { it.contains('_') }
@@ -124,6 +126,7 @@ class FactHasher(private val serverRepo: Repo = Repo(),
124126
others
125127
}
126128

129+
// Indentation.
127130
fsIndentation[email]!![FactCodes.INDENTATION_SPACES] +=
128131
lines.count { it.isNotBlank() && it.startsWith(" ") && !it.contains("\t")}
129132
fsIndentation[email]!![FactCodes.INDENTATION_TABS] +=

src/test/kotlin/test/tests/hashers/CommitHasherTest.kt

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package test.tests.hashers
66

77
import app.api.MockApi
8+
import app.extractors.Extractor
89
import app.hashers.CommitHasher
910
import app.hashers.CommitCrawler
1011
import app.model.*
@@ -13,6 +14,7 @@ import org.eclipse.jgit.api.Git
1314
import org.jetbrains.spek.api.Spek
1415
import org.jetbrains.spek.api.dsl.given
1516
import org.jetbrains.spek.api.dsl.it
17+
import test.utils.TestRepo
1618
import java.io.File
1719
import java.util.stream.StreamSupport.stream
1820
import kotlin.streams.toList
@@ -236,5 +238,64 @@ class CommitHasherTest : Spek({
236238
}
237239
}*/
238240

241+
given("commits with syntax stats") {
242+
243+
val lines = listOf("x = [i**2 for i range(9999)]", "def fn()", "x = 1",
244+
"x = map(lambda x: x**2, range(9999))",
245+
"x = map(lambda x: x**2, map(lambda x: x**3, range(10))",
246+
"x = map(lambda x: x**2, range(10))," +
247+
"map(lambda x: x**3, range(10)))")
248+
249+
val authorEmail = "[email protected]"
250+
val author = Author("Test", authorEmail)
251+
252+
val testRepoPath = "../testrepo-commit-hasher-"
253+
val testRepo = TestRepo(testRepoPath + "python-facts")
254+
255+
val emails = hashSetOf(authorEmail)
256+
val mockApi = MockApi(mockRepo = repo)
257+
val observable = CommitCrawler.getObservable(testRepo.git, repo)
258+
259+
it("sends stats") {
260+
for (i in 0..lines.size - 1) {
261+
val line = lines[i]
262+
val fileName = "file$i.py"
263+
testRepo.createFile(fileName, listOf(line))
264+
testRepo.commit(message = "$line in $fileName", author = author)
265+
}
266+
267+
val errors = mutableListOf<Throwable>()
268+
269+
val rehashes = (0..lines.size - 1).map { "r$it" }
270+
271+
CommitHasher(repo, mockApi, rehashes, emails)
272+
.updateFromObservable(observable, { e -> errors.add(e) })
273+
if (errors.size > 0) {
274+
println(errors[0].message)
275+
}
276+
assertEquals(0, errors.size)
277+
278+
val syntaxStats = mockApi.receivedAddedCommits
279+
.fold(mutableListOf<CommitStats>()) { allStats, commit ->
280+
allStats.addAll(commit.stats)
281+
allStats
282+
}.filter { it.type == Extractor.TYPE_SYNTAX }
283+
284+
val mapStats = syntaxStats.filter { it.tech == "python>map" }
285+
val listStats = syntaxStats.filter { it.tech == "python>list" }
286+
assertEquals(3, mapStats.size)
287+
assertEquals(1, listStats.size)
288+
assertEquals(5, mapStats.map { it.numLinesAdded }.sum())
289+
assertEquals(0, mapStats.map { it.numLinesDeleted }.sum())
290+
291+
assertEquals(1, listStats.map { it.numLinesAdded }.sum())
292+
assertEquals(0, listStats.map { it.numLinesDeleted }.sum())
293+
}
294+
295+
afterGroup {
296+
testRepo.destroy()
297+
}
298+
}
299+
239300
cleanRepos()
240301
})

src/test/kotlin/test/tests/hashers/FactHasherTest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,4 +369,5 @@ class FactHasherTest : Spek({
369369
testRepo.destroy()
370370
}
371371
}
372+
372373
})

0 commit comments

Comments
 (0)