Skip to content

Commit

Permalink
Merge branch 'master' into vtchem-patch-4
Browse files Browse the repository at this point in the history
  • Loading branch information
0x6675636b796f75676974687562 authored Jul 12, 2022
2 parents 819c3cd + e56c3b1 commit c822bd3
Show file tree
Hide file tree
Showing 10 changed files with 349 additions and 13 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ jobs:
cp diktat-rules/src/main/resources/diktat-analysis.yml $(dirname $file)
done
next_snapshot_version=$(printf 'VERSION=${project.version}\n0\n' | mvn help:evaluate | grep '^VERSION' | cut -d= -f2)
# Update the version in `examples/maven/pom.xml`
# (which is not a part of the multi-module project).
for file in examples/maven/pom.xml
do
sed -i "s|\(<version>\)[[:digit:]]\(\.[[:digit:]]\)\+-SNAPSHOT\(</version>\)|\1${next_snapshot_version}\3|g" "${file}" || echo "File ${file} hasn't been updated (2nd sed pass)"
done
echo "version=$next_snapshot_version" > info/buildSrc/gradle.properties
- name: Create pull request
uses: peter-evans/create-pull-request@v4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,11 +233,12 @@ class CommentsFormatting(configRules: List<RulesConfig>) : DiktatRule(
}

