diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java index d6c1be917f5..cbecc3a3a97 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -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 CONSTRAINT_SYSTEM_COMPLETER = new BasicWritableSlice(DO_NOTHING); WritableSlice CALL = new BasicWritableSlice(DO_NOTHING); + @KotlinSignature("val AMBIGUOUS_REFERENCE_TARGET: WritableSlice>") WritableSlice> AMBIGUOUS_REFERENCE_TARGET = new BasicWritableSlice>(DO_NOTHING); @@ -235,6 +237,7 @@ public interface BindingContext { .setFurtherLookupSlices(DECLARATIONS_TO_DESCRIPTORS).build(); WritableSlice LABEL_TARGET = Slices.sliceBuilder().build(); + @KotlinSignature("val AMBIGUOUS_LABEL_TARGET: WritableSlice>") WritableSlice> AMBIGUOUS_LABEL_TARGET = Slices.>sliceBuilder().build(); WritableSlice VALUE_PARAMETER_AS_PROPERTY = diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/lightClassUtils.kt b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/lightClassUtils.kt index 40df221c6bc..de39b1ea68a 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/lightClassUtils.kt +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/lightClassUtils.kt @@ -43,7 +43,7 @@ import com.intellij.psi.PsiClass fun JetClassOrObject.toLightClass(): PsiClass? = LightClassUtil.getPsiClass(this) -fun JetDeclaration.toLightElements(): List = +public fun JetDeclaration.toLightElements(): List = when (this) { is JetClassOrObject -> Collections.singletonList(LightClassUtil.getPsiClass(this)) is JetNamedFunction -> Collections.singletonList(LightClassUtil.getLightClassMethod(this)) @@ -59,7 +59,7 @@ fun JetDeclaration.toLightElements(): List = else -> Collections.emptyList() } -fun PsiElement.toLightMethods(): List = +public fun PsiElement.toLightMethods(): List = when (this) { is JetNamedFunction -> Collections.singletonList(LightClassUtil.getLightClassMethod(this)) is JetProperty -> LightClassUtil.getLightClassPropertyMethods(this).toList() @@ -69,7 +69,7 @@ fun PsiElement.toLightMethods(): List = 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()) if (paramList == null) return null @@ -100,7 +100,7 @@ fun JetParameter.toPsiParameter(): PsiParameter? { return method.getParameterList().getParameters()[lightParamIndex] } -fun JetTypeParameter.toPsiTypeParameters(): List { +public fun JetTypeParameter.toPsiTypeParameters(): List { val paramList = getParentByType(javaClass()) if (paramList == null) return Collections.emptyList() @@ -112,8 +112,8 @@ fun JetTypeParameter.toPsiTypeParameters(): List { } // 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()) \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/hierarchy/calls/KotlinCallerMethodsTreeStructure.java b/idea/src/org/jetbrains/jet/plugin/hierarchy/calls/KotlinCallerMethodsTreeStructure.java index d21e5972079..d6a964bfa42 100644 --- a/idea/src/org/jetbrains/jet/plugin/hierarchy/calls/KotlinCallerMethodsTreeStructure.java +++ b/idea/src/org/jetbrains/jet/plugin/hierarchy/calls/KotlinCallerMethodsTreeStructure.java @@ -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; } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportInsertHelper.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportInsertHelper.java index 4318beeb5c4..8742d1117ee 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportInsertHelper.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportInsertHelper.java @@ -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); diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinJavaSafeDeleteDelegate.kt b/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinJavaSafeDeleteDelegate.kt index 1184d98c3a6..4fdcf51a169 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinJavaSafeDeleteDelegate.kt +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinJavaSafeDeleteDelegate.kt @@ -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, parameter: PsiParameter, method: PsiMethod ) { - if (reference !is JetPsiReference) return + if (reference !is JetReference) return val element = reference.getElement() as JetElement diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinSafeDeleteProcessor.kt b/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinSafeDeleteProcessor.kt index 3367617eece..0e1e9a7ebf7 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinSafeDeleteProcessor.kt +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinSafeDeleteProcessor.kt @@ -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() diff --git a/idea/src/org/jetbrains/jet/plugin/references/JetArrayAccessReference.java b/idea/src/org/jetbrains/jet/plugin/references/JetArrayAccessReference.java index 2a2f16e3c33..9c1f4167688 100644 --- a/idea/src/org/jetbrains/jet/plugin/references/JetArrayAccessReference.java +++ b/idea/src/org/jetbrains/jet/plugin/references/JetArrayAccessReference.java @@ -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 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 getTargetDescriptors(@NotNull BindingContext context) { + protected Collection getTargetDescriptors(@NotNull BindingContext context) { List result = Lists.newArrayList(); - ResolvedCall getFunction = context.get(INDEXED_LVALUE_GET, expression); + ResolvedCall getFunction = context.get(INDEXED_LVALUE_GET, getExpression()); if (getFunction != null) { result.add(getFunction.getResultingDescriptor()); } - ResolvedCall setFunction = context.get(INDEXED_LVALUE_SET, expression); + ResolvedCall 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 getRanges() { List list = new ArrayList(); - 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); } diff --git a/idea/src/org/jetbrains/jet/plugin/references/JetInvokeFunctionReference.java b/idea/src/org/jetbrains/jet/plugin/references/JetInvokeFunctionReference.java index 46515f6f698..63cb5cb98b0 100644 --- a/idea/src/org/jetbrains/jet/plugin/references/JetInvokeFunctionReference.java +++ b/idea/src/org/jetbrains/jet/plugin/references/JetInvokeFunctionReference.java @@ -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 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 getTargetDescriptors(@NotNull BindingContext context) { - JetExpression calleeExpression = ((JetCallExpression) myExpression).getCalleeExpression(); - ResolvedCall resolvedCall = context.get(RESOLVED_CALL, calleeExpression); + protected Collection getTargetDescriptors(@NotNull BindingContext context) { + ResolvedCall resolvedCall = context.get(RESOLVED_CALL, getExpression().getCalleeExpression()); if (resolvedCall instanceof VariableAsFunctionResolvedCall) { - return Collections.singleton(((VariableAsFunctionResolvedCall) resolvedCall).getResultingDescriptor()); + return Collections.singleton(((VariableAsFunctionResolvedCall) resolvedCall).getResultingDescriptor()); } return null; } @Override public List getRanges() { - JetCallExpression callExpression = (JetCallExpression) myExpression; - List list = new ArrayList(); - 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 functionLiteralArguments = callExpression.getFunctionLiteralArguments(); + List 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()); } } diff --git a/idea/src/org/jetbrains/jet/plugin/references/JetPsiReference.java b/idea/src/org/jetbrains/jet/plugin/references/JetPsiReference.java deleted file mode 100644 index 70c07bc57fb..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/references/JetPsiReference.java +++ /dev/null @@ -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 psiElements = resolveToPsiElements(); - if (psiElements.size() == 1) { - return psiElements.iterator().next(); - } - return null; - } - - @NotNull - @Override - public String getCanonicalText() { - return ""; - } - - @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 resolveToPsiElements() { - BindingContext context = AnalyzerFacadeWithCache.getContextForElement(myExpression); - - return resolveToPsiElements(context); - } - - @NotNull - private Collection resolveToPsiElements(@NotNull BindingContext context) { - Collection targetDescriptors = getTargetDescriptors(context); - - if (targetDescriptors != null) { - assert !(targetDescriptors.isEmpty()) : "targetDescriptors is not null, but empty, for " + myExpression.getText(); - Set 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 labelTargets = getLabelTargets(context); - if (labelTargets != null) { - return labelTargets; - } - - return Collections.emptySet(); - } - - @Nullable - protected Collection 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 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); - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/references/JetReference.kt b/idea/src/org/jetbrains/jet/plugin/references/JetReference.kt new file mode 100644 index 00000000000..80c0940b96c --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/references/JetReference.kt @@ -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 +} + +abstract class AbstractJetReference(val expression: T) +: PsiPolyVariantReferenceBase(expression), JetReference { + override fun multiResolve(incompleteCode: Boolean): Array { + 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 = "" + + 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 = PsiReference.EMPTY_ARRAY as Array + + override fun isSoft(): Boolean = false + + private fun resolveToPsiElements(): Collection { + val context = AnalyzerFacadeWithCache.getContextForElement(expression) + return resolveToPsiElements(context, getTargetDescriptors(context)) + } + + override fun resolveToDescriptors(): Collection { + val context = AnalyzerFacadeWithCache.getContextForElement(expression) + val targetDescriptors = getTargetDescriptors(context) + return targetDescriptors ?: Collections.emptyList() + } + + private fun resolveToPsiElements(context: BindingContext, targetDescriptors: Collection?): Collection { + if (targetDescriptors != null) { + assert(!(targetDescriptors.isEmpty())) { "targetDescriptors is not null, but empty, for " + expression.getText() } + val result = HashSet() + 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? { + 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? { + val labelTarget = context.get(BindingContext.LABEL_TARGET, expression) + if (labelTarget != null) { + return listOf(labelTarget) + } + return context.get(BindingContext.AMBIGUOUS_LABEL_TARGET, expression) + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java b/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java index 1dd040074fa..258ad91089c 100644 --- a/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java +++ b/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java @@ -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 { 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(); } } diff --git a/idea/src/org/jetbrains/jet/plugin/references/JetThisReference.java b/idea/src/org/jetbrains/jet/plugin/references/JetThisReference.java index f7f81947d20..676f2b46713 100644 --- a/idea/src/org/jetbrains/jet/plugin/references/JetThisReference.java +++ b/idea/src/org/jetbrains/jet/plugin/references/JetThisReference.java @@ -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 { public JetThisReference(JetThisReferenceExpression expression) { super(expression); } diff --git a/idea/src/org/jetbrains/jet/plugin/search/usagesSearch/utils.kt b/idea/src/org/jetbrains/jet/plugin/search/usagesSearch/utils.kt index 4f66b40c29c..97d48450dc4 100644 --- a/idea/src/org/jetbrains/jet/plugin/search/usagesSearch/utils.kt +++ b/idea/src/org/jetbrains/jet/plugin/search/usagesSearch/utils.kt @@ -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 diff --git a/idea/tests/org/jetbrains/jet/plugin/libraries/NavigateToLibrarySourceTest.java b/idea/tests/org/jetbrains/jet/plugin/libraries/NavigateToLibrarySourceTest.java index aa916c22f03..6db239d0021 100644 --- a/idea/tests/org/jetbrains/jet/plugin/libraries/NavigateToLibrarySourceTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/libraries/NavigateToLibrarySourceTest.java @@ -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 collectInterestingReferences() { + private Collection collectInterestingReferences() { PsiFile psiFile = myFixture.getFile(); - Map referenceContainersToReferences = new LinkedHashMap(); + Map referenceContainersToReferences = new LinkedHashMap(); 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> filesToNumbersAndOffsets = new MultiMap>(); int refNumber = 1; - for (JetPsiReference ref : collectInterestingReferences()) { + for (JetReference ref : collectInterestingReferences()) { PsiElement target = ref.resolve(); assertNotNull(target); PsiElement navigationElement = target.getNavigationElement(); diff --git a/idea/tests/org/jetbrains/jet/plugin/references/BuiltInsReferenceResolverTest.java b/idea/tests/org/jetbrains/jet/plugin/references/BuiltInsReferenceResolverTest.java index 80aa2ef942e..ae3a77e6a67 100644 --- a/idea/tests/org/jetbrains/jet/plugin/references/BuiltInsReferenceResolverTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/references/BuiltInsReferenceResolverTest.java @@ -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);