Skip to content

Commit 72c1399

Browse files
committed
support closures in dependency declarations
fixes #204
1 parent f3dabec commit 72c1399

File tree

11 files changed

+560
-17
lines changed

11 files changed

+560
-17
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,5 @@ libs/
6363

6464
# all build dirs at any level
6565
**/build
66+
67+
**/*.hprof

modulecheck-core/src/main/kotlin/modulecheck/core/internal/project2.kt

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ fun Project2.statementOrNullIn(
3131
.parse(dependentBuildFile)
3232
.firstNotNullOfOrNull { block ->
3333
block.getOrEmpty(path, configuration.value)
34+
.takeIf { it.isNotEmpty() }
3435
}
3536
?.firstOrNull()
3637
?.statementWithSurroundingText

modulecheck-parsing/api/src/main/kotlin/modulecheck/parsing/DependenciesBlock.kt

+62-3
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,69 @@ abstract class DependenciesBlock(var contentString: String) {
107107
.orEmpty()
108108
}
109109

110-
protected abstract fun findOriginalStringIndex(parsedString: String): Int
110+
/**
111+
* Compares the target parsed string to the un-parsed lines of the original dependencies block,
112+
* and returns the index of **the last row** which matches the parsed string.
113+
*
114+
* So, given the target:
115+
* ```
116+
* api(projects.foo.bar) {
117+
* exclude(group = "androidx.appcompat")
118+
* }
119+
* ```
120+
* And given the dependencies lines:
121+
* ```
122+
* <blank line>
123+
* // Remove leaking AppCompat dependency
124+
* api(projects.foo.bar) {
125+
* exclude(group = "androidx.appcompat")
126+
* } // this is index 4
127+
* api(libs.junit)
128+
* ```
129+
*
130+
* This function would return index `4`, because rows 2-4 match the target parsed string.
131+
*
132+
* From this value, [getOriginalString] will return a multi-line string which includes
133+
* the blank line and the comment.
134+
*/
135+
private fun findLastMatchingRowIndex(parsedString: String): Int {
136+
val targetLines = parsedString.lines()
137+
.map { it.trimStart() }
138+
139+
// index is incremented at least once (if the first line is a match), so start at -1
140+
var index = -1
141+
142+
var matched: Boolean
143+
144+
do {
145+
val candidates = originalLines
146+
.drop(index + 1)
147+
.take(targetLines.size)
148+
.map { it.trimStart() }
149+
150+
matched = candidates.zip(targetLines)
151+
.all { (candidate, target) ->
152+
originalLineMatchesParsed(candidate, target)
153+
}
154+
155+
if (matched) {
156+
index += targetLines.size
157+
} else {
158+
159+
index++
160+
}
161+
} while (!matched)
162+
163+
return index
164+
}
165+
166+
protected abstract fun originalLineMatchesParsed(
167+
originalLine: String,
168+
parsedString: String
169+
): Boolean
111170

112-
protected fun getOriginalString(parsedString: String): String {
113-
val originalStringIndex = findOriginalStringIndex(parsedString)
171+
private fun getOriginalString(parsedString: String): String {
172+
val originalStringIndex = findLastMatchingRowIndex(parsedString)
114173

115174
val originalStringLines = List(originalStringIndex + 1) {
116175
originalLines.removeFirst()

modulecheck-parsing/groovy-antlr/src/main/kotlin/modulecheck/parsing/groovy/antlr/GroovyDependenciesBlock.kt

+10-7
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,16 @@ class GroovyDependenciesBlock(
2121
contentString: String
2222
) : DependenciesBlock(contentString) {
2323

24-
override fun findOriginalStringIndex(parsedString: String) = originalLines
25-
.indexOfFirst { originalLine ->
26-
originalLine.collapseBlockComments()
27-
.trimEachLineStart()
28-
.trimLinesLikeAntlr()
29-
.lines()
30-
.any { it.startsWith(parsedString) }
24+
override fun originalLineMatchesParsed(
25+
originalLine: String,
26+
parsedString: String
27+
) = originalLine.collapseBlockComments()
28+
.trimEachLineStart()
29+
.trimLinesLikeAntlr()
30+
.lines()
31+
.any { str ->
32+
33+
str.startsWith(parsedString)
3134
}
3235

3336
override fun toString(): String {

modulecheck-parsing/groovy-antlr/src/main/kotlin/modulecheck/parsing/groovy/antlr/GroovyDependencyBlockParser.kt

-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ class GroovyDependencyBlockParser {
9595
val blockStatementVisitor = object : GroovyParserBaseVisitor<Unit>() {
9696

9797
override fun visitBlockStatement(ctx: BlockStatementContext) {
98-
super.visitBlockStatement(ctx)
9998

10099
val config = ctx.start.text
101100

0 commit comments

Comments
 (0)