Closed kgevorkyan closed 11 months ago
Another evidence: when diktat is executed with ktlint like ktlint -R diktat-0.6.1.jar -F smoke/src/main/kotlin/Example1Test.kt
we also get this error, because ktlint mutates the tree:
[ERROR] 2021-06-23 11:52:49 Internal error has occurred in block-structure. Please make an issue on this bug at https://github.com/cqfn/diKTat/.
java.lang.NullPointerException
at org.jetbrains.kotlin.com.intellij.psi.impl.source.codeStyle.CodeEditUtil.saveWhitespacesInfo(CodeEditUtil.java:122)
at org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.ChangeUtil.saveIndentationToCopy(ChangeUtil.java:106)
at org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.ChangeUtil.copyLeafWithText(ChangeUtil.java:82)
at org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafElement.replaceWithText(LeafElement.java:154)
at org.cqfn.diktat.ruleset.rules.chapter3.BlockStructureBraces$checkCloseBrace$2.invoke(BlockStructureBraces.kt:248)
at org.cqfn.diktat.ruleset.rules.chapter3.BlockStructureBraces$checkCloseBrace$2.invoke(BlockStructureBraces.kt:244)
Possibe reason:
PsiFile file = psiElement.getContainingFile();
setOldIndentation((TreeElement)first, IndentHelper.getInstance().getIndent(file.getProject(), file.getFileType(), first));
where file
is null
The issue was in the replaceWithText
method.
It requires a special Indenting Service that saves original indenting in the node (useful in cases when you want just to change the functional part of the node without thinking about newlines and spaces).
But! if you will not provide this service during parsing (in ktlint for example), you will get an NPE (during the loading of the Service):
public static void saveWhitespacesInfo(ASTNode first) {
// if indentation was changed HERE <<<<
if (first != null && !isNodeGenerated(first) && getOldIndentation(first) < 0) {
PsiElement psiElement = first.getPsi();
if (psiElement != null) {
PsiFile file = psiElement.getContainingFile();
// IndentHelper.getInstance() will be null here if we will not pass this service to kotlin compiler
// and we will get NPE
setOldIndentation((TreeElement)first, IndentHelper.getInstance().getIndent(file, first));
}
}
}
Ktlint has already faced it in: https://github.com/pinterest/ktlint/commit/7fb5885c551ceea0329983dc1c15ce0993f1f6f9
Need to remove this method from diktat and replace it with some more reliable logic.
already done, we use rawReplaceWithText
Describe the bug
There is not the first time, when
public LeafElement replaceWithText()
fromLeafElement.java
causes the exceptions in diKTatSeems, that it can break the structure of AST tree in some cases, therefore we can met exceptions. But this behavior should be investigated, and probably, we must refuse to use this function in diKTat.
Steps to Reproduce
E.g.: In function
insertNewlinesBetweenBlocks
fromFileStructureRule
change line withreplaceChild
to the