Skip to content

Commit

Permalink
Merge pull request #246 from yokotaso/Issue-238
Browse files Browse the repository at this point in the history
Issues#238 Rule About package name
  • Loading branch information
shyiko committed Jul 24, 2018
2 parents 0c2fad9 + e471e6c commit 1ce58b3
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
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.psi.KtPackageDirective
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
import java.io.File

/**
* @see [kotlin style guide](https://kotlinlang.org/docs/reference/coding-conventions.html#naming-rules)
* @see [android style guide](https://android.github.io/kotlin-guides/style.html#package-names)
* @author yokotaso <yokotaso.t@gmail.com>
*/
class PackageNameRule : Rule("package-name-rule") {
private var filePath: String? = null

override fun visit(
node: ASTNode,
autoCorrect: Boolean,
emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit
) {
if (node.elementType == KtStubElementTypes.FILE) {
filePath = node.getUserData(KtLint.FILE_PATH_USER_DATA_KEY)
}

if (node.elementType == KtStubElementTypes.PACKAGE_DIRECTIVE) {
val qualifiedName = (node.psi as KtPackageDirective).qualifiedName
if (packageNameNotContainsDirectoryPath(qualifiedName)) {
emit(node.startOffset, "package name should match directory name.", false)
}

if (qualifiedName.contains('_', false)) {
emit(node.startOffset, "package names should be not contain underscore.", false)
}
}
}

private fun packageNameNotContainsDirectoryPath(qualifiedName: String): Boolean {
var filePathFromQualifiedName = qualifiedName.replace('.', File.separatorChar, false)
// Skip package name is empty
if (filePathFromQualifiedName.isEmpty()) {
return false
}

val actualFilePath = filePath.orEmpty()
return actualFilePath.contains(filePathFromQualifiedName).not()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class StandardRuleSetProvider : RuleSetProvider {
CommentSpacingRule(),
FilenameRule(),
FinalNewlineRule(),
PackageNameRule(),
UseWhiteSpaceInsteadOfTabRule(),
IfElseMultiLineBlockWithCurlBraceRule(),
// disabled until it's clear how to reconcile difference in Intellij & Android Studio import layout
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.github.shyiko.ktlint.ruleset.standard

import com.github.shyiko.ktlint.core.LintError
import com.github.shyiko.ktlint.test.lint
import org.assertj.core.api.Assertions.assertThat
import org.testng.annotations.Test
import java.net.URI
import java.nio.file.Paths

/**
* @author yokotaso <yokotaso.t@gmail.com>
*/
class PackageNameRuleTest {

@Test
fun testPackageName_Success() {
lintSuccess("package hoge.fuga", "/hoge/fuga/A.kt")
lintSuccess("package hoge.fuga\nclass B{}", "/hoge/fuga/B.kt")
lintSuccess("package hoge.fuga\nclass C{}", "/var/tmp/hoge/fuga/C.kt")
lintSuccess("package hoge.fuga\nclass B{}\nclass C{}", "/var/tmp/hoge/fuga/Mix.kt")
lintSuccess("package hoge.fuga\nfun main() {}", "/var/tmp/hoge/fuga/main.kt")
lintSuccess("class A{}", "/var/tmp/hoge/fuga/A.kt")
}

@Test
fun testPackageName_Failed() {
lintFailed(
"package hoge.fuga",
"/hoge/moge/A.kt",
listOf(LintError(1, 1, "package-name-rule", "package name should match directory name.")
))
}

@Test
fun testPackageName_UnderScoreContains() {
lintFailed(
"package hoge.moge.hoge_moge",
"/hoge/moge/hoge_moge/A.kt",
listOf(LintError(1, 1, "package-name-rule", "package names should be not contain underscore.")
))
}

@Test
fun testPackageName_UpperCaseContains() {
lintSuccess(
"package hoge.moge.hogeMoge",
"/hoge/moge/hogeMoge/A.kt")
}

private fun fileName(fileName: String) = mapOf("file_path" to Paths.get(URI.create("file:///$fileName")).toString())

private fun lintSuccess(ktScript: String, fileName: String) {
assertThat(PackageNameRule().lint(ktScript, fileName(fileName))).isEmpty()
}

private fun lintFailed(ktScript: String, fileName: String, lintErrors: List<LintError>) {
assertThat(PackageNameRule().lint(ktScript, fileName(fileName))).isEqualTo(lintErrors)
}
}

0 comments on commit 1ce58b3

Please sign in to comment.