moved more find usages-related stuff to idea-analysis for upsource
This commit is contained in:
+1
-1
@@ -102,4 +102,4 @@ object JetFileReferencesResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun JetExpression.referenceExpression(): JetReferenceExpression? =
|
fun JetExpression.referenceExpression(): JetReferenceExpression? =
|
||||||
(if (this is JetCallExpression) getCalleeExpression() else this) as? JetReferenceExpression
|
(if (this is JetCallExpression) getCalleeExpression() else this) as? JetReferenceExpression
|
||||||
+2
-2
@@ -99,7 +99,7 @@ public object ShortenReferences {
|
|||||||
|
|
||||||
private fun process(elements: Iterable<JetElement>, elementFilter: (PsiElement) -> FilterResult) {
|
private fun process(elements: Iterable<JetElement>, elementFilter: (PsiElement) -> FilterResult) {
|
||||||
for ((file, fileElements) in elements.groupBy { element -> element.getContainingJetFile() }) {
|
for ((file, fileElements) in elements.groupBy { element -> element.getContainingJetFile() }) {
|
||||||
ImportInsertHelper.optimizeImportsOnTheFly(file)
|
ImportInsertHelper.getInstance().optimizeImportsOnTheFly(file)
|
||||||
|
|
||||||
// first resolve all qualified references - optimization
|
// first resolve all qualified references - optimization
|
||||||
val referenceToContext = JetFileReferencesResolver.resolve(file, fileElements, resolveShortNames = false)
|
val referenceToContext = JetFileReferencesResolver.resolve(file, fileElements, resolveShortNames = false)
|
||||||
@@ -335,6 +335,6 @@ public object ShortenReferences {
|
|||||||
= "${getExtensionReceiver()}, ${getDispatchReceiver()} -> ${getResultingDescriptor()?.let {FQ_NAMES_IN_TYPES.render(it)}}"
|
= "${getExtensionReceiver()}, ${getDispatchReceiver()} -> ${getResultingDescriptor()?.let {FQ_NAMES_IN_TYPES.render(it)}}"
|
||||||
|
|
||||||
private fun addImport(descriptor: DeclarationDescriptor, file: JetFile) {
|
private fun addImport(descriptor: DeclarationDescriptor, file: JetFile) {
|
||||||
ImportInsertHelper.writeImportToFile(ImportPath(DescriptorUtils.getFqNameSafe(descriptor), false), file)
|
ImportInsertHelper.getInstance().writeImportToFile(ImportPath(DescriptorUtils.getFqNameSafe(descriptor), false), file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+72
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* 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.jet.plugin.codeInsight.shorten
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.SmartPsiElementPointer
|
||||||
|
import org.jetbrains.jet.lang.psi.JetElement
|
||||||
|
import org.jetbrains.jet.lang.psi.UserDataProperty
|
||||||
|
import com.intellij.openapi.util.Key
|
||||||
|
import org.jetbrains.jet.lang.psi.NotNullableUserDataProperty
|
||||||
|
import java.util.HashSet
|
||||||
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
|
import com.intellij.psi.SmartPointerManager
|
||||||
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
|
|
||||||
|
private var Project.elementsToShorten: MutableSet<SmartPsiElementPointer<JetElement>>?
|
||||||
|
by UserDataProperty(Key.create("ELEMENTS_TO_SHORTEN_KEY"))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When one refactoring invokes another this value must be set to false so that shortening wait-set is not cleared
|
||||||
|
* and previously collected references are processed correctly. Afterwards it must be reset to original value
|
||||||
|
*/
|
||||||
|
public var Project.ensureElementsToShortenIsEmptyBeforeRefactoring: Boolean
|
||||||
|
by NotNullableUserDataProperty(Key.create("ENSURE_ELEMENTS_TO_SHORTEN_IS_EMPTY"), true)
|
||||||
|
|
||||||
|
private fun Project.getOrCreateElementsToShorten(): MutableSet<SmartPsiElementPointer<JetElement>> {
|
||||||
|
var elements = elementsToShorten
|
||||||
|
if (elements == null) {
|
||||||
|
elements = HashSet()
|
||||||
|
elementsToShorten = elements
|
||||||
|
}
|
||||||
|
|
||||||
|
return elements!!
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun JetElement.addToShorteningWaitSet() {
|
||||||
|
assert (ApplicationManager.getApplication()!!.isWriteAccessAllowed(), "Write access needed")
|
||||||
|
val project = getProject()
|
||||||
|
project.getOrCreateElementsToShorten().add(SmartPointerManager.getInstance(project).createSmartPsiElementPointer(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun withElementsToShorten(project: Project, f: (Set<SmartPsiElementPointer<JetElement>>) -> Unit) {
|
||||||
|
project.elementsToShorten?.let { bindRequests ->
|
||||||
|
project.elementsToShorten = null
|
||||||
|
f(bindRequests)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private val LOG = Logger.getInstance(javaClass<Project>().getCanonicalName())
|
||||||
|
|
||||||
|
public fun prepareElementsToShorten(project: Project) {
|
||||||
|
val elementsToShorten = project.elementsToShorten
|
||||||
|
if (project.ensureElementsToShortenIsEmptyBeforeRefactoring && elementsToShorten != null && !elementsToShorten.isEmpty()) {
|
||||||
|
LOG.warn("Waiting set for reference shortening is not empty")
|
||||||
|
project.elementsToShorten = null
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,282 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* 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.jet.plugin.findUsages
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.jet.lang.psi.JetForExpression
|
||||||
|
import org.jetbrains.jet.lang.psi.JetMultiDeclaration
|
||||||
|
import org.jetbrains.jet.lang.psi.psiUtil.getParentByType
|
||||||
|
import org.jetbrains.jet.lang.psi.JetReferenceExpression
|
||||||
|
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
|
||||||
|
import org.jetbrains.jet.lang.psi.JetImportDirective
|
||||||
|
import org.jetbrains.jet.lang.psi.psiUtil.getParentByTypeAndBranch
|
||||||
|
import org.jetbrains.jet.lang.psi.JetCallableReferenceExpression
|
||||||
|
import org.jetbrains.jet.lang.psi.JetProperty
|
||||||
|
import org.jetbrains.jet.lang.psi.psiUtil.isAncestor
|
||||||
|
import org.jetbrains.jet.lang.psi.JetFunction
|
||||||
|
import org.jetbrains.jet.lang.psi.JetTypeParameter
|
||||||
|
import org.jetbrains.jet.lang.psi.JetTypeConstraint
|
||||||
|
import org.jetbrains.jet.lang.psi.JetDelegationSpecifier
|
||||||
|
import org.jetbrains.jet.lang.psi.JetTypedef
|
||||||
|
import org.jetbrains.jet.lang.psi.JetTypeProjection
|
||||||
|
import org.jetbrains.jet.lang.psi.JetParameter
|
||||||
|
import org.jetbrains.jet.lang.psi.JetIsExpression
|
||||||
|
import org.jetbrains.jet.lang.psi.JetBinaryExpressionWithTypeRHS
|
||||||
|
import org.jetbrains.jet.lexer.JetTokens
|
||||||
|
import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression
|
||||||
|
import org.jetbrains.jet.lang.psi.JetSuperExpression
|
||||||
|
import org.jetbrains.jet.lang.psi.JetDelegatorByExpressionSpecifier
|
||||||
|
import org.jetbrains.jet.lang.psi.psiUtil.getParentByTypesAndPredicate
|
||||||
|
import org.jetbrains.jet.lang.psi.JetBinaryExpression
|
||||||
|
import org.jetbrains.jet.lang.psi.JetPsiUtil
|
||||||
|
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
|
||||||
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.jet.plugin.references.JetArrayAccessReference
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||||
|
import org.jetbrains.jet.plugin.references.JetInvokeFunctionReference
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor
|
||||||
|
import org.jetbrains.jet.lang.psi.JetAnnotationEntry
|
||||||
|
import org.jetbrains.jet.lang.psi.JetCallExpression
|
||||||
|
import org.jetbrains.jet.lang.psi.JetUnaryExpression
|
||||||
|
import org.jetbrains.jet.lang.psi.JetWhenConditionInRange
|
||||||
|
import org.jetbrains.jet.lang.psi.JetPackageDirective
|
||||||
|
import org.jetbrains.jet.lang.psi.JetQualifiedExpression
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ClassKind
|
||||||
|
import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor
|
||||||
|
import com.intellij.psi.PsiPackage
|
||||||
|
import org.jetbrains.jet.lang.descriptors.VariableDescriptor
|
||||||
|
import org.jetbrains.jet.plugin.JetBundle
|
||||||
|
import org.jetbrains.jet.plugin.findUsages.UsageTypeEnum.*
|
||||||
|
|
||||||
|
public object UsageTypeUtils {
|
||||||
|
public fun getUsageType(element: PsiElement?): UsageTypeEnum? {
|
||||||
|
when (element) {
|
||||||
|
is JetForExpression -> return IMPLICIT_ITERATION
|
||||||
|
is JetMultiDeclaration -> return READ
|
||||||
|
}
|
||||||
|
|
||||||
|
val refExpr = element?.getParentByType(javaClass<JetReferenceExpression>())
|
||||||
|
if (refExpr == null) return null
|
||||||
|
|
||||||
|
val context = AnalyzerFacadeWithCache.getContextForElement(refExpr)
|
||||||
|
|
||||||
|
fun getCommonUsageType(): UsageTypeEnum? {
|
||||||
|
return when {
|
||||||
|
refExpr.getParentByType(javaClass<JetImportDirective>()) != null ->
|
||||||
|
CLASS_IMPORT
|
||||||
|
refExpr.getParentByTypeAndBranch(javaClass<JetCallableReferenceExpression>()) { getCallableReference() } != null ->
|
||||||
|
CALLABLE_REFERENCE
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getClassUsageType(): UsageTypeEnum? {
|
||||||
|
val property = refExpr.getParentByType(javaClass<JetProperty>())
|
||||||
|
if (property != null) {
|
||||||
|
when {
|
||||||
|
property.getTypeReference().isAncestor(refExpr) ->
|
||||||
|
return if (property.isLocal()) CLASS_LOCAL_VAR_DECLARATION else NON_LOCAL_PROPERTY_TYPE
|
||||||
|
|
||||||
|
property.getReceiverTypeReference().isAncestor(refExpr) ->
|
||||||
|
return EXTENSION_RECEIVER_TYPE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val function = refExpr.getParentByType(javaClass<JetFunction>())
|
||||||
|
if (function != null) {
|
||||||
|
when {
|
||||||
|
function.getTypeReference().isAncestor(refExpr) ->
|
||||||
|
return FUNCTION_RETURN_TYPE
|
||||||
|
function.getReceiverTypeReference().isAncestor(refExpr) ->
|
||||||
|
return EXTENSION_RECEIVER_TYPE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return when {
|
||||||
|
refExpr.getParentByTypeAndBranch(javaClass<JetTypeParameter>()) { getExtendsBound() } != null
|
||||||
|
|| refExpr.getParentByTypeAndBranch(javaClass<JetTypeConstraint>()) { getBoundTypeReference() } != null ->
|
||||||
|
TYPE_CONSTRAINT
|
||||||
|
|
||||||
|
refExpr is JetDelegationSpecifier
|
||||||
|
|| refExpr.getParentByTypeAndBranch(javaClass<JetDelegationSpecifier>()) { getTypeReference() } != null ->
|
||||||
|
SUPER_TYPE
|
||||||
|
|
||||||
|
refExpr.getParentByTypeAndBranch(javaClass<JetTypedef>()) { getTypeReference() } != null ->
|
||||||
|
TYPE_DEFINITION
|
||||||
|
|
||||||
|
refExpr.getParentByType(javaClass<JetTypeProjection>()) != null ->
|
||||||
|
TYPE_PARAMETER
|
||||||
|
|
||||||
|
refExpr.getParentByTypeAndBranch(javaClass<JetParameter>()) { getTypeReference() } != null ->
|
||||||
|
VALUE_PARAMETER_TYPE
|
||||||
|
|
||||||
|
refExpr.getParentByTypeAndBranch(javaClass<JetIsExpression>()) { getTypeReference() } != null ->
|
||||||
|
IS
|
||||||
|
|
||||||
|
with(refExpr.getParentByTypeAndBranch(javaClass<JetBinaryExpressionWithTypeRHS>()) { getRight() }) {
|
||||||
|
val opType = this?.getOperationReference()?.getReferencedNameElementType()
|
||||||
|
opType == JetTokens.AS_KEYWORD || opType == JetTokens.AS_SAFE
|
||||||
|
} ->
|
||||||
|
CLASS_CAST_TO
|
||||||
|
|
||||||
|
with(refExpr.getParentByType(javaClass<JetDotQualifiedExpression>())) {
|
||||||
|
if (this == null) false
|
||||||
|
else if (getReceiverExpression() == refExpr) true
|
||||||
|
else
|
||||||
|
getSelectorExpression() == refExpr
|
||||||
|
&& getParentByTypeAndBranch(javaClass<JetDotQualifiedExpression>(), true) { getReceiverExpression() } != null
|
||||||
|
} ->
|
||||||
|
CLASS_OBJECT_ACCESS
|
||||||
|
|
||||||
|
refExpr.getParentByTypeAndBranch(javaClass<JetSuperExpression>()) { getSuperTypeQualifier() } != null ->
|
||||||
|
SUPER_TYPE_QUALIFIER
|
||||||
|
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getVariableUsageType(): UsageTypeEnum? {
|
||||||
|
if (refExpr.getParentByTypeAndBranch(javaClass<JetDelegatorByExpressionSpecifier>()) { getDelegateExpression() } != null) {
|
||||||
|
return DELEGATE
|
||||||
|
}
|
||||||
|
|
||||||
|
val dotQualifiedExpression = refExpr.getParentByType(javaClass<JetDotQualifiedExpression>())
|
||||||
|
|
||||||
|
if (dotQualifiedExpression != null) {
|
||||||
|
val parent = dotQualifiedExpression.getParent()
|
||||||
|
when {
|
||||||
|
dotQualifiedExpression.getReceiverExpression().isAncestor(refExpr) ->
|
||||||
|
return RECEIVER
|
||||||
|
|
||||||
|
parent is JetDotQualifiedExpression && parent.getReceiverExpression().isAncestor(refExpr) ->
|
||||||
|
return RECEIVER
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return when {
|
||||||
|
(refExpr.getParentByTypesAndPredicate(false, javaClass<JetBinaryExpression>()) { JetPsiUtil.isAssignment(it) })
|
||||||
|
?.getLeft().isAncestor(refExpr) ->
|
||||||
|
WRITE
|
||||||
|
|
||||||
|
refExpr.getParentByType(javaClass<JetSimpleNameExpression>()) != null ->
|
||||||
|
READ
|
||||||
|
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getFunctionUsageType(descriptor: FunctionDescriptor): UsageTypeEnum? {
|
||||||
|
val ref = refExpr.getReference()
|
||||||
|
when (ref) {
|
||||||
|
is JetArrayAccessReference -> {
|
||||||
|
return when {
|
||||||
|
context[BindingContext.INDEXED_LVALUE_GET, refExpr] != null -> IMPLICIT_GET
|
||||||
|
context[BindingContext.INDEXED_LVALUE_SET, refExpr] != null -> IMPLICIT_SET
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is JetInvokeFunctionReference -> return IMPLICIT_INVOKE
|
||||||
|
}
|
||||||
|
|
||||||
|
return when {
|
||||||
|
refExpr.getParentByTypeAndBranch(javaClass<JetDelegationSpecifier>()) { getTypeReference() } != null ->
|
||||||
|
SUPER_TYPE
|
||||||
|
|
||||||
|
descriptor is ConstructorDescriptor
|
||||||
|
&& refExpr.getParentByTypeAndBranch(javaClass<JetAnnotationEntry>()) { getTypeReference() } != null ->
|
||||||
|
ANNOTATION
|
||||||
|
|
||||||
|
with(refExpr.getParentByTypeAndBranch(javaClass<JetCallExpression>()) { getCalleeExpression() }) {
|
||||||
|
this?.getCalleeExpression() is JetSimpleNameExpression
|
||||||
|
} ->
|
||||||
|
if (descriptor is ConstructorDescriptor) CLASS_NEW_OPERATOR else FUNCTION_CALL
|
||||||
|
|
||||||
|
refExpr.getParentByTypeAndBranch(javaClass<JetBinaryExpression>()) { getOperationReference() } != null,
|
||||||
|
refExpr.getParentByTypeAndBranch(javaClass<JetUnaryExpression>()) { getOperationReference() } != null,
|
||||||
|
refExpr.getParentByTypeAndBranch(javaClass<JetWhenConditionInRange>()) { getOperationReference() } != null ->
|
||||||
|
FUNCTION_CALL
|
||||||
|
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getPackageUsageType(): UsageTypeEnum? {
|
||||||
|
return when {
|
||||||
|
refExpr.getParentByType(javaClass<JetPackageDirective>()) != null -> PACKAGE_DIRECTIVE
|
||||||
|
refExpr.getParentByType(javaClass<JetQualifiedExpression>()) != null -> PACKAGE_MEMBER_ACCESS
|
||||||
|
else -> getClassUsageType()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val usageType = getCommonUsageType()
|
||||||
|
if (usageType != null) return usageType
|
||||||
|
|
||||||
|
val descriptor = context[BindingContext.REFERENCE_TARGET, refExpr]
|
||||||
|
|
||||||
|
return when (descriptor) {
|
||||||
|
is ClassifierDescriptor -> when ((descriptor as? ClassDescriptor)?.getKind()) {
|
||||||
|
// Treat object accesses as variables to simulate the old behaviour (when variables were created for objects)
|
||||||
|
ClassKind.OBJECT, ClassKind.ENUM_ENTRY -> getVariableUsageType()
|
||||||
|
else -> getClassUsageType()
|
||||||
|
}
|
||||||
|
is PackageViewDescriptor -> {
|
||||||
|
if (refExpr.getReference()?.resolve() is PsiPackage) getPackageUsageType() else getClassUsageType()
|
||||||
|
}
|
||||||
|
is VariableDescriptor -> getVariableUsageType()
|
||||||
|
is FunctionDescriptor -> getFunctionUsageType(descriptor)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class UsageTypeEnum {
|
||||||
|
TYPE_CONSTRAINT
|
||||||
|
VALUE_PARAMETER_TYPE
|
||||||
|
NON_LOCAL_PROPERTY_TYPE
|
||||||
|
FUNCTION_RETURN_TYPE
|
||||||
|
SUPER_TYPE
|
||||||
|
TYPE_DEFINITION
|
||||||
|
IS
|
||||||
|
CLASS_OBJECT_ACCESS
|
||||||
|
EXTENSION_RECEIVER_TYPE
|
||||||
|
SUPER_TYPE_QUALIFIER
|
||||||
|
|
||||||
|
FUNCTION_CALL
|
||||||
|
IMPLICIT_GET
|
||||||
|
IMPLICIT_SET
|
||||||
|
IMPLICIT_INVOKE
|
||||||
|
IMPLICIT_ITERATION
|
||||||
|
|
||||||
|
RECEIVER
|
||||||
|
DELEGATE
|
||||||
|
|
||||||
|
PACKAGE_DIRECTIVE
|
||||||
|
PACKAGE_MEMBER_ACCESS
|
||||||
|
|
||||||
|
CALLABLE_REFERENCE
|
||||||
|
|
||||||
|
READ
|
||||||
|
WRITE
|
||||||
|
CLASS_IMPORT
|
||||||
|
CLASS_LOCAL_VAR_DECLARATION
|
||||||
|
TYPE_PARAMETER
|
||||||
|
CLASS_CAST_TO
|
||||||
|
ANNOTATION
|
||||||
|
CLASS_NEW_OPERATOR
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* 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.jet.plugin.quickfix;
|
||||||
|
|
||||||
|
import com.intellij.openapi.components.ServiceManager;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetImportDirective;
|
||||||
|
import org.jetbrains.jet.lang.resolve.ImportPath;
|
||||||
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public abstract class ImportInsertHelper {
|
||||||
|
public static ImportInsertHelper getInstance() {
|
||||||
|
return ServiceManager.getService(ImportInsertHelper.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void addImportDirectiveIfNeeded(@NotNull FqName importFqn, @NotNull JetFile file);
|
||||||
|
|
||||||
|
public abstract boolean isImportedWithDefault(@NotNull ImportPath importPath, @NotNull JetFile contextFile);
|
||||||
|
|
||||||
|
public abstract boolean needImport(@NotNull FqName fqName, @NotNull JetFile file);
|
||||||
|
|
||||||
|
public abstract boolean needImport(@NotNull ImportPath importPath, @NotNull JetFile file);
|
||||||
|
|
||||||
|
public abstract boolean needImport(@NotNull ImportPath importPath, @NotNull JetFile file, List<JetImportDirective> importDirectives);
|
||||||
|
public abstract void optimizeImportsOnTheFly(JetFile file);
|
||||||
|
public abstract void writeImportToFile(@NotNull ImportPath importPath, @NotNull JetFile file);
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* 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.jet.plugin.refactoring.fqName
|
||||||
|
|
||||||
|
import org.jetbrains.jet.asJava.namedUnwrappedElement
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.jet.lang.resolve.name.FqName
|
||||||
|
import com.intellij.psi.PsiPackage
|
||||||
|
import com.intellij.psi.PsiClass
|
||||||
|
import com.intellij.psi.PsiMember
|
||||||
|
import org.jetbrains.jet.lang.psi.JetNamedDeclaration
|
||||||
|
import org.jetbrains.jet.lang.resolve.name.isOneSegmentFQN
|
||||||
|
import org.jetbrains.jet.lang.psi.psiUtil.getQualifiedElement
|
||||||
|
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
|
||||||
|
import org.jetbrains.jet.lang.psi.JetElement
|
||||||
|
import org.jetbrains.jet.lang.psi.JetCallExpression
|
||||||
|
import org.jetbrains.jet.lang.psi.JetUserType
|
||||||
|
import org.jetbrains.jet.lang.psi
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns FqName for given declaration (either Java or Kotlin)
|
||||||
|
*/
|
||||||
|
public fun PsiElement.getKotlinFqName(): FqName? {
|
||||||
|
val element = namedUnwrappedElement
|
||||||
|
return when (element) {
|
||||||
|
is PsiPackage -> FqName(element.getQualifiedName())
|
||||||
|
is PsiClass -> element.getQualifiedName()?.let { FqName(it) }
|
||||||
|
is PsiMember -> (element : PsiMember).getName()?.let { name ->
|
||||||
|
val prefix = element.getContainingClass()?.getQualifiedName()
|
||||||
|
FqName(if (prefix != null) "$prefix.$name" else name)
|
||||||
|
}
|
||||||
|
is JetNamedDeclaration -> element.getFqName()
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace [[JetSimpleNameExpression]] (and its enclosing qualifier) with qualified element given by FqName
|
||||||
|
* Result is either the same as original element, or [[JetQualifiedExpression]], or [[JetUserType]]
|
||||||
|
* Note that FqName may not be empty
|
||||||
|
*/
|
||||||
|
fun JetSimpleNameExpression.changeQualifiedName(fqName: FqName): JetElement {
|
||||||
|
assert (!fqName.isRoot(), "Can't set empty FqName for element $this")
|
||||||
|
|
||||||
|
val shortName = fqName.shortName().asString()
|
||||||
|
val psiFactory = psi.JetPsiFactory(this)
|
||||||
|
val fqNameBase = (getParent() as? JetCallExpression)?.let { parent ->
|
||||||
|
val callCopy = parent.copy() as JetCallExpression
|
||||||
|
callCopy.getCalleeExpression()!!.replace(psiFactory.createSimpleName(shortName)).getParent()!!.getText()
|
||||||
|
} ?: shortName
|
||||||
|
|
||||||
|
val text = if (!fqName.isOneSegmentFQN()) "${fqName.parent().asString()}.$fqNameBase" else fqNameBase
|
||||||
|
|
||||||
|
val elementToReplace = getQualifiedElement()
|
||||||
|
return when (elementToReplace) {
|
||||||
|
is JetUserType -> {
|
||||||
|
val typeText = "$text${elementToReplace.getTypeArgumentList()?.getText() ?: ""}"
|
||||||
|
elementToReplace.replace(psiFactory.createType(typeText).getTypeElement()!!)
|
||||||
|
}
|
||||||
|
else -> elementToReplace.replace(psiFactory.createExpression(text))
|
||||||
|
} as JetElement
|
||||||
|
}
|
||||||
+1
-1
@@ -59,4 +59,4 @@ public class JetReferenceContributor() : PsiReferenceContributor() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
-3
@@ -23,11 +23,11 @@ import org.jetbrains.jet.lang.psi.*
|
|||||||
import org.jetbrains.jet.lang.resolve.name.FqName
|
import org.jetbrains.jet.lang.resolve.name.FqName
|
||||||
import org.jetbrains.jet.lexer.JetTokens
|
import org.jetbrains.jet.lexer.JetTokens
|
||||||
import org.jetbrains.jet.plugin.codeInsight.ShortenReferences
|
import org.jetbrains.jet.plugin.codeInsight.ShortenReferences
|
||||||
import org.jetbrains.jet.plugin.refactoring.changeQualifiedName
|
import org.jetbrains.jet.plugin.refactoring.fqName.changeQualifiedName
|
||||||
import org.jetbrains.jet.lang.psi.psiUtil.getQualifiedElementSelector
|
import org.jetbrains.jet.lang.psi.psiUtil.getQualifiedElementSelector
|
||||||
import org.jetbrains.jet.lang.psi.psiUtil.getOutermostNonInterleavingQualifiedElement
|
import org.jetbrains.jet.lang.psi.psiUtil.getOutermostNonInterleavingQualifiedElement
|
||||||
import org.jetbrains.jet.plugin.codeInsight.addToShorteningWaitSet
|
import org.jetbrains.jet.plugin.codeInsight.shorten.addToShorteningWaitSet
|
||||||
import org.jetbrains.jet.plugin.refactoring.getKotlinFqName
|
import org.jetbrains.jet.plugin.refactoring.fqName.getKotlinFqName
|
||||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions
|
import org.jetbrains.jet.lang.types.expressions.OperatorConventions
|
||||||
import org.jetbrains.jet.lexer.JetToken
|
import org.jetbrains.jet.lexer.JetToken
|
||||||
import org.jetbrains.jet.plugin.intentions.OperatorToFunctionIntention
|
import org.jetbrains.jet.plugin.intentions.OperatorToFunctionIntention
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2013 JetBrains s.r.o.
|
* Copyright 2010-2014 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
-2
@@ -30,7 +30,6 @@ import com.intellij.psi.search.searches.ReferenceDescriptor
|
|||||||
import com.intellij.util.containers.ContainerUtil
|
import com.intellij.util.containers.ContainerUtil
|
||||||
import com.intellij.psi.search.UsageSearchContext
|
import com.intellij.psi.search.UsageSearchContext
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.search.RequestResultProcessor
|
|
||||||
import com.intellij.util.Processor
|
import com.intellij.util.Processor
|
||||||
import com.intellij.openapi.application.QueryExecutorBase
|
import com.intellij.openapi.application.QueryExecutorBase
|
||||||
import com.intellij.psi.PsiReferenceService
|
import com.intellij.psi.PsiReferenceService
|
||||||
@@ -49,7 +48,6 @@ import com.intellij.util.indexing.FileBasedIndex
|
|||||||
import com.intellij.psi.impl.cache.impl.id.IdIndex
|
import com.intellij.psi.impl.cache.impl.id.IdIndex
|
||||||
import org.jetbrains.jet.plugin.util.application.runReadAction
|
import org.jetbrains.jet.plugin.util.application.runReadAction
|
||||||
import com.intellij.psi.search.TextOccurenceProcessor
|
import com.intellij.psi.search.TextOccurenceProcessor
|
||||||
import org.jetbrains.jet.plugin.references.JetMultiDeclarationReference
|
|
||||||
import com.intellij.psi.PsiManager
|
import com.intellij.psi.PsiManager
|
||||||
import com.intellij.psi.impl.PsiManagerEx
|
import com.intellij.psi.impl.PsiManagerEx
|
||||||
|
|
||||||
+7
-7
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2013 JetBrains s.r.o.
|
* Copyright 2010-2014 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -24,13 +24,13 @@ import org.jetbrains.jet.lang.resolve.BindingContext
|
|||||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
|
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
|
||||||
import com.intellij.psi.PsiReference
|
import com.intellij.psi.PsiReference
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils
|
||||||
import org.jetbrains.jet.plugin.findUsages.JetUsageTypeProvider
|
|
||||||
import com.intellij.usages.impl.rules.UsageType
|
|
||||||
import org.jetbrains.jet.codegen.PropertyCodegen
|
import org.jetbrains.jet.codegen.PropertyCodegen
|
||||||
import org.jetbrains.jet.asJava.KotlinLightMethod
|
import org.jetbrains.jet.asJava.KotlinLightMethod
|
||||||
import org.jetbrains.jet.lang.resolve.OverrideResolver
|
import org.jetbrains.jet.lang.resolve.OverrideResolver
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils
|
import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils
|
||||||
import org.jetbrains.jet.plugin.references.*
|
import org.jetbrains.jet.plugin.references.*
|
||||||
|
import org.jetbrains.jet.plugin.findUsages.UsageTypeUtils
|
||||||
|
import org.jetbrains.jet.plugin.findUsages.UsageTypeEnum
|
||||||
|
|
||||||
val JetDeclaration.descriptor: DeclarationDescriptor?
|
val JetDeclaration.descriptor: DeclarationDescriptor?
|
||||||
get() = AnalyzerFacadeWithCache.getContextForElement(this).get(BindingContext.DECLARATION_TO_DESCRIPTOR, this)
|
get() = AnalyzerFacadeWithCache.getContextForElement(this).get(BindingContext.DECLARATION_TO_DESCRIPTOR, this)
|
||||||
@@ -106,7 +106,7 @@ fun PsiReference.isExtensionOfDeclarationClassUsage(declaration: JetNamedDeclara
|
|||||||
val containingDescriptor = targetDescriptor.getContainingDeclaration()
|
val containingDescriptor = targetDescriptor.getContainingDeclaration()
|
||||||
|
|
||||||
containingDescriptor == receiverDescriptor
|
containingDescriptor == receiverDescriptor
|
||||||
|| (containingDescriptor is ClassDescriptor
|
|| (containingDescriptor is ClassDescriptor
|
||||||
&& receiverDescriptor is ClassDescriptor
|
&& receiverDescriptor is ClassDescriptor
|
||||||
&& DescriptorUtils.isSubclass(containingDescriptor, receiverDescriptor))
|
&& DescriptorUtils.isSubclass(containingDescriptor, receiverDescriptor))
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,7 @@ fun PsiReference.isExtensionOfDeclarationClassUsage(declaration: JetNamedDeclara
|
|||||||
fun PsiReference.isUsageInContainingDeclaration(declaration: JetNamedDeclaration): Boolean =
|
fun PsiReference.isUsageInContainingDeclaration(declaration: JetNamedDeclaration): Boolean =
|
||||||
checkUsageVsOriginalDescriptor(declaration) { (usageDescriptor, targetDescriptor) ->
|
checkUsageVsOriginalDescriptor(declaration) { (usageDescriptor, targetDescriptor) ->
|
||||||
usageDescriptor != targetDescriptor
|
usageDescriptor != targetDescriptor
|
||||||
&& usageDescriptor.getContainingDeclaration() == targetDescriptor.getContainingDeclaration()
|
&& usageDescriptor.getContainingDeclaration() == targetDescriptor.getContainingDeclaration()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PsiReference.isCallableOverrideUsage(declaration: JetNamedDeclaration): Boolean {
|
fun PsiReference.isCallableOverrideUsage(declaration: JetNamedDeclaration): Boolean {
|
||||||
@@ -128,7 +128,7 @@ fun PsiReference.isCallableOverrideUsage(declaration: JetNamedDeclaration): Bool
|
|||||||
|
|
||||||
return checkUsageVsOriginalDescriptor(declaration, decl2Desc) { (usageDescriptor, targetDescriptor) ->
|
return checkUsageVsOriginalDescriptor(declaration, decl2Desc) { (usageDescriptor, targetDescriptor) ->
|
||||||
usageDescriptor is CallableDescriptor && targetDescriptor is CallableDescriptor
|
usageDescriptor is CallableDescriptor && targetDescriptor is CallableDescriptor
|
||||||
&& OverrideResolver.overrides(usageDescriptor, targetDescriptor)
|
&& OverrideResolver.overrides(usageDescriptor, targetDescriptor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ fun PsiReference.isCallableOverrideUsage(declaration: JetNamedDeclaration): Bool
|
|||||||
// Check if reference resolves to property getter
|
// Check if reference resolves to property getter
|
||||||
// Works for JetProperty and JetParameter
|
// Works for JetProperty and JetParameter
|
||||||
fun PsiReference.isPropertyReadOnlyUsage(): Boolean {
|
fun PsiReference.isPropertyReadOnlyUsage(): Boolean {
|
||||||
if (JetUsageTypeProvider.getUsageType(getElement()) == UsageType.READ) return true
|
if (UsageTypeUtils.getUsageType(getElement()) == UsageTypeEnum.READ) return true
|
||||||
|
|
||||||
val refTarget = resolve()
|
val refTarget = resolve()
|
||||||
if (refTarget is KotlinLightMethod) {
|
if (refTarget is KotlinLightMethod) {
|
||||||
@@ -131,6 +131,8 @@
|
|||||||
|
|
||||||
<applicationService serviceInterface="org.jetbrains.jet.plugin.configuration.JetModuleTypeManager"
|
<applicationService serviceInterface="org.jetbrains.jet.plugin.configuration.JetModuleTypeManager"
|
||||||
serviceImplementation="org.jetbrains.jet.plugin.JetModuleTypeManagerImpl"/>
|
serviceImplementation="org.jetbrains.jet.plugin.JetModuleTypeManagerImpl"/>
|
||||||
|
<applicationService serviceInterface="org.jetbrains.jet.plugin.quickfix.ImportInsertHelper"
|
||||||
|
serviceImplementation="org.jetbrains.jet.plugin.quickfix.ImportInsertHelperImpl"/>
|
||||||
|
|
||||||
<projectService serviceInterface="org.jetbrains.jet.plugin.caches.resolve.KotlinCacheService"
|
<projectService serviceInterface="org.jetbrains.jet.plugin.caches.resolve.KotlinCacheService"
|
||||||
serviceImplementation="org.jetbrains.jet.plugin.caches.resolve.KotlinCacheService"/>
|
serviceImplementation="org.jetbrains.jet.plugin.caches.resolve.KotlinCacheService"/>
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ public class JetAddImportAction implements QuestionAction {
|
|||||||
public void run() {
|
public void run() {
|
||||||
PsiFile file = element.getContainingFile();
|
PsiFile file = element.getContainingFile();
|
||||||
if (!(file instanceof JetFile)) return;
|
if (!(file instanceof JetFile)) return;
|
||||||
ImportInsertHelper.addImportDirectiveIfNeeded(selectedImport, (JetFile) file);
|
ImportInsertHelper.getInstance().addImportDirectiveIfNeeded(selectedImport, (JetFile) file);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<Refere
|
|||||||
return Collections.emptyList()
|
return Collections.emptyList()
|
||||||
}
|
}
|
||||||
return referenceData.map {
|
return referenceData.map {
|
||||||
if (ImportInsertHelper.needImport(it.fqName, file)) {
|
if (ImportInsertHelper.getInstance().needImport(it.fqName, file)) {
|
||||||
val referenceExpression = findReference(it, file, bounds)
|
val referenceExpression = findReference(it, file, bounds)
|
||||||
if (referenceExpression != null) createReferenceToRestoreData(referenceExpression, it.fqName) else null
|
if (referenceExpression != null) createReferenceToRestoreData(referenceExpression, it.fqName) else null
|
||||||
}
|
}
|
||||||
@@ -287,7 +287,7 @@ public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<Refere
|
|||||||
private fun restoreReferences(referencesToRestore: Collection<ReferenceToRestoreData>, file: JetFile) {
|
private fun restoreReferences(referencesToRestore: Collection<ReferenceToRestoreData>, file: JetFile) {
|
||||||
for ((referenceExpression, fqName, shouldLengthen) in referencesToRestore) {
|
for ((referenceExpression, fqName, shouldLengthen) in referencesToRestore) {
|
||||||
if (!shouldLengthen) {
|
if (!shouldLengthen) {
|
||||||
ImportInsertHelper.addImportDirectiveIfNeeded(fqName, file)
|
ImportInsertHelper.getInstance().addImportDirectiveIfNeeded(fqName, file)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//TODO: try to shorten reference after (sometimes is possible), need shorten reference to support all relevant cases
|
//TODO: try to shorten reference after (sometimes is possible), need shorten reference to support all relevant cases
|
||||||
|
|||||||
+4
-47
@@ -19,67 +19,24 @@ package org.jetbrains.jet.plugin.codeInsight
|
|||||||
import com.intellij.refactoring.RefactoringHelper
|
import com.intellij.refactoring.RefactoringHelper
|
||||||
import com.intellij.usageView.UsageInfo
|
import com.intellij.usageView.UsageInfo
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import java.util.HashSet
|
|
||||||
import com.intellij.openapi.util.Key
|
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
import com.intellij.psi.SmartPsiElementPointer
|
import org.jetbrains.jet.plugin.codeInsight.shorten.prepareElementsToShorten
|
||||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
|
import org.jetbrains.jet.plugin.codeInsight.shorten.withElementsToShorten
|
||||||
import com.intellij.openapi.diagnostic.Logger
|
|
||||||
import com.intellij.psi.SmartPointerManager
|
|
||||||
import org.jetbrains.jet.lang.psi.JetElement
|
|
||||||
import org.jetbrains.jet.lang.psi.JetQualifiedExpression
|
|
||||||
import org.jetbrains.jet.lang.psi.JetUserType
|
|
||||||
import org.jetbrains.jet.lang.psi.JetFile
|
|
||||||
import org.jetbrains.jet.lang.psi.UserDataProperty
|
|
||||||
import org.jetbrains.jet.lang.psi.NotNullableUserDataProperty
|
|
||||||
|
|
||||||
public class KotlinShortenReferencesRefactoringHelper: RefactoringHelper<Any> {
|
public class KotlinShortenReferencesRefactoringHelper: RefactoringHelper<Any> {
|
||||||
private val LOG = Logger.getInstance(javaClass<KotlinShortenReferencesRefactoringHelper>().getCanonicalName())
|
|
||||||
|
|
||||||
override fun prepareOperation(usages: Array<out UsageInfo>?): Any? {
|
override fun prepareOperation(usages: Array<out UsageInfo>?): Any? {
|
||||||
if (usages != null && usages.isNotEmpty()) {
|
if (usages != null && usages.isNotEmpty()) {
|
||||||
val project = usages[0].getProject()
|
val project = usages[0].getProject()
|
||||||
val elementsToShorten = project.elementsToShorten
|
prepareElementsToShorten(project)
|
||||||
if (project.ensureElementsToShortenIsEmptyBeforeRefactoring && elementsToShorten != null && !elementsToShorten.isEmpty()) {
|
|
||||||
LOG.warn("Waiting set for reference shortening is not empty")
|
|
||||||
project.elementsToShorten = null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun performOperation(project: Project, operationData: Any?) {
|
override fun performOperation(project: Project, operationData: Any?) {
|
||||||
ApplicationManager.getApplication()!!.runWriteAction {
|
ApplicationManager.getApplication()!!.runWriteAction {
|
||||||
project.elementsToShorten?.let { bindRequests ->
|
withElementsToShorten(project) { bindRequests ->
|
||||||
project.elementsToShorten = null
|
|
||||||
ShortenReferences.process(bindRequests.map() { it.getElement() }.filterNotNull())
|
ShortenReferences.process(bindRequests.map() { it.getElement() }.filterNotNull())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var Project.elementsToShorten: MutableSet<SmartPsiElementPointer<JetElement>>?
|
|
||||||
by UserDataProperty(Key.create("ELEMENTS_TO_SHORTEN_KEY"))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* When one refactoring invokes another this value must be set to false so that shortening wait-set is not cleared
|
|
||||||
* and previously collected references are processed correctly. Afterwards it must be reset to original value
|
|
||||||
*/
|
|
||||||
public var Project.ensureElementsToShortenIsEmptyBeforeRefactoring: Boolean
|
|
||||||
by NotNullableUserDataProperty(Key.create("ENSURE_ELEMENTS_TO_SHORTEN_IS_EMPTY"), true)
|
|
||||||
|
|
||||||
private fun Project.getOrCreateElementsToShorten(): MutableSet<SmartPsiElementPointer<JetElement>> {
|
|
||||||
var elements = elementsToShorten
|
|
||||||
if (elements == null) {
|
|
||||||
elements = HashSet()
|
|
||||||
elementsToShorten = elements
|
|
||||||
}
|
|
||||||
|
|
||||||
return elements!!
|
|
||||||
}
|
|
||||||
|
|
||||||
public fun JetElement.addToShorteningWaitSet() {
|
|
||||||
assert (ApplicationManager.getApplication()!!.isWriteAccessAllowed(), "Write access needed")
|
|
||||||
val project = getProject()
|
|
||||||
project.getOrCreateElementsToShorten().add(SmartPointerManager.getInstance(project).createSmartPsiElementPointer(this))
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -126,8 +126,8 @@ private class JetDeclarationRemotenessWeigher(private val file: JetFile) : Looku
|
|||||||
if (isValidJavaFqName(fqName)) {
|
if (isValidJavaFqName(fqName)) {
|
||||||
val importPath = ImportPath(fqName)
|
val importPath = ImportPath(fqName)
|
||||||
return when {
|
return when {
|
||||||
ImportInsertHelper.needImport(importPath, file) -> Weight.notImported
|
ImportInsertHelper.getInstance().needImport(importPath, file) -> Weight.notImported
|
||||||
ImportInsertHelper.isImportedWithDefault(importPath, file) -> Weight.kotlinDefaultImport
|
ImportInsertHelper.getInstance().isImportedWithDefault(importPath, file) -> Weight.kotlinDefaultImport
|
||||||
else -> Weight.imported
|
else -> Weight.imported
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -67,7 +67,7 @@ public abstract class JetCallableInsertHandler : BaseDeclarationInsertHandler()
|
|||||||
|
|
||||||
if (DescriptorUtils.isTopLevelDeclaration(descriptor)) {
|
if (DescriptorUtils.isTopLevelDeclaration(descriptor)) {
|
||||||
ApplicationManager.getApplication()?.runWriteAction {
|
ApplicationManager.getApplication()?.runWriteAction {
|
||||||
ImportInsertHelper.addImportDirectiveIfNeeded(DescriptorUtils.getFqNameSafe(descriptor), file)
|
ImportInsertHelper.getInstance().addImportDirectiveIfNeeded(DescriptorUtils.getFqNameSafe(descriptor), file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,16 +20,8 @@ import com.intellij.psi.PsiElement
|
|||||||
import com.intellij.usages.UsageTarget
|
import com.intellij.usages.UsageTarget
|
||||||
import com.intellij.usages.impl.rules.UsageType
|
import com.intellij.usages.impl.rules.UsageType
|
||||||
import com.intellij.usages.impl.rules.UsageTypeProviderEx
|
import com.intellij.usages.impl.rules.UsageTypeProviderEx
|
||||||
import org.jetbrains.jet.lang.descriptors.*
|
|
||||||
import org.jetbrains.jet.lang.psi.*
|
|
||||||
import org.jetbrains.jet.lang.psi.psiUtil.*
|
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
|
||||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
|
|
||||||
import org.jetbrains.jet.plugin.JetBundle
|
import org.jetbrains.jet.plugin.JetBundle
|
||||||
import com.intellij.psi.PsiPackage
|
import org.jetbrains.jet.plugin.findUsages.UsageTypeEnum.*
|
||||||
import org.jetbrains.jet.lexer.JetTokens
|
|
||||||
import org.jetbrains.jet.plugin.references.JetArrayAccessReference
|
|
||||||
import org.jetbrains.jet.plugin.references.JetInvokeFunctionReference
|
|
||||||
|
|
||||||
public object JetUsageTypeProvider : UsageTypeProviderEx {
|
public object JetUsageTypeProvider : UsageTypeProviderEx {
|
||||||
public override fun getUsageType(element: PsiElement?): UsageType? {
|
public override fun getUsageType(element: PsiElement?): UsageType? {
|
||||||
@@ -37,181 +29,46 @@ public object JetUsageTypeProvider : UsageTypeProviderEx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override fun getUsageType(element: PsiElement?, targets: Array<out UsageTarget>): UsageType? {
|
public override fun getUsageType(element: PsiElement?, targets: Array<out UsageTarget>): UsageType? {
|
||||||
when (element) {
|
val usageType = UsageTypeUtils.getUsageType(element)
|
||||||
is JetForExpression -> return JetUsageTypes.IMPLICIT_ITERATION
|
if (usageType == null) return null
|
||||||
is JetMultiDeclaration -> return UsageType.READ
|
return convertEnumToUsageType(usageType)
|
||||||
}
|
}
|
||||||
|
|
||||||
val refExpr = element?.getParentByType(javaClass<JetReferenceExpression>())
|
fun convertEnumToUsageType(usageType: UsageTypeEnum): UsageType {
|
||||||
if (refExpr == null) return null
|
return when (usageType) {
|
||||||
|
TYPE_CONSTRAINT -> JetUsageTypes.TYPE_CONSTRAINT
|
||||||
|
VALUE_PARAMETER_TYPE -> JetUsageTypes.VALUE_PARAMETER_TYPE
|
||||||
|
NON_LOCAL_PROPERTY_TYPE -> JetUsageTypes.NON_LOCAL_PROPERTY_TYPE
|
||||||
|
FUNCTION_RETURN_TYPE -> JetUsageTypes.FUNCTION_RETURN_TYPE
|
||||||
|
SUPER_TYPE -> JetUsageTypes.SUPER_TYPE
|
||||||
|
TYPE_DEFINITION -> JetUsageTypes.TYPE_DEFINITION
|
||||||
|
IS -> JetUsageTypes.IS
|
||||||
|
CLASS_OBJECT_ACCESS -> JetUsageTypes.CLASS_OBJECT_ACCESS
|
||||||
|
EXTENSION_RECEIVER_TYPE -> JetUsageTypes.EXTENSION_RECEIVER_TYPE
|
||||||
|
SUPER_TYPE_QUALIFIER -> JetUsageTypes.SUPER_TYPE_QUALIFIER
|
||||||
|
|
||||||
val context = AnalyzerFacadeWithCache.getContextForElement(refExpr)
|
FUNCTION_CALL -> JetUsageTypes.FUNCTION_CALL
|
||||||
|
IMPLICIT_GET -> JetUsageTypes.IMPLICIT_GET
|
||||||
|
IMPLICIT_SET -> JetUsageTypes.IMPLICIT_SET
|
||||||
|
IMPLICIT_INVOKE -> JetUsageTypes.IMPLICIT_INVOKE
|
||||||
|
IMPLICIT_ITERATION -> JetUsageTypes.IMPLICIT_ITERATION
|
||||||
|
|
||||||
fun getCommonUsageType(): UsageType? {
|
RECEIVER -> JetUsageTypes.RECEIVER
|
||||||
return when {
|
DELEGATE -> JetUsageTypes.DELEGATE
|
||||||
refExpr.getParentByType(javaClass<JetImportDirective>()) != null ->
|
|
||||||
UsageType.CLASS_IMPORT
|
|
||||||
refExpr.getParentByTypeAndBranch(javaClass<JetCallableReferenceExpression>()) { getCallableReference() } != null ->
|
|
||||||
JetUsageTypes.CALLABLE_REFERENCE
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getClassUsageType(): UsageType? {
|
PACKAGE_DIRECTIVE -> JetUsageTypes.PACKAGE_DIRECTIVE
|
||||||
val property = refExpr.getParentByType(javaClass<JetProperty>())
|
PACKAGE_MEMBER_ACCESS -> JetUsageTypes.PACKAGE_MEMBER_ACCESS
|
||||||
if (property != null) {
|
|
||||||
when {
|
|
||||||
property.getTypeReference().isAncestor(refExpr) ->
|
|
||||||
return if (property.isLocal()) UsageType.CLASS_LOCAL_VAR_DECLARATION else JetUsageTypes.NON_LOCAL_PROPERTY_TYPE
|
|
||||||
|
|
||||||
property.getReceiverTypeReference().isAncestor(refExpr) ->
|
CALLABLE_REFERENCE -> JetUsageTypes.CALLABLE_REFERENCE
|
||||||
return JetUsageTypes.EXTENSION_RECEIVER_TYPE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val function = refExpr.getParentByType(javaClass<JetFunction>())
|
READ -> UsageType.READ
|
||||||
if (function != null) {
|
WRITE -> UsageType.WRITE
|
||||||
when {
|
CLASS_IMPORT -> UsageType.CLASS_IMPORT
|
||||||
function.getTypeReference().isAncestor(refExpr) ->
|
CLASS_LOCAL_VAR_DECLARATION -> UsageType.CLASS_LOCAL_VAR_DECLARATION
|
||||||
return JetUsageTypes.FUNCTION_RETURN_TYPE
|
TYPE_PARAMETER -> UsageType.TYPE_PARAMETER
|
||||||
function.getReceiverTypeReference().isAncestor(refExpr) ->
|
CLASS_CAST_TO -> UsageType.CLASS_CAST_TO
|
||||||
return JetUsageTypes.EXTENSION_RECEIVER_TYPE
|
ANNOTATION -> UsageType.ANNOTATION
|
||||||
}
|
CLASS_NEW_OPERATOR -> UsageType.CLASS_NEW_OPERATOR
|
||||||
}
|
|
||||||
|
|
||||||
return when {
|
|
||||||
refExpr.getParentByTypeAndBranch(javaClass<JetTypeParameter>()) { getExtendsBound() } != null
|
|
||||||
|| refExpr.getParentByTypeAndBranch(javaClass<JetTypeConstraint>()) { getBoundTypeReference() } != null ->
|
|
||||||
JetUsageTypes.TYPE_CONSTRAINT
|
|
||||||
|
|
||||||
refExpr is JetDelegationSpecifier
|
|
||||||
|| refExpr.getParentByTypeAndBranch(javaClass<JetDelegationSpecifier>()) { getTypeReference() } != null ->
|
|
||||||
JetUsageTypes.SUPER_TYPE
|
|
||||||
|
|
||||||
refExpr.getParentByTypeAndBranch(javaClass<JetTypedef>()) { getTypeReference() } != null ->
|
|
||||||
JetUsageTypes.TYPE_DEFINITION
|
|
||||||
|
|
||||||
refExpr.getParentByType(javaClass<JetTypeProjection>()) != null ->
|
|
||||||
UsageType.TYPE_PARAMETER
|
|
||||||
|
|
||||||
refExpr.getParentByTypeAndBranch(javaClass<JetParameter>()) { getTypeReference() } != null ->
|
|
||||||
JetUsageTypes.VALUE_PARAMETER_TYPE
|
|
||||||
|
|
||||||
refExpr.getParentByTypeAndBranch(javaClass<JetIsExpression>()) { getTypeReference() } != null ->
|
|
||||||
JetUsageTypes.IS
|
|
||||||
|
|
||||||
with(refExpr.getParentByTypeAndBranch(javaClass<JetBinaryExpressionWithTypeRHS>()) { getRight() }) {
|
|
||||||
val opType = this?.getOperationReference()?.getReferencedNameElementType()
|
|
||||||
opType == JetTokens.AS_KEYWORD || opType == JetTokens.AS_SAFE
|
|
||||||
} ->
|
|
||||||
UsageType.CLASS_CAST_TO
|
|
||||||
|
|
||||||
with(refExpr.getParentByType(javaClass<JetDotQualifiedExpression>())) {
|
|
||||||
if (this == null) false
|
|
||||||
else if (getReceiverExpression() == refExpr) true
|
|
||||||
else
|
|
||||||
getSelectorExpression() == refExpr
|
|
||||||
&& getParentByTypeAndBranch(javaClass<JetDotQualifiedExpression>(), true) { getReceiverExpression() } != null
|
|
||||||
} ->
|
|
||||||
JetUsageTypes.CLASS_OBJECT_ACCESS
|
|
||||||
|
|
||||||
refExpr.getParentByTypeAndBranch(javaClass<JetSuperExpression>()) { getSuperTypeQualifier() } != null ->
|
|
||||||
JetUsageTypes.SUPER_TYPE_QUALIFIER
|
|
||||||
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getVariableUsageType(): UsageType? {
|
|
||||||
if (refExpr.getParentByTypeAndBranch(javaClass<JetDelegatorByExpressionSpecifier>()) { getDelegateExpression() } != null) {
|
|
||||||
return JetUsageTypes.DELEGATE
|
|
||||||
}
|
|
||||||
|
|
||||||
val dotQualifiedExpression = refExpr.getParentByType(javaClass<JetDotQualifiedExpression>())
|
|
||||||
|
|
||||||
if (dotQualifiedExpression != null) {
|
|
||||||
val parent = dotQualifiedExpression.getParent()
|
|
||||||
when {
|
|
||||||
dotQualifiedExpression.getReceiverExpression().isAncestor(refExpr) ->
|
|
||||||
return JetUsageTypes.RECEIVER
|
|
||||||
|
|
||||||
parent is JetDotQualifiedExpression && parent.getReceiverExpression().isAncestor(refExpr) ->
|
|
||||||
return JetUsageTypes.RECEIVER
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return when {
|
|
||||||
(refExpr.getParentByTypesAndPredicate(false, javaClass<JetBinaryExpression>()) { JetPsiUtil.isAssignment(it) })
|
|
||||||
?.getLeft().isAncestor(refExpr) ->
|
|
||||||
UsageType.WRITE
|
|
||||||
|
|
||||||
refExpr.getParentByType(javaClass<JetSimpleNameExpression>()) != null ->
|
|
||||||
UsageType.READ
|
|
||||||
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getFunctionUsageType(descriptor: FunctionDescriptor): UsageType? {
|
|
||||||
val ref = refExpr.getReference()
|
|
||||||
when (ref) {
|
|
||||||
is JetArrayAccessReference -> {
|
|
||||||
return when {
|
|
||||||
context[BindingContext.INDEXED_LVALUE_GET, refExpr] != null -> JetUsageTypes.IMPLICIT_GET
|
|
||||||
context[BindingContext.INDEXED_LVALUE_SET, refExpr] != null -> JetUsageTypes.IMPLICIT_SET
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is JetInvokeFunctionReference -> return JetUsageTypes.IMPLICIT_INVOKE
|
|
||||||
}
|
|
||||||
|
|
||||||
return when {
|
|
||||||
refExpr.getParentByTypeAndBranch(javaClass<JetDelegationSpecifier>()) { getTypeReference() } != null ->
|
|
||||||
JetUsageTypes.SUPER_TYPE
|
|
||||||
|
|
||||||
descriptor is ConstructorDescriptor
|
|
||||||
&& refExpr.getParentByTypeAndBranch(javaClass<JetAnnotationEntry>()) { getTypeReference() } != null ->
|
|
||||||
UsageType.ANNOTATION
|
|
||||||
|
|
||||||
with(refExpr.getParentByTypeAndBranch(javaClass<JetCallExpression>()) { getCalleeExpression() }) {
|
|
||||||
this?.getCalleeExpression() is JetSimpleNameExpression
|
|
||||||
} ->
|
|
||||||
if (descriptor is ConstructorDescriptor) UsageType.CLASS_NEW_OPERATOR else JetUsageTypes.FUNCTION_CALL
|
|
||||||
|
|
||||||
refExpr.getParentByTypeAndBranch(javaClass<JetBinaryExpression>()) { getOperationReference() } != null,
|
|
||||||
refExpr.getParentByTypeAndBranch(javaClass<JetUnaryExpression>()) { getOperationReference() } != null,
|
|
||||||
refExpr.getParentByTypeAndBranch(javaClass<JetWhenConditionInRange>()) { getOperationReference() } != null ->
|
|
||||||
JetUsageTypes.FUNCTION_CALL
|
|
||||||
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getPackageUsageType(): UsageType? {
|
|
||||||
return when {
|
|
||||||
refExpr.getParentByType(javaClass<JetPackageDirective>()) != null -> JetUsageTypes.PACKAGE_DIRECTIVE
|
|
||||||
refExpr.getParentByType(javaClass<JetQualifiedExpression>()) != null -> JetUsageTypes.PACKAGE_MEMBER_ACCESS
|
|
||||||
else -> getClassUsageType()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val usageType = getCommonUsageType()
|
|
||||||
if (usageType != null) return usageType
|
|
||||||
|
|
||||||
val descriptor = context[BindingContext.REFERENCE_TARGET, refExpr]
|
|
||||||
|
|
||||||
return when (descriptor) {
|
|
||||||
is ClassifierDescriptor -> when ((descriptor as? ClassDescriptor)?.getKind()) {
|
|
||||||
// Treat object accesses as variables to simulate the old behaviour (when variables were created for objects)
|
|
||||||
ClassKind.OBJECT, ClassKind.ENUM_ENTRY -> getVariableUsageType()
|
|
||||||
else -> getClassUsageType()
|
|
||||||
}
|
|
||||||
is PackageViewDescriptor -> {
|
|
||||||
if (refExpr.getReference()?.resolve() is PsiPackage) getPackageUsageType() else getClassUsageType()
|
|
||||||
}
|
|
||||||
is VariableDescriptor -> getVariableUsageType()
|
|
||||||
is FunctionDescriptor -> getFunctionUsageType(descriptor)
|
|
||||||
else -> null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ import org.jetbrains.jet.lang.resolve.ImportPath
|
|||||||
import org.jetbrains.jet.lang.resolve.name.*
|
import org.jetbrains.jet.lang.resolve.name.*
|
||||||
import org.jetbrains.jet.plugin.references.JetReference
|
import org.jetbrains.jet.plugin.references.JetReference
|
||||||
import java.util.HashSet
|
import java.util.HashSet
|
||||||
import org.jetbrains.jet.plugin.quickfix.ImportInsertHelper.needImport
|
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
|
import org.jetbrains.jet.plugin.quickfix.ImportInsertHelper
|
||||||
|
|
||||||
public class KotlinImportOptimizer() : ImportOptimizer {
|
public class KotlinImportOptimizer() : ImportOptimizer {
|
||||||
|
|
||||||
@@ -54,8 +54,8 @@ public class KotlinImportOptimizer() : ImportOptimizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isUseful(importPath, usedQualifiedNames)
|
if (isUseful(importPath, usedQualifiedNames)
|
||||||
&& needImport(importPath, jetFile, directivesBeforeCurrent)
|
&& ImportInsertHelper.getInstance().needImport(importPath, jetFile, directivesBeforeCurrent)
|
||||||
&& needImport(importPath, jetFile, directivesAfterCurrent)
|
&& ImportInsertHelper.getInstance().needImport(importPath, jetFile, directivesAfterCurrent)
|
||||||
) {
|
) {
|
||||||
directivesBeforeCurrent.add(anImport)
|
directivesBeforeCurrent.add(anImport)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ public class AutoImportFix(element: JetSimpleNameExpression) : JetHintAction<Jet
|
|||||||
result.addAll(getExtensions(referenceName, element, searchScope, resolveSession, file.getProject()))
|
result.addAll(getExtensions(referenceName, element, searchScope, resolveSession, file.getProject()))
|
||||||
|
|
||||||
return result
|
return result
|
||||||
.filter { ImportInsertHelper.needImport(ImportPath(it.fqName, false), file) }
|
.filter { ImportInsertHelper.getInstance().needImport(ImportPath(it.fqName, false), file) }
|
||||||
.sortBy { it.priority.ordinal() }
|
.sortBy { it.priority.ordinal() }
|
||||||
.map { it.fqName }
|
.map { it.fqName }
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-12
@@ -31,17 +31,15 @@ import java.util.List;
|
|||||||
|
|
||||||
import static org.jetbrains.jet.lang.psi.PsiPackage.JetPsiFactory;
|
import static org.jetbrains.jet.lang.psi.PsiPackage.JetPsiFactory;
|
||||||
|
|
||||||
public class ImportInsertHelper {
|
public class ImportInsertHelperImpl extends ImportInsertHelper {
|
||||||
private ImportInsertHelper() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add import directive into the PSI tree for the given package.
|
* Add import directive into the PSI tree for the given package.
|
||||||
*
|
*
|
||||||
* @param importFqn full name of the import
|
* @param importFqn full name of the import
|
||||||
* @param file File where directive should be added.
|
* @param file File where directive should be added.
|
||||||
*/
|
*/
|
||||||
public static void addImportDirectiveIfNeeded(@NotNull FqName importFqn, @NotNull JetFile file) {
|
@Override
|
||||||
|
public void addImportDirectiveIfNeeded(@NotNull FqName importFqn, @NotNull JetFile file) {
|
||||||
ImportPath importPath = new ImportPath(importFqn, false);
|
ImportPath importPath = new ImportPath(importFqn, false);
|
||||||
|
|
||||||
optimizeImportsOnTheFly(file);
|
optimizeImportsOnTheFly(file);
|
||||||
@@ -51,13 +49,14 @@ public class ImportInsertHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void optimizeImportsOnTheFly(JetFile file) {
|
@Override
|
||||||
|
public void optimizeImportsOnTheFly(JetFile file) {
|
||||||
if (CodeInsightSettings.getInstance().OPTIMIZE_IMPORTS_ON_THE_FLY) {
|
if (CodeInsightSettings.getInstance().OPTIMIZE_IMPORTS_ON_THE_FLY) {
|
||||||
new OptimizeImportsProcessor(file.getProject(), file).runWithoutProgress();
|
new OptimizeImportsProcessor(file.getProject(), file).runWithoutProgress();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeImportToFile(@NotNull ImportPath importPath, @NotNull JetFile file) {
|
public void writeImportToFile(@NotNull ImportPath importPath, @NotNull JetFile file) {
|
||||||
JetPsiFactory psiFactory = JetPsiFactory(file.getProject());
|
JetPsiFactory psiFactory = JetPsiFactory(file.getProject());
|
||||||
if (file instanceof JetCodeFragment) {
|
if (file instanceof JetCodeFragment) {
|
||||||
JetImportDirective newDirective = psiFactory.createImportDirective(importPath);
|
JetImportDirective newDirective = psiFactory.createImportDirective(importPath);
|
||||||
@@ -85,7 +84,7 @@ public class ImportInsertHelper {
|
|||||||
/**
|
/**
|
||||||
* Check that import is useless.
|
* Check that import is useless.
|
||||||
*/
|
*/
|
||||||
private static boolean isImportedByDefault(@NotNull ImportPath importPath, @NotNull JetFile jetFile) {
|
private boolean isImportedByDefault(@NotNull ImportPath importPath, @NotNull JetFile jetFile) {
|
||||||
if (importPath.fqnPart().isRoot()) {
|
if (importPath.fqnPart().isRoot()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -105,22 +104,26 @@ public class ImportInsertHelper {
|
|||||||
return isImportedWithDefault(importPath, jetFile);
|
return isImportedWithDefault(importPath, jetFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isImportedWithDefault(@NotNull ImportPath importPath, @NotNull JetFile contextFile) {
|
@Override
|
||||||
|
public boolean isImportedWithDefault(@NotNull ImportPath importPath, @NotNull JetFile contextFile) {
|
||||||
List<ImportPath> defaultImports = ProjectStructureUtil.isJsKotlinModule(contextFile)
|
List<ImportPath> defaultImports = ProjectStructureUtil.isJsKotlinModule(contextFile)
|
||||||
? TopDownAnalyzerFacadeForJS.DEFAULT_IMPORTS
|
? TopDownAnalyzerFacadeForJS.DEFAULT_IMPORTS
|
||||||
: TopDownAnalyzerFacadeForJVM.DEFAULT_IMPORTS;
|
: TopDownAnalyzerFacadeForJVM.DEFAULT_IMPORTS;
|
||||||
return NamePackage.isImported(importPath, defaultImports);
|
return NamePackage.isImported(importPath, defaultImports);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean needImport(@NotNull FqName fqName, @NotNull JetFile file) {
|
@Override
|
||||||
|
public boolean needImport(@NotNull FqName fqName, @NotNull JetFile file) {
|
||||||
return needImport(new ImportPath(fqName, false), file);
|
return needImport(new ImportPath(fqName, false), file);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean needImport(@NotNull ImportPath importPath, @NotNull JetFile file) {
|
@Override
|
||||||
|
public boolean needImport(@NotNull ImportPath importPath, @NotNull JetFile file) {
|
||||||
return needImport(importPath, file, file.getImportDirectives());
|
return needImport(importPath, file, file.getImportDirectives());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean needImport(@NotNull ImportPath importPath, @NotNull JetFile file, List<JetImportDirective> importDirectives) {
|
@Override
|
||||||
|
public boolean needImport(@NotNull ImportPath importPath, @NotNull JetFile file, List<JetImportDirective> importDirectives) {
|
||||||
if (isImportedByDefault(importPath, file)) {
|
if (isImportedByDefault(importPath, file)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -508,7 +508,7 @@ fun ExtractableCodeDescriptor.generateDeclaration(options: ExtractionGeneratorOp
|
|||||||
if (options.inTempFile) return ExtractionResult(declaration, Collections.emptyMap(), nameByOffset)
|
if (options.inTempFile) return ExtractionResult(declaration, Collections.emptyMap(), nameByOffset)
|
||||||
|
|
||||||
makeCall(this, declaration, controlFlow, extractionData.originalRange, parameters.map { it.argumentText })
|
makeCall(this, declaration, controlFlow, extractionData.originalRange, parameters.map { it.argumentText })
|
||||||
ShortenReferences.process(declaration)
|
ShortenReferences.process(declaration)
|
||||||
|
|
||||||
val duplicateReplacers = duplicates.map { it.range to { makeCall(this, declaration, it.controlFlow, it.range, it.arguments) } }.toMap()
|
val duplicateReplacers = duplicates.map { it.range to { makeCall(this, declaration, it.controlFlow, it.range, it.arguments) } }.toMap()
|
||||||
return ExtractionResult(declaration, duplicateReplacers, nameByOffset)
|
return ExtractionResult(declaration, duplicateReplacers, nameByOffset)
|
||||||
|
|||||||
@@ -74,33 +74,6 @@ import com.intellij.openapi.util.text.StringUtil
|
|||||||
import javax.swing.Icon
|
import javax.swing.Icon
|
||||||
import org.jetbrains.jet.plugin.util.string.collapseSpaces
|
import org.jetbrains.jet.plugin.util.string.collapseSpaces
|
||||||
|
|
||||||
/**
|
|
||||||
* Replace [[JetSimpleNameExpression]] (and its enclosing qualifier) with qualified element given by FqName
|
|
||||||
* Result is either the same as original element, or [[JetQualifiedExpression]], or [[JetUserType]]
|
|
||||||
* Note that FqName may not be empty
|
|
||||||
*/
|
|
||||||
fun JetSimpleNameExpression.changeQualifiedName(fqName: FqName): JetElement {
|
|
||||||
assert (!fqName.isRoot(), "Can't set empty FqName for element $this")
|
|
||||||
|
|
||||||
val shortName = fqName.shortName().asString()
|
|
||||||
val psiFactory = JetPsiFactory(this)
|
|
||||||
val fqNameBase = (getParent() as? JetCallExpression)?.let { parent ->
|
|
||||||
val callCopy = parent.copy() as JetCallExpression
|
|
||||||
callCopy.getCalleeExpression()!!.replace(psiFactory.createSimpleName(shortName)).getParent()!!.getText()
|
|
||||||
} ?: shortName
|
|
||||||
|
|
||||||
val text = if (!fqName.isOneSegmentFQN()) "${fqName.parent().asString()}.$fqNameBase" else fqNameBase
|
|
||||||
|
|
||||||
val elementToReplace = getQualifiedElement()
|
|
||||||
return when (elementToReplace) {
|
|
||||||
is JetUserType -> {
|
|
||||||
val typeText = "$text${elementToReplace.getTypeArgumentList()?.getText() ?: ""}"
|
|
||||||
elementToReplace.replace(psiFactory.createType(typeText).getTypeElement()!!)
|
|
||||||
}
|
|
||||||
else -> elementToReplace.replace(psiFactory.createExpression(text))
|
|
||||||
} as JetElement
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T: Any> PsiElement.getAndRemoveCopyableUserData(key: Key<T>): T? {
|
fun <T: Any> PsiElement.getAndRemoveCopyableUserData(key: Key<T>): T? {
|
||||||
val data = getCopyableUserData(key)
|
val data = getCopyableUserData(key)
|
||||||
putCopyableUserData(key, null)
|
putCopyableUserData(key, null)
|
||||||
@@ -124,23 +97,6 @@ public fun File.toPsiFile(project: Project): PsiFile? {
|
|||||||
return toVirtualFile()?.let { vfile -> PsiManager.getInstance(project).findFile(vfile) }
|
return toVirtualFile()?.let { vfile -> PsiManager.getInstance(project).findFile(vfile) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns FqName for given declaration (either Java or Kotlin)
|
|
||||||
*/
|
|
||||||
public fun PsiElement.getKotlinFqName(): FqName? {
|
|
||||||
val element = namedUnwrappedElement
|
|
||||||
return when (element) {
|
|
||||||
is PsiPackage -> FqName(element.getQualifiedName())
|
|
||||||
is PsiClass -> element.getQualifiedName()?.let { FqName(it) }
|
|
||||||
is PsiMember -> (element : PsiMember).getName()?.let { name ->
|
|
||||||
val prefix = element.getContainingClass()?.getQualifiedName()
|
|
||||||
FqName(if (prefix != null) "$prefix.$name" else name)
|
|
||||||
}
|
|
||||||
is JetNamedDeclaration -> element.getFqName()
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public fun PsiElement.getUsageContext(): PsiElement {
|
public fun PsiElement.getUsageContext(): PsiElement {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is JetElement -> PsiTreeUtil.getParentOfType(this, javaClass<JetNamedDeclaration>(), javaClass<JetFile>())!!
|
is JetElement -> PsiTreeUtil.getParentOfType(this, javaClass<JetNamedDeclaration>(), javaClass<JetFile>())!!
|
||||||
|
|||||||
+1
-1
@@ -36,7 +36,7 @@ import org.jetbrains.jet.plugin.refactoring.move.moveTopLevelDeclarations.MoveKo
|
|||||||
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil
|
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil
|
||||||
import org.jetbrains.jet.plugin.refactoring.move.moveTopLevelDeclarations.DeferredJetFileKotlinMoveTarget
|
import org.jetbrains.jet.plugin.refactoring.move.moveTopLevelDeclarations.DeferredJetFileKotlinMoveTarget
|
||||||
import org.jetbrains.jet.plugin.refactoring.move.moveTopLevelDeclarations.Mover
|
import org.jetbrains.jet.plugin.refactoring.move.moveTopLevelDeclarations.Mover
|
||||||
import org.jetbrains.jet.plugin.codeInsight.ensureElementsToShortenIsEmptyBeforeRefactoring
|
import org.jetbrains.jet.plugin.codeInsight.shorten.ensureElementsToShortenIsEmptyBeforeRefactoring
|
||||||
|
|
||||||
public class MoveKotlinFileHandler : MoveFileHandler() {
|
public class MoveKotlinFileHandler : MoveFileHandler() {
|
||||||
private var packageNameInfo: PackageNameInfo? = null
|
private var packageNameInfo: PackageNameInfo? = null
|
||||||
|
|||||||
+2
-3
@@ -38,7 +38,7 @@ import org.jetbrains.jet.lang.psi.psiUtil.getPackage
|
|||||||
import org.jetbrains.jet.lang.psi.JetFile
|
import org.jetbrains.jet.lang.psi.JetFile
|
||||||
import org.jetbrains.jet.plugin.refactoring.move.PackageNameInfo
|
import org.jetbrains.jet.plugin.refactoring.move.PackageNameInfo
|
||||||
import org.jetbrains.jet.plugin.refactoring.createKotlinFile
|
import org.jetbrains.jet.plugin.refactoring.createKotlinFile
|
||||||
import org.jetbrains.jet.plugin.codeInsight.addToShorteningWaitSet
|
import org.jetbrains.jet.plugin.codeInsight.shorten.addToShorteningWaitSet
|
||||||
import org.jetbrains.jet.plugin.refactoring.move.getFileNameAfterMove
|
import org.jetbrains.jet.plugin.refactoring.move.getFileNameAfterMove
|
||||||
import org.jetbrains.jet.lang.psi.JetNamedDeclaration
|
import org.jetbrains.jet.lang.psi.JetNamedDeclaration
|
||||||
import org.jetbrains.jet.asJava.toLightElements
|
import org.jetbrains.jet.asJava.toLightElements
|
||||||
@@ -64,7 +64,6 @@ import com.intellij.psi.PsiModifierListOwner
|
|||||||
import com.intellij.psi.PsiModifier
|
import com.intellij.psi.PsiModifier
|
||||||
import com.intellij.util.VisibilityUtil
|
import com.intellij.util.VisibilityUtil
|
||||||
import com.intellij.openapi.util.Ref
|
import com.intellij.openapi.util.Ref
|
||||||
import org.jetbrains.jet.plugin.refactoring.getKotlinFqName
|
|
||||||
import org.jetbrains.jet.plugin.search.projectScope
|
import org.jetbrains.jet.plugin.search.projectScope
|
||||||
import org.jetbrains.jet.plugin.refactoring.move.getInternalReferencesToUpdateOnPackageNameChange
|
import org.jetbrains.jet.plugin.refactoring.move.getInternalReferencesToUpdateOnPackageNameChange
|
||||||
import org.jetbrains.jet.plugin.refactoring.move.createMoveUsageInfo
|
import org.jetbrains.jet.plugin.refactoring.move.createMoveUsageInfo
|
||||||
@@ -72,7 +71,7 @@ import org.jetbrains.jet.plugin.refactoring.move.postProcessMoveUsages
|
|||||||
import org.jetbrains.jet.plugin.references.JetSimpleNameReference.ShorteningMode
|
import org.jetbrains.jet.plugin.references.JetSimpleNameReference.ShorteningMode
|
||||||
import org.jetbrains.jet.lang.psi.psiUtil.isAncestor
|
import org.jetbrains.jet.lang.psi.psiUtil.isAncestor
|
||||||
import org.jetbrains.jet.plugin.refactoring.move.MoveRenameUsageInfoForExtension
|
import org.jetbrains.jet.plugin.refactoring.move.MoveRenameUsageInfoForExtension
|
||||||
import org.jetbrains.jet.lang.psi.JetDeclaration
|
import org.jetbrains.jet.plugin.refactoring.fqName.getKotlinFqName
|
||||||
|
|
||||||
trait Mover: (originalElement: JetNamedDeclaration, targetFile: JetFile) -> JetNamedDeclaration {
|
trait Mover: (originalElement: JetNamedDeclaration, targetFile: JetFile) -> JetNamedDeclaration {
|
||||||
object Default: Mover {
|
object Default: Mover {
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ import org.jetbrains.jet.lang.psi.JetImportDirective
|
|||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import com.intellij.refactoring.util.NonCodeUsageInfo
|
import com.intellij.refactoring.util.NonCodeUsageInfo
|
||||||
import org.jetbrains.jet.plugin.quickfix.ImportInsertHelper
|
import org.jetbrains.jet.plugin.quickfix.ImportInsertHelper
|
||||||
import org.jetbrains.jet.plugin.refactoring.getKotlinFqName
|
import org.jetbrains.jet.plugin.refactoring.fqName.getKotlinFqName
|
||||||
import org.jetbrains.jet.lang.psi.JetThisExpression
|
import org.jetbrains.jet.lang.psi.JetThisExpression
|
||||||
import org.jetbrains.jet.plugin.references.JetSimpleNameReference.ShorteningMode
|
import org.jetbrains.jet.plugin.references.JetSimpleNameReference.ShorteningMode
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
@@ -186,7 +186,7 @@ fun postProcessMoveUsages(usages: List<UsageInfo>,
|
|||||||
is MoveRenameUsageInfoForExtension -> {
|
is MoveRenameUsageInfoForExtension -> {
|
||||||
val element = counterpart(usage.getReferencedElement()!!)
|
val element = counterpart(usage.getReferencedElement()!!)
|
||||||
val file = with(usage) { if (addImportToOriginalFile) originalFile else counterpart(originalFile) } as JetFile
|
val file = with(usage) { if (addImportToOriginalFile) originalFile else counterpart(originalFile) } as JetFile
|
||||||
ImportInsertHelper.addImportDirectiveIfNeeded(element.getKotlinFqName()!!, file)
|
ImportInsertHelper.getInstance().addImportDirectiveIfNeeded(element.getKotlinFqName()!!, file)
|
||||||
}
|
}
|
||||||
|
|
||||||
is MoveRenameUsageInfo -> {
|
is MoveRenameUsageInfo -> {
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ public abstract class AbstractCodeFragmentHighlightingTest : AbstractJetPsiCheck
|
|||||||
ApplicationManager.getApplication()?.runWriteAction {
|
ApplicationManager.getApplication()?.runWriteAction {
|
||||||
val fileText = FileUtil.loadFile(File(filePath), true)
|
val fileText = FileUtil.loadFile(File(filePath), true)
|
||||||
InTextDirectivesUtils.findListWithPrefixes(fileText, "// IMPORT: ").forEach {
|
InTextDirectivesUtils.findListWithPrefixes(fileText, "// IMPORT: ").forEach {
|
||||||
ImportInsertHelper.addImportDirectiveIfNeeded(FqName(it), (myFixture.getFile() as JetFile))
|
ImportInsertHelper.getInstance().addImportDirectiveIfNeeded(FqName(it), (myFixture.getFile() as JetFile))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class OptimizeImportsOnFlyTest extends LightDaemonAnalyzerTestCase {
|
|||||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
ImportInsertHelper.addImportDirectiveIfNeeded(new FqName("java.util.HashSet"), (JetFile) getFile());
|
ImportInsertHelper.getInstance().addImportDirectiveIfNeeded(new FqName("java.util.HashSet"), (JetFile) getFile());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public class ImportClassHelperTest extends LightDaemonAnalyzerTestCase {
|
|||||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
ImportInsertHelper.addImportDirectiveIfNeeded(new FqName("java.util.ArrayList"), (JetFile) getFile());
|
ImportInsertHelper.getInstance().addImportDirectiveIfNeeded(new FqName("java.util.ArrayList"), (JetFile) getFile());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ public class ImportClassHelperTest extends LightDaemonAnalyzerTestCase {
|
|||||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
ImportInsertHelper.addImportDirectiveIfNeeded(new FqName("java.util.ArrayList"), (JetFile) getFile());
|
ImportInsertHelper.getInstance().addImportDirectiveIfNeeded(new FqName("java.util.ArrayList"), (JetFile) getFile());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ public class ImportClassHelperTest extends LightDaemonAnalyzerTestCase {
|
|||||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
ImportInsertHelper.addImportDirectiveIfNeeded(new FqName(importString), (JetFile) getFile());
|
ImportInsertHelper.getInstance().addImportDirectiveIfNeeded(new FqName(importString), (JetFile) getFile());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
checkResultByFile(getTestName(false) + ".kt.after");
|
checkResultByFile(getTestName(false) + ".kt.after");
|
||||||
|
|||||||
Reference in New Issue
Block a user