if (node.elementType == BLOCK_COMMENT &&
(node
.text
.trim('/', '*')
.takeWhile { it == ' ' }
.length == configuration.maxSpacesInComment ||
(node.isIndentStyleComment() ||
node
.text
.trim('/', '*')
.takeWhile { it == ' ' }
.length == configuration.maxSpacesInComment ||
node
.text
.trim('/', '*')
Expand Down Expand Up @@ -343,6 +344,30 @@ class CommentsFormatting(configRules: List<RulesConfig>) : DiktatRule(

private fun ASTNode.isChildOfBlockOrClassBody(): Boolean = treeParent.elementType == BLOCK || treeParent.elementType == CLASS_BODY

/**
* Returns whether this block comment is a `indent`-style comment.
*
* `indent(1)` is a source code formatting utility for C-like languages.
* Historically, source code formatters are permitted to reformat and reflow
* the content of block comments, except for those comments which start with
* "&#x2f;*-".
*
* See also:
* - [5.1.1 Block Comments](https://www.oracle.com/java/technologies/javase/codeconventions-comments.html)
* - [`indent(1)`](https://man.openbsd.org/indent.1)
* - [`style(9)`](https://www.freebsd.org/cgi/man.cgi?query=style&sektion=9)
*
* @return `true` if this block comment is a `indent`-style comment, `false`
* otherwise.
*/
private fun ASTNode.isIndentStyleComment(): Boolean {
require(elementType == BLOCK_COMMENT) {
"The elementType of this node is $elementType while $BLOCK_COMMENT expected"
}

return text.matches(indentCommentMarker)
}

/**
* [RuleConfiguration] for [CommentsFormatting] rule
*/
Expand All @@ -361,5 +386,10 @@ class CommentsFormatting(configRules: List<RulesConfig>) : DiktatRule(
private const val APPROPRIATE_COMMENT_SPACES = 1
private const val MAX_SPACES = 1
const val NAME_ID = "kdoc-comments-codeblocks-formatting"

/**
* "&#x2f;*-" followed by anything but `*` or `-`.
*/
private val indentCommentMarker = Regex("""(?s)^\Q/*-\E[^*-].*?""")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -213,18 +213,33 @@ internal class DotCallChecker(config: IndentationConfig) : CustomIndentationChec
} || nextNode.isCommentBeforeDot()) && whiteSpace.parents.none { it.node.elementType == LONG_STRING_TEMPLATE_ENTRY }
}
?.let { node ->
val indentIncrement = (if (configuration.extendedIndentBeforeDot) 2 else 1) * configuration.indentationSize
if (node.isFromStringTemplate()) {
return CheckResult.from(indentError.actual, indentError.expected +
(if (configuration.extendedIndentBeforeDot) 2 else 1) * configuration.indentationSize, true)
indentIncrement, true)
}

// we need to get indent before the first expression in calls chain
return CheckResult.from(indentError.actual, (whiteSpace.run {
/*-
* If the parent indent (the one before a `DOT_QUALIFIED_EXPRESSION`
* or a `SAFE_ACCESS_EXPRESSION`) is `null`, then use 0 as the
* fallback value.
*
* If `indentError.expected` is used as a fallback (pre-1.2.2
* behaviour), this breaks chained dot-qualified or safe-access
* expressions (see #1336), e.g.:
*
* ```kotlin
* val a = first()
* .second()
* .third()
* ```
*/
val parentIndent = whiteSpace.run {
parents.takeWhile { it is KtDotQualifiedExpression || it is KtSafeQualifiedExpression }.lastOrNull() ?: this
}
.parentIndent()
?: indentError.expected) +
(if (configuration.extendedIndentBeforeDot) 2 else 1) * configuration.indentationSize, true)
}.parentIndent() ?: 0
val expectedIndent = parentIndent + indentIncrement
return CheckResult.from(indentError.actual, expectedIndent, true)
}
return null
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
package org.cqfn.diktat.ruleset.chapter2

import org.cqfn.diktat.ruleset.chapter2.CommentsFormattingTest.Companion.indentStyleComment
import org.cqfn.diktat.ruleset.chapter3.spaces.IndentationRuleTestMixin.describe
import org.cqfn.diktat.ruleset.rules.chapter2.kdoc.CommentsFormatting
import org.cqfn.diktat.util.FixTestBase

import generated.WarningNames.COMMENT_WHITE_SPACE
import generated.WarningNames.FIRST_COMMENT_NO_BLANK_LINE
import generated.WarningNames.IF_ELSE_COMMENTS
import generated.WarningNames.WRONG_NEWLINES_AROUND_KDOC
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Tags
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.io.TempDir

import java.nio.file.Path

class CommentsFormattingFixTest : FixTestBase("test/paragraph2/kdoc/", ::CommentsFormatting) {
@Test
Expand Down Expand Up @@ -40,4 +46,16 @@ class CommentsFormattingFixTest : FixTestBase("test/paragraph2/kdoc/", ::Comment
fun `regression - should not insert newline before the first comment in a file`() {
fixAndCompare("NoPackageNoImportExpected.kt", "NoPackageNoImportTest.kt")
}

/**
* `indent(1)` and `style(9)` style comments.
*/
@Test
@Tag(COMMENT_WHITE_SPACE)
fun `indent-style header in a block comment should be preserved`(@TempDir tempDir: Path) {
val lintResult = fixAndCompareContent(indentStyleComment, tempDir = tempDir)
assertThat(lintResult.actualContent)
.describedAs("lint result for ${indentStyleComment.describe()}")
.isEqualTo(lintResult.expectedContent)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.cqfn.diktat.util.LintTestBase

import com.pinterest.ktlint.core.LintError
import generated.WarningNames
import org.intellij.lang.annotations.Language
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Test

Expand Down Expand Up @@ -491,4 +492,35 @@ class CommentsFormattingTest : LintTestBase(::CommentsFormatting) {

lintMethod(code)
}

/**
* `indent(1)` and `style(9)` style comments.
*/
@Test
@Tag(WarningNames.COMMENT_WHITE_SPACE)
fun `indent-style header in a block comment should produce no warnings`() =
lintMethod(indentStyleComment)

internal companion object {
@Language("kotlin")
internal val indentStyleComment = """
|/*-
| * This is an indent-style comment, and it's different from regular
| * block comments in C-like languages.
| *
| * Code formatters should not wrap or reflow its content, so you can
| * safely insert code fragments:
| *
| * ```
| * int i = 42;
| * ```
| *
| * or ASCII diagrams:
| *
| * +-----+
| * | Box |
| * +-----+
| */
""".trimMargin()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.cqfn.diktat.ruleset.chapter3.spaces.IndentationRuleTestMixin.assertNo
import org.cqfn.diktat.ruleset.chapter3.spaces.IndentationRuleTestMixin.describe
import org.cqfn.diktat.ruleset.chapter3.spaces.IndentationRuleTestMixin.extendedIndent
import org.cqfn.diktat.ruleset.chapter3.spaces.IndentationRuleTestMixin.withCustomParameters
import org.cqfn.diktat.ruleset.chapter3.spaces.IndentationRuleTestResources.dotQualifiedExpressions
import org.cqfn.diktat.ruleset.chapter3.spaces.IndentationRuleTestResources.expressionBodyFunctions
import org.cqfn.diktat.ruleset.chapter3.spaces.IndentationRuleTestResources.expressionsWrappedAfterOperator
import org.cqfn.diktat.ruleset.chapter3.spaces.IndentationRuleTestResources.parenthesesSurroundedInfixExpressions
Expand Down Expand Up @@ -248,4 +249,38 @@ class IndentationRuleFixTest : FixTestBase("test/paragraph3/indentation",
rulesConfigList = customConfig.asRulesConfigList())
}
}

/**
* See [#1336](https://github.com/saveourtool/diktat/issues/1336).
*/
@Nested
@TestMethodOrder(DisplayName::class)
inner class `Dot- and safe-qualified expressions` {
@ParameterizedTest(name = "extendedIndentBeforeDot = {0}")
@ValueSource(booleans = [false, true])
@Tag(WarningNames.WRONG_INDENTATION)
fun `should be properly indented`(extendedIndentBeforeDot: Boolean, @TempDir tempDir: Path) {
val defaultConfig = IndentationConfig("newlineAtEnd" to false)
val customConfig = defaultConfig.withCustomParameters("extendedIndentBeforeDot" to extendedIndentBeforeDot)

lintMultipleMethods(
dotQualifiedExpressions[extendedIndentBeforeDot].assertNotNull(),
tempDir = tempDir,
rulesConfigList = customConfig.asRulesConfigList())
}

@ParameterizedTest(name = "extendedIndentBeforeDot = {0}")
@ValueSource(booleans = [false, true])
@Tag(WarningNames.WRONG_INDENTATION)
fun `should be reformatted if mis-indented`(extendedIndentBeforeDot: Boolean, @TempDir tempDir: Path) {
val defaultConfig = IndentationConfig("newlineAtEnd" to false)
val customConfig = defaultConfig.withCustomParameters("extendedIndentBeforeDot" to extendedIndentBeforeDot)

lintMultipleMethods(
actualContent = dotQualifiedExpressions[!extendedIndentBeforeDot].assertNotNull(),
expectedContent = dotQualifiedExpressions[extendedIndentBeforeDot].assertNotNull(),
tempDir = tempDir,
rulesConfigList = customConfig.asRulesConfigList())
}
}
}
Loading

0 comments on commit c822bd3

Please sign in to comment.