Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unused import inspection #2263

Merged
merged 1 commit into from
Apr 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ inline fun <reified T : PsiElement> PsiElement.findChildrenOfType(): Collection<
return PsiTreeUtil.findChildrenOfType(this, T::class.java)
}

inline fun <reified T : PsiElement> PsiElement.findChildOfType(): T? {
return PsiTreeUtil.findChildOfType(this, T::class.java)
}

fun PsiElement.childOfType(type: IElementType): PsiElement? {
return node.findChildByType(type)?.psi
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.squareup.sqldelight.intellij.inspections

import com.intellij.codeInsight.actions.OptimizeImportsProcessor
import com.intellij.codeInspection.InspectionManager
import com.intellij.codeInspection.LocalInspectionTool
import com.intellij.codeInspection.LocalQuickFixOnPsiElement
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.squareup.sqldelight.core.lang.psi.ImportStmtMixin
import com.squareup.sqldelight.core.lang.util.findChildrenOfType
import com.squareup.sqldelight.core.psi.SqlDelightJavaTypeName

class UnusedImportInspection : LocalInspectionTool() {

override fun runForWholeFile(): Boolean = true

override fun checkFile(
file: PsiFile,
manager: InspectionManager,
isOnTheFly: Boolean
): Array<ProblemDescriptor> {
val columnTypes = file.findChildrenOfType<SqlDelightJavaTypeName>()
.map { javaTypeName -> javaTypeName.text }

return file.findChildrenOfType<ImportStmtMixin>()
.filter { importStmtMixin -> importStmtMixin.text.findAnyOf(columnTypes) == null }
.map { importStmtMixin ->
manager.createProblemDescriptor(
importStmtMixin, "Unused import", isOnTheFly,
arrayOf(RemoveUnusedImportQuickFix(file)), ProblemHighlightType.LIKE_UNUSED_SYMBOL
)
}
.toTypedArray()
}

class RemoveUnusedImportQuickFix(file: PsiFile) : LocalQuickFixOnPsiElement(file) {

override fun getFamilyName(): String = name

override fun getText(): String = "Optimize imports"

override fun invoke(
project: Project,
file: PsiFile,
startElement: PsiElement,
endElement: PsiElement
) {
OptimizeImportsProcessor(project, file).run()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.squareup.sqldelight.intellij.lang

import com.intellij.lang.ImportOptimizer
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiFileFactory
import com.squareup.sqldelight.core.lang.MigrationFile
import com.squareup.sqldelight.core.lang.SqlDelightFile
import com.squareup.sqldelight.core.lang.SqlDelightFileType
import com.squareup.sqldelight.core.lang.psi.ImportStmtMixin
import com.squareup.sqldelight.core.lang.util.findChildOfType
import com.squareup.sqldelight.core.lang.util.findChildrenOfType
import com.squareup.sqldelight.core.psi.SqlDelightImportStmtList
import com.squareup.sqldelight.core.psi.SqlDelightJavaTypeName

class SqlDelightImportOptimizer : ImportOptimizer {

override fun supports(file: PsiFile): Boolean = file is SqlDelightFile || file is MigrationFile

override fun processFile(file: PsiFile): Runnable = Runnable {
val manager = PsiDocumentManager.getInstance(file.project)
val document = manager.getDocument(file) ?: return@Runnable
manager.commitDocument(document)

val columnTypes = file.findChildrenOfType<SqlDelightJavaTypeName>()
.map { javaTypeName -> javaTypeName.text }

val remainingImports = file.findChildrenOfType<ImportStmtMixin>()
.asSequence()
.map { import -> import.text }
.filter { import -> import.findAnyOf(columnTypes) != null }
.sorted()
.joinToString("\n")
val factory = PsiFileFactory.getInstance(file.project)
val dummyFile = factory.createFileFromText(
"_Dummy_.${SqlDelightFileType.EXTENSION}",
SqlDelightFileType, remainingImports
)
val newImportList = dummyFile.findChildOfType<SqlDelightImportStmtList>()
if (newImportList != null) {
file.findChildOfType<SqlDelightImportStmtList>()?.replace(newImportList)
}
}
}
12 changes: 12 additions & 0 deletions sqldelight-idea-plugin/src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,22 @@
<lang.parserDefinition language="SqlDelightMigration"
implementationClass="com.squareup.sqldelight.core.lang.MigrationParserDefinition"/>

<lang.importOptimizer language="SqlDelight" implementationClass="com.squareup.sqldelight.intellij.lang.SqlDelightImportOptimizer"/>

<lang.importOptimizer language="SqlDelightMigration" implementationClass="com.squareup.sqldelight.intellij.lang.SqlDelightImportOptimizer"/>

<intentionAction>
<className>com.squareup.sqldelight.intellij.intentions.ExpandColumnNamesWildcardQuickFix</className>
<category>SQLDelight</category>
</intentionAction>

<localInspection
enabledByDefault="true"
language="SqlDelight"
level="WARNING"
implementationClass="com.squareup.sqldelight.intellij.inspections.UnusedImportInspection"
displayName="Unused import inspection"
groupName="Declaration redundancy"/>
</extensions>

<actions>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.squareup.sqldelight.intellij.inspections

import com.intellij.codeInspection.ex.LocalInspectionToolWrapper
import com.squareup.sqldelight.intellij.SqlDelightFixtureTestCase

class UnusedImportInspectionTest : SqlDelightFixtureTestCase() {

override val fixtureDirectory: String = "inspections"

fun testUnusedImportInspection() {
myFixture.testInspection("", LocalInspectionToolWrapper(UnusedImportInspection()))
}
}
13 changes: 13 additions & 0 deletions sqldelight-idea-plugin/testData/inspections/expected.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
<problem>
<file>CreateTable.sq</file>
<line>1</line>
<description>Unused import</description>
</problem>
<problem>
<file>AlterTable.sqm</file>
<line>1</line>
<description>Unused import</description>
</problem>
</problems>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import java.time.OffsetDateTime;

ALTER TABLE hockeyPlayer ADD COLUMN draft_year TEXT;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import java.time.OffsetDateTime;

CREATE TABLE hockeyPlayer (
player_number INTEGER NOT NULL,
full_name TEXT NOT NULL
);