blob: 5740b86415acbb1890e3ae0d9fdf778809b69dbd [file] [log] [blame]
package com.github.shyiko.ktlint.ruleset.standard
import com.github.shyiko.ktlint.core.KtLint
import com.github.shyiko.ktlint.core.Rule
import org.jetbrains.kotlin.com.intellij.lang.ASTNode
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
import java.nio.file.Paths
/**
* If there is only one top level class in a given file, then its name should match the file's name
*/
class ClassNameMatchesFileNameRule : Rule("class-name-matches-file-name"), Rule.Modifier.RestrictToRoot {
override fun visit(
node: ASTNode,
autoCorrect: Boolean,
emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit
) {
// Ignore all non ".kt" files (including ".kts")
if (node.getUserData(KtLint.FILE_PATH_USER_DATA_KEY)?.endsWith(".kt") != true) {
return
}
val topLevelClassNames = mutableListOf<String>()
node.visit {
if (it.elementType == KtStubElementTypes.CLASS && it.treeParent.elementType == KtStubElementTypes.FILE) {
val classIdentifier = it.findChildByType(KtTokens.IDENTIFIER)
classIdentifier?.let {
val className = it.text
topLevelClassNames.add(className)
}
}
}
val name = Paths.get(node.getUserData(KtLint.FILE_PATH_USER_DATA_KEY)).fileName.toString().substringBefore(".")
if (topLevelClassNames.size == 1 && name != topLevelClassNames.first()) {
emit(0,
"Single top level class name [${topLevelClassNames.first()}] does not match file name",
false)
}
}
}