Skip to content
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 @@ -23,6 +23,7 @@ class DirectiveCompletion(
private val originalFile: PsiFile,
private val bindText: String,
private val element: PsiElement,
private val caretNextText: String,
private val result: CompletionResultSet,
) {
fun directiveHandle(symbol: String): Boolean {
Expand Down Expand Up @@ -52,6 +53,7 @@ class DirectiveCompletion(
StaticDirectiveHandler(
originalFile = originalFile,
element = element,
caretNextText = caretNextText,
result = result,
bindText = bindText,
).directiveHandle()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import com.intellij.openapi.module.Module
import com.intellij.psi.PsiElement
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.psi.util.elementType
import org.domaframework.doma.intellij.common.sql.directive.collector.StaticBuildFunctionCollector
import org.domaframework.doma.intellij.common.sql.directive.collector.FunctionCallCollector
import org.domaframework.doma.intellij.common.sql.directive.collector.StaticClassPackageCollector
import org.domaframework.doma.intellij.common.sql.directive.collector.StaticPropertyCollector
import org.domaframework.doma.intellij.psi.SqlElClass
Expand All @@ -31,12 +31,14 @@ import org.jetbrains.kotlin.idea.base.util.module
class StaticDirectiveHandler(
originalFile: PsiElement,
private val element: PsiElement,
private val caretNextText: String,
private val result: CompletionResultSet,
private val bindText: String,
) : DirectiveHandler(originalFile) {
override fun directiveHandle(): Boolean {
var handleResult = false
if (element.prevSibling is SqlElStaticFieldAccessExpr) {

if (isNextStaticFieldAccess(element)) {
handleResult = staticDirectiveHandler(element, result)
}
if (handleResult) return true
Expand All @@ -60,20 +62,30 @@ class StaticDirectiveHandler(
return handleResult
}

private fun isNextStaticFieldAccess(element: PsiElement): Boolean {
val prev = PsiTreeUtil.prevLeaf(element)
return element.prevSibling is SqlElStaticFieldAccessExpr ||
(
prev?.elementType == SqlTypes.AT_SIGN &&
prev.parent is SqlElStaticFieldAccessExpr
)
}

private fun staticDirectiveHandler(
element: PsiElement,
result: CompletionResultSet,
): Boolean {
val clazzRef =
PsiTreeUtil
.getChildOfType(element.prevSibling, SqlElClass::class.java)
?: PsiTreeUtil.getChildOfType(PsiTreeUtil.prevLeaf(element)?.parent, SqlElClass::class.java)
val fqdn =
PsiTreeUtil.getChildrenOfTypeAsList(clazzRef, PsiElement::class.java).joinToString("") { it.text }

val collector = StaticPropertyCollector(element, bindText)
val collector = StaticPropertyCollector(element, caretNextText, bindText)
val candidates = collector.collectCompletionSuggest(fqdn) ?: return false
result.addAllElements(candidates.field)
candidates.methods.map { m -> result.addElement(m) }
candidates.methods.forEach { m -> result.addElement(m) }
return true
}

Expand All @@ -93,7 +105,8 @@ class StaticDirectiveHandler(
): Boolean {
if (BindDirectiveUtil.getDirectiveType(element) == DirectiveType.BUILT_IN) {
val prefix = getBindSearchWord(element, bindText)
val collector = StaticBuildFunctionCollector(element.containingFile, prefix)
val collector =
FunctionCallCollector(element.containingFile, caretNextText, prefix)
val candidates = collector.collect()
candidates?.let { it1 -> result.addAllElements(it1) }
return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,6 @@ package org.domaframework.doma.intellij.common.sql.directive
import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.VariableLookupItem
import com.intellij.icons.AllIcons
import com.intellij.psi.PsiType

/**
* Function information displayed with code completion for built-in functions
*/
data class DomaFunction(
val name: String,
val returnType: PsiType,
val parameters: List<PsiType>,
)

/**
* Show parameters in code completion for fields and methods
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ import com.intellij.psi.PsiModifier
import org.domaframework.doma.intellij.common.CommonPathParameterUtil
import org.domaframework.doma.intellij.common.config.DomaCompileConfigUtil
import org.domaframework.doma.intellij.common.helper.ExpressionFunctionsHelper
import org.domaframework.doma.intellij.common.util.SqlCompletionUtil.createMethodLookupElement
import org.domaframework.doma.intellij.extension.getJavaClazz
import org.jetbrains.kotlin.idea.base.util.module

class StaticBuildFunctionCollector(
class FunctionCallCollector(
private val file: PsiFile?,
private val caretNextText: String,
private val bind: String,
) : StaticDirectiveHandlerCollector() {
public override fun collect(): List<LookupElement>? {
Expand All @@ -44,7 +46,13 @@ class StaticBuildFunctionCollector(
}

val customFunctionClassName =
project?.let { DomaCompileConfigUtil.getConfigValue(it, resourcePaths, "doma.expr.functions") }
project?.let {
DomaCompileConfigUtil.getConfigValue(
it,
resourcePaths,
"doma.expr.functions",
)
}

val expressionFunctionInterface =
project?.let { ExpressionFunctionsHelper.setExpressionFunctionsInterface(it) }
Expand All @@ -62,21 +70,19 @@ class StaticBuildFunctionCollector(
)
}

if (functions.isEmpty()) {
functions.addAll(
expressionFunctionInterface.allMethods.filter {
isPublicFunction(it)
},
)
}
functions.addAll(
expressionFunctionInterface.allMethods.filter {
isPublicFunction(it) && !functions.contains(it)
},
)

return functions
.filter {
it.name.startsWith(bind.substringAfter("@"))
}.map {
val parameters = it.parameterList.parameters.toList()
LookupElementBuilder
.create("${it.name}()")
.create(createMethodLookupElement(caretNextText, it))
.withPresentableText(it.name)
.withTailText(
"(${
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ import com.intellij.psi.PsiElement
import org.domaframework.doma.intellij.common.psi.PsiParentClass
import org.domaframework.doma.intellij.common.psi.PsiStaticElement
import org.domaframework.doma.intellij.common.sql.directive.CompletionSuggest
import org.domaframework.doma.intellij.common.util.SqlCompletionUtil.createMethodLookupElement
import org.domaframework.doma.intellij.extension.psi.psiClassType

class StaticPropertyCollector(
private val element: PsiElement,
private val caretNextText: String,
private val bind: String,
) : StaticDirectiveHandlerCollector() {
public override fun collectCompletionSuggest(fqdn: String): CompletionSuggest? {
Expand All @@ -39,7 +41,7 @@ class StaticPropertyCollector(
val methods =
clazz.searchStaticMethod(bind)?.map { m ->
LookupElementBuilder
.create("${m.name}()")
.create(createMethodLookupElement(caretNextText, m))
.withPresentableText(m.name)
.withTailText(m.parameterList.text, true)
.withIcon(AllIcons.Nodes.Method)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ class ForDirectiveUtil {
val classType = lastType.type as? PsiClassType
val nestClass =
if (classType != null &&
PsiClassTypeUtil.Companion.isIterableType(
PsiClassTypeUtil.isIterableType(
classType,
project,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright Doma Tools Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.domaframework.doma.intellij.common.util

import com.intellij.psi.PsiMethod

object SqlCompletionUtil {
fun createMethodLookupElement(
caretNextText: String,
method: PsiMethod,
): String =
if (caretNextText == "(") {
method.name
} else {
"${method.name}()"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import org.domaframework.doma.intellij.common.sql.directive.DirectiveCompletion
import org.domaframework.doma.intellij.common.sql.validator.result.ValidationCompleteResult
import org.domaframework.doma.intellij.common.util.ForDirectiveUtil
import org.domaframework.doma.intellij.common.util.PluginLoggerUtil
import org.domaframework.doma.intellij.common.util.SqlCompletionUtil.createMethodLookupElement
import org.domaframework.doma.intellij.extension.getJavaClazz
import org.domaframework.doma.intellij.extension.psi.findNodeParent
import org.domaframework.doma.intellij.extension.psi.findSelfBlocks
Expand Down Expand Up @@ -78,6 +79,11 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
val startTime = System.nanoTime()

var isDirective = false
val offset = parameters.editor.caretModel.currentCaret.offset
val range =
com.intellij.openapi.util
.TextRange(offset, offset + 1)
val caretNextText = parameters.editor.document.getText(range)
try {
val originalFile = parameters.originalFile
val pos = parameters.originalPosition ?: return
Expand All @@ -86,7 +92,7 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
.substringAfter("/*")
.substringBefore("*/")

val handler = DirectiveCompletion(originalFile, bindText, pos, result)
val handler = DirectiveCompletion(originalFile, bindText, pos, caretNextText, result)
val directiveSymbols = listOf("%", "#", "^", "@")
directiveSymbols.forEach {
if (!isDirective) {
Expand Down Expand Up @@ -118,6 +124,7 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
blockElements,
pos,
originalFile,
caretNextText,
result,
)
PluginLoggerUtil.countLogging(
Expand Down Expand Up @@ -268,6 +275,7 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
elements: List<PsiElement>,
position: PsiElement,
originalFile: PsiFile,
caretNextText: String,
result: CompletionResultSet,
) {
val daoMethod = findDaoMethod(originalFile)
Expand All @@ -281,7 +289,7 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
val topText = cleanString(getSearchElementText(top))
val prevWord = PsiPatternUtil.getBindSearchWord(originalFile, elements.last(), " ")
if (prevWord.startsWith("@") && prevWord.endsWith("@")) {
setCompletionStaticFieldAccess(top, prevWord, topText, result)
setCompletionStaticFieldAccess(top, prevWord, caretNextText, topText, result)
return
}

Expand All @@ -298,7 +306,7 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
val psiDaoMethod = PsiDaoMethod(project, daoMethod)
if (topElementType == null) {
isBatchAnnotation = psiDaoMethod.daoType.isBatchAnnotation()
if (isFieldAccessByForItem(top, elements, searchText, isBatchAnnotation, result)) return
if (isFieldAccessByForItem(top, elements, searchText, caretNextText, isBatchAnnotation, result)) return
topElementType =
getElementTypeByFieldAccess(originalFile, position, elements, daoMethod, result) ?: return
}
Expand All @@ -309,6 +317,7 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
isBatchAnnotation,
elements,
searchText,
caretNextText,
result,
)
}
Expand Down Expand Up @@ -399,6 +408,7 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
): PsiClass? = top.project.getJavaClazz(fqdnGetter())

private fun setFieldsAndMethodsCompletionResultSet(
caretNextText: String,
fields: Array<PsiField>,
methods: Array<PsiMethod>,
result: CompletionResultSet,
Expand All @@ -407,7 +417,7 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
methods.forEach { method ->
val lookupElm =
LookupElementBuilder
.create("${method.name}()")
.create(createMethodLookupElement(caretNextText, method))
.withPresentableText(method.name)
.withTailText(method.parameterList.text, true)
.withTypeText(method.returnType?.presentableText ?: "")
Expand All @@ -422,6 +432,7 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
top: PsiElement,
elements: List<PsiElement>,
searchWord: String,
caretNextText: String,
isBatchAnnotation: Boolean = false,
result: CompletionResultSet,
): Boolean {
Expand All @@ -448,6 +459,7 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
dropLastIndex = 1,
complete = { lastType ->
setFieldsAndMethodsCompletionResultSet(
caretNextText,
lastType.searchField(searchWord)?.toTypedArray() ?: emptyArray(),
lastType.searchMethod(searchWord)?.toTypedArray() ?: emptyArray(),
result,
Expand All @@ -463,6 +475,7 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
isBatchAnnotation: Boolean,
elements: List<PsiElement>,
searchWord: String,
caretNextText: String,
result: CompletionResultSet,
) {
var psiParentClass = PsiParentClass(topElementType)
Expand All @@ -477,6 +490,7 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
dropLastIndex = 1,
complete = { lastType ->
setFieldsAndMethodsCompletionResultSet(
caretNextText,
lastType.searchField(searchWord)?.toTypedArray() ?: emptyArray(),
lastType.searchMethod(searchWord)?.toTypedArray() ?: emptyArray(),
result,
Expand All @@ -488,6 +502,7 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
private fun setCompletionStaticFieldAccess(
top: PsiElement,
prevWord: String,
caretNextText: String,
topText: String,
result: CompletionResultSet,
) {
Expand All @@ -496,6 +511,6 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
val matchMethod = clazz.searchStaticMethod(topText)

// When you enter here, it is the top element, so return static fields and methods.
setFieldsAndMethodsCompletionResultSet(matchFields, matchMethod, result)
setFieldsAndMethodsCompletionResultSet(caretNextText, matchFields, matchMethod, result)
}
}
Loading