Skip to content

Commit

Permalink
feat: improve support for parsing dependencies.
Browse files Browse the repository at this point in the history
  • Loading branch information
autonomousapps committed Aug 6, 2024
1 parent 90970f8 commit e59da91
Show file tree
Hide file tree
Showing 9 changed files with 436 additions and 66 deletions.
2 changes: 1 addition & 1 deletion core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ plugins {
}

dependencies {
api(project((":grammar")))
api(project(":grammar"))

api(libs.antlr.runtime)
api(libs.kotlinStdLib)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,56 @@ package cash.grammar.kotlindsl.model
* terms, and can be one of three kinds. See [Capability].
*
* Finally we have [type], which tells us whether this dependency declaration is for an internal
* project declaration or an external module declaration. See [Type] and
* project declaration, an external module declaration, or a local file dependency. See [Type] and
* [ModuleDependency](https://docs.gradle.org/current/javadoc/org/gradle/api/artifacts/ModuleDependency.html).
*/
public data class DependencyDeclaration(
val configuration: String,
val identifier: String,
val identifier: Identifier,
val capability: Capability,
val type: Type,
val fullText: String,
val precedingComment: String? = null,
) {

public data class Identifier @JvmOverloads constructor(
public val path: String,
public val configuration: String? = null,
public val explicitPath: Boolean = false,
) {

/**
* ```
* 1. "g:a:v"
* 2. path = "g:a:v"
* 3. path = "g:a:v", configuration = "foo"
* 4. "g:a:v", configuration = "foo"
* ```
*/
override fun toString(): String = buildString {
if (explicitPath) {
append("path = ")
}

append(path)

if (configuration != null) {
append(", configuration = ")
append(configuration)
}
}

internal companion object {
fun String?.asSimpleIdentifier(): Identifier? {
return if (this != null) {
Identifier(path = this)
} else {
null
}
}
}
}

/**
* @see <a href="https://docs.gradle.org/current/userguide/component_capabilities.html">Component Capabilities</a>
*/
Expand Down Expand Up @@ -71,8 +111,11 @@ public data class DependencyDeclaration(
* @see <a href="https://docs.gradle.org/current/javadoc/org/gradle/api/artifacts/ModuleDependency.html">ModuleDependency</a>
*/
public enum class Type {
PROJECT,
FILE,
FILES,
FILE_TREE,
MODULE,
PROJECT,
;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package cash.grammar.kotlindsl.model.gradle

import cash.grammar.kotlindsl.model.DependencyDeclaration

/**
* A container for all the [Statements][com.squareup.cash.grammar.KotlinParser.StatementsContext] in
* a `dependencies` block in a Gradle build script. These statements are an ordered (not sorted!)
* list of "raw" statements and modeled
* [DependencyDeclarations][cash.grammar.kotlindsl.model.DependencyDeclaration].
*
* Rather than attempt to model everything that might possibly be found inside a build script, we
* declare defeat on anything that isn't a standard dependency declaration and simply retain it
* as-is.
*/
public class DependencyContainer(
private val statements: List<Any>,
) {

public fun getDependencyDeclarations(): List<DependencyDeclaration> {
return statements.filterIsInstance<DependencyDeclaration>()
}

public fun getNonDeclarations(): List<String> {
return statements.filterIsInstance<String>()
}

internal companion object {
val EMPTY = DependencyContainer(emptyList())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public class Rewriter(
}

/**
* Deletes all comments "to the right of" [after], returning the list of comment tokens, if they
* Deletes all comments "to the left of" [before], returning the list of comment tokens, if they
* exist.
*/
public fun deleteCommentsToLeft(
Expand Down
69 changes: 69 additions & 0 deletions core/src/main/kotlin/cash/grammar/kotlindsl/utils/Comments.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package cash.grammar.kotlindsl.utils

import com.squareup.cash.grammar.KotlinLexer
import org.antlr.v4.runtime.CommonTokenStream
import org.antlr.v4.runtime.ParserRuleContext
import org.antlr.v4.runtime.Token

public class Comments(
private val tokens: CommonTokenStream,
private val indent: String,
) {

private var level = 0

public fun onEnterBlock() {
level++
}

public fun onExitBlock() {
level--
}

public fun getCommentsToLeft(before: ParserRuleContext): String? {
return getCommentsToLeft(before.start)
}

public fun getCommentsToLeft(before: Token): String? {
var index = before.tokenIndex - 1
if (index <= 0) return null

var next = tokens.get(index)

while (next != null && next.isWhitespace()) {
next = tokens.get(--index)
}

if (next == null) return null

val comments = ArrayDeque<String>()

while (next != null) {
if (next.isComment()) {
comments.addFirst(next.text)
} else if (next.isNotWhitespace()) {
break
}

next = tokens.get(--index)
}

if (comments.isEmpty()) return null

return comments.joinToString(separator = "\n") {
"${indent.repeat(level)}$it"
}
}

private fun Token.isWhitespace(): Boolean {
return text.isBlank()
}

private fun Token.isNotWhitespace(): Boolean {
return text.isNotBlank()
}

private fun Token.isComment(): Boolean {
return type == KotlinLexer.LineComment || type == KotlinLexer.DelimitedComment
}
}
Loading

0 comments on commit e59da91

Please sign in to comment.