Refactor: unite two hierarchies or reference, use common code across all references
Jet*Reference#getTargetDescriptors() no longer returns nullable value (convention is dropped) Use ResolvedCall#getCandidateDescriptor() instead of ResolvedCall#getResultingDescriptor() because unsubstituted descriptors are expected Add JetReference#resolveMap() function
This commit is contained in:
@@ -1,78 +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.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiPolyVariantReference;
|
||||
import com.intellij.psi.ResolveResult;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
|
||||
public abstract class AbstractPolyVariantJetReference<T extends JetElement> implements PsiPolyVariantReference {
|
||||
protected final T element;
|
||||
|
||||
public AbstractPolyVariantJetReference(@NotNull T element) {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiElement resolve() {
|
||||
ResolveResult[] results = multiResolve(false);
|
||||
if (results.length == 1) return results[0].getElement();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
|
||||
throw new IncorrectOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
|
||||
throw new IncorrectOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReferenceTo(PsiElement element) {
|
||||
if (element == null) return false;
|
||||
|
||||
ResolveResult[] results = multiResolve(false);
|
||||
for (ResolveResult result : results) {
|
||||
if (element.equals(result.getElement())) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Object[] getVariants() {
|
||||
return EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSoft() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -20,9 +20,7 @@ import com.google.common.collect.Lists;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.MultiRangeReference;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetArrayAccessExpression;
|
||||
@@ -38,11 +36,7 @@ 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 AbstractJetReference<JetArrayAccessExpression> implements MultiRangeReference {
|
||||
|
||||
public static PsiReference[] create(JetArrayAccessExpression expression) {
|
||||
return new PsiReference[] { new JetArrayAccessReference(expression) };
|
||||
}
|
||||
class JetArrayAccessReference extends JetSimpleReference<JetArrayAccessExpression> implements MultiRangeReference {
|
||||
|
||||
public JetArrayAccessReference(@NotNull JetArrayAccessExpression expression) {
|
||||
super(expression);
|
||||
@@ -53,19 +47,19 @@ class JetArrayAccessReference extends AbstractJetReference<JetArrayAccessExpress
|
||||
return getElement().getTextRange().shiftRight(-getElement().getTextOffset());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
@NotNull
|
||||
protected Collection<DeclarationDescriptor> getTargetDescriptors(@NotNull BindingContext context) {
|
||||
List<DeclarationDescriptor> result = Lists.newArrayList();
|
||||
|
||||
ResolvedCall<FunctionDescriptor> getFunction = context.get(INDEXED_LVALUE_GET, getExpression());
|
||||
if (getFunction != null) {
|
||||
result.add(getFunction.getResultingDescriptor());
|
||||
result.add(getFunction.getCandidateDescriptor());
|
||||
}
|
||||
|
||||
ResolvedCall<FunctionDescriptor> setFunction = context.get(INDEXED_LVALUE_SET, getExpression());
|
||||
if (setFunction != null) {
|
||||
result.add(setFunction.getResultingDescriptor());
|
||||
result.add(setFunction.getCandidateDescriptor());
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -1,88 +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.Lists;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.ResolveResult;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetForExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||
import org.jetbrains.jet.util.slicedmap.WritableSlice;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class JetForLoopInReference extends AbstractPolyVariantJetReference<JetForExpression> {
|
||||
|
||||
public static PsiReference[] create(@NotNull JetForExpression delegate) {
|
||||
return new PsiReference[] { new JetForLoopInReference(delegate) };
|
||||
}
|
||||
|
||||
private JetForLoopInReference(@NotNull JetForExpression element) {
|
||||
super(element);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ResolveResult[] multiResolve(boolean incompleteCode) {
|
||||
BindingContext context = AnalyzerFacadeWithCache.getContextForElement(element);
|
||||
|
||||
JetExpression loopRange = element.getLoopRange();
|
||||
if (loopRange == null) return ResolveResult.EMPTY_ARRAY;
|
||||
|
||||
List<ResolveResult> results = Lists.newArrayList();
|
||||
|
||||
addResultsForKey(context, results, loopRange, BindingContext.LOOP_RANGE_ITERATOR_RESOLVED_CALL);
|
||||
addResultsForKey(context, results, loopRange, BindingContext.LOOP_RANGE_NEXT_RESOLVED_CALL);
|
||||
addResultsForKey(context, results, loopRange, BindingContext.LOOP_RANGE_HAS_NEXT_RESOLVED_CALL);
|
||||
|
||||
return results.toArray(new ResolveResult[results.size()]);
|
||||
}
|
||||
|
||||
private void addResultsForKey(
|
||||
BindingContext context,
|
||||
List<ResolveResult> results,
|
||||
JetExpression loopRange,
|
||||
WritableSlice<JetExpression, ResolvedCall<FunctionDescriptor>> key
|
||||
) {
|
||||
ResolvedCall<FunctionDescriptor> resolvedCall = context.get(key, loopRange);
|
||||
if (resolvedCall == null) return;
|
||||
|
||||
JetReferenceUtil.findPsiElements(element.getProject(), context, results, resolvedCall.getResultingDescriptor());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextRange getRangeInElement() {
|
||||
ASTNode inKeywordNode = element.getInKeywordNode();
|
||||
if (inKeywordNode == null) return TextRange.EMPTY_RANGE;
|
||||
|
||||
int offset = inKeywordNode.getPsi().getStartOffsetInParent();
|
||||
return new TextRange(offset, offset + inKeywordNode.getTextLength());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getCanonicalText() {
|
||||
return "<unknown>";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.openapi.util.TextRange
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.jet.lang.psi.JetForExpression
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import java.util.Collections
|
||||
|
||||
public class JetForLoopInReference(element: JetForExpression) : JetMultiReference<JetForExpression>(element) {
|
||||
|
||||
override fun getRangeInElement(): TextRange {
|
||||
val inKeywordNode = expression.getInKeywordNode()
|
||||
if (inKeywordNode == null)
|
||||
return TextRange.EMPTY_RANGE
|
||||
|
||||
val offset = inKeywordNode.getPsi()!!.getStartOffsetInParent()
|
||||
return TextRange(offset, offset + inKeywordNode.getTextLength())
|
||||
}
|
||||
|
||||
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||
val loopRange = expression.getLoopRange()
|
||||
if (loopRange == null) {
|
||||
return Collections.emptyList()
|
||||
}
|
||||
return LOOP_RANGE_KEYS.map { key -> context.get(key, loopRange)?.getCandidateDescriptor() }.filterNotNull()
|
||||
}
|
||||
|
||||
class object {
|
||||
private val LOOP_RANGE_KEYS = array(
|
||||
BindingContext.LOOP_RANGE_ITERATOR_RESOLVED_CALL,
|
||||
BindingContext.LOOP_RANGE_NEXT_RESOLVED_CALL,
|
||||
BindingContext.LOOP_RANGE_HAS_NEXT_RESOLVED_CALL
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -19,9 +19,7 @@ package org.jetbrains.jet.plugin.references;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.MultiRangeReference;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
@@ -37,11 +35,7 @@ import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.RESOLVED_CALL;
|
||||
|
||||
class JetInvokeFunctionReference extends AbstractJetReference<JetCallExpression> implements MultiRangeReference {
|
||||
|
||||
public static PsiReference[] create(@NotNull JetCallExpression expression) {
|
||||
return new PsiReference[] { new JetInvokeFunctionReference(expression) };
|
||||
}
|
||||
class JetInvokeFunctionReference extends JetSimpleReference<JetCallExpression> implements MultiRangeReference {
|
||||
|
||||
public JetInvokeFunctionReference(@NotNull JetCallExpression expression) {
|
||||
super(expression);
|
||||
@@ -52,15 +46,14 @@ class JetInvokeFunctionReference extends AbstractJetReference<JetCallExpression>
|
||||
return getElement().getTextRange().shiftRight(-getElement().getTextOffset());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
@NotNull
|
||||
protected Collection<DeclarationDescriptor> getTargetDescriptors(@NotNull BindingContext context) {
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = context.get(RESOLVED_CALL, getExpression().getCalleeExpression());
|
||||
|
||||
if (resolvedCall instanceof VariableAsFunctionResolvedCall) {
|
||||
return Collections.<DeclarationDescriptor>singleton(((VariableAsFunctionResolvedCall) resolvedCall).getResultingDescriptor());
|
||||
return Collections.<DeclarationDescriptor>singleton(((VariableAsFunctionResolvedCall) resolvedCall).getCandidateDescriptor());
|
||||
}
|
||||
return null;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
-100
@@ -1,100 +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.Lists;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.ResolveResult;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetProperty;
|
||||
import org.jetbrains.jet.lang.psi.JetPropertyDelegate;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class JetPropertyDelegationMethodsReference extends AbstractPolyVariantJetReference<JetPropertyDelegate> {
|
||||
|
||||
public static PsiReference[] create(@NotNull JetPropertyDelegate delegate) {
|
||||
return new PsiReference[] { new JetPropertyDelegationMethodsReference(delegate) };
|
||||
}
|
||||
|
||||
public JetPropertyDelegationMethodsReference(@NotNull JetPropertyDelegate element) {
|
||||
super(element);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ResolveResult[] multiResolve(boolean incompleteCode) {
|
||||
JetProperty property = PsiTreeUtil.getParentOfType(element, JetProperty.class);
|
||||
if (property == null) {
|
||||
return ResolveResult.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
BindingContext context = AnalyzerFacadeWithCache.getContextForElement(element);
|
||||
|
||||
DeclarationDescriptor descriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, property);
|
||||
if (!(descriptor instanceof PropertyDescriptor)) {
|
||||
return ResolveResult.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
List<ResolveResult> results = Lists.newArrayList();
|
||||
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
||||
addResultsForAccessor(property.getProject(), context, results, propertyDescriptor.getGetter());
|
||||
addResultsForAccessor(property.getProject(), context, results, propertyDescriptor.getSetter());
|
||||
|
||||
return results.toArray(new ResolveResult[results.size()]);
|
||||
}
|
||||
|
||||
private static void addResultsForAccessor(
|
||||
Project project,
|
||||
BindingContext context,
|
||||
List<ResolveResult> results,
|
||||
@Nullable PropertyAccessorDescriptor accessor
|
||||
) {
|
||||
if (accessor == null) return;
|
||||
|
||||
ResolvedCall<FunctionDescriptor> resolvedCall = context.get(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, accessor);
|
||||
if (resolvedCall == null) return;
|
||||
|
||||
JetReferenceUtil.findPsiElements(project, context, results, resolvedCall.getResultingDescriptor());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextRange getRangeInElement() {
|
||||
ASTNode byKeywordNode = element.getByKeywordNode();
|
||||
int offset = byKeywordNode.getPsi().getStartOffsetInParent();
|
||||
return new TextRange(offset, offset + byKeywordNode.getTextLength());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getCanonicalText() {
|
||||
return "<unknown>";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.openapi.util.TextRange
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.jet.lang.psi.JetProperty
|
||||
import org.jetbrains.jet.lang.psi.JetPropertyDelegate
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import java.util.Collections
|
||||
|
||||
public class JetPropertyDelegationMethodsReference(element: JetPropertyDelegate) : JetMultiReference<JetPropertyDelegate>(element) {
|
||||
|
||||
override fun getRangeInElement(): TextRange {
|
||||
val byKeywordNode = expression.getByKeywordNode()
|
||||
val offset = byKeywordNode.getPsi()!!.getStartOffsetInParent()
|
||||
return TextRange(offset, offset + byKeywordNode.getTextLength())
|
||||
}
|
||||
|
||||
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||
val property = PsiTreeUtil.getParentOfType(expression, javaClass<JetProperty>())
|
||||
if (property == null) {
|
||||
return Collections.emptyList()
|
||||
}
|
||||
val descriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, property)
|
||||
if (descriptor !is PropertyDescriptor) {
|
||||
return Collections.emptyList()
|
||||
}
|
||||
return descriptor.getAccessors().map {
|
||||
accessor ->
|
||||
val candidateDescriptor = context.get(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, accessor)?.getCandidateDescriptor()
|
||||
//TODO: should not getOriginal here, because candidate descriptor should not have substituted type parameters
|
||||
// remove after problem is solved
|
||||
candidateDescriptor?.getOriginal()
|
||||
}.filterNotNull()
|
||||
}
|
||||
}
|
||||
@@ -36,13 +36,20 @@ import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.jet.plugin.codeInsight.DescriptorToDeclarationUtil
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.jet.asJava.*
|
||||
import org.jetbrains.jet.lang.psi.JetElement
|
||||
import org.jetbrains.jet.utils.keysToMap
|
||||
|
||||
public trait JetReference : PsiPolyVariantReference {
|
||||
public fun resolveToDescriptors(): Collection<DeclarationDescriptor>
|
||||
public fun resolveMap(): Map<DeclarationDescriptor, Collection<PsiElement>>
|
||||
}
|
||||
|
||||
abstract class AbstractJetReference<T : JetReferenceExpression>(val expression: T)
|
||||
: PsiPolyVariantReferenceBase<T>(expression), JetReference {
|
||||
abstract class AbstractJetReference<T : JetElement>(element: T)
|
||||
: PsiPolyVariantReferenceBase<T>(element), JetReference {
|
||||
|
||||
val expression: T
|
||||
get() = getElement()!!
|
||||
|
||||
override fun multiResolve(incompleteCode: Boolean): Array<ResolveResult> {
|
||||
return PsiElementResolveResult.createResults(resolveToPsiElements())
|
||||
}
|
||||
@@ -61,13 +68,7 @@ abstract class AbstractJetReference<T : JetReferenceExpression>(val expression:
|
||||
|
||||
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
|
||||
}
|
||||
protected fun areElementsEquivalent(el1: PsiElement, el2: PsiElement): Boolean = el1.namedUnwrappedElement == el2.namedUnwrappedElement
|
||||
|
||||
[suppress("CAST_NEVER_SUCCEEDS")]
|
||||
override fun getVariants(): Array<Any> = PsiReference.EMPTY_ARRAY as Array<Any>
|
||||
@@ -81,27 +82,17 @@ abstract class AbstractJetReference<T : JetReferenceExpression>(val expression:
|
||||
|
||||
override fun resolveToDescriptors(): Collection<DeclarationDescriptor> {
|
||||
val context = AnalyzerFacadeWithCache.getContextForElement(expression)
|
||||
val targetDescriptors = getTargetDescriptors(context)
|
||||
return targetDescriptors ?: Collections.emptyList<DeclarationDescriptor>()
|
||||
return getTargetDescriptors(context)
|
||||
}
|
||||
|
||||
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))
|
||||
override fun resolveMap(): Map<DeclarationDescriptor, Collection<PsiElement>> {
|
||||
val context = AnalyzerFacadeWithCache.getContextForElement(expression)
|
||||
return getTargetDescriptors(context) keysToMap { resolveToPsiElements(context, it) }
|
||||
}
|
||||
|
||||
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
|
||||
private fun resolveToPsiElements(context: BindingContext, targetDescriptors: Collection<DeclarationDescriptor>): Collection<PsiElement> {
|
||||
if (targetDescriptors.isNotEmpty()) {
|
||||
return targetDescriptors flatMap { target -> resolveToPsiElements(context, target) }
|
||||
}
|
||||
|
||||
val labelTargets = getLabelTargets(context)
|
||||
@@ -112,19 +103,59 @@ abstract class AbstractJetReference<T : JetReferenceExpression>(val expression:
|
||||
return Collections.emptySet()
|
||||
}
|
||||
|
||||
protected open fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor>? {
|
||||
private fun resolveToPsiElements(context: BindingContext, targetDescriptor: DeclarationDescriptor): Collection<PsiElement> {
|
||||
val result = HashSet<PsiElement>()
|
||||
val project = expression.getProject()
|
||||
result.addAll(BindingContextUtils.descriptorToDeclarations(context, targetDescriptor))
|
||||
result.addAll(DescriptorToDeclarationUtil.findDeclarationsForDescriptorWithoutTrace(project, targetDescriptor))
|
||||
|
||||
if (targetDescriptor is PackageViewDescriptor) {
|
||||
val psiFacade = JavaPsiFacade.getInstance(project)
|
||||
val fqName = (targetDescriptor as PackageViewDescriptor).getFqName().asString()
|
||||
ContainerUtil.addIfNotNull(result, psiFacade.findPackage(fqName))
|
||||
ContainerUtil.addIfNotNull(result, psiFacade.findClass(fqName, GlobalSearchScope.allScope(project)))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
protected abstract fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor>
|
||||
|
||||
private fun getLabelTargets(context: BindingContext): Collection<PsiElement>? {
|
||||
val reference = expression
|
||||
if (reference !is JetReferenceExpression) {
|
||||
return null
|
||||
}
|
||||
val labelTarget = context.get(BindingContext.LABEL_TARGET, reference)
|
||||
if (labelTarget != null) {
|
||||
return listOf(labelTarget)
|
||||
}
|
||||
return context.get(BindingContext.AMBIGUOUS_LABEL_TARGET, reference)
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class JetSimpleReference<T : JetReferenceExpression>(expression: T) : AbstractJetReference<T>(expression) {
|
||||
override 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)
|
||||
return context.get(BindingContext.AMBIGUOUS_REFERENCE_TARGET, expression).orEmpty()
|
||||
}
|
||||
|
||||
private fun getLabelTargets(context: BindingContext): Collection<PsiElement>? {
|
||||
val labelTarget = context.get(BindingContext.LABEL_TARGET, expression)
|
||||
if (labelTarget != null) {
|
||||
return listOf(labelTarget)
|
||||
override fun isReferenceTo(element: PsiElement?): Boolean {
|
||||
val resolvedElement = resolve()
|
||||
if (resolvedElement == null || element == null) {
|
||||
return false
|
||||
}
|
||||
return context.get(BindingContext.AMBIGUOUS_LABEL_TARGET, expression)
|
||||
return areElementsEquivalent(element, resolvedElement)
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class JetMultiReference<T : JetElement>(expression: T) : AbstractJetReference<T>(expression) {
|
||||
override fun isReferenceTo(element: PsiElement?): Boolean {
|
||||
if (element == null) {
|
||||
return false
|
||||
}
|
||||
return multiResolve(false).map { it.getElement() }.filterNotNull().any { areElementsEquivalent(it, element) }
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@ public class JetReferenceContributor extends PsiReferenceContributor {
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext processingContext) {
|
||||
return new PsiReference[] { new JetSimpleNameReference((JetSimpleNameExpression) element) };
|
||||
return toArray(new JetSimpleNameReference((JetSimpleNameExpression) element));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -40,7 +40,7 @@ public class JetReferenceContributor extends PsiReferenceContributor {
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext processingContext) {
|
||||
return new PsiReference[] { new JetThisReference((JetThisReferenceExpression) element) };
|
||||
return toArray(new JetThisReference((JetThisReferenceExpression) element));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -49,7 +49,7 @@ public class JetReferenceContributor extends PsiReferenceContributor {
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext processingContext) {
|
||||
return JetArrayAccessReference.create((JetArrayAccessExpression) element);
|
||||
return toArray(new JetArrayAccessReference((JetArrayAccessExpression) element));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -58,7 +58,7 @@ public class JetReferenceContributor extends PsiReferenceContributor {
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext processingContext) {
|
||||
return JetInvokeFunctionReference.create((JetCallExpression) element);
|
||||
return toArray(new JetInvokeFunctionReference((JetCallExpression) element));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -67,7 +67,8 @@ public class JetReferenceContributor extends PsiReferenceContributor {
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext processingContext) {
|
||||
return JetPropertyDelegationMethodsReference.create((JetPropertyDelegate) element);
|
||||
return toArray(
|
||||
new JetPropertyDelegationMethodsReference((JetPropertyDelegate) element));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -76,8 +77,13 @@ public class JetReferenceContributor extends PsiReferenceContributor {
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext processingContext) {
|
||||
return JetForLoopInReference.create((JetForExpression) element);
|
||||
return toArray(new JetForLoopInReference((JetForExpression) element));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JetReference[] toArray(@NotNull JetReference reference) {
|
||||
return new JetReference[] {reference};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,53 +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.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementResolveResult;
|
||||
import com.intellij.psi.ResolveResult;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
import org.jetbrains.jet.plugin.codeInsight.DescriptorToDeclarationUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class JetReferenceUtil {
|
||||
private JetReferenceUtil() {}
|
||||
|
||||
public static void findPsiElements(
|
||||
@NotNull Project project,
|
||||
@NotNull BindingContext context,
|
||||
@NotNull List<ResolveResult> results,
|
||||
@Nullable DeclarationDescriptor resultingDescriptor
|
||||
) {
|
||||
if (resultingDescriptor == null) return;
|
||||
|
||||
DeclarationDescriptor original = resultingDescriptor.getOriginal();
|
||||
|
||||
for (PsiElement declaration : BindingContextUtils.descriptorToDeclarations(context, original)) {
|
||||
results.add(new PsiElementResolveResult(declaration));
|
||||
}
|
||||
|
||||
for (PsiElement declaration : DescriptorToDeclarationUtil.findDeclarationsForDescriptorWithoutTrace(project, original)) {
|
||||
results.add(new PsiElementResolveResult(declaration));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ import org.jetbrains.jet.lang.psi.JetPsiFactory;
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
public class JetSimpleNameReference extends AbstractJetReference<JetSimpleNameExpression> {
|
||||
public class JetSimpleNameReference extends JetSimpleReference<JetSimpleNameExpression> {
|
||||
|
||||
public JetSimpleNameReference(@NotNull JetSimpleNameExpression jetSimpleNameExpression) {
|
||||
super(jetSimpleNameExpression);
|
||||
|
||||
@@ -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 AbstractJetReference<JetThisReferenceExpression> {
|
||||
public class JetThisReference extends JetSimpleReference<JetThisReferenceExpression> {
|
||||
public JetThisReference(JetThisReferenceExpression expression) {
|
||||
super(expression);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user