Support toRegex() standard function
#KT-8088 Fixed
This commit is contained in:
@@ -5,5 +5,8 @@
|
||||
<place><![CDATA[
|
||||
psiParameter().ofMethod(0, psiMethod().withName("Regex").definedInClass("kotlin.text.Regex"))
|
||||
]]></place>
|
||||
<place><![CDATA[
|
||||
receiver().ofMethod(psiMethod().withName("toRegex").withReceiver("kotlin.String").definedInPackage("kotlin.text"))
|
||||
]]></place>
|
||||
</injection>
|
||||
</component>
|
||||
|
||||
@@ -18,13 +18,11 @@ package org.jetbrains.kotlin.idea.injection
|
||||
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.InjectedLanguagePlaces
|
||||
import com.intellij.psi.LanguageInjector
|
||||
import com.intellij.psi.PsiLanguageInjectionHost
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.intellij.plugins.intelliLang.Configuration
|
||||
import org.intellij.plugins.intelliLang.inject.InjectorUtils
|
||||
import org.intellij.plugins.intelliLang.inject.config.BaseInjection
|
||||
import org.intellij.plugins.intelliLang.inject.java.JavaLanguageInjectionSupport
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import java.util.*
|
||||
@@ -41,6 +39,7 @@ class KotlinLanguageInjector : LanguageInjector {
|
||||
val injectionInfo =
|
||||
injectWithExplicitCodeInstruction(ktHost)
|
||||
?: injectWithCall(ktHost)
|
||||
?: injectWithReceiver(ktHost)
|
||||
?: return
|
||||
|
||||
val language = InjectorUtils.getLanguageByString(injectionInfo.languageId) ?: return
|
||||
@@ -53,6 +52,28 @@ class KotlinLanguageInjector : LanguageInjector {
|
||||
return InjectionInfo(languageId, null, null)
|
||||
}
|
||||
|
||||
private fun injectWithReceiver(host: KtElement): InjectionInfo? {
|
||||
val qualifiedExpression = host.parent as? KtDotQualifiedExpression ?: return null
|
||||
if (qualifiedExpression.receiverExpression != host) return null
|
||||
|
||||
val callExpression = qualifiedExpression.selectorExpression as? KtCallExpression ?: return null
|
||||
val callee = callExpression.calleeExpression ?: return null
|
||||
|
||||
for (reference in callee.references) {
|
||||
ProgressManager.checkCanceled()
|
||||
|
||||
val resolvedTo = reference.resolve()
|
||||
if (resolvedTo is KtFunction) {
|
||||
val injectionInfo = findInjection(resolvedTo.receiverTypeReference, Configuration.getInstance().getInjections(KOTLIN_SUPPORT_ID))
|
||||
if (injectionInfo != null) {
|
||||
return injectionInfo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun injectWithCall(host: KtElement): InjectionInfo? {
|
||||
val ktHost: KtElement = host
|
||||
val argument = ktHost.parent as? KtValueArgument ?: return null
|
||||
@@ -85,26 +106,19 @@ class KotlinLanguageInjector : LanguageInjector {
|
||||
val argumentIndex = (argument.parent as KtValueArgumentList).arguments.indexOf(argument)
|
||||
val psiParameter = javaMethod.parameterList.parameters.getOrNull(argumentIndex) ?: return null
|
||||
|
||||
val injections = Configuration.getInstance().getInjections(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID)
|
||||
|
||||
for (injection in injections) {
|
||||
if (injection.acceptsPsiElement(psiParameter)) {
|
||||
// ?? if (!processXmlInjections(injection, owner, method, paramIndex)) {
|
||||
return InjectionInfo(injection.injectedLanguageId, injection.prefix, injection.suffix)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
return findInjection(psiParameter, Configuration.getInstance().getInjections(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID))
|
||||
}
|
||||
|
||||
private fun injectionForKotlinCall(argument: KtValueArgument, ktFunction: KtFunction): InjectionInfo? {
|
||||
val argumentIndex = (argument.parent as KtValueArgumentList).arguments.indexOf(argument)
|
||||
val ktParameter = ktFunction.valueParameters.getOrNull(argumentIndex) ?: return null
|
||||
|
||||
val injections = Configuration.getInstance().getInjections(KOTLIN_SUPPORT_ID)
|
||||
return findInjection(ktParameter, Configuration.getInstance().getInjections(KOTLIN_SUPPORT_ID))
|
||||
}
|
||||
|
||||
private fun findInjection(element: PsiElement?, injections: List<BaseInjection>): InjectionInfo? {
|
||||
for (injection in injections) {
|
||||
if (injection.acceptsPsiElement(ktParameter)) {
|
||||
if (injection.acceptsPsiElement(element)) {
|
||||
return InjectionInfo(injection.injectedLanguageId, injection.prefix, injection.suffix)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
object KotlinPatterns: StandardPatterns() {
|
||||
@JvmStatic fun psiParameter() = KtParameterPattern()
|
||||
@JvmStatic fun psiMethod() = KotlinFunctionPattern()
|
||||
@JvmStatic fun receiver() = KotlinReceiverPattern()
|
||||
}
|
||||
|
||||
// Methods in this class are used through reflection during pattern construction
|
||||
@@ -119,3 +120,21 @@ class KtParameterPattern : PsiElementPattern<KtParameter, KtParameterPattern>(Kt
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
class KotlinReceiverPattern : PsiElementPattern<KtTypeReference, KotlinReceiverPattern>(KtTypeReference::class.java) {
|
||||
fun ofMethod(pattern: ElementPattern<Any>): KotlinReceiverPattern {
|
||||
return with(object : PatternConditionPlus<KtTypeReference, KtFunction>("KtReceiverPattern-ofMethod", pattern) {
|
||||
override fun processValues(typeReference: KtTypeReference, context: ProcessingContext?, processor: PairProcessor<KtFunction, ProcessingContext>): Boolean {
|
||||
return processor.process(typeReference.parent as? KtFunction, context)
|
||||
}
|
||||
|
||||
override fun accepts(typeReference: KtTypeReference, context: ProcessingContext?): Boolean {
|
||||
val ktFunction = typeReference.parent as? KtFunction ?: return false
|
||||
if (ktFunction.receiverTypeReference != typeReference) return false
|
||||
|
||||
return super.accepts(typeReference, context)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,27 @@ class KotlinStdlibInjectionTest : AbstractInjectionTest() {
|
||||
RegExpLanguage.INSTANCE.id
|
||||
)
|
||||
|
||||
fun testToRegex0() = testInjection(
|
||||
"""
|
||||
|val test = "hi<caret>".toRegex()
|
||||
""",
|
||||
RegExpLanguage.INSTANCE.id
|
||||
)
|
||||
|
||||
fun testToRegex1() = testInjection(
|
||||
"""
|
||||
|val test = "hi<caret>".toRegex(RegexOption.CANON_EQ)
|
||||
""",
|
||||
RegExpLanguage.INSTANCE.id
|
||||
)
|
||||
|
||||
fun testToRegex2() = testInjection(
|
||||
"""
|
||||
|val test = "hi<caret>".toRegex(setOf(RegexOption.LITERAL))
|
||||
""",
|
||||
RegExpLanguage.INSTANCE.id
|
||||
)
|
||||
|
||||
private fun testInjection(text: String, languageId: String) {
|
||||
testInjectionPresent(text, languageId, false)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user