Skip to content

Commit

Permalink
Adds dynamic text to the InlineDebugIntention
Browse files Browse the repository at this point in the history
To help the user determine what gets debugged when they debug a certain piece of code, the intention will change its text to better describe what gets debugged.

This commit also adds a way to test that the text is as expected.
  • Loading branch information
KasMA1990 committed Apr 14, 2024
1 parent 69d5fb7 commit 56a86e2
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 32 deletions.
77 changes: 65 additions & 12 deletions src/main/kotlin/org/elm/ide/intentions/InlineDebugIntention.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,61 @@ class InlineDebugIntention : ElmAtCaretIntentionActionBase<InlineDebugIntention.

override fun getFamilyName() = text

private sealed class MessageContext {
object DebugValue : MessageContext()
object DebugFunctionCall : MessageContext()
object DebugParentFunctionCall : MessageContext()
object DebugBinaryOpt : MessageContext()
object DebugPipeline : MessageContext()
object DebugCase : MessageContext()
object DebugExpression : MessageContext()
}

override fun findApplicableContext(project: Project, editor: Editor, element: PsiElement): Context? {
val contexts = getContext(project, editor, element)

if (contexts != null) {
val firstPartOfDescription = "Debug.log "
val (context, messageContext) = contexts
when (messageContext) {
is MessageContext.DebugValue -> {
super.setText(firstPartOfDescription + "this value")
}
is MessageContext.DebugFunctionCall -> {
super.setText(firstPartOfDescription + "output of function")
}
is MessageContext.DebugParentFunctionCall -> {
super.setText(firstPartOfDescription + "output of parent function")
}
is MessageContext.DebugBinaryOpt -> {
super.setText(firstPartOfDescription + "expression")
}
MessageContext.DebugPipeline -> {
super.setText(firstPartOfDescription + "output of pipeline")
}
is MessageContext.DebugCase -> {
super.setText(firstPartOfDescription + "output of case statement")
}
is MessageContext.DebugExpression -> {
super.setText(firstPartOfDescription + "expression")
}
}

return context
} else {
return null
}
}


private fun getContext(project: Project, editor: Editor, element: PsiElement): Pair<Context, MessageContext>? {
element.ancestors.forEach { currentExpr ->
when (currentExpr) {
is ElmConstantTag -> {
// A constant is unlikely to be interesting to debug.
// It is more likely the context the constant is used in, that is interesting.
currentExpr.parentOfType<ElmBinOpExpr>()
?.let { parentBinOpExpr -> return Context(parentBinOpExpr) }
?.let { parentBinOpExpr -> return Pair(Context(parentBinOpExpr), MessageContext.DebugBinaryOpt) }
return null
}
is ElmParenthesizedExpr -> {
Expand All @@ -38,7 +85,7 @@ class InlineDebugIntention : ElmAtCaretIntentionActionBase<InlineDebugIntention.
return if (parentCallExpr != null && isDebugCall(parentCallExpr) && parentCallExpr.arguments.contains(currentExpr)) {
null
} else {
Context(currentExpr)
Pair(Context(currentExpr), MessageContext.DebugExpression)
}
}
is ElmValueExpr -> {
Expand All @@ -59,7 +106,7 @@ class InlineDebugIntention : ElmAtCaretIntentionActionBase<InlineDebugIntention.
} else if (parentCallExpr.target == currentExpr) {
// If the intention is invoked on a non-debug function, it is likely the output of that function,
// that the user is interested in.
return Context(parentCallExpr)
return Pair(Context(parentCallExpr), MessageContext.DebugFunctionCall)
}
}

Expand All @@ -73,27 +120,33 @@ class InlineDebugIntention : ElmAtCaretIntentionActionBase<InlineDebugIntention.
}
// A separate intention is intended to allow users to insert log statements inside the pipeline.
binOpParent.asPipeline() != null -> {
Context(binOpParent)
Pair(Context(binOpParent), MessageContext.DebugPipeline)
}
else -> {
Context(currentExpr)
Pair(Context(currentExpr), MessageContext.DebugValue)
}
}
} else {
Context(currentExpr)
Pair(Context(currentExpr), MessageContext.DebugValue)
}
}
is ElmCaseOfExpr -> {
return Context(currentExpr)
return Pair(Context(currentExpr), MessageContext.DebugCase)
}
is ElmAtomTag -> {
return Context(currentExpr)
return Pair(Context(currentExpr), MessageContext.DebugValue)
}
is ElmBinOpExpr -> {
return if (isFunComposition(currentExpr)) {
null
} else {
Context(currentExpr)
return when {
isFunComposition(currentExpr) -> {
null
}
currentExpr.asPipeline() != null -> {
Pair(Context(currentExpr), MessageContext.DebugPipeline)
}
else -> {
Pair(Context(currentExpr), MessageContext.DebugBinaryOpt)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,21 @@ package org.elm.ide.intentions

import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.testFramework.PlatformTestUtil
import junit.framework.ComparisonFailure
import org.elm.fileTreeFromText
import org.elm.lang.ElmTestBase
import org.intellij.lang.annotations.Language


abstract class ElmIntentionTestBase(val intention: IntentionAction) : ElmTestBase() {

protected fun doAvailableTest(@Language("Elm") before: String, @Language("Elm") after: String) {
protected fun doAvailableTest(@Language("Elm") before: String, @Language("Elm") after: String, expectedIntentionText: String? = null) {
InlineFile(before).withCaret()
launchAction()
myFixture.checkResult(replaceCaretMarker(after))
if (expectedIntentionText != null && expectedIntentionText != intention.text) {
throw ComparisonFailure("Intention text did not match", expectedIntentionText, intention.text)
}
}

protected fun doAvailableTestWithFileTree(@Language("Elm") fileStructureBefore: String, @Language("Elm") openedFileAfter: String) {
Expand Down
55 changes: 36 additions & 19 deletions src/test/kotlin/org/elm/ide/intentions/InlineDebugIntentionTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ f0 =
module Foo exposing (f0)
f0 =
List.map f (Debug.log "items" (items))
""")
""",
"Debug.log this value")

fun `test debugging function call`() = doAvailableTest(
"""
Expand All @@ -24,18 +25,20 @@ f0 =
module Foo exposing (f0)
f0 =
(Debug.log "List.map f items" (List.map f items))
""")
""",
"Debug.log output of function")

fun `test debugging expr with double quotes`() = doAvailableTest(
"""
"""
module Foo exposing (f0)
f0 =
Str{-caret-}ing.length "foo"
""", """
module Foo exposing (f0)
f0 =
(Debug.log "String.length \"foo\"" (String.length "foo"))
""")
""",
"Debug.log output of function")

fun `test debugging pattern matching input`() = doAvailableTest(
"""
Expand All @@ -54,7 +57,8 @@ f0 =
f1 =
case (Debug.log "f0" (f0)) of
_ -> 1
""")
""",
"Debug.log this value")

fun `test debugging pattern matching output`() = doAvailableTest(
"""
Expand All @@ -78,7 +82,8 @@ f1 =
_ -> 1
)
)
""")
""",
"Debug.log output of case statement")

fun `test debugging case branch`() = doAvailableTest(
"""
Expand All @@ -102,7 +107,8 @@ f1 =
_ -> 1
)
)
""")
""",
"Debug.log output of case statement")

fun `test debugging case branch value`() = doAvailableTest(
"""
Expand All @@ -121,9 +127,10 @@ f0 =
f1 =
case f0 of
_ -> (Debug.log "1 + 1" (1 + 1))
""")
""",
"Debug.log expression")

fun `test debugging case on function call`() = doAvailableTest(
fun `test debugging case on function`() = doAvailableTest(
"""
module Foo exposing (f0)
f0 _ =
Expand All @@ -140,7 +147,8 @@ f0 _ =
f1 =
case ((Debug.log "f0 42" (f0 42))) of
_ -> 1
""")
""",
"Debug.log output of function")

