More correct operator treatment

This commit is contained in:
Valentin Kipyatkov
2016-09-02 14:50:04 +03:00
parent 43f8fbea2b
commit 322df5b348
8 changed files with 20 additions and 39 deletions
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.types.expressions; package org.jetbrains.kotlin.types.expressions;
import com.google.common.collect.ImmutableBiMap; import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -56,16 +55,6 @@ public class OperatorConventions {
.put(KtTokens.EXCL, NOT) .put(KtTokens.EXCL, NOT)
.build(); .build();
public static final ImmutableMap<Name, KtSingleValueToken> UNARY_OPERATION_NAMES_WITH_DEPRECATED_INVERTED = ImmutableMap.<Name, KtSingleValueToken>builder()
.put(INC, KtTokens.PLUSPLUS)
.put(DEC, KtTokens.MINUSMINUS)
.put(UNARY_PLUS, KtTokens.PLUS)
.put(PLUS, KtTokens.PLUS)
.put(UNARY_MINUS, KtTokens.MINUS)
.put(MINUS, KtTokens.MINUS)
.put(NOT, KtTokens.EXCL)
.build();
public static final ImmutableBiMap<KtSingleValueToken, Name> BINARY_OPERATION_NAMES = ImmutableBiMap.<KtSingleValueToken, Name>builder() public static final ImmutableBiMap<KtSingleValueToken, Name> BINARY_OPERATION_NAMES = ImmutableBiMap.<KtSingleValueToken, Name>builder()
.put(KtTokens.MUL, TIMES) .put(KtTokens.MUL, TIMES)
.put(KtTokens.PLUS, PLUS) .put(KtTokens.PLUS, PLUS)
@@ -82,7 +82,7 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
val specialSymbols = runReadAction { unwrappedElement.getSpecialNamesToSearch(kotlinOptions) } val specialSymbols = runReadAction { unwrappedElement.getSpecialNamesToSearch(kotlinOptions) }
val words = runReadAction { val words = runReadAction {
val classNameForCompanionObject = unwrappedElement.getClassNameForCompanionObject() val classNameForCompanionObject = unwrappedElement.getClassNameForCompanionObject()
specialSymbols.first + (specialSymbols?.first ?: emptyList()) +
(if (classNameForCompanionObject != null) listOf(classNameForCompanionObject) else emptyList()) (if (classNameForCompanionObject != null) listOf(classNameForCompanionObject) else emptyList())
} }
@@ -93,7 +93,7 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
val refFilter: (PsiReference) -> Boolean = when { val refFilter: (PsiReference) -> Boolean = when {
unwrappedElement is KtParameter -> ({ ref: PsiReference -> !ref.isNamedArgumentReference()/* they are processed later*/ }) unwrappedElement is KtParameter -> ({ ref: PsiReference -> !ref.isNamedArgumentReference()/* they are processed later*/ })
specialSymbols.second != null -> { ref -> ref.javaClass == specialSymbols.second } specialSymbols != null -> { ref -> ref.javaClass == specialSymbols.second }
else -> ({true}) else -> ({true})
} }
@@ -28,8 +28,10 @@ import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.util.Processor import com.intellij.util.Processor
import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.asJava.classes.KtLightClass import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.asJava.toLightClass import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
@@ -44,7 +46,9 @@ import org.jetbrains.kotlin.idea.search.restrictToKotlinSources
import org.jetbrains.kotlin.idea.util.FuzzyType import org.jetbrains.kotlin.idea.util.FuzzyType
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
import org.jetbrains.kotlin.kdoc.psi.impl.KDocName import org.jetbrains.kotlin.kdoc.psi.impl.KDocName
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
@@ -584,13 +588,12 @@ class ExpressionsOfTypeProcessor(
} }
private fun PsiElement.isOperatorExpensiveToSearch(): Boolean { private fun PsiElement.isOperatorExpensiveToSearch(): Boolean {
return false //TODO
/*
when (this) { when (this) {
is KtFunction -> { is KtFunction -> {
if (name?.startsWith("component") == true || name == OperatorNameConventions.INVOKE.asString()) return false val isOperator = hasModifier(KtTokens.OPERATOR_KEYWORD)
return hasModifier(KtTokens.OPERATOR_KEYWORD) || hasModifier(KtTokens.OVERRIDE_KEYWORD) && (resolveToDescriptorIfAny() as? FunctionDescriptor)?.isOperator == true
|| hasModifier(KtTokens.OVERRIDE_KEYWORD) && (resolveToDescriptorIfAny() as? FunctionDescriptor)?.isOperator == true val name = name
return isOperator && name != null && Name.isValidIdentifier(name) && Name.identifier(name).getOperationSymbolsToSearch() != null
} }
is KtLightMethod -> { is KtLightMethod -> {
@@ -601,7 +604,6 @@ class ExpressionsOfTypeProcessor(
return false return false
} }
} }
*/
} }
private fun KotlinType.containsTypeOrDerivedInside(type: FuzzyType): Boolean { private fun KotlinType.containsTypeOrDerivedInside(type: FuzzyType): Boolean {
@@ -48,7 +48,7 @@ val IN_OPERATIONS_TO_SEARCH = setOf(KtTokens.IN_KEYWORD)
val COMPARISON_OPERATIONS_TO_SEARCH = setOf(KtTokens.LT, KtTokens.GT) val COMPARISON_OPERATIONS_TO_SEARCH = setOf(KtTokens.LT, KtTokens.GT)
fun Name.getOperationSymbolsToSearch(): Pair<Set<KtToken>, Class<*>?> { fun Name.getOperationSymbolsToSearch(): Pair<Set<KtToken>, Class<*>>? {
when (this) { when (this) {
OperatorNameConventions.COMPARE_TO -> return COMPARISON_OPERATIONS_TO_SEARCH to KtSimpleNameReference::class.java OperatorNameConventions.COMPARE_TO -> return COMPARISON_OPERATIONS_TO_SEARCH to KtSimpleNameReference::class.java
OperatorNameConventions.EQUALS -> return EQUALS_OPERATIONS to KtSimpleNameReference::class.java OperatorNameConventions.EQUALS -> return EQUALS_OPERATIONS to KtSimpleNameReference::class.java
@@ -59,19 +59,11 @@ fun Name.getOperationSymbolsToSearch(): Pair<Set<KtToken>, Class<*>?> {
DelegatedPropertyResolver.PROPERTY_DELEGATED_FUNCTION_NAME -> return setOf(KtTokens.BY_KEYWORD) to KtPropertyDelegationMethodsReference::class.java DelegatedPropertyResolver.PROPERTY_DELEGATED_FUNCTION_NAME -> return setOf(KtTokens.BY_KEYWORD) to KtPropertyDelegationMethodsReference::class.java
} }
val unaryOp = UNARY_OPERATION_NAMES_WITH_DEPRECATED_INVERTED[this] val unaryOp = UNARY_OPERATION_NAMES.inverse()[this]
if (unaryOp != null) return setOf(unaryOp) to KtSimpleNameReference::class.java if (unaryOp != null) return setOf(unaryOp) to KtSimpleNameReference::class.java
/*
val binaryOp = BINARY_OPERATION_NAMES.inverse()[this]
if (binaryOp != null) {
val assignmentOp = ASSIGNMENT_OPERATION_COUNTERPARTS.inverse()[binaryOp]
return (if (assignmentOp != null) setOf(binaryOp, assignmentOp) else setOf(binaryOp)) to KtSimpleNameReference::class.java
}
*/
val assignmentOp = ASSIGNMENT_OPERATIONS.inverse()[this] val assignmentOp = ASSIGNMENT_OPERATIONS.inverse()[this]
if (assignmentOp != null) return setOf(assignmentOp) to KtSimpleNameReference::class.java if (assignmentOp != null) return setOf(assignmentOp) to KtSimpleNameReference::class.java
return emptySet<KtToken>() to null return null
} }
@@ -63,14 +63,14 @@ fun PsiNamedElement.getClassNameForCompanionObject(): String? {
} }
} }
fun PsiNamedElement.getSpecialNamesToSearch(options: KotlinReferencesSearchOptions): Pair<List<String>, Class<*>?> { fun PsiNamedElement.getSpecialNamesToSearch(options: KotlinReferencesSearchOptions): Pair<List<String>, Class<*>>? {
val name = name val name = name
return when { when {
name == null || !Name.isValidIdentifier(name) -> Collections.emptyList<String>() to null name == null || !Name.isValidIdentifier(name) -> return null
else -> { else -> {
val operationSymbolsToSearch = Name.identifier(name).getOperationSymbolsToSearch() val operationSymbolsToSearch = Name.identifier(name).getOperationSymbolsToSearch() ?: return null
operationSymbolsToSearch.first.map { (it as KtSingleValueToken).value } to operationSymbolsToSearch.second return operationSymbolsToSearch.first.map { (it as KtSingleValueToken).value } to operationSymbolsToSearch.second
} }
} }
} }
@@ -41,9 +41,8 @@ class KotlinConventionMethodReferencesSearcher() : QueryExecutorBase<PsiReferenc
operatorSearcher.run() operatorSearcher.run()
} }
else { else {
val operationSymbolsToSearch = identifier.getOperationSymbolsToSearch() val operationSymbolsToSearch = identifier.getOperationSymbolsToSearch() ?: return
val wordsToSearch = operationSymbolsToSearch.first.map { (it as KtSingleValueToken).value } val wordsToSearch = operationSymbolsToSearch.first.map { (it as KtSingleValueToken).value }
if (wordsToSearch.isEmpty()) return
val resultProcessor = KotlinRequestResultProcessor(method, val resultProcessor = KotlinRequestResultProcessor(method,
filter = { ref -> ref.javaClass == operationSymbolsToSearch.second }) filter = { ref -> ref.javaClass == operationSymbolsToSearch.second })
-1
View File
@@ -7,7 +7,6 @@ Resolved A(0) + A(1) + 2
Resolved A(0) + A(1) + 2 Resolved A(0) + A(1) + 2
Resolved A(0) + A(1) + 2 Resolved A(0) + A(1) + 2
Resolved A(0) + A(1) + 2 Resolved A(0) + A(1) + 2
Resolved A(0) + A(1) + 2
Resolved a += 1 Resolved a += 1
Resolved a += 1 Resolved a += 1
Resolved a += A(1) Resolved a += A(1)
@@ -199,7 +199,7 @@ public enum PrimitiveUnaryOperationFIF implements FunctionIntrinsicFactory {
jsOperator = JsUnaryOperator.BIT_NOT; jsOperator = JsUnaryOperator.BIT_NOT;
} }
else { else {
KtToken jetToken = OperatorConventions.UNARY_OPERATION_NAMES_WITH_DEPRECATED_INVERTED.get(name); KtToken jetToken = OperatorConventions.UNARY_OPERATION_NAMES.inverse().get(name);
jsOperator = OperatorTable.getUnaryOperator(jetToken); jsOperator = OperatorTable.getUnaryOperator(jetToken);
} }