Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

fix: check size before calling single(). Declare IllegalArgumentException. #29

Merged
merged 2 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -326,9 +326,14 @@ public class DependencyExtractor(
}

private fun PostfixUnaryExpressionContext.isDependencyDeclaration(): DeclarationDetectionResult {
// Something strange
if (postfixUnarySuffix().size != 1) return DeclarationDetectionResult.STATEMENT

// This is everything after the configuration, including optionally a trailing lambda
val rawDependency = postfixUnarySuffix().single().callSuffix()
val args = rawDependency.valueArguments().valueArgument()
// Probably not actually a dependencies block
val valueArguments = rawDependency.valueArguments() ?: return DeclarationDetectionResult.STATEMENT
val args = valueArguments.valueArgument()

// If there are more than one argument, it's a function call, not a dependency declaration
return if (args.size <= 1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import cash.grammar.kotlindsl.model.DependencyDeclaration
import cash.grammar.kotlindsl.parse.KotlinParseException
import cash.grammar.kotlindsl.parse.Parser
import cash.grammar.kotlindsl.parse.Rewriter
import cash.grammar.kotlindsl.utils.Blocks.isBuildscript
import cash.grammar.kotlindsl.utils.Blocks.isDependencies
import cash.grammar.kotlindsl.utils.CollectingErrorListener
import cash.grammar.kotlindsl.utils.Context.leafRule
Expand All @@ -14,6 +13,7 @@ import cash.grammar.kotlindsl.utils.Whitespace.trimGently
import cash.grammar.utils.ifNotEmpty
import com.squareup.cash.grammar.KotlinParser.NamedBlockContext
import com.squareup.cash.grammar.KotlinParser.PostfixUnaryExpressionContext
import com.squareup.cash.grammar.KotlinParser.ScriptContext
import com.squareup.cash.grammar.KotlinParser.StatementContext
import com.squareup.cash.grammar.KotlinParserBaseListener
import org.antlr.v4.runtime.CharStream
Expand All @@ -34,7 +34,6 @@ public class DependenciesSimplifier private constructor(
private val dependencyExtractor = DependencyExtractor(input, tokens, indent)

private var changes = false
private var isInBuildscriptBlock = false

public fun isChanged(): Boolean = changes

Expand All @@ -49,24 +48,24 @@ public class DependenciesSimplifier private constructor(

override fun enterNamedBlock(ctx: NamedBlockContext) {
dependencyExtractor.onEnterBlock()

if (ctx.isBuildscript) {
isInBuildscriptBlock = true
}
}

override fun exitNamedBlock(ctx: NamedBlockContext) {
if (ctx.isDependencies && !isInBuildscriptBlock) {
if (isRealDependenciesBlock(ctx)) {
onExitDependenciesBlock(ctx)
}

if (ctx.isBuildscript) {
isInBuildscriptBlock = false
}

dependencyExtractor.onExitBlock()
}

private fun isRealDependenciesBlock(ctx: NamedBlockContext): Boolean {
// parent is StatementContext. Parent of that should be ScriptContext
// In contrast, with tasks.shadowJar { dependencies { ... } }, the parent.parent is StatementsContext
if (ctx.parent.parent !is ScriptContext) return false

return ctx.isDependencies
}

private fun onExitDependenciesBlock(ctx: NamedBlockContext) {
val container = dependencyExtractor.collectDependencies(ctx)
container.getDependencyDeclarationsWithContext()
Expand Down Expand Up @@ -119,8 +118,9 @@ public class DependenciesSimplifier private constructor(
* Returns a [DependenciesSimplifier], which eagerly parses [buildScript].
*
* @throws IllegalStateException if [DependencyExtractor] sees an expression it doesn't understand.
* @throws IllegalArgumentException if [DependencyExtractor] sees an expression it doesn't understand.
*/
@Throws(IllegalStateException::class)
@Throws(IllegalStateException::class, IllegalArgumentException::class)
public fun of(buildScript: Path): DependenciesSimplifier {
return of(Parser.readOnlyInputStream(buildScript))
}
Expand All @@ -129,8 +129,9 @@ public class DependenciesSimplifier private constructor(
* Returns a [DependenciesSimplifier], which eagerly parses [buildScript].
*
* @throws IllegalStateException if [DependencyExtractor] sees an expression it doesn't understand.
* @throws IllegalArgumentException if [DependencyExtractor] sees an expression it doesn't understand.
*/
@Throws(IllegalStateException::class)
@Throws(IllegalStateException::class, IllegalArgumentException::class)
public fun of(buildScript: String): DependenciesSimplifier {
return of(buildScript.byteInputStream())
}
Expand All @@ -139,8 +140,9 @@ public class DependenciesSimplifier private constructor(
* Returns a [DependenciesSimplifier], which eagerly parses [buildScript].
*
* @throws IllegalStateException if [DependencyExtractor] sees an expression it doesn't understand.
* @throws IllegalArgumentException if [DependencyExtractor] sees an expression it doesn't understand.
*/
@Throws(IllegalStateException::class)
@Throws(IllegalStateException::class, IllegalArgumentException::class)
private fun of(buildScript: InputStream): DependenciesSimplifier {
val errorListener = CollectingErrorListener()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,32 @@ internal class DependenciesSimplifierTest {
""".trimIndent()
)
}

@Test fun `can handle user weirdness`() {
// Expect parsing not to throw exception
DependenciesSimplifier.of(
"""
dependencies {
tasks.withType<Foo>().configureEach {
doThing(listOf("--a", "b"))
}
}
""".trimIndent()
)
}

@Test fun `handles dependencies blocks that aren't actually dependencies blocks`() {
// Expect parsing not to throw exception
DependenciesSimplifier.of(
"""
tasks.shadowJar {
dependencies {
exclude { dep ->
dep.name != "foo"
}
}
}
""".trimIndent()
)
}
}
Loading