Refactor: introduce JetReference, rename: JetPsiReference -> AbstractJetReference
Add resolveToDescriptors() to JetReference trait Rewrite JetPsiReference to kotlin
This commit is contained in:
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import jet.runtime.typeinfo.KotlinSignature;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
@@ -92,6 +93,7 @@ public interface BindingContext {
|
||||
WritableSlice<JetElement, ConstraintSystemCompleter> CONSTRAINT_SYSTEM_COMPLETER = new BasicWritableSlice<JetElement, ConstraintSystemCompleter>(DO_NOTHING);
|
||||
WritableSlice<JetElement, Call> CALL = new BasicWritableSlice<JetElement, Call>(DO_NOTHING);
|
||||
|
||||
@KotlinSignature("val AMBIGUOUS_REFERENCE_TARGET: WritableSlice<JetReferenceExpression, Collection<DeclarationDescriptor>>")
|
||||
WritableSlice<JetReferenceExpression, Collection<? extends DeclarationDescriptor>> AMBIGUOUS_REFERENCE_TARGET =
|
||||
new BasicWritableSlice<JetReferenceExpression, Collection<? extends DeclarationDescriptor>>(DO_NOTHING);
|
||||
|
||||
@@ -235,6 +237,7 @@ public interface BindingContext {
|
||||
.setFurtherLookupSlices(DECLARATIONS_TO_DESCRIPTORS).build();
|
||||
|
||||
WritableSlice<JetReferenceExpression, PsiElement> LABEL_TARGET = Slices.<JetReferenceExpression, PsiElement>sliceBuilder().build();
|
||||
@KotlinSignature("val AMBIGUOUS_LABEL_TARGET: WritableSlice<JetReferenceExpression, Collection<PsiElement>>")
|
||||
WritableSlice<JetReferenceExpression, Collection<? extends PsiElement>> AMBIGUOUS_LABEL_TARGET =
|
||||
Slices.<JetReferenceExpression, Collection<? extends PsiElement>>sliceBuilder().build();
|
||||
WritableSlice<ValueParameterDescriptor, PropertyDescriptor> VALUE_PARAMETER_AS_PROPERTY =
|
||||
|
||||
@@ -43,7 +43,7 @@ import com.intellij.psi.PsiClass
|
||||
|
||||
fun JetClassOrObject.toLightClass(): PsiClass? = LightClassUtil.getPsiClass(this)
|
||||
|
||||
fun JetDeclaration.toLightElements(): List<PsiElement> =
|
||||
public fun JetDeclaration.toLightElements(): List<PsiElement> =
|
||||
when (this) {
|
||||
is JetClassOrObject -> Collections.singletonList(LightClassUtil.getPsiClass(this))
|
||||
is JetNamedFunction -> Collections.singletonList(LightClassUtil.getLightClassMethod(this))
|
||||
@@ -59,7 +59,7 @@ fun JetDeclaration.toLightElements(): List<PsiElement> =
|
||||
else -> Collections.emptyList()
|
||||
}
|
||||
|
||||
fun PsiElement.toLightMethods(): List<PsiMethod> =
|
||||
public fun PsiElement.toLightMethods(): List<PsiMethod> =
|
||||
when (this) {
|
||||
is JetNamedFunction -> Collections.singletonList(LightClassUtil.getLightClassMethod(this))
|
||||
is JetProperty -> LightClassUtil.getLightClassPropertyMethods(this).toList()
|
||||
@@ -69,7 +69,7 @@ fun PsiElement.toLightMethods(): List<PsiMethod> =
|
||||
else -> Collections.emptyList()
|
||||
}
|
||||
|
||||
fun PsiElement.getRepresentativeLightMethod(): PsiMethod? =
|
||||
public fun PsiElement.getRepresentativeLightMethod(): PsiMethod? =
|
||||
when (this) {
|
||||
is JetNamedFunction -> LightClassUtil.getLightClassMethod(this)
|
||||
is JetProperty -> LightClassUtil.getLightClassPropertyMethods(this).getGetter()
|
||||
@@ -79,7 +79,7 @@ fun PsiElement.getRepresentativeLightMethod(): PsiMethod? =
|
||||
else -> null
|
||||
}
|
||||
|
||||
fun JetParameter.toPsiParameter(): PsiParameter? {
|
||||
public fun JetParameter.toPsiParameter(): PsiParameter? {
|
||||
val paramList = getParentByType(javaClass<JetParameterList>())
|
||||
if (paramList == null) return null
|
||||
|
||||
@@ -100,7 +100,7 @@ fun JetParameter.toPsiParameter(): PsiParameter? {
|
||||
return method.getParameterList().getParameters()[lightParamIndex]
|
||||
}
|
||||
|
||||
fun JetTypeParameter.toPsiTypeParameters(): List<PsiTypeParameter> {
|
||||
public fun JetTypeParameter.toPsiTypeParameters(): List<PsiTypeParameter> {
|
||||
val paramList = getParentByType(javaClass<JetTypeParameterList>())
|
||||
if (paramList == null) return Collections.emptyList()
|
||||
|
||||
@@ -112,8 +112,8 @@ fun JetTypeParameter.toPsiTypeParameters(): List<PsiTypeParameter> {
|
||||
}
|
||||
|
||||
// Returns original declaration if given PsiElement is a Kotlin light element, and element itself otherwise
|
||||
val PsiElement.unwrapped: PsiElement?
|
||||
public val PsiElement.unwrapped: PsiElement?
|
||||
get() = if (this is KotlinLightElement<*, *>) origin else this
|
||||
|
||||
val PsiElement.namedUnwrappedElement: PsiNamedElement?
|
||||
public val PsiElement.namedUnwrappedElement: PsiNamedElement?
|
||||
get() = unwrapped?.getParentByType(javaClass<PsiNamedElement>())
|
||||
+2
-2
@@ -38,7 +38,7 @@ import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.plugin.hierarchy.HierarchyUtils;
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||
import org.jetbrains.jet.plugin.references.JetPsiReference;
|
||||
import org.jetbrains.jet.plugin.references.JetReference;
|
||||
import org.jetbrains.jet.plugin.search.usagesSearch.UsagesSearchPackage;
|
||||
|
||||
import java.util.*;
|
||||
@@ -196,7 +196,7 @@ public abstract class KotlinCallerMethodsTreeStructure extends KotlinCallTreeStr
|
||||
@Override
|
||||
public boolean processInReadAction(PsiReference ref) {
|
||||
// copied from Java
|
||||
if (!(ref instanceof PsiReferenceExpression || ref instanceof JetPsiReference)) {
|
||||
if (!(ref instanceof PsiReferenceExpression || ref instanceof JetReference)) {
|
||||
if (!(ref instanceof PsiElement)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.plugin.project.ProjectStructureUtil;
|
||||
import org.jetbrains.jet.plugin.references.JetPsiReference;
|
||||
import org.jetbrains.jet.plugin.references.JetReference;
|
||||
import org.jetbrains.jet.util.QualifiedNamesUtil;
|
||||
import org.jetbrains.k2js.analyze.AnalyzerFacadeForJS;
|
||||
|
||||
@@ -50,7 +50,7 @@ public class ImportInsertHelper {
|
||||
|
||||
public static void addImportDirectiveOrChangeToFqName(@NotNull FqName importFqn, @NotNull JetFile file, int refOffset, @NotNull PsiElement targetElement) {
|
||||
PsiReference reference = file.findReferenceAt(refOffset);
|
||||
if (reference instanceof JetPsiReference) {
|
||||
if (reference instanceof JetReference) {
|
||||
PsiElement target = reference.resolve();
|
||||
if (target != null) {
|
||||
boolean same = file.getManager().areElementsEquivalent(target, targetElement);
|
||||
|
||||
+2
-2
@@ -30,7 +30,7 @@ import org.jetbrains.jet.lang.psi.*
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
|
||||
import org.jetbrains.jet.plugin.references.JetPsiReference
|
||||
import org.jetbrains.jet.plugin.references.JetReference
|
||||
import org.jetbrains.jet.lang.psi.psiUtil.getParentByType
|
||||
import org.jetbrains.jet.lang.psi.psiUtil.isAncestor
|
||||
import org.jetbrains.jet.lang.psi.psiUtil.parameterIndex
|
||||
@@ -39,7 +39,7 @@ public class KotlinJavaSafeDeleteDelegate : JavaSafeDeleteDelegate {
|
||||
override fun createUsageInfoForParameter(
|
||||
reference: PsiReference, usages: MutableList<UsageInfo>, parameter: PsiParameter, method: PsiMethod
|
||||
) {
|
||||
if (reference !is JetPsiReference) return
|
||||
if (reference !is JetReference) return
|
||||
|
||||
val element = reference.getElement() as JetElement
|
||||
|
||||
|
||||
+2
-2
@@ -41,7 +41,7 @@ import org.jetbrains.jet.lexer.JetTokens
|
||||
import org.jetbrains.jet.plugin.JetBundle
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
|
||||
import org.jetbrains.jet.plugin.refactoring.JetRefactoringUtil
|
||||
import org.jetbrains.jet.plugin.references.JetPsiReference
|
||||
import org.jetbrains.jet.plugin.references.JetReference
|
||||
import java.util.*
|
||||
import org.jetbrains.jet.lang.psi.psiUtil.getParentByType
|
||||
import org.jetbrains.jet.lang.psi.psiUtil.deleteElementAndCleanParent
|
||||
@@ -142,7 +142,7 @@ public class KotlinSafeDeleteProcessor : JavaSafeDeleteProcessor() {
|
||||
val parameterIndex = parameterList.indexOf(parameter)
|
||||
|
||||
for (reference in ReferencesSearch.search(owner)) {
|
||||
if (reference !is JetPsiReference) continue
|
||||
if (reference !is JetReference) continue
|
||||
|
||||
val referencedElement = reference.getElement()
|
||||
|
||||
|
||||
@@ -38,17 +38,14 @@ import java.util.List;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.INDEXED_LVALUE_GET;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.INDEXED_LVALUE_SET;
|
||||
|
||||
class JetArrayAccessReference extends JetPsiReference implements MultiRangeReference {
|
||||
private final JetArrayAccessExpression expression;
|
||||
class JetArrayAccessReference extends AbstractJetReference<JetArrayAccessExpression> implements MultiRangeReference {
|
||||
|
||||
public static PsiReference[] create(JetArrayAccessExpression expression) {
|
||||
JetContainerNode indicesNode = expression.getIndicesNode();
|
||||
return indicesNode == null ? PsiReference.EMPTY_ARRAY : new PsiReference[] { new JetArrayAccessReference(expression) };
|
||||
return new PsiReference[] { new JetArrayAccessReference(expression) };
|
||||
}
|
||||
|
||||
public JetArrayAccessReference(@NotNull JetArrayAccessExpression expression) {
|
||||
super(expression);
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,15 +55,15 @@ class JetArrayAccessReference extends JetPsiReference implements MultiRangeRefer
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected Collection<? extends DeclarationDescriptor> getTargetDescriptors(@NotNull BindingContext context) {
|
||||
protected Collection<DeclarationDescriptor> getTargetDescriptors(@NotNull BindingContext context) {
|
||||
List<DeclarationDescriptor> result = Lists.newArrayList();
|
||||
|
||||
ResolvedCall<FunctionDescriptor> getFunction = context.get(INDEXED_LVALUE_GET, expression);
|
||||
ResolvedCall<FunctionDescriptor> getFunction = context.get(INDEXED_LVALUE_GET, getExpression());
|
||||
if (getFunction != null) {
|
||||
result.add(getFunction.getResultingDescriptor());
|
||||
}
|
||||
|
||||
ResolvedCall<FunctionDescriptor> setFunction = context.get(INDEXED_LVALUE_SET, expression);
|
||||
ResolvedCall<FunctionDescriptor> setFunction = context.get(INDEXED_LVALUE_SET, getExpression());
|
||||
if (setFunction != null) {
|
||||
result.add(setFunction.getResultingDescriptor());
|
||||
}
|
||||
@@ -78,16 +75,16 @@ class JetArrayAccessReference extends JetPsiReference implements MultiRangeRefer
|
||||
public List<TextRange> getRanges() {
|
||||
List<TextRange> list = new ArrayList<TextRange>();
|
||||
|
||||
JetContainerNode indices = expression.getIndicesNode();
|
||||
JetContainerNode indices = getExpression().getIndicesNode();
|
||||
TextRange textRange = indices.getNode().findChildByType(JetTokens.LBRACKET).getTextRange();
|
||||
TextRange lBracketRange = textRange.shiftRight(-expression.getTextOffset());
|
||||
TextRange lBracketRange = textRange.shiftRight(-getExpression().getTextOffset());
|
||||
|
||||
list.add(lBracketRange);
|
||||
|
||||
ASTNode rBracket = indices.getNode().findChildByType(JetTokens.RBRACKET);
|
||||
if (rBracket != null) {
|
||||
textRange = rBracket.getTextRange();
|
||||
TextRange rBracketRange = textRange.shiftRight(-expression.getTextOffset());
|
||||
TextRange rBracketRange = textRange.shiftRight(-getExpression().getTextOffset());
|
||||
list.add(rBracketRange);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.RESOLVED_CALL;
|
||||
|
||||
class JetInvokeFunctionReference extends JetPsiReference implements MultiRangeReference {
|
||||
class JetInvokeFunctionReference extends AbstractJetReference<JetCallExpression> implements MultiRangeReference {
|
||||
|
||||
public static PsiReference[] create(@NotNull JetCallExpression expression) {
|
||||
return new PsiReference[] { new JetInvokeFunctionReference(expression) };
|
||||
@@ -54,22 +54,19 @@ class JetInvokeFunctionReference extends JetPsiReference implements MultiRangeRe
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected Collection<? extends DeclarationDescriptor> getTargetDescriptors(@NotNull BindingContext context) {
|
||||
JetExpression calleeExpression = ((JetCallExpression) myExpression).getCalleeExpression();
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = context.get(RESOLVED_CALL, calleeExpression);
|
||||
protected Collection<DeclarationDescriptor> getTargetDescriptors(@NotNull BindingContext context) {
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = context.get(RESOLVED_CALL, getExpression().getCalleeExpression());
|
||||
|
||||
if (resolvedCall instanceof VariableAsFunctionResolvedCall) {
|
||||
return Collections.singleton(((VariableAsFunctionResolvedCall) resolvedCall).getResultingDescriptor());
|
||||
return Collections.<DeclarationDescriptor>singleton(((VariableAsFunctionResolvedCall) resolvedCall).getResultingDescriptor());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TextRange> getRanges() {
|
||||
JetCallExpression callExpression = (JetCallExpression) myExpression;
|
||||
|
||||
List<TextRange> list = new ArrayList<TextRange>();
|
||||
JetValueArgumentList valueArgumentList = callExpression.getValueArgumentList();
|
||||
JetValueArgumentList valueArgumentList = getExpression().getValueArgumentList();
|
||||
if (valueArgumentList != null) {
|
||||
if (valueArgumentList.getArguments().size() > 0) {
|
||||
ASTNode valueArgumentListNode = valueArgumentList.getNode();
|
||||
@@ -88,7 +85,7 @@ class JetInvokeFunctionReference extends JetPsiReference implements MultiRangeRe
|
||||
}
|
||||
}
|
||||
|
||||
List<JetExpression> functionLiteralArguments = callExpression.getFunctionLiteralArguments();
|
||||
List<JetExpression> functionLiteralArguments = getExpression().getFunctionLiteralArguments();
|
||||
for (JetExpression functionLiteralArgument : functionLiteralArguments) {
|
||||
while (functionLiteralArgument instanceof JetPrefixExpression) {
|
||||
functionLiteralArgument = ((JetPrefixExpression) functionLiteralArgument).getBaseExpression();
|
||||
@@ -109,6 +106,6 @@ class JetInvokeFunctionReference extends JetPsiReference implements MultiRangeRe
|
||||
|
||||
private TextRange getRange(ASTNode node) {
|
||||
TextRange textRange = node.getTextRange();
|
||||
return textRange.shiftRight(-myExpression.getTextOffset());
|
||||
return textRange.shiftRight(-getExpression().getTextOffset());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2013 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.references;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.asJava.AsJavaPackage;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.jet.plugin.codeInsight.DescriptorToDeclarationUtil.findDeclarationsForDescriptorWithoutTrace;
|
||||
|
||||
public abstract class JetPsiReference implements PsiPolyVariantReference {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jet.plugin.references.JetPsiReference");
|
||||
|
||||
@NotNull
|
||||
protected final JetReferenceExpression myExpression;
|
||||
|
||||
protected JetPsiReference(@NotNull JetReferenceExpression expression) {
|
||||
this.myExpression = expression;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElement getElement() {
|
||||
return myExpression;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ResolveResult[] multiResolve(boolean incompleteCode) {
|
||||
return PsiElementResolveResult.createResults(resolveToPsiElements());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement resolve() {
|
||||
Collection<? extends PsiElement> psiElements = resolveToPsiElements();
|
||||
if (psiElements.size() == 1) {
|
||||
return psiElements.iterator().next();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getCanonicalText() {
|
||||
return "<TBD>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
|
||||
throw new IncorrectOperationException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
|
||||
throw new IncorrectOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReferenceTo(PsiElement element) {
|
||||
PsiElement resolvedElement = resolve();
|
||||
if (resolvedElement == null) return false;
|
||||
|
||||
PsiNamedElement namedDeclaration = AsJavaPackage.getNamedUnwrappedElement(element);
|
||||
PsiNamedElement namedResolvedDeclaration = AsJavaPackage.getNamedUnwrappedElement(resolvedElement);
|
||||
|
||||
return namedDeclaration != null && namedDeclaration.equals(namedResolvedDeclaration);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Object[] getVariants() {
|
||||
return EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSoft() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Collection<? extends PsiElement> resolveToPsiElements() {
|
||||
BindingContext context = AnalyzerFacadeWithCache.getContextForElement(myExpression);
|
||||
|
||||
return resolveToPsiElements(context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Collection<? extends PsiElement> resolveToPsiElements(@NotNull BindingContext context) {
|
||||
Collection<? extends DeclarationDescriptor> targetDescriptors = getTargetDescriptors(context);
|
||||
|
||||
if (targetDescriptors != null) {
|
||||
assert !(targetDescriptors.isEmpty()) : "targetDescriptors is not null, but empty, for " + myExpression.getText();
|
||||
Set<PsiElement> result = Sets.newHashSet();
|
||||
Project project = myExpression.getProject();
|
||||
for (DeclarationDescriptor target : targetDescriptors) {
|
||||
result.addAll(BindingContextUtils.descriptorToDeclarations(context, target));
|
||||
result.addAll(findDeclarationsForDescriptorWithoutTrace(project, target));
|
||||
|
||||
if (target instanceof PackageViewDescriptor) {
|
||||
JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
|
||||
String fqName = ((PackageViewDescriptor) target).getFqName().asString();
|
||||
ContainerUtil.addIfNotNull(result, psiFacade.findPackage(fqName));
|
||||
ContainerUtil.addIfNotNull(result, psiFacade.findClass(fqName, GlobalSearchScope.allScope(project)));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Collection<? extends PsiElement> labelTargets = getLabelTargets(context);
|
||||
if (labelTargets != null) {
|
||||
return labelTargets;
|
||||
}
|
||||
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected Collection<? extends DeclarationDescriptor> getTargetDescriptors(@NotNull BindingContext context) {
|
||||
DeclarationDescriptor targetDescriptor = context.get(BindingContext.REFERENCE_TARGET, myExpression);
|
||||
if (targetDescriptor != null) {
|
||||
return Collections.singleton(targetDescriptor);
|
||||
}
|
||||
return context.get(BindingContext.AMBIGUOUS_REFERENCE_TARGET, myExpression);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Collection<? extends PsiElement> getLabelTargets(@NotNull BindingContext context) {
|
||||
PsiElement labelTarget = context.get(BindingContext.LABEL_TARGET, myExpression);
|
||||
if (labelTarget != null) {
|
||||
return Collections.singleton(labelTarget);
|
||||
}
|
||||
return context.get(BindingContext.AMBIGUOUS_LABEL_TARGET, myExpression);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* 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.references
|
||||
|
||||
import com.intellij.psi.PsiPolyVariantReference
|
||||
import com.intellij.psi.PsiPolyVariantReferenceBase
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.ResolveResult
|
||||
import com.intellij.psi.PsiElementResolveResult
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import com.intellij.psi.PsiReference
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
|
||||
import java.util.Collections
|
||||
import java.util.HashSet
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils
|
||||
import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor
|
||||
import com.intellij.psi.JavaPsiFacade
|
||||
import org.jetbrains.jet.lang.psi.JetReferenceExpression
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.jet.plugin.codeInsight.DescriptorToDeclarationUtil
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.jet.asJava.*
|
||||
|
||||
public trait JetReference : PsiPolyVariantReference {
|
||||
public fun resolveToDescriptors(): Collection<DeclarationDescriptor>
|
||||
}
|
||||
|
||||
abstract class AbstractJetReference<T : JetReferenceExpression>(val expression: T)
|
||||
: PsiPolyVariantReferenceBase<T>(expression), JetReference {
|
||||
override fun multiResolve(incompleteCode: Boolean): Array<ResolveResult> {
|
||||
return PsiElementResolveResult.createResults(resolveToPsiElements())
|
||||
}
|
||||
|
||||
override fun resolve(): PsiElement? {
|
||||
val psiElements = resolveToPsiElements()
|
||||
if (psiElements.size() == 1) {
|
||||
return psiElements.iterator().next()
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getCanonicalText(): String = "<TBD>"
|
||||
|
||||
override fun handleElementRename(newElementName: String?): PsiElement? = throw IncorrectOperationException()
|
||||
|
||||
override fun bindToElement(element: PsiElement): PsiElement = throw IncorrectOperationException()
|
||||
|
||||
public override fun isReferenceTo(element: PsiElement?): Boolean {
|
||||
val resolvedElement = resolve()
|
||||
if (resolvedElement == null) {
|
||||
return false
|
||||
}
|
||||
return element?.namedUnwrappedElement == resolvedElement.namedUnwrappedElement
|
||||
}
|
||||
|
||||
[suppress("CAST_NEVER_SUCCEEDS")]
|
||||
override fun getVariants(): Array<Any> = PsiReference.EMPTY_ARRAY as Array<Any>
|
||||
|
||||
override fun isSoft(): Boolean = false
|
||||
|
||||
private fun resolveToPsiElements(): Collection<PsiElement> {
|
||||
val context = AnalyzerFacadeWithCache.getContextForElement(expression)
|
||||
return resolveToPsiElements(context, getTargetDescriptors(context))
|
||||
}
|
||||
|
||||
override fun resolveToDescriptors(): Collection<DeclarationDescriptor> {
|
||||
val context = AnalyzerFacadeWithCache.getContextForElement(expression)
|
||||
val targetDescriptors = getTargetDescriptors(context)
|
||||
return targetDescriptors ?: Collections.emptyList<DeclarationDescriptor>()
|
||||
}
|
||||
|
||||
private fun resolveToPsiElements(context: BindingContext, targetDescriptors: Collection<DeclarationDescriptor>?): Collection<PsiElement> {
|
||||
if (targetDescriptors != null) {
|
||||
assert(!(targetDescriptors.isEmpty())) { "targetDescriptors is not null, but empty, for " + expression.getText() }
|
||||
val result = HashSet<PsiElement>()
|
||||
val project = expression.getProject()
|
||||
for (target in targetDescriptors) {
|
||||
result.addAll(BindingContextUtils.descriptorToDeclarations(context, target))
|
||||
result.addAll(DescriptorToDeclarationUtil.findDeclarationsForDescriptorWithoutTrace(project, target))
|
||||
|
||||
if (target is PackageViewDescriptor) {
|
||||
val psiFacade = JavaPsiFacade.getInstance(project)
|
||||
val fqName = (target as PackageViewDescriptor).getFqName().asString()
|
||||
ContainerUtil.addIfNotNull(result, psiFacade.findPackage(fqName))
|
||||
ContainerUtil.addIfNotNull(result, psiFacade.findClass(fqName, GlobalSearchScope.allScope(project)))
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
val labelTargets = getLabelTargets(context)
|
||||
if (labelTargets != null) {
|
||||
return labelTargets
|
||||
}
|
||||
|
||||
return Collections.emptySet()
|
||||
}
|
||||
|
||||
protected open fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor>? {
|
||||
val targetDescriptor = context.get(BindingContext.REFERENCE_TARGET, expression)
|
||||
if (targetDescriptor != null) {
|
||||
return listOf(targetDescriptor)
|
||||
}
|
||||
return context.get(BindingContext.AMBIGUOUS_REFERENCE_TARGET, expression)
|
||||
}
|
||||
|
||||
private fun getLabelTargets(context: BindingContext): Collection<PsiElement>? {
|
||||
val labelTarget = context.get(BindingContext.LABEL_TARGET, expression)
|
||||
if (labelTarget != null) {
|
||||
return listOf(labelTarget)
|
||||
}
|
||||
return context.get(BindingContext.AMBIGUOUS_LABEL_TARGET, expression)
|
||||
}
|
||||
}
|
||||
@@ -26,19 +26,10 @@ import org.jetbrains.jet.lang.psi.JetPsiFactory;
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
public class JetSimpleNameReference extends JetPsiReference {
|
||||
|
||||
@NotNull
|
||||
private final JetSimpleNameExpression myExpression;
|
||||
public class JetSimpleNameReference extends AbstractJetReference<JetSimpleNameExpression> {
|
||||
|
||||
public JetSimpleNameReference(@NotNull JetSimpleNameExpression jetSimpleNameExpression) {
|
||||
super(jetSimpleNameExpression);
|
||||
myExpression = jetSimpleNameExpression;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetSimpleNameExpression getExpression() {
|
||||
return myExpression;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -49,8 +40,8 @@ public class JetSimpleNameReference extends JetPsiReference {
|
||||
|
||||
@Override
|
||||
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
|
||||
IElementType type = myExpression.getReferencedNameElementType();
|
||||
Project project = myExpression.getProject();
|
||||
IElementType type = getExpression().getReferencedNameElementType();
|
||||
Project project = getExpression().getProject();
|
||||
PsiElement element;
|
||||
if (JetTokens.FIELD_IDENTIFIER == type) {
|
||||
element = JetPsiFactory.createFieldIdentifier(project, newElementName);
|
||||
@@ -61,11 +52,11 @@ public class JetSimpleNameReference extends JetPsiReference {
|
||||
else {
|
||||
element = JetPsiFactory.createNameIdentifier(project, newElementName);
|
||||
}
|
||||
return myExpression.getReferencedNameElement().replace(element);
|
||||
return getExpression().getReferencedNameElement().replace(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return JetSimpleNameReference.class.getSimpleName() + ": " + myExpression.getText();
|
||||
return JetSimpleNameReference.class.getSimpleName() + ": " + getExpression().getText();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.jetbrains.jet.plugin.references;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import org.jetbrains.jet.lang.psi.JetThisReferenceExpression;
|
||||
|
||||
public class JetThisReference extends JetPsiReference {
|
||||
public class JetThisReference extends AbstractJetReference<JetThisReferenceExpression> {
|
||||
public JetThisReference(JetThisReferenceExpression expression) {
|
||||
super(expression);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
|
||||
import com.intellij.psi.PsiReference
|
||||
import org.jetbrains.jet.lang.resolve.java.jetAsJava.KotlinLightMethod
|
||||
import org.jetbrains.jet.lang.resolve.OverridingUtil
|
||||
import org.jetbrains.jet.plugin.references.JetPsiReference
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils
|
||||
|
||||
@@ -30,7 +30,7 @@ import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.plugin.JdkAndMockLibraryProjectDescriptor;
|
||||
import org.jetbrains.jet.plugin.references.JetPsiReference;
|
||||
import org.jetbrains.jet.plugin.references.JetReference;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -106,12 +106,12 @@ public class NavigateToLibrarySourceTest extends AbstractNavigateToLibraryTest {
|
||||
assertSameLines(expectedCode, actualCode);
|
||||
}
|
||||
|
||||
private Collection<JetPsiReference> collectInterestingReferences() {
|
||||
private Collection<JetReference> collectInterestingReferences() {
|
||||
PsiFile psiFile = myFixture.getFile();
|
||||
Map<PsiElement, JetPsiReference> referenceContainersToReferences = new LinkedHashMap<PsiElement, JetPsiReference>();
|
||||
Map<PsiElement, JetReference> referenceContainersToReferences = new LinkedHashMap<PsiElement, JetReference>();
|
||||
for (int offset = 0; offset < psiFile.getTextLength(); offset++) {
|
||||
PsiReference ref = psiFile.findReferenceAt(offset);
|
||||
if (ref instanceof JetPsiReference && !referenceContainersToReferences.containsKey(ref.getElement())) {
|
||||
if (ref instanceof JetReference && !referenceContainersToReferences.containsKey(ref.getElement())) {
|
||||
PsiElement target = ref.resolve();
|
||||
if (target == null) continue;
|
||||
PsiFile targetNavPsiFile = target.getNavigationElement().getContainingFile();
|
||||
@@ -119,7 +119,7 @@ public class NavigateToLibrarySourceTest extends AbstractNavigateToLibraryTest {
|
||||
VirtualFile targetNavFile = targetNavPsiFile.getVirtualFile();
|
||||
if (targetNavFile == null) continue;
|
||||
if (ProjectFileIndex.SERVICE.getInstance(getProject()).isInLibrarySource(targetNavFile)) {
|
||||
referenceContainersToReferences.put(ref.getElement(), (JetPsiReference)ref);
|
||||
referenceContainersToReferences.put(ref.getElement(), (JetReference)ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,7 +129,7 @@ public class NavigateToLibrarySourceTest extends AbstractNavigateToLibraryTest {
|
||||
private String getActualAnnotatedLibraryCode() {
|
||||
MultiMap<PsiFile, Pair<Integer, Integer>> filesToNumbersAndOffsets = new MultiMap<PsiFile, Pair<Integer, Integer>>();
|
||||
int refNumber = 1;
|
||||
for (JetPsiReference ref : collectInterestingReferences()) {
|
||||
for (JetReference ref : collectInterestingReferences()) {
|
||||
PsiElement target = ref.resolve();
|
||||
assertNotNull(target);
|
||||
PsiElement navigationElement = target.getNavigationElement();
|
||||
|
||||
@@ -104,7 +104,7 @@ public class BuiltInsReferenceResolverTest extends ResolveTestCase {
|
||||
}
|
||||
|
||||
private void doTest() throws Exception {
|
||||
JetPsiReference reference = (JetPsiReference) configureByFile(getTestName(true) + ".kt");
|
||||
JetReference reference = (JetReference) configureByFile(getTestName(true) + ".kt");
|
||||
PsiElement resolved = reference.resolve();
|
||||
assertNotNull(resolved);
|
||||
assertEquals(1, reference.multiResolve(false).length);
|
||||
|
||||
Reference in New Issue
Block a user