[Kotlin] Report escaped dollar characters that can be simplified

KTIJ-31651

GitOrigin-RevId: bba1c376e29ab296b4279cae67c2c4e7ac262161
This commit is contained in:
Pavel Kirpichenkov
2024-10-17 18:04:59 +00:00
committed by intellij-monorepo-bot
parent 6dfc53b736
commit 3f0b8f7532
84 changed files with 1108 additions and 6 deletions
@@ -2285,6 +2285,8 @@ inspection.remove.setter.parameter.type.display.name=Redundant setter parameter
inspection.convert.reference.to.lambda.display.name=Can be replaced with lambda
inspection.convert.lambda.to.reference.display.name=Can be replaced with function reference
inspection.can.be.primary.constructor.property.display.name=Property is explicitly assigned to constructor parameter
inspection.can.unescape.dollar.literal.inspection.display.name=Escaped dollar characters in the string can be simplified
replace.with.dollar.literals=Replace escaped dollars with literals
inspection.has.platform.type.display.name=Function or property has platform type
inspection.leaking.this.display.name=Leaking 'this' in constructor
inspection.redundant.if.display.name=Redundant 'if' statement
@@ -0,0 +1,21 @@
<html>
<body>
Reports that escaped dollar characters in a string can be replaced with regular literals.
<p>
Escaping is only necessary when string content after dollar can be misinterpreted as a string interpolation entry.
</p>
<p><b>Example:</b></p>
<pre><code>
fun example() {
"The price today is \$10. The price tomorrow will be ${'$'}20."
}
</code></pre>
The quick fix converts all safely replaceable escaped dollar characters to regular dollar characters:
<pre><code>
fun example() {
"The price today is $10. The price tomorrow will be $20."
}
</code></pre>
<!-- tooltip end -->
</body>
</html>
@@ -16,8 +16,6 @@ val dollarLiteralExpressions: Array<String> = arrayOf(
"'$'", "\"$\""
)
private object PrefixedStringTemplateUtils
/**
* Convert this string template to a new one with the specified interpolation prefix length.
* The content of the template does not change.
@@ -67,7 +65,7 @@ fun KtStringTemplateExpression.changeInterpolationPrefix(
if (isDestinationSingleQuoted) {
factory.createStringTemplate(contentText)
} else {
// hack until KtPsiFactory has a triple-quoted template generation
// hack until KtPsiFactory has a triple-quoted template generation, KTIJ-31681
factory.createExpression("\"\"\"$contentText\"\"\"") as KtStringTemplateExpression
}
} else {
@@ -250,7 +248,24 @@ fun KtStringTemplateEntry.unescapeIfPossible(newPrefixLength: Int): KtStringTemp
* println("\$`"); println("`")
* ```
*/
fun KtLiteralStringTemplateEntry.canBeConsideredIdentifierOrBlock(): Boolean {
val firstChar = text.firstOrNull() ?: return false
return firstChar.isLetter() || firstChar == '_' || firstChar == '{' || firstChar == '`'
fun KtLiteralStringTemplateEntry.canBeConsideredIdentifierOrBlock(): Boolean =
text.firstOrNull()?.canBeStartOfIdentifierOrBlock() == true
fun Char.canBeStartOfIdentifierOrBlock(): Boolean {
@Suppress("KotlinConstantConditions") // K2 inspection false positive, `isLetter` returns false for these chars KTIJ-31678
return isLetter() || this == '_' || this == '{' || this == '`'
}
fun KtStringTemplateEntry.isEscapedDollar(): Boolean {
return when (this) {
is KtEscapeStringTemplateEntry -> {
return unescapedValue == "$"
}
is KtBlockStringTemplateEntry -> {
expression?.text in dollarLiteralExpressions
}
else -> false
}
}
@@ -60,6 +60,14 @@
language="kotlin"
key="inspection.can.be.primary.constructor.property.display.name" bundle="messages.KotlinBundle"/>
<localInspection implementationClass="org.jetbrains.kotlin.idea.k2.codeinsight.inspections.CanUnescapeDollarLiteralInspection"
groupPath="Kotlin"
groupBundle="messages.KotlinBundle" groupKey="group.names.redundant.constructs"
enabledByDefault="true"
level="WARNING"
language="kotlin"
key="inspection.can.unescape.dollar.literal.inspection.display.name" bundle="messages.KotlinBundle"/>
<localInspection implementationClass="org.jetbrains.kotlin.idea.k2.codeinsight.inspections.diagnosticBased.RedundantModalityModifierInspection"
groupPath="Kotlin"
groupBundle="messages.KotlinBundle" groupKey="group.names.redundant.constructs"
@@ -0,0 +1,152 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.k2.codeinsight.inspections
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.codeInspection.util.InspectionMessage
import com.intellij.codeInspection.util.IntentionFamilyName
import com.intellij.modcommand.ModPsiUpdater
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analysis.api.KaSession
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.idea.base.projectStructure.languageVersionSettings
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
import org.jetbrains.kotlin.idea.codeinsight.api.applicable.inspections.KotlinApplicableInspectionBase
import org.jetbrains.kotlin.idea.codeinsight.api.applicable.inspections.KotlinModCommandQuickFix
import org.jetbrains.kotlin.idea.codeinsights.impl.base.canBeStartOfIdentifierOrBlock
import org.jetbrains.kotlin.idea.codeinsights.impl.base.dollarLiteralExpressions
import org.jetbrains.kotlin.idea.codeinsights.impl.base.isEscapedDollar
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.isSingleQuoted
class CanUnescapeDollarLiteralInspection :
KotlinApplicableInspectionBase.Simple<KtStringTemplateExpression, CanUnescapeDollarLiteralInspection.Context>() {
class Context(
val oldText: String,
val indicesToReplace: Set<Int>,
)
override fun getProblemDescription(
element: KtStringTemplateExpression,
context: Context,
): @InspectionMessage String {
return KotlinBundle.message("inspection.can.unescape.dollar.literal.inspection.display.name")
}
override fun createQuickFix(
element: KtStringTemplateExpression,
context: Context,
): KotlinModCommandQuickFix<KtStringTemplateExpression> = object : KotlinModCommandQuickFix<KtStringTemplateExpression>() {
override fun getFamilyName(): @IntentionFamilyName String {
return KotlinBundle.message("replace.with.dollar.literals")
}
override fun applyFix(
project: Project,
element: KtStringTemplateExpression,
updater: ModPsiUpdater,
) {
val prefixLength = element.interpolationPrefix?.textLength ?: 0
if (element.text != context.oldText) return
val psiFactory = KtPsiFactory(project)
for (entryIndexToReplace in context.indicesToReplace) {
element.entries[entryIndexToReplace].replace(psiFactory.createLiteralStringTemplateEntry("$"))
}
val updatedTemplateText = element.entries.joinToString("") { it.text }
val recreatedTemplate = createReplacementTemplate(
psiFactory, updatedTemplateText, prefixLength,
isSingleQuoted = element.isSingleQuoted(),
)
element.replace(recreatedTemplate)
}
private fun createReplacementTemplate(
ktPsiFactory: KtPsiFactory,
updatedTemplateText: String,
prefixLength: Int,
isSingleQuoted: Boolean,
): KtStringTemplateExpression {
return when {
prefixLength > 0 -> {
ktPsiFactory.createMultiDollarStringTemplate(updatedTemplateText, prefixLength, forceMultiQuoted = !isSingleQuoted)
}
else -> {
if (isSingleQuoted) {
ktPsiFactory.createStringTemplate(updatedTemplateText)
} else {
// KTIJ-31681
val quote = "\"\"\""
ktPsiFactory.createExpression("$quote$updatedTemplateText$quote") as KtStringTemplateExpression
}
}
}
}
}
override fun isApplicableByPsi(element: KtStringTemplateExpression): Boolean {
return element.interpolationPrefix?.textLength?.let { it > 1 } != true
|| element.languageVersionSettings.supportsFeature(LanguageFeature.MultiDollarInterpolation)
}
override fun buildVisitor(
holder: ProblemsHolder,
isOnTheFly: Boolean,
): KtVisitor<*, *> {
return object : KtVisitorVoid() {
override fun visitStringTemplateExpression(entry: KtStringTemplateExpression) {
visitTargetElement(entry, holder, isOnTheFly)
}
}
}
/**
* Find indices of replaceable entries in a string.
* Going through the string entries, count sequential dollars and keep indices of potentially replaceable entries.
* If the length exceeds `prefixLength - 1`, don't add the index of the last entry as replacing it will change the string.
* However, it's still safe to replace all the dollars before the unsafe one.
*/
context(KaSession)
override fun prepareContext(element: KtStringTemplateExpression): Context? {
val prefixLength = element.interpolationPrefix?.textLength ?: 0
var sequentialDollarsCounter = 0
val confirmedReplaceableIndices = mutableSetOf<Int>()
val candidateReplaceableIndices = mutableListOf<Int>()
for ((entryIndex, entry) in element.entries.withIndex()) {
if (entry.isEscapedDollar()) {
candidateReplaceableIndices.add(entryIndex)
sequentialDollarsCounter++
} else if (entry is KtLiteralStringTemplateEntry) {
val lastDollarsCount = entry.text.takeLastWhile { it == '$' }.count()
if (lastDollarsCount == entry.text.length) {
// if the whole line is $, add its length to the previous result
sequentialDollarsCounter += entry.text.length
} else {
// The chain of dollars ended. Check the beginning for $, then the first character after for being unsafe.
val firstDollarsCount = entry.text.takeWhile { it == '$' }.count()
sequentialDollarsCounter += firstDollarsCount
val isSafe = sequentialDollarsCounter < prefixLength
|| entry.text.getOrNull(firstDollarsCount)?.canBeStartOfIdentifierOrBlock() != true
if (isSafe) {
confirmedReplaceableIndices.addAll(candidateReplaceableIndices)
} else if (candidateReplaceableIndices.isNotEmpty()) {
confirmedReplaceableIndices.addAll(candidateReplaceableIndices.dropLast(1))
}
candidateReplaceableIndices.clear()
sequentialDollarsCounter = lastDollarsCount
}
} else if (sequentialDollarsCounter > 0) {
confirmedReplaceableIndices.addAll(candidateReplaceableIndices)
candidateReplaceableIndices.clear()
sequentialDollarsCounter = 0
}
}
// A template can end with several replaceable dollars.
// Add the accumulated indices, it's safe to replace the corresponding entries — there is nothing after them.
confirmedReplaceableIndices.addAll(candidateReplaceableIndices)
return Context(element.text, confirmedReplaceableIndices).takeIf { confirmedReplaceableIndices.isNotEmpty() }
}
}
@@ -8028,6 +8028,230 @@ public abstract class K2LocalInspectionTestGenerated extends AbstractK2LocalInsp
}
}
@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral")
public static class CanSimplifyDollarLiteral extends AbstractK2LocalInspectionTest {
@java.lang.Override
@org.jetbrains.annotations.NotNull
public final KotlinPluginMode getPluginMode() {
return KotlinPluginMode.K2;
}
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
@TestMetadata("beforeAndAfterBlockExpression.kt")
public void testBeforeAndAfterBlockExpression() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/beforeAndAfterBlockExpression.kt");
}
@TestMetadata("beforeAndAfterEscapeSequence.kt")
public void testBeforeAndAfterEscapeSequence() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/beforeAndAfterEscapeSequence.kt");
}
@TestMetadata("beforeAndAfterSimpleNameExpression.kt")
public void testBeforeAndAfterSimpleNameExpression() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/beforeAndAfterSimpleNameExpression.kt");
}
@TestMetadata("blockSlashEscapeOnlyFirst.kt")
public void testBlockSlashEscapeOnlyFirst() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/blockSlashEscapeOnlyFirst.kt");
}
@TestMetadata("blockSlashEscapingMixed.kt")
public void testBlockSlashEscapingMixed() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/blockSlashEscapingMixed.kt");
}
@TestMetadata("canEscapeAllBeforeNumber.kt")
public void testCanEscapeAllBeforeNumber() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/canEscapeAllBeforeNumber.kt");
}
@TestMetadata("multipleBlockEscapedDollars.kt")
public void testMultipleBlockEscapedDollars() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/multipleBlockEscapedDollars.kt");
}
@TestMetadata("multipleSlashEscapedDollars.kt")
public void testMultipleSlashEscapedDollars() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/multipleSlashEscapedDollars.kt");
}
@TestMetadata("noPrefixSimplifiableBeforeBlockExpression.kt")
public void testNoPrefixSimplifiableBeforeBlockExpression() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSimplifiableBeforeBlockExpression.kt");
}
@TestMetadata("noPrefixSingleQuoteBlockEscape.kt")
public void testNoPrefixSingleQuoteBlockEscape() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteBlockEscape.kt");
}
@TestMetadata("noPrefixSingleQuoteBlockEscapeBeforeBacktick.kt")
public void testNoPrefixSingleQuoteBlockEscapeBeforeBacktick() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteBlockEscapeBeforeBacktick.kt");
}
@TestMetadata("noPrefixSingleQuoteBlockEscapeBeforeLetter.kt")
public void testNoPrefixSingleQuoteBlockEscapeBeforeLetter() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteBlockEscapeBeforeLetter.kt");
}
@TestMetadata("noPrefixSingleQuoteBlockEscapeBeforeUnderscore.kt")
public void testNoPrefixSingleQuoteBlockEscapeBeforeUnderscore() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteBlockEscapeBeforeUnderscore.kt");
}
@TestMetadata("noPrefixSingleQuoteBlockEscapeNoReplacement.kt")
public void testNoPrefixSingleQuoteBlockEscapeNoReplacement() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteBlockEscapeNoReplacement.kt");
}
@TestMetadata("noPrefixSingleQuoteMultipleReplacements.kt")
public void testNoPrefixSingleQuoteMultipleReplacements() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteMultipleReplacements.kt");
}
@TestMetadata("noPrefixSingleQuoteSlashEscape.kt")
public void testNoPrefixSingleQuoteSlashEscape() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteSlashEscape.kt");
}
@TestMetadata("noPrefixSingleQuoteSlashEscapeBeforeBackticks.kt")
public void testNoPrefixSingleQuoteSlashEscapeBeforeBackticks() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteSlashEscapeBeforeBackticks.kt");
}
@TestMetadata("noPrefixSingleQuoteSlashEscapeBeforeLetter.kt")
public void testNoPrefixSingleQuoteSlashEscapeBeforeLetter() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteSlashEscapeBeforeLetter.kt");
}
@TestMetadata("noPrefixSingleQuoteSlashEscapeBeforeUnderscore.kt")
public void testNoPrefixSingleQuoteSlashEscapeBeforeUnderscore() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteSlashEscapeBeforeUnderscore.kt");
}
@TestMetadata("noPrefixSingleQuoteSlashEscapeNoReplacement.kt")
public void testNoPrefixSingleQuoteSlashEscapeNoReplacement() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteSlashEscapeNoReplacement.kt");
}
@TestMetadata("noPrefixTripleQuote.kt")
public void testNoPrefixTripleQuote() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixTripleQuote.kt");
}
@TestMetadata("noPrefixTripleQuoteBeforeBacktick.kt")
public void testNoPrefixTripleQuoteBeforeBacktick() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixTripleQuoteBeforeBacktick.kt");
}
@TestMetadata("noPrefixTripleQuoteBeforeBlock.kt")
public void testNoPrefixTripleQuoteBeforeBlock() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixTripleQuoteBeforeBlock.kt");
}
@TestMetadata("noPrefixTripleQuoteBeforeLetter.kt")
public void testNoPrefixTripleQuoteBeforeLetter() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixTripleQuoteBeforeLetter.kt");
}
@TestMetadata("noPrefixTripleQuoteBeforeUnderscore.kt")
public void testNoPrefixTripleQuoteBeforeUnderscore() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixTripleQuoteBeforeUnderscore.kt");
}
@TestMetadata("noPrefixTripleQuoteMultipleReplacements.kt")
public void testNoPrefixTripleQuoteMultipleReplacements() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixTripleQuoteMultipleReplacements.kt");
}
@TestMetadata("noPrefixTripleQuoteNonEscapingBackslashes.kt")
public void testNoPrefixTripleQuoteNonEscapingBackslashes() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixTripleQuoteNonEscapingBackslashes.kt");
}
@TestMetadata("notApplicableBacktickIdentifier.kt")
public void testNotApplicableBacktickIdentifier() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/notApplicableBacktickIdentifier.kt");
}
@TestMetadata("notApplicableBlockEscapedAfterDollar.kt")
public void testNotApplicableBlockEscapedAfterDollar() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/notApplicableBlockEscapedAfterDollar.kt");
}
@TestMetadata("notApplicableBlockEscapedBeforeDollar.kt")
public void testNotApplicableBlockEscapedBeforeDollar() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/notApplicableBlockEscapedBeforeDollar.kt");
}
@TestMetadata("notApplicableCurlyBraces.kt")
public void testNotApplicableCurlyBraces() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/notApplicableCurlyBraces.kt");
}
@TestMetadata("notApplicableSlashEscapedAfterDollar.kt")
public void testNotApplicableSlashEscapedAfterDollar() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/notApplicableSlashEscapedAfterDollar.kt");
}
@TestMetadata("notApplicableSlashEscapedBeforeDollar.kt")
public void testNotApplicableSlashEscapedBeforeDollar() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/notApplicableSlashEscapedBeforeDollar.kt");
}
@TestMetadata("notApplicableUnderscoredIdentifier.kt")
public void testNotApplicableUnderscoredIdentifier() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/notApplicableUnderscoredIdentifier.kt");
}
@TestMetadata("prefix4Safe.kt")
public void testPrefix4Safe() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/prefix4Safe.kt");
}
@TestMetadata("prefix4SafeLong.kt")
public void testPrefix4SafeLong() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/prefix4SafeLong.kt");
}
@TestMetadata("prefix4Unsafe.kt")
public void testPrefix4Unsafe() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/prefix4Unsafe.kt");
}
@TestMetadata("singleBlockEscapedDollar.kt")
public void testSingleBlockEscapedDollar() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/singleBlockEscapedDollar.kt");
}
@TestMetadata("singleDollarPrefixSingleQuoteMultipleReplacements.kt")
public void testSingleDollarPrefixSingleQuoteMultipleReplacements() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/singleDollarPrefixSingleQuoteMultipleReplacements.kt");
}
@TestMetadata("singleDollarPrefixTripleQuoteMultipleReplacements.kt")
public void testSingleDollarPrefixTripleQuoteMultipleReplacements() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/singleDollarPrefixTripleQuoteMultipleReplacements.kt");
}
@TestMetadata("singleSlashEscapedDollar.kt")
public void testSingleSlashEscapedDollar() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/singleSlashEscapedDollar.kt");
}
@TestMetadata("slashBlockEscapeOnlyFirst.kt")
public void testSlashBlockEscapeOnlyFirst() throws Exception {
runTest("../../../idea/tests/testData/inspectionsLocal/canSimplifyDollarLiteral/slashBlockEscapeOnlyFirst.kt");
}
}
@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("testData/inspectionsLocal")
public abstract static class InspectionsLocal extends AbstractK2LocalInspectionTest {
@@ -83,6 +83,8 @@ abstract class AbstractLocalInspectionTest : KotlinLightCodeInsightFixtureTestCa
}
val className = FileUtil.loadFile(candidateFiles[0]).trim { it <= ' ' }
if (className.isBlank()) return object : LocalInspectionTool() {} // return a stub inspection if K1 is not supported
return Class.forName(className).getDeclaredConstructor().newInstance() as LocalInspectionTool
}
@@ -1316,6 +1316,230 @@ public abstract class LocalInspectionTestGenerated extends AbstractLocalInspecti
}
}
@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("testData/inspectionsLocal/canSimplifyDollarLiteral")
public static class CanSimplifyDollarLiteral extends AbstractLocalInspectionTest {
@java.lang.Override
@org.jetbrains.annotations.NotNull
public final KotlinPluginMode getPluginMode() {
return KotlinPluginMode.K1;
}
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
@TestMetadata("beforeAndAfterBlockExpression.kt")
public void testBeforeAndAfterBlockExpression() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/beforeAndAfterBlockExpression.kt");
}
@TestMetadata("beforeAndAfterEscapeSequence.kt")
public void testBeforeAndAfterEscapeSequence() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/beforeAndAfterEscapeSequence.kt");
}
@TestMetadata("beforeAndAfterSimpleNameExpression.kt")
public void testBeforeAndAfterSimpleNameExpression() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/beforeAndAfterSimpleNameExpression.kt");
}
@TestMetadata("blockSlashEscapeOnlyFirst.kt")
public void testBlockSlashEscapeOnlyFirst() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/blockSlashEscapeOnlyFirst.kt");
}
@TestMetadata("blockSlashEscapingMixed.kt")
public void testBlockSlashEscapingMixed() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/blockSlashEscapingMixed.kt");
}
@TestMetadata("canEscapeAllBeforeNumber.kt")
public void testCanEscapeAllBeforeNumber() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/canEscapeAllBeforeNumber.kt");
}
@TestMetadata("multipleBlockEscapedDollars.kt")
public void testMultipleBlockEscapedDollars() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/multipleBlockEscapedDollars.kt");
}
@TestMetadata("multipleSlashEscapedDollars.kt")
public void testMultipleSlashEscapedDollars() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/multipleSlashEscapedDollars.kt");
}
@TestMetadata("noPrefixSimplifiableBeforeBlockExpression.kt")
public void testNoPrefixSimplifiableBeforeBlockExpression() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSimplifiableBeforeBlockExpression.kt");
}
@TestMetadata("noPrefixSingleQuoteBlockEscape.kt")
public void testNoPrefixSingleQuoteBlockEscape() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteBlockEscape.kt");
}
@TestMetadata("noPrefixSingleQuoteBlockEscapeBeforeBacktick.kt")
public void testNoPrefixSingleQuoteBlockEscapeBeforeBacktick() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteBlockEscapeBeforeBacktick.kt");
}
@TestMetadata("noPrefixSingleQuoteBlockEscapeBeforeLetter.kt")
public void testNoPrefixSingleQuoteBlockEscapeBeforeLetter() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteBlockEscapeBeforeLetter.kt");
}
@TestMetadata("noPrefixSingleQuoteBlockEscapeBeforeUnderscore.kt")
public void testNoPrefixSingleQuoteBlockEscapeBeforeUnderscore() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteBlockEscapeBeforeUnderscore.kt");
}
@TestMetadata("noPrefixSingleQuoteBlockEscapeNoReplacement.kt")
public void testNoPrefixSingleQuoteBlockEscapeNoReplacement() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteBlockEscapeNoReplacement.kt");
}
@TestMetadata("noPrefixSingleQuoteMultipleReplacements.kt")
public void testNoPrefixSingleQuoteMultipleReplacements() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteMultipleReplacements.kt");
}
@TestMetadata("noPrefixSingleQuoteSlashEscape.kt")
public void testNoPrefixSingleQuoteSlashEscape() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteSlashEscape.kt");
}
@TestMetadata("noPrefixSingleQuoteSlashEscapeBeforeBackticks.kt")
public void testNoPrefixSingleQuoteSlashEscapeBeforeBackticks() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteSlashEscapeBeforeBackticks.kt");
}
@TestMetadata("noPrefixSingleQuoteSlashEscapeBeforeLetter.kt")
public void testNoPrefixSingleQuoteSlashEscapeBeforeLetter() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteSlashEscapeBeforeLetter.kt");
}
@TestMetadata("noPrefixSingleQuoteSlashEscapeBeforeUnderscore.kt")
public void testNoPrefixSingleQuoteSlashEscapeBeforeUnderscore() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteSlashEscapeBeforeUnderscore.kt");
}
@TestMetadata("noPrefixSingleQuoteSlashEscapeNoReplacement.kt")
public void testNoPrefixSingleQuoteSlashEscapeNoReplacement() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixSingleQuoteSlashEscapeNoReplacement.kt");
}
@TestMetadata("noPrefixTripleQuote.kt")
public void testNoPrefixTripleQuote() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixTripleQuote.kt");
}
@TestMetadata("noPrefixTripleQuoteBeforeBacktick.kt")
public void testNoPrefixTripleQuoteBeforeBacktick() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixTripleQuoteBeforeBacktick.kt");
}
@TestMetadata("noPrefixTripleQuoteBeforeBlock.kt")
public void testNoPrefixTripleQuoteBeforeBlock() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixTripleQuoteBeforeBlock.kt");
}
@TestMetadata("noPrefixTripleQuoteBeforeLetter.kt")
public void testNoPrefixTripleQuoteBeforeLetter() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixTripleQuoteBeforeLetter.kt");
}
@TestMetadata("noPrefixTripleQuoteBeforeUnderscore.kt")
public void testNoPrefixTripleQuoteBeforeUnderscore() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixTripleQuoteBeforeUnderscore.kt");
}
@TestMetadata("noPrefixTripleQuoteMultipleReplacements.kt")
public void testNoPrefixTripleQuoteMultipleReplacements() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixTripleQuoteMultipleReplacements.kt");
}
@TestMetadata("noPrefixTripleQuoteNonEscapingBackslashes.kt")
public void testNoPrefixTripleQuoteNonEscapingBackslashes() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/noPrefixTripleQuoteNonEscapingBackslashes.kt");
}
@TestMetadata("notApplicableBacktickIdentifier.kt")
public void testNotApplicableBacktickIdentifier() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/notApplicableBacktickIdentifier.kt");
}
@TestMetadata("notApplicableBlockEscapedAfterDollar.kt")
public void testNotApplicableBlockEscapedAfterDollar() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/notApplicableBlockEscapedAfterDollar.kt");
}
@TestMetadata("notApplicableBlockEscapedBeforeDollar.kt")
public void testNotApplicableBlockEscapedBeforeDollar() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/notApplicableBlockEscapedBeforeDollar.kt");
}
@TestMetadata("notApplicableCurlyBraces.kt")
public void testNotApplicableCurlyBraces() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/notApplicableCurlyBraces.kt");
}
@TestMetadata("notApplicableSlashEscapedAfterDollar.kt")
public void testNotApplicableSlashEscapedAfterDollar() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/notApplicableSlashEscapedAfterDollar.kt");
}
@TestMetadata("notApplicableSlashEscapedBeforeDollar.kt")
public void testNotApplicableSlashEscapedBeforeDollar() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/notApplicableSlashEscapedBeforeDollar.kt");
}
@TestMetadata("notApplicableUnderscoredIdentifier.kt")
public void testNotApplicableUnderscoredIdentifier() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/notApplicableUnderscoredIdentifier.kt");
}
@TestMetadata("prefix4Safe.kt")
public void testPrefix4Safe() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/prefix4Safe.kt");
}
@TestMetadata("prefix4SafeLong.kt")
public void testPrefix4SafeLong() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/prefix4SafeLong.kt");
}
@TestMetadata("prefix4Unsafe.kt")
public void testPrefix4Unsafe() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/prefix4Unsafe.kt");
}
@TestMetadata("singleBlockEscapedDollar.kt")
public void testSingleBlockEscapedDollar() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/singleBlockEscapedDollar.kt");
}
@TestMetadata("singleDollarPrefixSingleQuoteMultipleReplacements.kt")
public void testSingleDollarPrefixSingleQuoteMultipleReplacements() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/singleDollarPrefixSingleQuoteMultipleReplacements.kt");
}
@TestMetadata("singleDollarPrefixTripleQuoteMultipleReplacements.kt")
public void testSingleDollarPrefixTripleQuoteMultipleReplacements() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/singleDollarPrefixTripleQuoteMultipleReplacements.kt");
}
@TestMetadata("singleSlashEscapedDollar.kt")
public void testSingleSlashEscapedDollar() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/singleSlashEscapedDollar.kt");
}
@TestMetadata("slashBlockEscapeOnlyFirst.kt")
public void testSlashBlockEscapeOnlyFirst() throws Exception {
runTest("testData/inspectionsLocal/canSimplifyDollarLiteral/slashBlockEscapeOnlyFirst.kt");
}
}
@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("testData/inspectionsLocal/cascadeIf")
public static class CascadeIf extends AbstractLocalInspectionTest {
@@ -0,0 +1 @@
org.jetbrains.kotlin.idea.k2.codeinsight.inspections.CanUnescapeDollarLiteralInspection
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$"$${'$'}\$$\$<caret>$${42}\$Foo"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$"$$$$$${42}$Foo"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$"$${'$'}\$$\$<caret>\t\$Foo"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$"$$$$\t$Foo"
}
@@ -0,0 +1,7 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
val a = "A"
$$"$${'$'}\$$\$<caret>$$a\$Foo"
}
@@ -0,0 +1,7 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
val a = "A"
$$"$$$$$$a$Foo"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$"$${'$'}\$<caret>Foo"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$"$\$Foo"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$"\$$${'$'}$${'$'}\$<caret>"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$"$$$$"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$"\$\$\$\$<caret>1"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$"$$$$1"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$"$${'$'}$${'$'}$${'$'}<caret>"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$"$$$"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$"\$\$\$<caret>"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$"$$$"
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"${'$'}$\$${'$'}${42 + 15}<caret>"
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"$$$$${42 + 15}"
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"${'$'}${'$'}${'$'}<caret>"
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"${'$'}${'$'}${'$'}<caret>`Foo Bar`"
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"$$${'$'}`Foo Bar`"
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"${'$'}${'$'}${'$'}<caret>Foo"
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"${'$'}${'$'}${'$'}<caret>_Foo"
}
@@ -0,0 +1,6 @@
// IGNORE_K1
// PROBLEM: none
fun test() {
"Foo${'$'}Bar<caret>"
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"${'$'}\$ Foo\$Bar \$${'$'}`Boo` ${'$'}\$\$${'$'}_Baz\$$$$${'$'} \$\$\$\$ Bee \$\$42 \$<caret>"
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"$$ Foo\$Bar $${'$'}`Boo` $$$${'$'}_Baz$$$$$ $$$$ Bee $$42 $"
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"\$\$\$<caret>"
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"\$\$\$<caret>`Foo Bar`"
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"\$\$\$<caret>Foo"
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"\$\$\$<caret>_Foo"
}
@@ -0,0 +1,6 @@
// IGNORE_K1
// PROBLEM: none
fun test() {
"Foo\$Bar<caret>"
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"""${'$'}${'$'}${'$'}<caret>"""
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"""$$$"""
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"""${'$'}${'$'}${'$'}<caret>`Foo`"""
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"""$$${'$'}`Foo`"""
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"""${'$'}${'$'}${'$'}<caret>{Foo}"""
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"""$$${'$'}{Foo}"""
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"""${'$'}${'$'}${'$'}<caret>Foo"""
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"""$$${'$'}Foo"""
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"""${'$'}${'$'}${'$'}<caret>_Foo"""
}
@@ -0,0 +1,5 @@
// IGNORE_K1
fun test() {
"""$$${'$'}_Foo"""
}
@@ -0,0 +1,14 @@
// IGNORE_K1
fun test() {
"""
\$\$\$
Foo${'$'}Bar
${'$'}${'$'}${'$'}
${'$'}${'$'}`Baz Boo`
${'$'}${'$'}{}
${'$'}${'$'}_Goo${'$'}${'$'}
${'$'}${'$'} Foo
${'$'}${'$'}${'$'}
<caret>${'$'}${'$'}"""
}
@@ -0,0 +1,14 @@
// IGNORE_K1
fun test() {
"""
\$\$\$
Foo${'$'}Bar
$$$
$${'$'}`Baz Boo`
$${'$'}{}
$${'$'}_Goo$$
$$ Foo
$$$
$$"""
}
@@ -0,0 +1,6 @@
// IGNORE_K1
// PROBLEM: none
fun test() {
"""\$\$\$<caret>"""
}
@@ -0,0 +1,7 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
// PROBLEM: none
fun test() {
$$"\$$<caret>`Foo Bar`"
}
@@ -0,0 +1,7 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
// PROBLEM: none
fun test() {
$$"$$${'$'}<caret>Foo"
}
@@ -0,0 +1,7 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
// PROBLEM: none
fun test() {
$$"$${'$'}$<caret>Foo"
}
@@ -0,0 +1,7 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
// PROBLEM: none
fun test() {
$$"\$$<caret>{Foo}"
}
@@ -0,0 +1,7 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
// PROBLEM: none
fun test() {
$$"$\$<caret>Foo"
}
@@ -0,0 +1,7 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
// PROBLEM: none
fun test() {
$$"\$$<caret>Foo"
}
@@ -0,0 +1,7 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
// PROBLEM: none
fun test() {
$$"\$$<caret>_Foo"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$$$"\$$$$$${'$'}<caret>Foo"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$$$"$$$Foo"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$$$"\$$$$$${'$'}<caret>Foo\$\$\$\$\$\$\$\$"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$$$"$$$Foo$$$$$$$$"
}
@@ -0,0 +1,7 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
// PROBLEM: none
fun test() {
$$$$"\$$$$<caret>Foo"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$"$${'$'}<caret>"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$"$"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$"${'$'}\$ Foo\$Bar \$${'$'}`Boo` ${'$'}\$\$${'$'}_Baz\$$$$${'$'} \$\$\$\$ Bee \$\$42 \$<caret>"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$"$$ Foo\$Bar $${'$'}`Boo` $$$${'$'}_Baz$$$$$ $$$$ Bee $$42 $"
}
@@ -0,0 +1,15 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$"""
\$\$\$
Foo${'$'}Bar
${'$'}${'$'}${'$'}
${'$'}${'$'}`Baz Boo`
${'$'}${'$'}{}
${'$'}${'$'}_Goo${'$'}${'$'}
${'$'}${'$'} Foo
${'$'}${'$'}${'$'}
<caret>${'$'}${'$'}"""
}
@@ -0,0 +1,15 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$"""
\$\$\$
Foo${'$'}Bar
$$$
$${'$'}`Baz Boo`
$${'$'}{}
$${'$'}_Goo$$
$$ Foo
$$$
$$"""
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$"\$<caret>"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$"$"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$"\$$${'$'}<caret>Foo"
}
@@ -0,0 +1,6 @@
// COMPILER_ARGUMENTS: -Xmulti-dollar-interpolation
// IGNORE_K1
fun test() {
$$"$$${'$'}Foo"
}
@@ -65,6 +65,7 @@ internal fun MutableTWorkspace.generateK2InspectionTests() {
model("${idea}/inspectionsLocal/canBeParameter")
model("${idea}/inspectionsLocal/arrayInDataClass")
model("${idea}/inspectionsLocal/collections/simplifiableCallChain")
model("${idea}/inspectionsLocal/canSimplifyDollarLiteral")
model("code-insight/inspections-k2/tests/testData/inspectionsLocal", pattern = pattern)
}
/**