fun `test debugging constants with binary operators`() = doAvailableTest(
"""
Expand All @@ -155,7 +163,8 @@ f1 = 1
f0 =
1 + (Debug.log "f1" (f1))
""")
""",
"Debug.log this value")

fun `test debugging binary operator operation`() = doAvailableTest(
"""
Expand All @@ -166,7 +175,8 @@ f0 =
module Foo exposing (f0)
f0 =
(Debug.log "1 + 1" (1 + 1))
""")
""",
"Debug.log expression")

fun `test debugging multiple binary operator operations`() = doAvailableTest(
"""
Expand All @@ -177,7 +187,8 @@ f0 =
module Foo exposing (f0)
f0 =
(Debug.log "1 + 1 + 1" (1 + 1 + 1))
""")
""",
"Debug.log expression")

fun `test debugging piped operations`() = doAvailableTest(
"""
Expand All @@ -188,7 +199,8 @@ f0 =
module Foo exposing (f0)
f0 =
(Debug.log "1 + 1 + 1 |> (+) 1" (1 + 1 + 1 |> (+) 1))
""")
""",
"Debug.log output of pipeline")

fun `test debugging piped operations with function`() = doAvailableTest(
"""
Expand All @@ -199,7 +211,8 @@ f0 =
module Foo exposing (f0)
f0 =
(Debug.log "1 + 1 + 1 |> String.fromInt" (1 + 1 + 1 |> String.fromInt))
""")
""",
"Debug.log output of pipeline")

fun `test debugging multiline piped operations with function`() = doAvailableTest(
"""
Expand All @@ -217,7 +230,8 @@ f0 =
|> String.fromInt
)
)
""")
""",
"Debug.log output of pipeline")

fun `test debugging function composition`() = doUnavailableTest(
"""
Expand Down Expand Up @@ -256,7 +270,8 @@ f0 =
module Foo exposing (f0)
f0 =
Debug.log "hello" (List.map (Debug.log "identity" (identity)) [ 0 ])
""")
""",
"Debug.log this value")

fun `test debugging nested log function calls with binary operators`() = doAvailableTest(
"""
Expand All @@ -267,7 +282,8 @@ f0 =
module Foo exposing (f0)
f0 =
Debug.log "hello" (2 + ((Debug.log "1 + 1" (1 + 1))))
""")
""",
"Debug.log expression")

fun `test debugging todo statements`() = doUnavailableTest(
"""
Expand Down Expand Up @@ -326,6 +342,7 @@ f0 =
f1 =
(Debug.log "f0" (f0))
""")
""",
"Debug.log this value")

}

0 comments on commit 56a86e2

Please sign in to comment.