Inspection for scope functions conversion
#KT-17047 Fixed
This commit is contained in:
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
*
|
* that can be found in the license/LICENSE.txt file.
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://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.jetbrains.kotlin.psi
|
package org.jetbrains.kotlin.psi
|
||||||
@@ -85,6 +74,9 @@ class KtPsiFactory @JvmOverloads constructor(private val project: Project, val m
|
|||||||
fun createThisExpression() =
|
fun createThisExpression() =
|
||||||
(createExpression("this.x") as KtQualifiedExpression).receiverExpression as KtThisExpression
|
(createExpression("this.x") as KtQualifiedExpression).receiverExpression as KtThisExpression
|
||||||
|
|
||||||
|
fun createThisExpression(qualifier: String) =
|
||||||
|
(createExpression("this@$qualifier.x") as KtQualifiedExpression).receiverExpression as KtThisExpression
|
||||||
|
|
||||||
fun createCallArguments(text: String): KtValueArgumentList {
|
fun createCallArguments(text: String): KtValueArgumentList {
|
||||||
val property = createProperty("val x = foo $text")
|
val property = createProperty("val x = foo $text")
|
||||||
return (property.initializer as KtCallExpression).valueArgumentList!!
|
return (property.initializer as KtCallExpression).valueArgumentList!!
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
Provides actions for converting scope functions ('let', 'run', 'apply', 'also') between each other.
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -2644,6 +2644,15 @@
|
|||||||
language="kotlin"
|
language="kotlin"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.ScopeFunctionConversionInspection"
|
||||||
|
displayName="Scope function can be converted to another one"
|
||||||
|
groupPath="Kotlin"
|
||||||
|
groupName="Style issues"
|
||||||
|
enabledByDefault="true"
|
||||||
|
level="INFORMATION"
|
||||||
|
language="kotlin"
|
||||||
|
/>
|
||||||
|
|
||||||
<referenceImporter implementation="org.jetbrains.kotlin.idea.quickfix.KotlinReferenceImporter"/>
|
<referenceImporter implementation="org.jetbrains.kotlin.idea.quickfix.KotlinReferenceImporter"/>
|
||||||
|
|
||||||
<fileType.fileViewProviderFactory filetype="KJSM" implementationClass="com.intellij.psi.ClassFileViewProviderFactory"/>
|
<fileType.fileViewProviderFactory filetype="KJSM" implementationClass="com.intellij.psi.ClassFileViewProviderFactory"/>
|
||||||
|
|||||||
@@ -0,0 +1,364 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.inspections
|
||||||
|
|
||||||
|
import com.intellij.codeInspection.*
|
||||||
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
|
import com.intellij.openapi.fileEditor.FileEditorManager
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.PsiDocumentManager
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiElementVisitor
|
||||||
|
import com.intellij.psi.SmartPsiElementPointer
|
||||||
|
import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler
|
||||||
|
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
|
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
|
||||||
|
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.getThisLabelName
|
||||||
|
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
|
||||||
|
import org.jetbrains.kotlin.idea.util.getReceiverTargetDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||||
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getOrCreateParameterList
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext.FUNCTION
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.utils.collectDescriptorsFiltered
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.utils.findVariable
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
|
private val counterpartNames = mapOf(
|
||||||
|
"apply" to "also",
|
||||||
|
"run" to "let",
|
||||||
|
"also" to "apply",
|
||||||
|
"let" to "run"
|
||||||
|
)
|
||||||
|
|
||||||
|
class ScopeFunctionConversionInspection : AbstractKotlinInspection() {
|
||||||
|
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
|
||||||
|
return callExpressionVisitor { expression ->
|
||||||
|
val counterpartName = getCounterpart(expression)
|
||||||
|
if (counterpartName != null) {
|
||||||
|
holder.registerProblem(
|
||||||
|
expression.calleeExpression!!,
|
||||||
|
"Call can be replaced with another scope function",
|
||||||
|
ProblemHighlightType.INFORMATION,
|
||||||
|
if (counterpartName == "also" || counterpartName == "let")
|
||||||
|
ConvertScopeFunctionToParameter(counterpartName)
|
||||||
|
else
|
||||||
|
ConvertScopeFunctionToReceiver(counterpartName)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getCounterpart(expression: KtCallExpression): String? {
|
||||||
|
val callee = expression.calleeExpression as? KtNameReferenceExpression ?: return null
|
||||||
|
val calleeName = callee.getReferencedName()
|
||||||
|
val counterpartName = counterpartNames[calleeName]
|
||||||
|
val lambdaArgument = expression.lambdaArguments.singleOrNull()
|
||||||
|
if (counterpartName != null && lambdaArgument != null) {
|
||||||
|
if (lambdaArgument.getLambdaExpression().valueParameters.isNotEmpty()) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
val bindingContext = callee.analyze(BodyResolveMode.PARTIAL)
|
||||||
|
val resolvedCall = callee.getResolvedCall(bindingContext) ?: return null
|
||||||
|
if (resolvedCall.resultingDescriptor.fqNameSafe.asString() == "kotlin.$calleeName" &&
|
||||||
|
nameResolvesToStdlib(expression, bindingContext, counterpartName)
|
||||||
|
) {
|
||||||
|
return counterpartName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun nameResolvesToStdlib(expression: KtCallExpression, bindingContext: BindingContext, name: String): Boolean {
|
||||||
|
val scope = expression.getResolutionScope(bindingContext) ?: return true
|
||||||
|
val descriptors = scope.collectDescriptorsFiltered(nameFilter = { it.asString() == name })
|
||||||
|
return descriptors.isNotEmpty() && descriptors.all { it.fqNameSafe.asString() == "kotlin.$name" }
|
||||||
|
}
|
||||||
|
|
||||||
|
class Replacement<T : PsiElement> private constructor(
|
||||||
|
private val elementPointer: SmartPsiElementPointer<T>,
|
||||||
|
private val replacementFactory: KtPsiFactory.(T) -> PsiElement
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
fun <T : PsiElement> create(element: T, replacementFactory: KtPsiFactory.(T) -> PsiElement): Replacement<T> {
|
||||||
|
return Replacement(element.createSmartPointer(), replacementFactory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun apply(factory: KtPsiFactory) {
|
||||||
|
elementPointer.element?.let {
|
||||||
|
it.replace(factory.replacementFactory(it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val endOffset
|
||||||
|
get() = elementPointer.element!!.endOffset
|
||||||
|
}
|
||||||
|
|
||||||
|
class ReplacementCollection {
|
||||||
|
private lateinit var project: Project
|
||||||
|
private val replacements = mutableListOf<Replacement<out PsiElement>>()
|
||||||
|
var createParameter: KtPsiFactory.() -> PsiElement? = { null }
|
||||||
|
var elementToRename: PsiElement? = null
|
||||||
|
|
||||||
|
fun <T : PsiElement> add(element: T, replacementFactory: KtPsiFactory.(T) -> PsiElement) {
|
||||||
|
project = element.project
|
||||||
|
replacements.add(Replacement.create(element, replacementFactory))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun apply() {
|
||||||
|
if (replacements.isNotEmpty()) {
|
||||||
|
val factory = KtPsiFactory(project)
|
||||||
|
elementToRename = factory.createParameter()
|
||||||
|
|
||||||
|
// Calls need to be processed in outside-in order
|
||||||
|
replacements.sortBy { it.endOffset }
|
||||||
|
|
||||||
|
for (replacement in replacements) {
|
||||||
|
replacement.apply(factory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isNotEmpty() = replacements.isNotEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ConvertScopeFunctionFix(private val counterpartName: String) : LocalQuickFix {
|
||||||
|
override fun getFamilyName() = "Convert to '$counterpartName'"
|
||||||
|
|
||||||
|
override fun applyFix(project: Project, problemDescriptor: ProblemDescriptor) {
|
||||||
|
val callee = problemDescriptor.psiElement as KtNameReferenceExpression
|
||||||
|
val callExpression = callee.parent as? KtCallExpression ?: return
|
||||||
|
val bindingContext = callExpression.analyze()
|
||||||
|
|
||||||
|
val lambda = callExpression.lambdaArguments.firstOrNull() ?: return
|
||||||
|
val functionLiteral = lambda.getLambdaExpression().functionLiteral
|
||||||
|
val lambdaDescriptor = bindingContext[FUNCTION, functionLiteral] ?: return
|
||||||
|
|
||||||
|
val replacements = ReplacementCollection()
|
||||||
|
analyzeLambda(bindingContext, lambda, lambdaDescriptor, replacements)
|
||||||
|
callee.replace(KtPsiFactory(project).createExpression(counterpartName) as KtNameReferenceExpression)
|
||||||
|
if (replacements.isNotEmpty()) {
|
||||||
|
replacements.apply()
|
||||||
|
}
|
||||||
|
postprocessLambda(lambda)
|
||||||
|
|
||||||
|
if (replacements.isNotEmpty() && replacements.elementToRename != null && !ApplicationManager.getApplication().isUnitTestMode) {
|
||||||
|
replacements.elementToRename!!.startInPlaceRename()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract fun postprocessLambda(lambda: KtLambdaArgument)
|
||||||
|
|
||||||
|
protected abstract fun analyzeLambda(
|
||||||
|
bindingContext: BindingContext,
|
||||||
|
lambda: KtLambdaArgument,
|
||||||
|
lambdaDescriptor: SimpleFunctionDescriptor,
|
||||||
|
replacements: ReplacementCollection
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConvertScopeFunctionToParameter(counterpartName: String) : ConvertScopeFunctionFix(counterpartName) {
|
||||||
|
override fun analyzeLambda(
|
||||||
|
bindingContext: BindingContext,
|
||||||
|
lambda: KtLambdaArgument,
|
||||||
|
lambdaDescriptor: SimpleFunctionDescriptor,
|
||||||
|
replacements: ReplacementCollection
|
||||||
|
) {
|
||||||
|
val project = lambda.project
|
||||||
|
val factory = KtPsiFactory(project)
|
||||||
|
val functionLiteral = lambda.getLambdaExpression().functionLiteral
|
||||||
|
val lambdaExtensionReceiver = lambdaDescriptor.extensionReceiverParameter
|
||||||
|
val lambdaDispatchReceiver = lambdaDescriptor.dispatchReceiverParameter
|
||||||
|
|
||||||
|
var parameterName = "it"
|
||||||
|
val scopes = mutableSetOf<LexicalScope>()
|
||||||
|
if (needUniqueNameForParameter(lambda, scopes)) {
|
||||||
|
val parameterType = lambdaExtensionReceiver?.type ?: lambdaDispatchReceiver?.type
|
||||||
|
parameterName = findUniqueParameterName(parameterType, scopes)
|
||||||
|
replacements.createParameter = {
|
||||||
|
val lambdaParameterList = functionLiteral.getOrCreateParameterList()
|
||||||
|
val parameterToAdd = createLambdaParameterList(parameterName).parameters.first()
|
||||||
|
lambdaParameterList.addParameterBefore(parameterToAdd, lambdaParameterList.parameters.firstOrNull())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lambda.accept(object : KtTreeVisitorVoid() {
|
||||||
|
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
|
||||||
|
super.visitSimpleNameExpression(expression)
|
||||||
|
val resolvedCall = expression.getResolvedCall(bindingContext) ?: return
|
||||||
|
val dispatchReceiverTarget = resolvedCall.dispatchReceiver?.getReceiverTargetDescriptor(bindingContext)
|
||||||
|
val extensionReceiverTarget = resolvedCall.extensionReceiver?.getReceiverTargetDescriptor(bindingContext)
|
||||||
|
if (dispatchReceiverTarget == lambdaDescriptor || extensionReceiverTarget == lambdaDescriptor) {
|
||||||
|
val parent = expression.parent
|
||||||
|
if (parent is KtCallExpression && expression == parent.calleeExpression) {
|
||||||
|
replacements.add(parent) { element ->
|
||||||
|
factory.createExpressionByPattern("$0.$1", parameterName, element)
|
||||||
|
}
|
||||||
|
} else if (parent is KtQualifiedExpression && parent.receiverExpression is KtThisExpression) {
|
||||||
|
// do nothing
|
||||||
|
} else {
|
||||||
|
val referencedName = expression.getReferencedName()
|
||||||
|
replacements.add(expression) {
|
||||||
|
createExpression("$parameterName.$referencedName")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitThisExpression(expression: KtThisExpression) {
|
||||||
|
val resolvedCall = expression.getResolvedCall(bindingContext) ?: return
|
||||||
|
if (resolvedCall.resultingDescriptor == lambdaDispatchReceiver ||
|
||||||
|
resolvedCall.resultingDescriptor == lambdaExtensionReceiver) {
|
||||||
|
replacements.add(expression) { createExpression(parameterName) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun postprocessLambda(lambda: KtLambdaArgument) {
|
||||||
|
ShortenReferences { ShortenReferences.Options(removeThisLabels = true) }.process(lambda) { element ->
|
||||||
|
if (element is KtThisExpression && element.getLabelName() != null)
|
||||||
|
ShortenReferences.FilterResult.PROCESS
|
||||||
|
else
|
||||||
|
ShortenReferences.FilterResult.GO_INSIDE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun needUniqueNameForParameter(
|
||||||
|
lambdaArgument: KtLambdaArgument,
|
||||||
|
scopes: MutableSet<LexicalScope>
|
||||||
|
): Boolean {
|
||||||
|
val resolutionScope = lambdaArgument.getResolutionScope()
|
||||||
|
scopes.add(resolutionScope)
|
||||||
|
var needUniqueName = false
|
||||||
|
if (resolutionScope.findVariable(Name.identifier("it"), NoLookupLocation.FROM_IDE) != null) {
|
||||||
|
needUniqueName = true
|
||||||
|
// Don't return here - we still need to gather the list of nested scopes
|
||||||
|
}
|
||||||
|
|
||||||
|
lambdaArgument.accept(object : KtTreeVisitorVoid() {
|
||||||
|
override fun visitDeclaration(dcl: KtDeclaration) {
|
||||||
|
super.visitDeclaration(dcl)
|
||||||
|
checkNeedUniqueName(dcl)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitLambdaExpression(lambdaExpression: KtLambdaExpression) {
|
||||||
|
super.visitLambdaExpression(lambdaExpression)
|
||||||
|
lambdaExpression.bodyExpression?.statements?.firstOrNull()?.let { checkNeedUniqueName(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkNeedUniqueName(dcl: KtElement) {
|
||||||
|
val nestedResolutionScope = dcl.getResolutionScope()
|
||||||
|
scopes.add(nestedResolutionScope)
|
||||||
|
if (nestedResolutionScope.findVariable(Name.identifier("it"), NoLookupLocation.FROM_IDE) != null) {
|
||||||
|
needUniqueName = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return needUniqueName
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun findUniqueParameterName(
|
||||||
|
parameterType: KotlinType?,
|
||||||
|
resolutionScopes: Collection<LexicalScope>
|
||||||
|
): String {
|
||||||
|
fun isNameUnique(parameterName: String): Boolean {
|
||||||
|
return resolutionScopes.none { it.findVariable(Name.identifier(parameterName), NoLookupLocation.FROM_IDE) != null }
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (parameterType != null)
|
||||||
|
KotlinNameSuggester.suggestNamesByType(parameterType, ::isNameUnique).first()
|
||||||
|
else {
|
||||||
|
KotlinNameSuggester.suggestNameByName("p", ::isNameUnique)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConvertScopeFunctionToReceiver(counterpartName: String) : ConvertScopeFunctionFix(counterpartName) {
|
||||||
|
override fun analyzeLambda(
|
||||||
|
bindingContext: BindingContext,
|
||||||
|
lambda: KtLambdaArgument,
|
||||||
|
lambdaDescriptor: SimpleFunctionDescriptor,
|
||||||
|
replacements: ReplacementCollection
|
||||||
|
) {
|
||||||
|
lambda.accept(object : KtTreeVisitorVoid() {
|
||||||
|
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
|
||||||
|
super.visitSimpleNameExpression(expression)
|
||||||
|
if (expression.getReferencedName() == "it") {
|
||||||
|
val result = expression.resolveMainReferenceToDescriptors().singleOrNull()
|
||||||
|
if (result is ValueParameterDescriptor && result.containingDeclaration == lambdaDescriptor) {
|
||||||
|
replacements.add(expression) { createThisExpression() }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val resolvedCall = expression.getResolvedCall(bindingContext) ?: return
|
||||||
|
val dispatchReceiver = resolvedCall.dispatchReceiver
|
||||||
|
if (dispatchReceiver is ImplicitReceiver) {
|
||||||
|
val parent = expression.parent
|
||||||
|
val thisLabelName = dispatchReceiver.declarationDescriptor.getThisLabelName()
|
||||||
|
if (parent is KtCallExpression && expression == parent.calleeExpression) {
|
||||||
|
replacements.add(parent) { element ->
|
||||||
|
createExpressionByPattern("this@$0.$1", thisLabelName, element)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val referencedName = expression.getReferencedName()
|
||||||
|
replacements.add(expression) {
|
||||||
|
createExpression("this@$thisLabelName.$referencedName")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitThisExpression(expression: KtThisExpression) {
|
||||||
|
val resolvedCall = expression.getResolvedCall(bindingContext) ?: return
|
||||||
|
val qualifierName = resolvedCall.resultingDescriptor.containingDeclaration.name
|
||||||
|
replacements.add(expression) { createThisExpression(qualifierName.asString()) }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun postprocessLambda(lambda: KtLambdaArgument) {
|
||||||
|
ShortenReferences { ShortenReferences.Options(removeThis = true, removeThisLabels = true) }.process(lambda) { element ->
|
||||||
|
if (element is KtThisExpression && element.getLabelName() != null)
|
||||||
|
ShortenReferences.FilterResult.PROCESS
|
||||||
|
else if (element is KtQualifiedExpression && element.receiverExpression is KtThisExpression)
|
||||||
|
ShortenReferences.FilterResult.PROCESS
|
||||||
|
else
|
||||||
|
ShortenReferences.FilterResult.GO_INSIDE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun PsiElement.startInPlaceRename() {
|
||||||
|
val project = project
|
||||||
|
val document = containingFile.viewProvider.document ?: return
|
||||||
|
val editor = FileEditorManager.getInstance(project).selectedTextEditor ?: return
|
||||||
|
if (editor.document == document) {
|
||||||
|
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.document)
|
||||||
|
|
||||||
|
editor.caretModel.moveToOffset(startOffset)
|
||||||
|
VariableInplaceRenameHandler().doRename(this, editor, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
*
|
* that can be found in the license/LICENSE.txt file.
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://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.jetbrains.kotlin.idea.refactoring
|
package org.jetbrains.kotlin.idea.refactoring
|
||||||
@@ -835,6 +824,7 @@ internal fun DeclarationDescriptor.getThisLabelName(): String {
|
|||||||
if (this is AnonymousFunctionDescriptor) {
|
if (this is AnonymousFunctionDescriptor) {
|
||||||
val function = source.getPsi() as? KtFunction
|
val function = source.getPsi() as? KtFunction
|
||||||
val argument = function?.parent as? KtValueArgument
|
val argument = function?.parent as? KtValueArgument
|
||||||
|
?: (function?.parent as? KtLambdaExpression)?.parent as? KtValueArgument
|
||||||
val callElement = argument?.getStrictParentOfType<KtCallElement>()
|
val callElement = argument?.getStrictParentOfType<KtCallElement>()
|
||||||
val callee = callElement?.calleeExpression as? KtSimpleNameExpression
|
val callee = callElement?.calleeExpression as? KtSimpleNameExpression
|
||||||
if (callee != null) return callee.text
|
if (callee != null) return callee.text
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
org.jetbrains.kotlin.idea.inspections.ScopeFunctionConversionInspection
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
val x = "".<caret>also {
|
||||||
|
it.length
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
val x = "".<caret>apply {
|
||||||
|
length
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
val x = hashSetOf("abc").<caret>apply {
|
||||||
|
forEach {
|
||||||
|
forEach {
|
||||||
|
println(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
val x = hashSetOf("abc").also { hashSet ->
|
||||||
|
hashSet.forEach {
|
||||||
|
hashSet.forEach {
|
||||||
|
println(hashSet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// FIX: Convert to 'also'
|
||||||
|
|
||||||
|
val x = "".also {
|
||||||
|
"".<caret>apply {
|
||||||
|
this.length + it.length
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// FIX: Convert to 'also'
|
||||||
|
|
||||||
|
val x = "".also {
|
||||||
|
"".also { s ->
|
||||||
|
s.length + it.length
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
val x = hashSetOf("abc").<caret>apply {
|
||||||
|
forEach {
|
||||||
|
println(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
val x = hashSetOf("abc").also { hashSet ->
|
||||||
|
hashSet.forEach {
|
||||||
|
println(hashSet)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// FIX: Convert to 'also'
|
||||||
|
|
||||||
|
val x = hashSetOf<String>().<caret>apply {
|
||||||
|
add("x")
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// FIX: Convert to 'also'
|
||||||
|
|
||||||
|
val x = hashSetOf<String>().<caret>also {
|
||||||
|
it.add("x")
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// FIX: Convert to 'also'
|
||||||
|
|
||||||
|
val x = "".<caret>apply {
|
||||||
|
"".apply {
|
||||||
|
this.length
|
||||||
|
length
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// FIX: Convert to 'also'
|
||||||
|
|
||||||
|
val x = "".<caret>also {
|
||||||
|
"".apply {
|
||||||
|
this.length
|
||||||
|
length
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// FIX: Convert to 'also'
|
||||||
|
|
||||||
|
val x = "".<caret>apply {
|
||||||
|
this.length
|
||||||
|
length
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// FIX: Convert to 'also'
|
||||||
|
|
||||||
|
val x = "".<caret>also {
|
||||||
|
it.length
|
||||||
|
it.length
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// FIX: Convert to 'also'
|
||||||
|
|
||||||
|
class C {
|
||||||
|
val x = hashSetOf<C>().<caret>apply {
|
||||||
|
add(this@C)
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// FIX: Convert to 'also'
|
||||||
|
|
||||||
|
class C {
|
||||||
|
val x = hashSetOf<C>().<caret>also {
|
||||||
|
it.add(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
val x = hashSetOf("abc").<caret>let {
|
||||||
|
it.forEach {
|
||||||
|
println(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
val x = hashSetOf("abc").<caret>run {
|
||||||
|
forEach {
|
||||||
|
println(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
class C {
|
||||||
|
val c = "abc".<caret>let {
|
||||||
|
println(it + this)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
class C {
|
||||||
|
val c = "abc".<caret>run {
|
||||||
|
println(this + this@C)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
class C {
|
||||||
|
fun foo() = "c"
|
||||||
|
val bar = "C"
|
||||||
|
}
|
||||||
|
|
||||||
|
class D {
|
||||||
|
fun foo() = "d"
|
||||||
|
val bar = "D"
|
||||||
|
|
||||||
|
val x = C().<caret>let {
|
||||||
|
foo() + it.foo() + bar + it.bar
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
class C {
|
||||||
|
fun foo() = "c"
|
||||||
|
val bar = "C"
|
||||||
|
}
|
||||||
|
|
||||||
|
class D {
|
||||||
|
fun foo() = "d"
|
||||||
|
val bar = "D"
|
||||||
|
|
||||||
|
val x = C().<caret>run {
|
||||||
|
this@D.foo() + foo() + this@D.bar + bar
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
class C {
|
||||||
|
fun foo(s: String, s2: String = ""): String = "c"
|
||||||
|
val bar = "C"
|
||||||
|
}
|
||||||
|
|
||||||
|
class D {
|
||||||
|
fun baz(s: String): String = "d"
|
||||||
|
val quux = "D"
|
||||||
|
|
||||||
|
val x = C().<caret>let {
|
||||||
|
it.foo(baz(it.foo(quux + it.bar)), baz(it.bar))
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
class C {
|
||||||
|
fun foo(s: String, s2: String = ""): String = "c"
|
||||||
|
val bar = "C"
|
||||||
|
}
|
||||||
|
|
||||||
|
class D {
|
||||||
|
fun baz(s: String): String = "d"
|
||||||
|
val quux = "D"
|
||||||
|
|
||||||
|
val x = C().<caret>run {
|
||||||
|
foo(baz(foo(quux + bar)), baz(bar))
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
class C {
|
||||||
|
fun foo() = "c"
|
||||||
|
val bar = "C"
|
||||||
|
}
|
||||||
|
|
||||||
|
class D {
|
||||||
|
fun foo() = "d"
|
||||||
|
val bar = "D"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
val d = D()
|
||||||
|
val x = d.apply {
|
||||||
|
C().<caret>let {
|
||||||
|
foo() + it.foo() + bar + it.bar
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
class C {
|
||||||
|
fun foo() = "c"
|
||||||
|
val bar = "C"
|
||||||
|
}
|
||||||
|
|
||||||
|
class D {
|
||||||
|
fun foo() = "d"
|
||||||
|
val bar = "D"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
val d = D()
|
||||||
|
val x = d.apply {
|
||||||
|
C().<caret>run {
|
||||||
|
this@apply.foo() + foo() + this@apply.bar + bar
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
class C {
|
||||||
|
fun foo() = "c"
|
||||||
|
val bar = "C"
|
||||||
|
}
|
||||||
|
|
||||||
|
class D {
|
||||||
|
fun baz() = "d"
|
||||||
|
val quux = "D"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
val d = D()
|
||||||
|
val x = d.apply {
|
||||||
|
C().<caret>let {
|
||||||
|
baz() + it.foo() + quux + it.bar
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+19
@@ -0,0 +1,19 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
class C {
|
||||||
|
fun foo() = "c"
|
||||||
|
val bar = "C"
|
||||||
|
}
|
||||||
|
|
||||||
|
class D {
|
||||||
|
fun baz() = "d"
|
||||||
|
val quux = "D"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
val d = D()
|
||||||
|
val x = d.apply {
|
||||||
|
C().<caret>run {
|
||||||
|
baz() + foo() + quux + bar
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// FIX: Convert to 'run'
|
||||||
|
|
||||||
|
val x = "".<caret>let {
|
||||||
|
it.length
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// FIX: Convert to 'run'
|
||||||
|
|
||||||
|
val x = "".<caret>run {
|
||||||
|
length
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
class C {
|
||||||
|
val c = "abc".<caret>let {
|
||||||
|
println("$it")
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
class C {
|
||||||
|
val c = "abc".<caret>run {
|
||||||
|
println("$this")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// FIX: Convert to 'let'
|
||||||
|
|
||||||
|
val x = "".<caret>run {
|
||||||
|
this.length
|
||||||
|
length
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// FIX: Convert to 'let'
|
||||||
|
|
||||||
|
val x = "".<caret>let {
|
||||||
|
it.length
|
||||||
|
it.length
|
||||||
|
}
|
||||||
+147
@@ -3421,6 +3421,153 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/inspectionsLocal/scopeFunctions")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class ScopeFunctions extends AbstractLocalInspectionTest {
|
||||||
|
public void testAllFilesPresentInScopeFunctions() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/scopeFunctions"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/inspectionsLocal/scopeFunctions/alsoToApply")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class AlsoToApply extends AbstractLocalInspectionTest {
|
||||||
|
public void testAllFilesPresentInAlsoToApply() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/scopeFunctions/alsoToApply"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simple.kt")
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/scopeFunctions/alsoToApply/simple.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/inspectionsLocal/scopeFunctions/applyToAlso")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class ApplyToAlso extends AbstractLocalInspectionTest {
|
||||||
|
public void testAllFilesPresentInApplyToAlso() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/scopeFunctions/applyToAlso"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("doubleNestedLambdas.kt")
|
||||||
|
public void testDoubleNestedLambdas() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/scopeFunctions/applyToAlso/doubleNestedLambdas.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("innerLambda.kt")
|
||||||
|
public void testInnerLambda() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/scopeFunctions/applyToAlso/innerLambda.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("itInNestedLambda.kt")
|
||||||
|
public void testItInNestedLambda() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/scopeFunctions/applyToAlso/itInNestedLambda.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("method.kt")
|
||||||
|
public void testMethod() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/scopeFunctions/applyToAlso/method.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("outerLambda.kt")
|
||||||
|
public void testOuterLambda() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/scopeFunctions/applyToAlso/outerLambda.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simple.kt")
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/scopeFunctions/applyToAlso/simple.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("thisQualifier.kt")
|
||||||
|
public void testThisQualifier() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/scopeFunctions/applyToAlso/thisQualifier.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/inspectionsLocal/scopeFunctions/letToRun")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class LetToRun extends AbstractLocalInspectionTest {
|
||||||
|
public void testAllFilesPresentInLetToRun() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/scopeFunctions/letToRun"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nestedLambda.kt")
|
||||||
|
public void testNestedLambda() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/scopeFunctions/letToRun/nestedLambda.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("outerThis.kt")
|
||||||
|
public void testOuterThis() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/scopeFunctions/letToRun/outerThis.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("qualifyThis.kt")
|
||||||
|
public void testQualifyThis() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/scopeFunctions/letToRun/qualifyThis.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("qualifyThisNoConflict.kt")
|
||||||
|
public void testQualifyThisNoConflict() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/scopeFunctions/letToRun/qualifyThisNoConflict.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("qualifyThisWithLambda.kt")
|
||||||
|
public void testQualifyThisWithLambda() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/scopeFunctions/letToRun/qualifyThisWithLambda.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("qualifyThisWithLambdaNoConflict.kt")
|
||||||
|
public void testQualifyThisWithLambdaNoConflict() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/scopeFunctions/letToRun/qualifyThisWithLambdaNoConflict.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simple.kt")
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/scopeFunctions/letToRun/simple.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("thisInStringTemplate.kt")
|
||||||
|
public void testThisInStringTemplate() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/scopeFunctions/letToRun/thisInStringTemplate.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/inspectionsLocal/scopeFunctions/runToLet")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class RunToLet extends AbstractLocalInspectionTest {
|
||||||
|
public void testAllFilesPresentInRunToLet() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/scopeFunctions/runToLet"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simple.kt")
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/scopeFunctions/runToLet/simple.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/inspectionsLocal/selfAssignment")
|
@TestMetadata("idea/testData/inspectionsLocal/selfAssignment")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user