From 614810f8cd65710598dec6c5ffe8189a3ee1fb6b Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Fri, 15 Sep 2017 12:12:38 +0300 Subject: [PATCH] type casts in relevant method chain completion: various renames --- .../backwardRefs/CompilerReferenceReader.java | 10 +- .../CompilerReferenceServiceEx.java | 8 +- .../CompilerReferenceServiceImpl.java | 18 +-- .../compiler/chainsSearch/ChainSearcher.java | 93 ++++++++------- .../MethodChainLookupRangingHelper.java | 2 +- ...nces.java => MethodRefAndOccurrences.java} | 10 +- .../{CallChain.java => OperationChain.java} | 61 +++++----- .../chainsSearch/RefChainOperation.java | 25 ---- ...pleteSignature.kt => RefChainOperation.kt} | 107 +++++++++--------- .../chainsSearch/SearchInitializer.java | 28 ++--- .../compiler/chainsSearch/TypeCast.kt | 44 ------- .../MethodChainCompletionContributor.java | 6 +- .../context/ChainCompletionContext.java | 15 ++- 13 files changed, 184 insertions(+), 243 deletions(-) rename java/compiler/impl/src/com/intellij/compiler/chainsSearch/{SignatureAndOccurrences.java => MethodRefAndOccurrences.java} (76%) rename java/compiler/impl/src/com/intellij/compiler/chainsSearch/{CallChain.java => OperationChain.java} (76%) delete mode 100644 java/compiler/impl/src/com/intellij/compiler/chainsSearch/RefChainOperation.java rename java/compiler/impl/src/com/intellij/compiler/chainsSearch/{MethodIncompleteSignature.kt => RefChainOperation.kt} (52%) delete mode 100644 java/compiler/impl/src/com/intellij/compiler/chainsSearch/TypeCast.kt diff --git a/java/compiler/impl/src/com/intellij/compiler/backwardRefs/CompilerReferenceReader.java b/java/compiler/impl/src/com/intellij/compiler/backwardRefs/CompilerReferenceReader.java index 1b6d39d653d9..79650074d237 100644 --- a/java/compiler/impl/src/com/intellij/compiler/backwardRefs/CompilerReferenceReader.java +++ b/java/compiler/impl/src/com/intellij/compiler/backwardRefs/CompilerReferenceReader.java @@ -179,13 +179,13 @@ class CompilerReferenceReader { return myIndex; } - TObjectIntHashMap getTypeCastsInside(@NotNull LightRef.LightClassHierarchyElementDef toType, @NotNull TIntHashSet ids) throws StorageException { + TObjectIntHashMap getTypeCasts(@NotNull LightRef.LightClassHierarchyElementDef castType, @NotNull TIntHashSet fileIds) throws StorageException { TObjectIntHashMap typeCastStats = new TObjectIntHashMap<>(); - myIndex.get(CompilerIndices.BACK_CAST).getData(toType).forEach(new ValueContainer.ContainerAction>() { + myIndex.get(CompilerIndices.BACK_CAST).getData(castType).forEach(new ValueContainer.ContainerAction>() { @Override - public boolean perform(int id, Collection value) { - if (!ids.contains(id)) return true; - for (LightRef ref : value) { + public boolean perform(int id, Collection values) { + if (!fileIds.contains(id)) return true; + for (LightRef ref : values) { if (!typeCastStats.adjustValue(ref, 1)) { typeCastStats.put(ref, 1); } diff --git a/java/compiler/impl/src/com/intellij/compiler/backwardRefs/CompilerReferenceServiceEx.java b/java/compiler/impl/src/com/intellij/compiler/backwardRefs/CompilerReferenceServiceEx.java index 4cfc7c2173ee..b69e08d824e1 100644 --- a/java/compiler/impl/src/com/intellij/compiler/backwardRefs/CompilerReferenceServiceEx.java +++ b/java/compiler/impl/src/com/intellij/compiler/backwardRefs/CompilerReferenceServiceEx.java @@ -16,7 +16,8 @@ package com.intellij.compiler.backwardRefs; import com.intellij.compiler.CompilerReferenceService; -import com.intellij.compiler.chainsSearch.SignatureAndOccurrences; +import com.intellij.compiler.chainsSearch.MethodRefAndOccurrences; +import com.intellij.compiler.chainsSearch.context.ChainCompletionContext; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -34,8 +35,9 @@ public abstract class CompilerReferenceServiceEx extends CompilerReferenceServic } @NotNull - public abstract SortedSet findMethodReferenceOccurrences(@NotNull String rawReturnType, - @SignatureData.IteratorKind byte iteratorKind) + public abstract SortedSet findMethodReferenceOccurrences(@NotNull String rawReturnType, + @SignatureData.IteratorKind byte iteratorKind, + @NotNull ChainCompletionContext context) throws ReferenceIndexUnavailableException; @Nullable diff --git a/java/compiler/impl/src/com/intellij/compiler/backwardRefs/CompilerReferenceServiceImpl.java b/java/compiler/impl/src/com/intellij/compiler/backwardRefs/CompilerReferenceServiceImpl.java index e768b8cc5b49..16a6e7961459 100644 --- a/java/compiler/impl/src/com/intellij/compiler/backwardRefs/CompilerReferenceServiceImpl.java +++ b/java/compiler/impl/src/com/intellij/compiler/backwardRefs/CompilerReferenceServiceImpl.java @@ -20,8 +20,9 @@ import com.intellij.compiler.backwardRefs.view.CompilerReferenceFindUsagesTestIn import com.intellij.compiler.backwardRefs.view.CompilerReferenceHierarchyTestInfo; import com.intellij.compiler.backwardRefs.view.DirtyScopeTestInfo; import com.intellij.compiler.chainsSearch.ChainSearchMagicConstants; -import com.intellij.compiler.chainsSearch.MethodIncompleteSignature; -import com.intellij.compiler.chainsSearch.SignatureAndOccurrences; +import com.intellij.compiler.chainsSearch.MethodCall; +import com.intellij.compiler.chainsSearch.MethodRefAndOccurrences; +import com.intellij.compiler.chainsSearch.context.ChainCompletionContext; import com.intellij.compiler.server.BuildManager; import com.intellij.compiler.server.BuildManagerListener; import com.intellij.lang.injection.InjectedLanguageManager; @@ -222,8 +223,9 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceServiceEx imp @NotNull @Override - public SortedSet findMethodReferenceOccurrences(@NotNull String rawReturnType, - @SignatureData.IteratorKind byte iteratorKind) { + public SortedSet findMethodReferenceOccurrences(@NotNull String rawReturnType, + @SignatureData.IteratorKind byte iteratorKind, + @NotNull ChainCompletionContext context) { try { myReadDataLock.lock(); try { @@ -242,15 +244,15 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceServiceEx imp .distinct() .map(r -> { int count = myReader.getOccurrenceCount(r); - return count <= 1 ? null : new SignatureAndOccurrences( - new MethodIncompleteSignature((LightRef.JavaLightMethodRef)r, sd, this), + return count <= 1 ? null : new MethodRefAndOccurrences( + new MethodCall((LightRef.JavaLightMethodRef)r, sd, context), count); })) .filter(Objects::nonNull) .collect(Collectors.groupingBy(x -> x.getSignature(), Collectors.summarizingInt(x -> x.getOccurrenceCount()))) .entrySet() .stream() - .map(e -> new SignatureAndOccurrences(e.getKey(), (int)e.getValue().getSum())) + .map(e -> new MethodRefAndOccurrences(e.getKey(), (int)e.getValue().getSum())) .collect(Collectors.toCollection(TreeSet::new)); } finally { @@ -280,7 +282,7 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceServiceEx imp LightRef.LightClassHierarchyElementDef owner = method.getOwner(); - TObjectIntHashMap typeCasts = myReader.getTypeCastsInside(owner, ids); + TObjectIntHashMap typeCasts = myReader.getTypeCasts(owner, ids); LightRef[] best = {null}; int[] bestFileCount = {0}; diff --git a/java/compiler/impl/src/com/intellij/compiler/chainsSearch/ChainSearcher.java b/java/compiler/impl/src/com/intellij/compiler/chainsSearch/ChainSearcher.java index cb9c793b9667..9163bb2716d6 100644 --- a/java/compiler/impl/src/com/intellij/compiler/chainsSearch/ChainSearcher.java +++ b/java/compiler/impl/src/com/intellij/compiler/chainsSearch/ChainSearcher.java @@ -28,11 +28,11 @@ import java.util.*; public class ChainSearcher { @NotNull - public static List search(int pathMaximalLength, - ChainSearchTarget searchTarget, - int maxResultSize, - ChainCompletionContext context, - CompilerReferenceServiceEx compilerReferenceServiceEx) { + public static List search(int pathMaximalLength, + ChainSearchTarget searchTarget, + int maxResultSize, + ChainCompletionContext context, + CompilerReferenceServiceEx compilerReferenceServiceEx) { SearchInitializer initializer = createInitializer(searchTarget, compilerReferenceServiceEx, context); return search(compilerReferenceServiceEx, initializer, pathMaximalLength, maxResultSize, context); } @@ -41,54 +41,49 @@ public class ChainSearcher { private static SearchInitializer createInitializer(ChainSearchTarget target, CompilerReferenceServiceEx referenceServiceEx, ChainCompletionContext context) { - SortedSet methods = null; + SortedSet methods = Collections.emptySortedSet(); for (byte kind : target.getArrayKind()) { - SortedSet currentMethods = - referenceServiceEx.findMethodReferenceOccurrences(target.getClassQName(), kind); - if (methods == null) { - methods = currentMethods; - } else { - methods = unionSortedSet(currentMethods, methods); - } + SortedSet currentMethods = referenceServiceEx.findMethodReferenceOccurrences(target.getClassQName(), kind, context); + methods = methods == null ? currentMethods : unionSortedSet(currentMethods, methods); } return new SearchInitializer(methods, context); } @NotNull - private static List search(CompilerReferenceServiceEx referenceServiceEx, - SearchInitializer initializer, - int chainMaxLength, - int maxResultSize, - ChainCompletionContext context) { - LinkedList q = initializer.getChainQueue(); + private static List search(CompilerReferenceServiceEx referenceServiceEx, + SearchInitializer initializer, + int chainMaxLength, + int maxResultSize, + ChainCompletionContext context) { + LinkedList q = initializer.getChainQueue(); - List result = new ArrayList<>(); + List result = new ArrayList<>(); while (!q.isEmpty()) { ProgressManager.checkCanceled(); - CallChain currentChain = q.poll(); - RefChainOperation headSignature = currentChain.getHeadSignature(); + OperationChain currentChain = q.poll(); + RefChainOperation head = currentChain.getHead(); if (addChainIfTerminal(currentChain, result, chainMaxLength, context)) continue; // otherwise try to find chain continuation boolean updated = false; - SortedSet candidates = referenceServiceEx.findMethodReferenceOccurrences(headSignature.getOwner1(), SignatureData.ZERO_DIM); - LightRef ref1 = headSignature.getRef1(); - for (SignatureAndOccurrences candidate : candidates) { + SortedSet candidates = referenceServiceEx.findMethodReferenceOccurrences(head.getQualifierRawName(), SignatureData.ZERO_DIM, context); + LightRef ref = head.getLightRef(); + for (MethodRefAndOccurrences candidate : candidates) { if (candidate.getOccurrenceCount() * ChainSearchMagicConstants.FILTER_RATIO < currentChain.getChainWeight()) { break; } - MethodIncompleteSignature sign = candidate.getSignature(); - if ((sign.isStatic() || !sign.getOwner().equals(context.getTarget().getClassQName())) && - (!(ref1 instanceof LightRef.JavaLightMethodRef) || - referenceServiceEx - .mayHappen(candidate.getSignature().getRef(), ref1, ChainSearchMagicConstants.METHOD_PROBABILITY_THRESHOLD))) { + MethodCall sign = candidate.getSignature(); + if ((sign.isStatic() || !sign.getQualifierRawName().equals(context.getTarget().getClassQName())) && + (!(ref instanceof LightRef.JavaLightMethodRef) || + referenceServiceEx.mayHappen(candidate.getSignature().getLightRef(), ref, ChainSearchMagicConstants.METHOD_PROBABILITY_THRESHOLD))) { - CallChain continuation = currentChain.continuation(candidate.getSignature(), candidate.getOccurrenceCount(), context); + OperationChain + continuation = currentChain.continuationWithMethod(candidate.getSignature(), candidate.getOccurrenceCount(), context); if (continuation != null) { boolean stopChain = - candidate.getSignature().isStatic() || context.hasQualifier(context.resolvePsiClass(candidate.getSignature().getOwnerRef())); + candidate.getSignature().isStatic() || context.hasQualifier(context.resolvePsiClass(candidate.getSignature().getQualifierDef())); if (stopChain) { addChainIfNotPresent(continuation, result); } @@ -100,11 +95,12 @@ public class ChainSearcher { } } - if (ref1 instanceof LightRef.JavaLightMethodRef) { + if (ref instanceof LightRef.JavaLightMethodRef) { LightRef.LightClassHierarchyElementDef def = - referenceServiceEx.mayCallOfTypeCast((LightRef.JavaLightMethodRef)ref1, ChainSearchMagicConstants.METHOD_PROBABILITY_THRESHOLD); + referenceServiceEx.mayCallOfTypeCast((LightRef.JavaLightMethodRef)ref, ChainSearchMagicConstants.METHOD_PROBABILITY_THRESHOLD); if (def != null) { - CallChain continuation = currentChain.continuationWithCast(new TypeCast(def, ((MethodIncompleteSignature)headSignature).getOwnerRef(), referenceServiceEx, 0), context); + OperationChain + continuation = currentChain.continuationWithCast(new TypeCast(def, head.getQualifierDef(), referenceServiceEx), context); if (continuation != null) { q.addFirst(continuation); updated = true; @@ -126,17 +122,18 @@ public class ChainSearcher { /** * To reduce false-positives we add a method to result only if its qualifier can be occurred together with context variables. */ - private static void addChainIfQualifierCanBeOccurredInContext(CallChain currentChain, - List result, + private static void addChainIfQualifierCanBeOccurredInContext(OperationChain currentChain, + List result, ChainCompletionContext context, CompilerReferenceServiceEx referenceServiceEx) { - RefChainOperation signature = currentChain.getLastMethodSign(); + RefChainOperation signature = currentChain.getHeadMethodCall(); + // type cast + introduced qualifier: it's too complex chain if (currentChain.hasCast()) return; - if (!context.getTarget().getClassQName().equals(((MethodIncompleteSignature)signature).getOwner())) { + if (!context.getTarget().getClassQName().equals(signature.getQualifierRawName())) { Set references = context.getContextClassReferences(); boolean isRelevantQualifier = false; for (LightRef ref: references) { - if (referenceServiceEx.mayHappen(((MethodIncompleteSignature)signature).getOwnerRef(), ref, ChainSearchMagicConstants.VAR_PROBABILITY_THRESHOLD)) { + if (referenceServiceEx.mayHappen(signature.getQualifierDef(), ref, ChainSearchMagicConstants.VAR_PROBABILITY_THRESHOLD)) { isRelevantQualifier = true; break; } @@ -148,12 +145,12 @@ public class ChainSearcher { } } - private static boolean addChainIfTerminal(CallChain currentChain, List result, int pathMaximalLength, + private static boolean addChainIfTerminal(OperationChain currentChain, List result, int pathMaximalLength, ChainCompletionContext context) { - RefChainOperation signature = currentChain.getLastMethodSign(); - RefChainOperation head = currentChain.getHeadSignature(); - if (((MethodIncompleteSignature)signature).isStatic() || - context.hasQualifier(context.resolvePsiClass(head.getOwnerRef1())) || + RefChainOperation signature = currentChain.getHeadMethodCall(); + RefChainOperation head = currentChain.getHead(); + if (((MethodCall)signature).isStatic() || + context.hasQualifier(context.resolvePsiClass(head.getQualifierDef())) || currentChain.length() >= pathMaximalLength) { addChainIfNotPresent(currentChain, result); return true; @@ -161,7 +158,7 @@ public class ChainSearcher { return false; } - private static void addChainIfNotPresent(CallChain newChain, List result) { + private static void addChainIfNotPresent(OperationChain newChain, List result) { if (result.isEmpty()) { result.add(newChain); return; @@ -169,8 +166,8 @@ public class ChainSearcher { boolean doAdd = true; IntStack indicesToRemove = new IntStack(); for (int i = 0; i < result.size(); i++) { - CallChain chain = result.get(i); - CallChain.CompareResult r = CallChain.compare(chain, newChain); + OperationChain chain = result.get(i); + OperationChain.CompareResult r = OperationChain.compare(chain, newChain); switch (r) { case LEFT_CONTAINS_RIGHT: indicesToRemove.push(i); diff --git a/java/compiler/impl/src/com/intellij/compiler/chainsSearch/MethodChainLookupRangingHelper.java b/java/compiler/impl/src/com/intellij/compiler/chainsSearch/MethodChainLookupRangingHelper.java index a23e3246b0f3..256e8c16ca40 100644 --- a/java/compiler/impl/src/com/intellij/compiler/chainsSearch/MethodChainLookupRangingHelper.java +++ b/java/compiler/impl/src/com/intellij/compiler/chainsSearch/MethodChainLookupRangingHelper.java @@ -41,7 +41,7 @@ import java.util.stream.Collectors; public class MethodChainLookupRangingHelper { @NotNull - public static LookupElement toLookupElement(CallChain chain, + public static LookupElement toLookupElement(OperationChain chain, ChainCompletionContext context) { int unreachableParametersCount = 0; int matchedParametersInContext = 0; diff --git a/java/compiler/impl/src/com/intellij/compiler/chainsSearch/SignatureAndOccurrences.java b/java/compiler/impl/src/com/intellij/compiler/chainsSearch/MethodRefAndOccurrences.java similarity index 76% rename from java/compiler/impl/src/com/intellij/compiler/chainsSearch/SignatureAndOccurrences.java rename to java/compiler/impl/src/com/intellij/compiler/chainsSearch/MethodRefAndOccurrences.java index 69e15ef02ee1..239503978f39 100644 --- a/java/compiler/impl/src/com/intellij/compiler/chainsSearch/SignatureAndOccurrences.java +++ b/java/compiler/impl/src/com/intellij/compiler/chainsSearch/MethodRefAndOccurrences.java @@ -17,16 +17,16 @@ package com.intellij.compiler.chainsSearch; import org.jetbrains.annotations.NotNull; -public class SignatureAndOccurrences implements Comparable { - private final MethodIncompleteSignature mySignature; +public class MethodRefAndOccurrences implements Comparable { + private final MethodCall mySignature; private final int myOccurrences; - public SignatureAndOccurrences(final MethodIncompleteSignature signature, final int occurrences) { + public MethodRefAndOccurrences(final MethodCall signature, final int occurrences) { mySignature = signature; myOccurrences = occurrences; } - public MethodIncompleteSignature getSignature() { + public MethodCall getSignature() { return mySignature; } @@ -35,7 +35,7 @@ public class SignatureAndOccurrences implements Comparable op instanceof ChainOperation.TypeCast); } - public MethodIncompleteSignature getLastMethodSign() { - return myLastMethodSign; + @NotNull + public MethodCall getHeadMethodCall() { + return myHeadMethodCall; } @NotNull - public RefChainOperation getHeadSignature() { - return mySignature; + public RefChainOperation getHead() { + return myHeadOperation; } public int length() { @@ -107,28 +108,30 @@ public class CallChain { return myWeight; } - public CallChain continuation(@NotNull MethodIncompleteSignature signature, - int weight, - @NotNull ChainCompletionContext context) { - CallChain head = create(signature, weight, context); + @Nullable + OperationChain continuationWithMethod(@NotNull MethodCall signature, + int weight, + @NotNull ChainCompletionContext context) { + OperationChain head = create(signature, weight, context); if (head == null) return null; ChainOperation[] newReverseOperations = new ChainOperation[length() + 1]; System.arraycopy(myReverseOperations, 0, newReverseOperations, 0, myReverseOperations.length); newReverseOperations[length()] = head.getPath()[0]; - return new CallChain(head.getQualifierClass(), newReverseOperations, head.getHeadSignature(), signature, Math.min(weight, getChainWeight())); + return new OperationChain(head.getQualifierClass(), newReverseOperations, head.getHead(), signature, Math.min(weight, getChainWeight())); } - public CallChain continuationWithCast(@NotNull TypeCast cast, - @NotNull ChainCompletionContext context) { - PsiClass operand = context.resolvePsiClass(cast.getOperandRef()); + @Nullable + OperationChain continuationWithCast(@NotNull TypeCast cast, + @NotNull ChainCompletionContext context) { + PsiClass operand = context.resolvePsiClass(cast.getLightRef()); PsiClass castType = context.resolvePsiClass(cast.getCastTypeRef()); if (operand == null || castType == null) return null; ChainOperation[] newReverseOperations = new ChainOperation[length() + 1]; System.arraycopy(myReverseOperations, 0, newReverseOperations, 0, myReverseOperations.length); newReverseOperations[length()] = new ChainOperation.TypeCast(operand, castType); - return new CallChain(operand, newReverseOperations, cast, myLastMethodSign, getChainWeight()); + return new OperationChain(operand, newReverseOperations, cast, myHeadMethodCall, getChainWeight()); } @Override @@ -138,7 +141,7 @@ public class CallChain { } @SuppressWarnings("ConstantConditions") - public static CompareResult compare(@NotNull CallChain left, @NotNull CallChain right) { + public static CompareResult compare(@NotNull OperationChain left, @NotNull OperationChain right) { if (left.length() == 0 || right.length() == 0) { throw new IllegalStateException("chains can't be empty"); } diff --git a/java/compiler/impl/src/com/intellij/compiler/chainsSearch/RefChainOperation.java b/java/compiler/impl/src/com/intellij/compiler/chainsSearch/RefChainOperation.java deleted file mode 100644 index 2f9b381b9f77..000000000000 --- a/java/compiler/impl/src/com/intellij/compiler/chainsSearch/RefChainOperation.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2000-2017 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 com.intellij.compiler.chainsSearch; - -import org.jetbrains.jps.backwardRefs.LightRef; - -public interface RefChainOperation { - String getOwner1(); - LightRef.LightClassHierarchyElementDef getOwnerRef1(); - - LightRef getRef1(); -} diff --git a/java/compiler/impl/src/com/intellij/compiler/chainsSearch/MethodIncompleteSignature.kt b/java/compiler/impl/src/com/intellij/compiler/chainsSearch/RefChainOperation.kt similarity index 52% rename from java/compiler/impl/src/com/intellij/compiler/chainsSearch/MethodIncompleteSignature.kt rename to java/compiler/impl/src/com/intellij/compiler/chainsSearch/RefChainOperation.kt index 14762a99f1ef..b12ace2190a6 100644 --- a/java/compiler/impl/src/com/intellij/compiler/chainsSearch/MethodIncompleteSignature.kt +++ b/java/compiler/impl/src/com/intellij/compiler/chainsSearch/RefChainOperation.kt @@ -16,73 +16,74 @@ package com.intellij.compiler.chainsSearch import com.intellij.compiler.backwardRefs.CompilerReferenceServiceEx +import com.intellij.compiler.chainsSearch.context.ChainCompletionContext import com.intellij.compiler.chainsSearch.context.ChainSearchTarget -import com.intellij.openapi.project.Project -import com.intellij.psi.* -import com.intellij.psi.search.GlobalSearchScope +import com.intellij.psi.PsiArrayType +import com.intellij.psi.PsiClassType +import com.intellij.psi.PsiMethod +import com.intellij.psi.PsiModifier import com.intellij.psi.util.PsiUtil import org.jetbrains.jps.backwardRefs.LightRef import org.jetbrains.jps.backwardRefs.SignatureData -import java.util.function.Predicate -class MethodIncompleteSignature(val ref: LightRef.JavaLightMethodRef, - private val signatureData: SignatureData, - private val refService: CompilerReferenceServiceEx): RefChainOperation { - override fun getOwnerRef1(): LightRef.LightClassHierarchyElementDef { - return ownerRef +sealed class RefChainOperation { + abstract val qualifierRawName: String + + abstract val qualifierDef: LightRef.LightClassHierarchyElementDef + + abstract val lightRef: LightRef +} + +class TypeCast(override val lightRef: LightRef.LightClassHierarchyElementDef, + val castTypeRef: LightRef.LightClassHierarchyElementDef, + refService: CompilerReferenceServiceEx): RefChainOperation() { + override val qualifierRawName + get() = operandName.value + override val qualifierDef + get() = lightRef + + private val operandName = lazy(LazyThreadSafetyMode.NONE) { + refService.getName(lightRef.name) } +} - override fun getOwner1(): String { - return owner - } +class MethodCall(override val lightRef: LightRef.JavaLightMethodRef, + private val signatureData: SignatureData, + private val context: ChainCompletionContext): RefChainOperation() { - override fun getRef1(): LightRef { - return ref - } - - companion object { + private companion object { val CONSTRUCTOR_METHOD_NAME = "" } - val name: String by lazy(LazyThreadSafetyMode.NONE) { - refService.getName(ref.name) + override val qualifierRawName: String + get() = owner.value + override val qualifierDef: LightRef.LightClassHierarchyElementDef + get() = lightRef.owner + + private val name = lazy(LazyThreadSafetyMode.NONE) { + context.refService.getName(lightRef.name) } - val ownerRef = ref.owner - - val owner: String by lazy(LazyThreadSafetyMode.NONE) { - refService.getName(ref.owner.name) + private val owner = lazy(LazyThreadSafetyMode.NONE) { + context.refService.getName(lightRef.owner.name) } - private val rawReturnType: String by lazy(LazyThreadSafetyMode.NONE) { - refService.getName(signatureData.rawReturnType) + private val rawReturnType = lazy(LazyThreadSafetyMode.NONE) { + context.refService.getName(signatureData.rawReturnType) } - private val parameterCount: Int - get() = ref.parameterCount - val isStatic: Boolean get() = signatureData.isStatic - //TODO remove - fun resolveQualifier(project: Project, - resolveScope: GlobalSearchScope, - accessValidator: Predicate): PsiClass? { - val clazz = JavaPsiFacade.getInstance(project).findClass(owner, resolveScope) - return if (clazz != null && accessValidator.test(clazz)) clazz else null - } - - fun resolve(project: Project, - resolveScope: GlobalSearchScope, - accessValidator: Predicate): Array { - if (CONSTRUCTOR_METHOD_NAME == name) { + fun resolve(): Array { + if (CONSTRUCTOR_METHOD_NAME == name.value) { return PsiMethod.EMPTY_ARRAY } - val aClass = resolveQualifier(project, resolveScope, accessValidator) ?: return PsiMethod.EMPTY_ARRAY - return aClass.findMethodsByName(name, true) + val aClass = context.resolvePsiClass(qualifierDef) ?: return PsiMethod.EMPTY_ARRAY + return aClass.findMethodsByName(name.value, true) .filter { it.hasModifierProperty(PsiModifier.STATIC) == isStatic } .filter { !it.isDeprecated } - .filter { accessValidator.test(it) } + .filter { context.accessValidator().test(it) } .filter { val returnType = it.returnType when (signatureData.iteratorKind) { @@ -90,7 +91,7 @@ class MethodIncompleteSignature(val ref: LightRef.JavaLightMethodRef, when (returnType) { is PsiArrayType -> { val componentType = returnType.componentType - componentType is PsiClassType && componentType.resolve()?.qualifiedName == rawReturnType + componentType is PsiClassType && componentType.resolve()?.qualifiedName == rawReturnType.value } else -> false } @@ -98,11 +99,11 @@ class MethodIncompleteSignature(val ref: LightRef.JavaLightMethodRef, SignatureData.ITERATOR_ONE_DIM -> { val iteratorKind = ChainSearchTarget.getIteratorKind(PsiUtil.resolveClassInClassTypeOnly(returnType)) when { - iteratorKind != null -> PsiUtil.resolveClassInClassTypeOnly(PsiUtil.substituteTypeParameter(returnType, iteratorKind, 0, false))?.qualifiedName == rawReturnType + iteratorKind != null -> PsiUtil.resolveClassInClassTypeOnly(PsiUtil.substituteTypeParameter(returnType, iteratorKind, 0, false))?.qualifiedName == rawReturnType.value else -> false } } - SignatureData.ZERO_DIM -> returnType is PsiClassType && returnType.resolve()?.qualifiedName == rawReturnType + SignatureData.ZERO_DIM -> returnType is PsiClassType && returnType.resolve()?.qualifiedName == rawReturnType.value else -> throw IllegalStateException("kind is unsupported ${signatureData.iteratorKind}") } } @@ -114,23 +115,23 @@ class MethodIncompleteSignature(val ref: LightRef.JavaLightMethodRef, if (this === other) return true if (other?.javaClass != javaClass) return false - other as MethodIncompleteSignature + other as MethodCall - if (ref.owner != other.ref.owner) return false - if (ref.name != other.ref.name) return false + if (lightRef.owner != other.lightRef.owner) return false + if (lightRef.name != other.lightRef.name) return false if (signatureData != other.signatureData) return false return true } override fun hashCode(): Int { - var result = ref.owner.hashCode() - result = 31 * result + ref.name.hashCode() + var result = lightRef.owner.hashCode() + result = 31 * result + lightRef.name.hashCode() result = 31 * result + signatureData.hashCode() return result } override fun toString(): String { - return owner + (if (isStatic) "" else "#") + name + "(" + parameterCount + ")" + return qualifierRawName + (if (isStatic) "." else "#") + name + "(" + lightRef.parameterCount + ")" } -} \ No newline at end of file +} diff --git a/java/compiler/impl/src/com/intellij/compiler/chainsSearch/SearchInitializer.java b/java/compiler/impl/src/com/intellij/compiler/chainsSearch/SearchInitializer.java index 8c074b7f5c5f..0dd1efe69859 100644 --- a/java/compiler/impl/src/com/intellij/compiler/chainsSearch/SearchInitializer.java +++ b/java/compiler/impl/src/com/intellij/compiler/chainsSearch/SearchInitializer.java @@ -21,39 +21,39 @@ import java.util.*; public class SearchInitializer { private final ChainCompletionContext myContext; - private final LinkedList myQueue; - private final LinkedHashMap myChains; + private final LinkedList myQueue; + private final LinkedHashMap myChains; - public SearchInitializer(SortedSet indexValues, + public SearchInitializer(SortedSet indexValues, ChainCompletionContext context) { myContext = context; int size = indexValues.size(); - List chains = new ArrayList<>(size); + List chains = new ArrayList<>(size); populateFrequentlyUsedMethod(indexValues, chains); myQueue = new LinkedList<>(); myChains = new LinkedHashMap<>(chains.size()); - for (CallChain chain : chains) { - MethodIncompleteSignature signature = (MethodIncompleteSignature)chain.getHeadSignature(); + for (OperationChain chain : chains) { + MethodCall signature = (MethodCall)chain.getHead(); myQueue.add(chain); myChains.put(signature, chain); } } - public LinkedList getChainQueue() { + public LinkedList getChainQueue() { return myQueue; } - public LinkedHashMap getChains() { + public LinkedHashMap getChains() { return myChains; } - private void populateFrequentlyUsedMethod(SortedSet signatures, - List chains) { + private void populateFrequentlyUsedMethod(SortedSet signatures, + List chains) { int bestOccurrences = -1; - for (SignatureAndOccurrences indexValue : signatures) { - CallChain callChain = CallChain.create(indexValue.getSignature(), indexValue.getOccurrenceCount(), myContext); - if (callChain != null) { - chains.add(callChain); + for (MethodRefAndOccurrences indexValue : signatures) { + OperationChain operationChain = OperationChain.create(indexValue.getSignature(), indexValue.getOccurrenceCount(), myContext); + if (operationChain != null) { + chains.add(operationChain); int occurrences = indexValue.getOccurrenceCount(); if (bestOccurrences == -1) { bestOccurrences = occurrences; diff --git a/java/compiler/impl/src/com/intellij/compiler/chainsSearch/TypeCast.kt b/java/compiler/impl/src/com/intellij/compiler/chainsSearch/TypeCast.kt deleted file mode 100644 index 9fa09601eeae..000000000000 --- a/java/compiler/impl/src/com/intellij/compiler/chainsSearch/TypeCast.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2000-2017 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 com.intellij.compiler.chainsSearch - -import com.intellij.compiler.backwardRefs.CompilerReferenceServiceEx -import org.jetbrains.jps.backwardRefs.LightRef - -class TypeCast(val operandRef: LightRef.LightClassHierarchyElementDef, - val castTypeRef: LightRef.LightClassHierarchyElementDef, - refService: CompilerReferenceServiceEx, - val occurrences: Int): RefChainOperation { - override fun getOwnerRef1(): LightRef.LightClassHierarchyElementDef { - return operandRef - } - - override fun getOwner1(): String { - return operandName - } - - override fun getRef1(): LightRef { - return operandRef - } - - val operandName: String by lazy(LazyThreadSafetyMode.NONE) { - refService.getName(operandRef.name) - } - - val castTypeName: String by lazy(LazyThreadSafetyMode.NONE) { - refService.getName(castTypeRef.name) - } -} diff --git a/java/compiler/impl/src/com/intellij/compiler/chainsSearch/completion/MethodChainCompletionContributor.java b/java/compiler/impl/src/com/intellij/compiler/chainsSearch/completion/MethodChainCompletionContributor.java index 95a4631cc877..6dcc2f11fb54 100644 --- a/java/compiler/impl/src/com/intellij/compiler/chainsSearch/completion/MethodChainCompletionContributor.java +++ b/java/compiler/impl/src/com/intellij/compiler/chainsSearch/completion/MethodChainCompletionContributor.java @@ -22,7 +22,7 @@ import com.intellij.compiler.backwardRefs.CompilerReferenceServiceEx; import com.intellij.compiler.backwardRefs.ReferenceIndexUnavailableException; import com.intellij.compiler.chainsSearch.ChainSearchMagicConstants; import com.intellij.compiler.chainsSearch.ChainSearcher; -import com.intellij.compiler.chainsSearch.CallChain; +import com.intellij.compiler.chainsSearch.OperationChain; import com.intellij.compiler.chainsSearch.MethodChainLookupRangingHelper; import com.intellij.compiler.chainsSearch.context.ChainCompletionContext; import com.intellij.compiler.chainsSearch.context.ChainSearchTarget; @@ -92,13 +92,13 @@ public class MethodChainCompletionContributor extends CompletionContributor { private static List searchForLookups(ChainCompletionContext context) { CompilerReferenceServiceEx methodsUsageIndexReader = (CompilerReferenceServiceEx)CompilerReferenceService.getInstance(context.getProject()); ChainSearchTarget target = context.getTarget(); - List searchResult = + List searchResult = ChainSearcher.search(ChainSearchMagicConstants.MAX_CHAIN_SIZE, target, ChainSearchMagicConstants.MAX_SEARCH_RESULT_SIZE, context, methodsUsageIndexReader); - int maxWeight = searchResult.stream().mapToInt(CallChain::getChainWeight).max().orElse(0); + int maxWeight = searchResult.stream().mapToInt(OperationChain::getChainWeight).max().orElse(0); return searchResult .stream() diff --git a/java/compiler/impl/src/com/intellij/compiler/chainsSearch/context/ChainCompletionContext.java b/java/compiler/impl/src/com/intellij/compiler/chainsSearch/context/ChainCompletionContext.java index b480da460e2d..b67bcdfcb083 100644 --- a/java/compiler/impl/src/com/intellij/compiler/chainsSearch/context/ChainCompletionContext.java +++ b/java/compiler/impl/src/com/intellij/compiler/chainsSearch/context/ChainCompletionContext.java @@ -17,7 +17,7 @@ package com.intellij.compiler.chainsSearch.context; import com.intellij.compiler.CompilerReferenceService; import com.intellij.compiler.backwardRefs.CompilerReferenceServiceEx; -import com.intellij.compiler.chainsSearch.MethodIncompleteSignature; +import com.intellij.compiler.chainsSearch.MethodCall; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.NotNullLazyValue; @@ -68,7 +68,7 @@ public class ChainCompletionContext { @NotNull private final TIntObjectHashMap myQualifierClassResolver; @NotNull - private final Map myResolver; + private final Map myResolver; @NotNull private final CompilerReferenceServiceEx myRefServiceEx; @@ -98,7 +98,7 @@ public class ChainCompletionContext { myProject = context.getProject(); myResolveHelper = PsiResolveHelper.SERVICE.getInstance(myProject); myQualifierClassResolver = new TIntObjectHashMap<>(); - myResolver = FactoryMap.createMap(sign -> sign.resolve(myProject, myResolveScope, accessValidator())); + myResolver = FactoryMap.createMap(sign -> sign.resolve()); myRefServiceEx = (CompilerReferenceServiceEx)CompilerReferenceService.getInstance(myProject); } @@ -119,6 +119,11 @@ public class ChainCompletionContext { return false; } + @NotNull + public CompilerReferenceServiceEx getRefService() { + return myRefServiceEx; + } + @NotNull public PsiElement getContextPsi() { return myContext; @@ -182,11 +187,11 @@ public class ChainCompletionContext { } @NotNull - public PsiMethod[] resolve(MethodIncompleteSignature sign) { + public PsiMethod[] resolve(MethodCall sign) { return myResolver.get(sign); } - private Predicate accessValidator() { + public Predicate accessValidator() { return m -> myResolveHelper.isAccessible(m, myContext, null); }