Skip to content

Commit

Permalink
feat(core): refactor code
Browse files Browse the repository at this point in the history
  • Loading branch information
Q-Peppa committed Sep 22, 2024
1 parent 6caf793 commit 1cbc7c5
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 57 deletions.
Original file line number Diff line number Diff line change
@@ -1,61 +1,11 @@
package com.example.ide.css

import com.example.ide.message.QCssMessageBundle
import com.intellij.codeInsight.completion.*
import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.LookupElementBuilder
import com.intellij.icons.AllIcons
import com.intellij.lang.javascript.psi.JSLiteralExpression
import com.intellij.patterns.PlatformPatterns
import com.intellij.psi.PsiElement
import com.intellij.psi.css.StylesheetFile
import com.intellij.util.ProcessingContext

class CssModulesClassNameCompletionContributor : CompletionContributor() {

private val projectName = QCssMessageBundle.message("projectName")

init {
fun buildLookupElement(name: String, desc: String, psiElement: PsiElement?): LookupElement {
return LookupElementBuilder.create(name)
.withTailText(desc)
.withIcon(AllIcons.Xml.Css_class)
.bold()
.withCaseSensitivity(true)
.apply { psiElement?.let { withPsiElement(it) } }
}


fun completionHelper(resultSet: CompletionResultSet, stylesheetFile: StylesheetFile) {
stylesheetFile.parent?.let { parent ->
val folderName = parent.name
val fileName = stylesheetFile.name
val psiElementRefHashMap = QCssModuleParseUtil.parseCssSelectorFormFile(stylesheetFile)
psiElementRefHashMap.forEach { (name, cssSelectors) ->
if (cssSelectors.isNotEmpty()) {
val desc = " ($folderName/$fileName:${cssSelectors[0].lineNumber})_by_$projectName"
resultSet.addElement(buildLookupElement(name, desc, cssSelectors[0]))
}
}
}
}
val provider = object : CompletionProvider<CompletionParameters>() {
override fun addCompletions(
parameters: CompletionParameters,
context: ProcessingContext,
resultSet: CompletionResultSet
) {
val completionElement = parameters.originalPosition ?: parameters.position
if (completionElement.parent is JSLiteralExpression) {
val literalExpression = completionElement.parent as JSLiteralExpression
QCssModulesUtil.getCssClassNamesImportOrRequireDeclaration(literalExpression)?.let { declaration ->
QCssModulesUtil.resolveStyleSheetFile(declaration)?.let { styleSheetFile ->
completionHelper(resultSet, styleSheetFile)
}
}
}
}
}
extend(CompletionType.BASIC, PlatformPatterns.psiElement(), provider)
extend(CompletionType.BASIC, PlatformPatterns.psiElement(), CssModulesClassNameCompletionContributorImpl())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.example.ide.css

import com.example.ide.message.QCssMessageBundle
import com.intellij.codeInsight.completion.CompletionParameters
import com.intellij.codeInsight.completion.CompletionProvider
import com.intellij.codeInsight.completion.CompletionResultSet
import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.LookupElementBuilder
import com.intellij.icons.AllIcons
import com.intellij.lang.javascript.psi.JSLiteralExpression
import com.intellij.psi.PsiElement
import com.intellij.psi.css.StylesheetFile
import com.intellij.util.ProcessingContext

class CssModulesClassNameCompletionContributorImpl: CompletionProvider<CompletionParameters>() {
private val projectName = QCssMessageBundle.message("projectName")
private fun buildLookupElement(name: String, desc: String, psiElement: PsiElement?): LookupElement {
return LookupElementBuilder.create(name)
.withTailText(desc)
.withIcon(AllIcons.Xml.Css_class)
.bold()
.withCaseSensitivity(true)
.apply { psiElement?.let { withPsiElement(it) } }
}
private fun completionHelper(resultSet: CompletionResultSet, stylesheetFile: StylesheetFile) {
stylesheetFile.parent?.let { parent ->
val folderName = parent.name
val fileName = stylesheetFile.name
val psiElementRefHashMap = QCssModuleParseUtil.parseCssSelectorFormFile(stylesheetFile)
psiElementRefHashMap.forEach { (name, cssSelectors) ->
if (cssSelectors.isNotEmpty()) {
val desc = " ($folderName/$fileName:${cssSelectors[0].lineNumber})_by_$projectName"
resultSet.addElement(buildLookupElement(name, desc, cssSelectors[0]))
}
}
}
}

override fun addCompletions(
parameters: CompletionParameters,
context: ProcessingContext,
resultSet: CompletionResultSet
) {
val completionElement = parameters.originalPosition ?: parameters.position
if (completionElement.parent is JSLiteralExpression) {
val literalExpression = completionElement.parent as JSLiteralExpression
QCssModulesUtil.getCssClassNamesImportOrRequireDeclaration(literalExpression)?.let { declaration ->
QCssModulesUtil.resolveStyleSheetFile(declaration)?.let { styleSheetFile ->
completionHelper(resultSet, styleSheetFile)
}
}
}
}
}
3 changes: 1 addition & 2 deletions src/main/java/com/example/ide/css/QCssModuleParseUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import java.util.stream.Collectors

private val LOG = logger<QCssModuleParseUtil>()

internal object QCssModuleParseUtil {
object QCssModuleParseUtil {

private const val COMMA: String = ","
private const val EMPTY_STRING: String = ""
Expand Down Expand Up @@ -97,7 +97,6 @@ internal object QCssModuleParseUtil {
* 解析样式表文件, 此方法对外暴露, 外部调用的时候不需要关心是css还是scss还是less
* @param stylesheetFile 样式表文件
*/
@JvmStatic
fun parseCssSelectorFormFile(stylesheetFile: StylesheetFile?): MutableMap<String, Array<CssSelector>> {
if (stylesheetFile == null || PsiTreeUtil.hasErrorElements(stylesheetFile)) return mutableMapOf()
if (contentMap.containsKey(stylesheetFile.text.length.toString())) return contentMap[stylesheetFile.text.length.toString()] ?: mutableMapOf()
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/com/example/ide/css/QCssModulesUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ internal object QCssModulesUtil {
* @param classNameLiteral CSS 类名的字面量表达式
* @return 对应的 PsiElement 对象,如果不存在则返回 null
*/
@JvmStatic

fun getCssClassNamesImportOrRequireDeclaration(classNameLiteral: JSLiteralExpression): PsiElement? {
val expression = PsiTreeUtil.getParentOfType(classNameLiteral, JSIndexedPropertyAccessExpression::class.java)
if (expression?.qualifier?.reference?.resolve() != null) {
Expand All @@ -40,7 +40,7 @@ internal object QCssModulesUtil {
* @param cssFileNameLiteralParent CSS 文件名的字面量表达式的父元素
* @return 对应的 StylesheetFile 对象,如果不存在则返回 null
*/
@JvmStatic

fun resolveStyleSheetFile(cssFileNameLiteralParent: PsiElement): StylesheetFile? {
val stylesheetFileRef = Ref<StylesheetFile>()
cssFileNameLiteralParent.accept(object : PsiRecursiveElementVisitor() {
Expand Down Expand Up @@ -99,7 +99,7 @@ internal object QCssModulesUtil {
* @param rs 用于存储解析后的 StylesheetFile 的引用
* @return 对应的 CssSelector 对象,如果不存在则返回 null
*/
@JvmStatic

fun getCssClass(element: PsiElement, cssClass: String, rs: Ref<StylesheetFile>): PsiElement? {
val styleSheetFile = resolveStyleSheetFile(element)
if (styleSheetFile == null) {
Expand Down Expand Up @@ -128,7 +128,7 @@ internal object QCssModulesUtil {
* @param sr 用于存储解析后的 StylesheetFile 的引用
* @return 如果解析成功则返回 true,否则返回 false
*/
@JvmStatic

fun resolveStyleSheetFile(element: PsiElement, sr: Ref<StylesheetFile>): Boolean {
element.references.find { it.resolve() is StylesheetFile }?.resolve()?.let {
sr.set(it as StylesheetFile)
Expand Down

0 comments on commit 1cbc7c5

Please sign in to comment.