diff --git a/src/main/kotlin/com/funivan/idea/phpClean/inspections/classNameCollision/ClassNameCollisionInspection.html b/src/main/kotlin/com/funivan/idea/phpClean/inspections/classNameCollision/ClassNameCollisionInspection.html index bf14027..90b6259 100644 --- a/src/main/kotlin/com/funivan/idea/phpClean/inspections/classNameCollision/ClassNameCollisionInspection.html +++ b/src/main/kotlin/com/funivan/idea/phpClean/inspections/classNameCollision/ClassNameCollisionInspection.html @@ -1,5 +1,6 @@ Classes with same name in different namespaces can be confused. (Disabled by default) +
Option: Ignore vendor classes. When enabled, class name collisions with classes defined in the project's vendor directory are ignored.
namespace App {
class User {}; // <- Class name collision with \Cli\User
diff --git a/src/main/kotlin/com/funivan/idea/phpClean/inspections/classNameCollision/ClassNameCollisionInspection.kt b/src/main/kotlin/com/funivan/idea/phpClean/inspections/classNameCollision/ClassNameCollisionInspection.kt
index 6ab4793..cb0454a 100644
--- a/src/main/kotlin/com/funivan/idea/phpClean/inspections/classNameCollision/ClassNameCollisionInspection.kt
+++ b/src/main/kotlin/com/funivan/idea/phpClean/inspections/classNameCollision/ClassNameCollisionInspection.kt
@@ -2,19 +2,42 @@ package com.funivan.idea.phpClean.inspections.classNameCollision
import com.funivan.idea.phpClean.spl.PhpCleanInspection
import com.intellij.codeInspection.ProblemsHolder
+import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.vfs.LocalFileSystem
+import com.intellij.openapi.vfs.VfsUtilCore
+import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiElementVisitor
import com.jetbrains.php.PhpIndex
import com.jetbrains.php.lang.psi.elements.PhpClass
import com.jetbrains.php.lang.psi.visitors.PhpElementVisitor
+import javax.swing.JComponent
class ClassNameCollisionInspection : PhpCleanInspection() {
+ companion object {
+ private const val VENDOR_DIR_NAME = "vendor"
+ }
+
+ @JvmField
+ var ignoreVendorClasses = false
+
override fun getShortName() = "ClassNameCollisionInspection"
+
+ override fun createOptionsPanel(): JComponent {
+ return SingleCheckboxOptionsPanel(
+ "Ignore vendor classes",
+ this,
+ "ignoreVendorClasses"
+ )
+ }
+
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
+ val vendorDir = if (ignoreVendorClasses) findVendorDir(holder.project) else null
return object : PhpElementVisitor() {
override fun visitPhpClass(phpClass: PhpClass) {
phpClass.nameIdentifier?.let { name ->
- find(phpClass, name)?.let { clazz ->
+ find(phpClass, name, vendorDir)?.let { clazz ->
holder.registerProblem(
name,
"Class name collision with ${clazz.fqn}"
@@ -27,8 +50,32 @@ class ClassNameCollisionInspection : PhpCleanInspection() {
private fun find(
origin: PhpClass,
- name: PsiElement
- ) = PhpIndex.getInstance(origin.project)
- .getClassesByName(name.text)
- .firstOrNull { it.fqn != origin.fqn }
+ name: PsiElement,
+ vendorDir: VirtualFile?
+ ): PhpClass? {
+ val collisions = PhpIndex.getInstance(origin.project)
+ .getClassesByName(name.text)
+ .filter { it.fqn != origin.fqn }
+ val filtered = if (vendorDir == null) {
+ collisions
+ } else {
+ collisions.filterNot { isVendorClass(it, vendorDir) }
+ }
+ return filtered.firstOrNull()
+ }
+
+ private fun findVendorDir(project: Project): VirtualFile? {
+ val basePath = project.basePath
+ ?: return null
+ val projectDir = LocalFileSystem.getInstance().findFileByPath(basePath)
+ ?: return null
+ return projectDir.findChild(VENDOR_DIR_NAME)
+ }
+
+ private fun isVendorClass(phpClass: PhpClass, vendorDir: VirtualFile): Boolean {
+ val file = phpClass.containingFile.virtualFile
+ ?: return false
+
+ return VfsUtilCore.isAncestor(vendorDir, file, true)
+ }
}
diff --git a/src/test/kotlin/com/funivan/idea/phpClean/inspections/classNameCollision/ClassNameCollisionInspectionTest.kt b/src/test/kotlin/com/funivan/idea/phpClean/inspections/classNameCollision/ClassNameCollisionInspectionTest.kt
index 3612e69..b32060c 100644
--- a/src/test/kotlin/com/funivan/idea/phpClean/inspections/classNameCollision/ClassNameCollisionInspectionTest.kt
+++ b/src/test/kotlin/com/funivan/idea/phpClean/inspections/classNameCollision/ClassNameCollisionInspectionTest.kt
@@ -34,4 +34,46 @@ class ClassNameCollisionInspectionTest : BaseInspectionTest() {
"""
)
}
+
+ @Test
+ fun testVendorCollisionIgnoredWhenOptionEnabled() {
+ myFixture.addFileToProject(
+ "vendor/lib/User.php",
+ """User {};
+ }
+ """
+ )
+ }
}